1 /* $Id: points.c,v 1.2 1999/09/18 20:41:23 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 #include "GL/xf86glx.h"
50 void gl_PointSize( GLcontext
*ctx
, GLfloat size
)
53 gl_error( ctx
, GL_INVALID_VALUE
, "glPointSize" );
56 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointSize");
58 if (ctx
->Point
.Size
!= size
) {
59 ctx
->Point
.Size
= size
;
60 ctx
->TriangleCaps
&= ~DD_POINT_SIZE
;
61 if (size
!= 1.0) ctx
->TriangleCaps
|= DD_POINT_SIZE
;
62 ctx
->NewState
|= NEW_RASTER_OPS
;
68 void gl_PointParameterfvEXT( GLcontext
*ctx
, GLenum pname
,
69 const GLfloat
*params
)
71 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointParameterfvEXT");
72 if(pname
==GL_DISTANCE_ATTENUATION_EXT
) {
73 GLboolean tmp
= ctx
->Point
.Attenuated
;
74 COPY_3V(ctx
->Point
.Params
,params
);
75 ctx
->Point
.Attenuated
= (params
[0] != 1.0 ||
79 if (tmp
!= ctx
->Point
.Attenuated
) {
80 ctx
->Enabled
^= ENABLE_POINT_ATTEN
;
81 ctx
->TriangleCaps
^= DD_POINT_ATTEN
;
82 ctx
->NewState
|= NEW_RASTER_OPS
;
86 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
90 case GL_POINT_SIZE_MIN_EXT
:
91 ctx
->Point
.MinSize
=*params
;
93 case GL_POINT_SIZE_MAX_EXT
:
94 ctx
->Point
.MaxSize
=*params
;
96 case GL_POINT_FADE_THRESHOLD_SIZE_EXT
:
97 ctx
->Point
.Threshold
=*params
;
100 gl_error( ctx
, GL_INVALID_ENUM
, "glPointParameterfvEXT" );
104 ctx
->NewState
|= NEW_RASTER_OPS
;
108 /**********************************************************************/
109 /***** Rasterization *****/
110 /**********************************************************************/
114 * There are 3 pairs (RGBA, CI) of point rendering functions:
115 * 1. simple: size=1 and no special rasterization functions (fastest)
116 * 2. size1: size=1 and any rasterization functions
117 * 3. general: any size and rasterization functions (slowest)
119 * All point rendering functions take the same two arguments: first and
120 * last which specify that the points specified by VB[first] through
121 * VB[last] are to be rendered.
129 * CI points with size == 1.0
131 void size1_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
133 struct vertex_buffer
*VB
= ctx
->VB
;
134 struct pixel_buffer
*PB
= ctx
->PB
;
136 GLint
*pbx
= PB
->x
, *pby
= PB
->y
;
137 GLdepth
*pbz
= PB
->z
;
139 GLuint pbcount
= PB
->count
;
142 win
= &VB
->Win
.data
[first
][0];
143 for (i
=first
;i
<=last
;i
++) {
144 if (VB
->ClipMask
[i
]==0) {
145 pbx
[pbcount
] = (GLint
) win
[0];
146 pby
[pbcount
] = (GLint
) win
[1];
147 pbz
[pbcount
] = (GLint
) (win
[2] + ctx
->PointZoffset
);
148 pbi
[pbcount
] = VB
->IndexPtr
->data
[i
];
154 PB_CHECK_FLUSH(ctx
, PB
);
160 * RGBA points with size == 1.0
162 static void size1_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
164 struct vertex_buffer
*VB
= ctx
->VB
;
165 struct pixel_buffer
*PB
= ctx
->PB
;
168 for (i
=first
;i
<=last
;i
++) {
169 if (VB
->ClipMask
[i
]==0) {
171 GLint red
, green
, blue
, alpha
;
173 x
= (GLint
) VB
->Win
.data
[i
][0];
174 y
= (GLint
) VB
->Win
.data
[i
][1];
175 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
177 red
= VB
->ColorPtr
->data
[i
][0];
178 green
= VB
->ColorPtr
->data
[i
][1];
179 blue
= VB
->ColorPtr
->data
[i
][2];
180 alpha
= VB
->ColorPtr
->data
[i
][3];
182 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
);
185 PB_CHECK_FLUSH(ctx
,PB
);
193 static void general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
195 struct vertex_buffer
*VB
= ctx
->VB
;
196 struct pixel_buffer
*PB
= ctx
->PB
;
198 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
199 GLint radius
= isize
>> 1;
201 for (i
=first
;i
<=last
;i
++) {
202 if (VB
->ClipMask
[i
]==0) {
204 GLint x0
, x1
, y0
, y1
;
207 x
= (GLint
) VB
->Win
.data
[i
][0];
208 y
= (GLint
) VB
->Win
.data
[i
][1];
209 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
220 x0
= (GLint
) (x
+ 1.5F
) - radius
;
222 y0
= (GLint
) (y
+ 1.5F
) - radius
;
226 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
228 for (iy
=y0
;iy
<=y1
;iy
++) {
229 for (ix
=x0
;ix
<=x1
;ix
++) {
230 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
233 PB_CHECK_FLUSH(ctx
,PB
);
240 * General RGBA points.
242 static void general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
244 struct vertex_buffer
*VB
= ctx
->VB
;
245 struct pixel_buffer
*PB
= ctx
->PB
;
247 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
248 GLint radius
= isize
>> 1;
250 for (i
=first
;i
<=last
;i
++) {
251 if (VB
->ClipMask
[i
]==0) {
253 GLint x0
, x1
, y0
, y1
;
256 x
= (GLint
) VB
->Win
.data
[i
][0];
257 y
= (GLint
) VB
->Win
.data
[i
][1];
258 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
269 x0
= (GLint
) (x
+ 1.5F
) - radius
;
271 y0
= (GLint
) (y
+ 1.5F
) - radius
;
275 PB_SET_COLOR( ctx
, PB
,
276 VB
->ColorPtr
->data
[i
][0],
277 VB
->ColorPtr
->data
[i
][1],
278 VB
->ColorPtr
->data
[i
][2],
279 VB
->ColorPtr
->data
[i
][3] );
281 for (iy
=y0
;iy
<=y1
;iy
++) {
282 for (ix
=x0
;ix
<=x1
;ix
++) {
283 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
286 PB_CHECK_FLUSH(ctx
,PB
);
295 * Textured RGBA points.
297 static void textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
299 struct vertex_buffer
*VB
= ctx
->VB
;
300 struct pixel_buffer
*PB
= ctx
->PB
;
303 for (i
=first
;i
<=last
;i
++) {
304 if (VB
->ClipMask
[i
]==0) {
306 GLint x0
, x1
, y0
, y1
;
309 GLint red
, green
, blue
, alpha
;
312 x
= (GLint
) VB
->Win
.data
[i
][0];
313 y
= (GLint
) VB
->Win
.data
[i
][1];
314 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
317 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
332 x0
= (GLint
) (x
+ 1.5F
) - radius
;
334 y0
= (GLint
) (y
+ 1.5F
) - radius
;
338 red
= VB
->ColorPtr
->data
[i
][0];
339 green
= VB
->ColorPtr
->data
[i
][1];
340 blue
= VB
->ColorPtr
->data
[i
][2];
341 alpha
= VB
->ColorPtr
->data
[i
][3];
343 switch (VB
->TexCoordPtr
[0]->size
) {
345 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
346 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
347 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
350 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
351 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
352 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
355 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
356 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
360 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
369 /* don't think this is needed
370 PB_SET_COLOR( red, green, blue, alpha );
373 for (iy
=y0
;iy
<=y1
;iy
++) {
374 for (ix
=x0
;ix
<=x1
;ix
++) {
375 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
378 PB_CHECK_FLUSH(ctx
,PB
);
385 * Multitextured RGBA points.
387 static void multitextured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
389 struct vertex_buffer
*VB
= ctx
->VB
;
390 struct pixel_buffer
*PB
= ctx
->PB
;
393 for (i
=first
;i
<=last
;i
++) {
394 if (VB
->ClipMask
[i
]==0) {
396 GLint x0
, x1
, y0
, y1
;
399 GLint red
, green
, blue
, alpha
;
403 x
= (GLint
) VB
->Win
.data
[i
][0];
404 y
= (GLint
) VB
->Win
.data
[i
][1];
405 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
408 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
423 x0
= (GLint
) (x
+ 1.5F
) - radius
;
425 y0
= (GLint
) (y
+ 1.5F
) - radius
;
429 red
= VB
->ColorPtr
->data
[i
][0];
430 green
= VB
->ColorPtr
->data
[i
][1];
431 blue
= VB
->ColorPtr
->data
[i
][2];
432 alpha
= VB
->ColorPtr
->data
[i
][3];
434 switch (VB
->TexCoordPtr
[0]->size
) {
436 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
437 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
438 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
441 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
442 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
443 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
446 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
447 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
451 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
457 switch (VB
->TexCoordPtr
[1]->size
) {
459 s1
= VB
->TexCoordPtr
[1]->data
[i
][0]/VB
->TexCoordPtr
[1]->data
[i
][3];
460 t1
= VB
->TexCoordPtr
[1]->data
[i
][1]/VB
->TexCoordPtr
[1]->data
[i
][3];
461 u1
= VB
->TexCoordPtr
[1]->data
[i
][2]/VB
->TexCoordPtr
[1]->data
[i
][3];
464 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
465 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
466 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
469 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
470 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
474 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
480 for (iy
=y0
;iy
<=y1
;iy
++) {
481 for (ix
=x0
;ix
<=x1
;ix
++) {
482 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
485 PB_CHECK_FLUSH(ctx
,PB
);
494 * Antialiased points with or without texture mapping.
496 static void antialiased_rgba_points( GLcontext
*ctx
,
497 GLuint first
, GLuint last
)
499 struct vertex_buffer
*VB
= ctx
->VB
;
500 struct pixel_buffer
*PB
= ctx
->PB
;
502 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
504 radius
= CLAMP( ctx
->Point
.Size
, MIN_POINT_SIZE
, MAX_POINT_SIZE
) * 0.5F
;
505 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
506 rmax
= radius
+ 0.7071F
;
509 cscale
= 256.0F
/ (rmax2
-rmin2
);
511 if (ctx
->Texture
.ReallyEnabled
) {
512 for (i
=first
;i
<=last
;i
++) {
513 if (VB
->ClipMask
[i
]==0) {
514 GLint xmin
, ymin
, xmax
, ymax
;
516 GLint red
, green
, blue
, alpha
;
520 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
521 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
522 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
523 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
524 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
526 red
= VB
->ColorPtr
->data
[i
][0];
527 green
= VB
->ColorPtr
->data
[i
][1];
528 blue
= VB
->ColorPtr
->data
[i
][2];
530 switch (VB
->TexCoordPtr
[0]->size
) {
532 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
533 VB
->TexCoordPtr
[0]->data
[i
][3]);
534 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
535 VB
->TexCoordPtr
[0]->data
[i
][3]);
536 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
537 VB
->TexCoordPtr
[0]->data
[i
][3]);
540 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
541 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
542 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
545 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
546 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
550 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
556 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
557 /* Multitextured! This is probably a slow enough path that
558 there's no reason to specialize the multitexture case. */
559 switch (VB
->TexCoordPtr
[1]->size
) {
561 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
562 VB
->TexCoordPtr
[1]->data
[i
][3]);
563 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
564 VB
->TexCoordPtr
[1]->data
[i
][3]);
565 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
566 VB
->TexCoordPtr
[1]->data
[i
][3]);
569 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
570 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
571 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
574 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
575 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
579 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
586 for (y
=ymin
;y
<=ymax
;y
++) {
587 for (x
=xmin
;x
<=xmax
;x
++) {
588 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
589 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
590 GLfloat dist2
= dx
*dx
+ dy
*dy
;
592 alpha
= VB
->ColorPtr
->data
[i
][3];
594 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
595 /* coverage is in [0,256] */
596 alpha
= (alpha
* coverage
) >> 8;
598 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
599 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
600 alpha
, s
, t
, u
, s1
, t1
, u1
);
602 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
609 PB_CHECK_FLUSH(ctx
,PB
);
614 /* Not texture mapped */
615 for (i
=first
;i
<=last
;i
++) {
616 if (VB
->ClipMask
[i
]==0) {
617 GLint xmin
, ymin
, xmax
, ymax
;
619 GLint red
, green
, blue
, alpha
;
621 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
622 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
623 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
624 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
625 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
627 red
= VB
->ColorPtr
->data
[i
][0];
628 green
= VB
->ColorPtr
->data
[i
][1];
629 blue
= VB
->ColorPtr
->data
[i
][2];
631 for (y
=ymin
;y
<=ymax
;y
++) {
632 for (x
=xmin
;x
<=xmax
;x
++) {
633 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
634 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
635 GLfloat dist2
= dx
*dx
+ dy
*dy
;
637 alpha
= VB
->ColorPtr
->data
[i
][3];
639 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
640 /* coverage is in [0,256] */
641 alpha
= (alpha
* coverage
) >> 8;
643 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
,
648 PB_CHECK_FLUSH(ctx
,PB
);
657 * Null rasterizer for measuring transformation speed.
659 static void null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
668 /* Definition of the functions for GL_EXT_point_parameters */
670 /* Calculates the distance attenuation formula of a vector of points in
671 * eye space coordinates
673 static void dist3(GLfloat
*out
, GLuint first
, GLuint last
,
674 const GLcontext
*ctx
, const GLvector4f
*v
)
676 GLuint stride
= v
->stride
;
677 GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
680 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) )
682 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
683 out
[i
] = 1/(ctx
->Point
.Params
[0]+
684 dist
* (ctx
->Point
.Params
[1] +
685 dist
* ctx
->Point
.Params
[2]));
689 static void dist2(GLfloat
*out
, GLuint first
, GLuint last
,
690 const GLcontext
*ctx
, const GLvector4f
*v
)
692 GLuint stride
= v
->stride
;
693 GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
696 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) )
698 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
699 out
[i
] = 1/(ctx
->Point
.Params
[0]+
700 dist
* (ctx
->Point
.Params
[1] +
701 dist
* ctx
->Point
.Params
[2]));
706 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
707 const GLcontext
*ctx
, const GLvector4f
*v
);
710 static dist_func eye_dist_tab
[5] = {
719 static void clip_dist(GLfloat
*out
, GLuint first
, GLuint last
,
720 const GLcontext
*ctx
, GLvector4f
*clip
)
722 /* this is never called */
723 gl_problem(NULL
, "clip_dist() called - dead code!\n");
733 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
734 const GLuint stride
= clip_vec
->stride
;
736 for (i
= first
; i
<= last
; i
++ )
738 GLfloat dist
= win
[i
][2];
739 out
[i
] = 1/(ctx
->Point
.Params
[0]+
740 dist
* (ctx
->Point
.Params
[1] +
741 dist
* ctx
->Point
.Params
[2]));
749 * Distance Attenuated General CI points.
751 static void dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
,
754 struct vertex_buffer
*VB
= ctx
->VB
;
755 struct pixel_buffer
*PB
= ctx
->PB
;
758 GLfloat dist
[VB_SIZE
];
759 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
761 if (ctx
->NeedEyeCoords
)
762 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
764 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
766 for (i
=first
;i
<=last
;i
++) {
767 if (VB
->ClipMask
[i
]==0) {
769 GLint x0
, x1
, y0
, y1
;
773 x
= (GLint
) VB
->Win
.data
[i
][0];
774 y
= (GLint
) VB
->Win
.data
[i
][1];
775 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
778 if(dsize
>=ctx
->Point
.Threshold
) {
779 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
781 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
794 x0
= (GLint
) (x
+ 1.5F
) - radius
;
796 y0
= (GLint
) (y
+ 1.5F
) - radius
;
800 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
802 for (iy
=y0
;iy
<=y1
;iy
++) {
803 for (ix
=x0
;ix
<=x1
;ix
++) {
804 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
807 PB_CHECK_FLUSH(ctx
,PB
);
813 * Distance Attenuated General RGBA points.
815 static void dist_atten_general_rgba_points( GLcontext
*ctx
, GLuint first
,
818 struct vertex_buffer
*VB
= ctx
->VB
;
819 struct pixel_buffer
*PB
= ctx
->PB
;
823 GLfloat dist
[VB_SIZE
];
824 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
826 if (ctx
->NeedEyeCoords
)
827 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
829 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
831 for (i
=first
;i
<=last
;i
++) {
832 if (VB
->ClipMask
[i
]==0) {
834 GLint x0
, x1
, y0
, y1
;
838 x
= (GLint
) VB
->Win
.data
[i
][0];
839 y
= (GLint
) VB
->Win
.data
[i
][1];
840 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
842 if (dsize
>= ctx
->Point
.Threshold
) {
843 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
844 alpha
= VB
->ColorPtr
->data
[i
][3];
847 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
848 dsize
/= ctx
->Point
.Threshold
;
849 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
862 x0
= (GLint
) (x
+ 1.5F
) - radius
;
864 y0
= (GLint
) (y
+ 1.5F
) - radius
;
868 PB_SET_COLOR( ctx
, PB
,
869 VB
->ColorPtr
->data
[i
][0],
870 VB
->ColorPtr
->data
[i
][1],
871 VB
->ColorPtr
->data
[i
][2],
874 for (iy
=y0
;iy
<=y1
;iy
++) {
875 for (ix
=x0
;ix
<=x1
;ix
++) {
876 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
879 PB_CHECK_FLUSH(ctx
,PB
);
885 * Distance Attenuated Textured RGBA points.
887 static void dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
,
890 struct vertex_buffer
*VB
= ctx
->VB
;
891 struct pixel_buffer
*PB
= ctx
->PB
;
894 GLfloat dist
[VB_SIZE
];
895 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
897 if (ctx
->NeedEyeCoords
)
898 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
900 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
902 for (i
=first
;i
<=last
;i
++) {
903 if (VB
->ClipMask
[i
]==0) {
905 GLint x0
, x1
, y0
, y1
;
908 GLint red
, green
, blue
, alpha
;
912 x
= (GLint
) VB
->Win
.data
[i
][0];
913 y
= (GLint
) VB
->Win
.data
[i
][1];
914 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
917 if(dsize
>=ctx
->Point
.Threshold
) {
918 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
919 alpha
=VB
->ColorPtr
->data
[i
][3];
921 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
922 dsize
/=ctx
->Point
.Threshold
;
923 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
940 x0
= (GLint
) (x
+ 1.5F
) - radius
;
942 y0
= (GLint
) (y
+ 1.5F
) - radius
;
946 red
= VB
->ColorPtr
->data
[i
][0];
947 green
= VB
->ColorPtr
->data
[i
][1];
948 blue
= VB
->ColorPtr
->data
[i
][2];
950 switch (VB
->TexCoordPtr
[0]->size
) {
952 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
953 VB
->TexCoordPtr
[0]->data
[i
][3]);
954 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
955 VB
->TexCoordPtr
[0]->data
[i
][3]);
956 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
957 VB
->TexCoordPtr
[0]->data
[i
][3]);
960 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
961 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
962 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
965 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
966 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
970 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
976 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
977 /* Multitextured! This is probably a slow enough path that
978 there's no reason to specialize the multitexture case. */
979 switch (VB
->TexCoordPtr
[1]->size
) {
981 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
982 VB
->TexCoordPtr
[1]->data
[i
][3] );
983 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
984 VB
->TexCoordPtr
[1]->data
[i
][3] );
985 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
986 VB
->TexCoordPtr
[1]->data
[i
][3] );
989 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
990 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
991 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
994 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
995 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
999 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1006 /* don't think this is needed
1007 PB_SET_COLOR( red, green, blue, alpha );
1010 for (iy
=y0
;iy
<=y1
;iy
++) {
1011 for (ix
=x0
;ix
<=x1
;ix
++) {
1012 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1013 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1015 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
1019 PB_CHECK_FLUSH(ctx
,PB
);
1025 * Distance Attenuated Antialiased points with or without texture mapping.
1027 static void dist_atten_antialiased_rgba_points( GLcontext
*ctx
,
1028 GLuint first
, GLuint last
)
1030 struct vertex_buffer
*VB
= ctx
->VB
;
1031 struct pixel_buffer
*PB
= ctx
->PB
;
1033 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
1034 GLfloat psize
,dsize
,alphaf
;
1035 GLfloat dist
[VB_SIZE
];
1036 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
1038 if (ctx
->NeedEyeCoords
)
1039 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
1041 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
1043 if (ctx
->Texture
.ReallyEnabled
) {
1044 for (i
=first
;i
<=last
;i
++) {
1045 if (VB
->ClipMask
[i
]==0) {
1046 GLint xmin
, ymin
, xmax
, ymax
;
1048 GLint red
, green
, blue
, alpha
;
1052 dsize
=psize
*dist
[i
];
1053 if(dsize
>=ctx
->Point
.Threshold
) {
1054 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1057 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1058 dsize
/=ctx
->Point
.Threshold
;
1059 alphaf
=(dsize
*dsize
);
1061 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1062 rmax
= radius
+ 0.7071F
;
1065 cscale
= 256.0F
/ (rmax2
-rmin2
);
1067 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1068 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1069 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1070 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1071 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1073 red
= VB
->ColorPtr
->data
[i
][0];
1074 green
= VB
->ColorPtr
->data
[i
][1];
1075 blue
= VB
->ColorPtr
->data
[i
][2];
1077 switch (VB
->TexCoordPtr
[0]->size
) {
1079 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
1080 VB
->TexCoordPtr
[0]->data
[i
][3]);
1081 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
1082 VB
->TexCoordPtr
[0]->data
[i
][3]);
1083 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
1084 VB
->TexCoordPtr
[0]->data
[i
][3]);
1087 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1088 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1089 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
1092 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1093 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1097 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1103 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1104 /* Multitextured! This is probably a slow enough path that
1105 there's no reason to specialize the multitexture case. */
1106 switch (VB
->TexCoordPtr
[1]->size
) {
1108 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1109 VB
->TexCoordPtr
[1]->data
[i
][3] );
1110 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1111 VB
->TexCoordPtr
[1]->data
[i
][3] );
1112 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1113 VB
->TexCoordPtr
[1]->data
[i
][3] );
1116 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1117 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1118 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1121 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1122 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1126 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1133 for (y
=ymin
;y
<=ymax
;y
++) {
1134 for (x
=xmin
;x
<=xmax
;x
++) {
1135 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1136 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1137 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1139 alpha
= VB
->ColorPtr
->data
[i
][3];
1141 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1142 /* coverage is in [0,256] */
1143 alpha
= (alpha
* coverage
) >> 8;
1145 alpha
= (GLint
) (alpha
* alphaf
);
1146 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1147 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1149 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
);
1154 PB_CHECK_FLUSH(ctx
,PB
);
1159 /* Not texture mapped */
1160 for (i
=first
;i
<=last
;i
++) {
1161 if (VB
->ClipMask
[i
]==0) {
1162 GLint xmin
, ymin
, xmax
, ymax
;
1164 GLint red
, green
, blue
, alpha
;
1166 dsize
=psize
*dist
[i
];
1167 if(dsize
>=ctx
->Point
.Threshold
) {
1168 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1171 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1172 dsize
/=ctx
->Point
.Threshold
;
1173 alphaf
=(dsize
*dsize
);
1175 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1176 rmax
= radius
+ 0.7071F
;
1179 cscale
= 256.0F
/ (rmax2
-rmin2
);
1181 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1182 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1183 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1184 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1185 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1187 red
= VB
->ColorPtr
->data
[i
][0];
1188 green
= VB
->ColorPtr
->data
[i
][1];
1189 blue
= VB
->ColorPtr
->data
[i
][2];
1191 for (y
=ymin
;y
<=ymax
;y
++) {
1192 for (x
=xmin
;x
<=xmax
;x
++) {
1193 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1194 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1195 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1197 alpha
= VB
->ColorPtr
->data
[i
][3];
1199 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1200 /* coverage is in [0,256] */
1201 alpha
= (alpha
* coverage
) >> 8;
1203 alpha
= (GLint
) (alpha
* alphaf
);
1204 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
)
1209 PB_CHECK_FLUSH(ctx
,PB
);
1217 * Examine the current context to determine which point drawing function
1220 void gl_set_point_function( GLcontext
*ctx
)
1222 GLboolean rgbmode
= ctx
->Visual
->RGBAflag
;
1224 if (ctx
->RenderMode
==GL_RENDER
) {
1225 if (ctx
->NoRaster
) {
1226 ctx
->Driver
.PointsFunc
= null_points
;
1229 if (ctx
->Driver
.PointsFunc
) {
1230 /* Device driver will draw points. */
1231 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1235 if (!ctx
->Point
.Attenuated
) {
1236 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1237 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1239 else if (ctx
->Texture
.ReallyEnabled
) {
1240 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1241 ctx
->Driver
.PointsFunc
= multitextured_rgba_points
;
1244 ctx
->Driver
.PointsFunc
= textured_rgba_points
;
1247 else if (ctx
->Point
.Size
==1.0) {
1248 /* size=1, any raster ops */
1250 ctx
->Driver
.PointsFunc
= size1_rgba_points
;
1252 ctx
->Driver
.PointsFunc
= size1_ci_points
;
1255 /* every other kind of point rendering */
1257 ctx
->Driver
.PointsFunc
= general_rgba_points
;
1259 ctx
->Driver
.PointsFunc
= general_ci_points
;
1262 else if(ctx
->Point
.SmoothFlag
&& rgbmode
) {
1263 ctx
->Driver
.PointsFunc
= dist_atten_antialiased_rgba_points
;
1265 else if (ctx
->Texture
.ReallyEnabled
) {
1266 ctx
->Driver
.PointsFunc
= dist_atten_textured_rgba_points
;
1269 /* every other kind of point rendering */
1271 ctx
->Driver
.PointsFunc
= dist_atten_general_rgba_points
;
1273 ctx
->Driver
.PointsFunc
= dist_atten_general_ci_points
;
1276 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
1277 ctx
->Driver
.PointsFunc
= gl_feedback_points
;
1280 /* GL_SELECT mode */
1281 ctx
->Driver
.PointsFunc
= gl_select_points
;