1 /* $Id: points.c,v 1.4 1999/10/21 12:45:53 brianp 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.
26 /* $XFree86: xc/lib/GL/mesa/src/points.c,v 1.4 1999/04/04 00:20:29 dawes Exp $ */
36 #include "GL/xf86glx.h"
53 void gl_PointSize( GLcontext
*ctx
, GLfloat size
)
56 gl_error( ctx
, GL_INVALID_VALUE
, "glPointSize" );
59 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointSize");
61 if (ctx
->Point
.Size
!= size
) {
62 ctx
->Point
.Size
= size
;
63 ctx
->TriangleCaps
&= ~DD_POINT_SIZE
;
64 if (size
!= 1.0) ctx
->TriangleCaps
|= DD_POINT_SIZE
;
65 ctx
->NewState
|= NEW_RASTER_OPS
;
71 void gl_PointParameterfvEXT( GLcontext
*ctx
, GLenum pname
,
72 const GLfloat
*params
)
74 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointParameterfvEXT");
75 if(pname
==GL_DISTANCE_ATTENUATION_EXT
) {
76 GLboolean tmp
= ctx
->Point
.Attenuated
;
77 COPY_3V(ctx
->Point
.Params
,params
);
78 ctx
->Point
.Attenuated
= (params
[0] != 1.0 ||
82 if (tmp
!= ctx
->Point
.Attenuated
) {
83 ctx
->Enabled
^= ENABLE_POINT_ATTEN
;
84 ctx
->TriangleCaps
^= DD_POINT_ATTEN
;
85 ctx
->NewState
|= NEW_RASTER_OPS
;
89 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
93 case GL_POINT_SIZE_MIN_EXT
:
94 ctx
->Point
.MinSize
=*params
;
96 case GL_POINT_SIZE_MAX_EXT
:
97 ctx
->Point
.MaxSize
=*params
;
99 case GL_POINT_FADE_THRESHOLD_SIZE_EXT
:
100 ctx
->Point
.Threshold
=*params
;
103 gl_error( ctx
, GL_INVALID_ENUM
, "glPointParameterfvEXT" );
107 ctx
->NewState
|= NEW_RASTER_OPS
;
111 /**********************************************************************/
112 /***** Rasterization *****/
113 /**********************************************************************/
117 * There are 3 pairs (RGBA, CI) of point rendering functions:
118 * 1. simple: size=1 and no special rasterization functions (fastest)
119 * 2. size1: size=1 and any rasterization functions
120 * 3. general: any size and rasterization functions (slowest)
122 * All point rendering functions take the same two arguments: first and
123 * last which specify that the points specified by VB[first] through
124 * VB[last] are to be rendered.
132 * CI points with size == 1.0
134 static void size1_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
136 struct vertex_buffer
*VB
= ctx
->VB
;
137 struct pixel_buffer
*PB
= ctx
->PB
;
139 GLint
*pbx
= PB
->x
, *pby
= PB
->y
;
140 GLdepth
*pbz
= PB
->z
;
142 GLuint pbcount
= PB
->count
;
145 win
= &VB
->Win
.data
[first
][0];
146 for (i
=first
;i
<=last
;i
++) {
147 if (VB
->ClipMask
[i
]==0) {
148 pbx
[pbcount
] = (GLint
) win
[0];
149 pby
[pbcount
] = (GLint
) win
[1];
150 pbz
[pbcount
] = (GLint
) (win
[2] + ctx
->PointZoffset
);
151 pbi
[pbcount
] = VB
->IndexPtr
->data
[i
];
157 PB_CHECK_FLUSH(ctx
, PB
);
163 * RGBA points with size == 1.0
165 static void size1_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
167 struct vertex_buffer
*VB
= ctx
->VB
;
168 struct pixel_buffer
*PB
= ctx
->PB
;
171 for (i
=first
;i
<=last
;i
++) {
172 if (VB
->ClipMask
[i
]==0) {
174 GLint red
, green
, blue
, alpha
;
176 x
= (GLint
) VB
->Win
.data
[i
][0];
177 y
= (GLint
) VB
->Win
.data
[i
][1];
178 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
180 red
= VB
->ColorPtr
->data
[i
][0];
181 green
= VB
->ColorPtr
->data
[i
][1];
182 blue
= VB
->ColorPtr
->data
[i
][2];
183 alpha
= VB
->ColorPtr
->data
[i
][3];
185 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
);
188 PB_CHECK_FLUSH(ctx
,PB
);
196 static void general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
198 struct vertex_buffer
*VB
= ctx
->VB
;
199 struct pixel_buffer
*PB
= ctx
->PB
;
201 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
202 GLint radius
= isize
>> 1;
204 for (i
=first
;i
<=last
;i
++) {
205 if (VB
->ClipMask
[i
]==0) {
207 GLint x0
, x1
, y0
, y1
;
210 x
= (GLint
) VB
->Win
.data
[i
][0];
211 y
= (GLint
) VB
->Win
.data
[i
][1];
212 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
223 x0
= (GLint
) (x
+ 1.5F
) - radius
;
225 y0
= (GLint
) (y
+ 1.5F
) - radius
;
229 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
231 for (iy
=y0
;iy
<=y1
;iy
++) {
232 for (ix
=x0
;ix
<=x1
;ix
++) {
233 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
236 PB_CHECK_FLUSH(ctx
,PB
);
243 * General RGBA points.
245 static void general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
247 struct vertex_buffer
*VB
= ctx
->VB
;
248 struct pixel_buffer
*PB
= ctx
->PB
;
250 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
251 GLint radius
= isize
>> 1;
253 for (i
=first
;i
<=last
;i
++) {
254 if (VB
->ClipMask
[i
]==0) {
256 GLint x0
, x1
, y0
, y1
;
259 x
= (GLint
) VB
->Win
.data
[i
][0];
260 y
= (GLint
) VB
->Win
.data
[i
][1];
261 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
272 x0
= (GLint
) (x
+ 1.5F
) - radius
;
274 y0
= (GLint
) (y
+ 1.5F
) - radius
;
278 PB_SET_COLOR( ctx
, PB
,
279 VB
->ColorPtr
->data
[i
][0],
280 VB
->ColorPtr
->data
[i
][1],
281 VB
->ColorPtr
->data
[i
][2],
282 VB
->ColorPtr
->data
[i
][3] );
284 for (iy
=y0
;iy
<=y1
;iy
++) {
285 for (ix
=x0
;ix
<=x1
;ix
++) {
286 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
289 PB_CHECK_FLUSH(ctx
,PB
);
298 * Textured RGBA points.
300 static void textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
302 struct vertex_buffer
*VB
= ctx
->VB
;
303 struct pixel_buffer
*PB
= ctx
->PB
;
306 for (i
=first
;i
<=last
;i
++) {
307 if (VB
->ClipMask
[i
]==0) {
309 GLint x0
, x1
, y0
, y1
;
312 GLint red
, green
, blue
, alpha
;
315 x
= (GLint
) VB
->Win
.data
[i
][0];
316 y
= (GLint
) VB
->Win
.data
[i
][1];
317 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
320 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
335 x0
= (GLint
) (x
+ 1.5F
) - radius
;
337 y0
= (GLint
) (y
+ 1.5F
) - radius
;
341 red
= VB
->ColorPtr
->data
[i
][0];
342 green
= VB
->ColorPtr
->data
[i
][1];
343 blue
= VB
->ColorPtr
->data
[i
][2];
344 alpha
= VB
->ColorPtr
->data
[i
][3];
346 switch (VB
->TexCoordPtr
[0]->size
) {
348 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
349 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
350 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
353 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
354 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
355 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
358 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
359 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
363 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
368 /* should never get here */
370 gl_problem(ctx
, "unexpected texcoord size in textured_rgba_points()");
373 /* don't think this is needed
374 PB_SET_COLOR( red, green, blue, alpha );
377 for (iy
=y0
;iy
<=y1
;iy
++) {
378 for (ix
=x0
;ix
<=x1
;ix
++) {
379 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
382 PB_CHECK_FLUSH(ctx
,PB
);
389 * Multitextured RGBA points.
391 static void multitextured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
393 struct vertex_buffer
*VB
= ctx
->VB
;
394 struct pixel_buffer
*PB
= ctx
->PB
;
397 for (i
=first
;i
<=last
;i
++) {
398 if (VB
->ClipMask
[i
]==0) {
400 GLint x0
, x1
, y0
, y1
;
403 GLint red
, green
, blue
, alpha
;
407 x
= (GLint
) VB
->Win
.data
[i
][0];
408 y
= (GLint
) VB
->Win
.data
[i
][1];
409 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
412 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
427 x0
= (GLint
) (x
+ 1.5F
) - radius
;
429 y0
= (GLint
) (y
+ 1.5F
) - radius
;
433 red
= VB
->ColorPtr
->data
[i
][0];
434 green
= VB
->ColorPtr
->data
[i
][1];
435 blue
= VB
->ColorPtr
->data
[i
][2];
436 alpha
= VB
->ColorPtr
->data
[i
][3];
438 switch (VB
->TexCoordPtr
[0]->size
) {
440 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
441 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
442 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
445 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
446 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
447 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
450 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
451 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
455 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
460 /* should never get here */
462 gl_problem(ctx
, "unexpected texcoord size in multitextured_rgba_points()");
465 switch (VB
->TexCoordPtr
[1]->size
) {
467 s1
= VB
->TexCoordPtr
[1]->data
[i
][0]/VB
->TexCoordPtr
[1]->data
[i
][3];
468 t1
= VB
->TexCoordPtr
[1]->data
[i
][1]/VB
->TexCoordPtr
[1]->data
[i
][3];
469 u1
= VB
->TexCoordPtr
[1]->data
[i
][2]/VB
->TexCoordPtr
[1]->data
[i
][3];
472 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
473 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
474 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
477 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
478 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
482 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
487 /* should never get here */
489 gl_problem(ctx
, "unexpected texcoord size in multitextured_rgba_points()");
492 for (iy
=y0
;iy
<=y1
;iy
++) {
493 for (ix
=x0
;ix
<=x1
;ix
++) {
494 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
497 PB_CHECK_FLUSH(ctx
,PB
);
506 * Antialiased points with or without texture mapping.
508 static void antialiased_rgba_points( GLcontext
*ctx
,
509 GLuint first
, GLuint last
)
511 struct vertex_buffer
*VB
= ctx
->VB
;
512 struct pixel_buffer
*PB
= ctx
->PB
;
514 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
516 radius
= CLAMP( ctx
->Point
.Size
, MIN_POINT_SIZE
, MAX_POINT_SIZE
) * 0.5F
;
517 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
518 rmax
= radius
+ 0.7071F
;
521 cscale
= 256.0F
/ (rmax2
-rmin2
);
523 if (ctx
->Texture
.ReallyEnabled
) {
524 for (i
=first
;i
<=last
;i
++) {
525 if (VB
->ClipMask
[i
]==0) {
526 GLint xmin
, ymin
, xmax
, ymax
;
528 GLint red
, green
, blue
, alpha
;
532 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
533 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
534 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
535 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
536 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
538 red
= VB
->ColorPtr
->data
[i
][0];
539 green
= VB
->ColorPtr
->data
[i
][1];
540 blue
= VB
->ColorPtr
->data
[i
][2];
542 switch (VB
->TexCoordPtr
[0]->size
) {
544 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
545 VB
->TexCoordPtr
[0]->data
[i
][3]);
546 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
547 VB
->TexCoordPtr
[0]->data
[i
][3]);
548 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
549 VB
->TexCoordPtr
[0]->data
[i
][3]);
552 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
553 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
554 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
557 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
558 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
562 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
567 /* should never get here */
569 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
572 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
573 /* Multitextured! This is probably a slow enough path that
574 there's no reason to specialize the multitexture case. */
575 switch (VB
->TexCoordPtr
[1]->size
) {
577 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
578 VB
->TexCoordPtr
[1]->data
[i
][3]);
579 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
580 VB
->TexCoordPtr
[1]->data
[i
][3]);
581 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
582 VB
->TexCoordPtr
[1]->data
[i
][3]);
585 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
586 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
587 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
590 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
591 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
595 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
600 /* should never get here */
602 gl_problem(ctx
, "unexpected texcoord size in antialiased_rgba_points()");
606 for (y
=ymin
;y
<=ymax
;y
++) {
607 for (x
=xmin
;x
<=xmax
;x
++) {
608 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
609 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
610 GLfloat dist2
= dx
*dx
+ dy
*dy
;
612 alpha
= VB
->ColorPtr
->data
[i
][3];
614 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
615 /* coverage is in [0,256] */
616 alpha
= (alpha
* coverage
) >> 8;
618 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
619 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
620 alpha
, s
, t
, u
, s1
, t1
, u1
);
622 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
629 PB_CHECK_FLUSH(ctx
,PB
);
634 /* Not texture mapped */
635 for (i
=first
;i
<=last
;i
++) {
636 if (VB
->ClipMask
[i
]==0) {
637 GLint xmin
, ymin
, xmax
, ymax
;
639 GLint red
, green
, blue
, alpha
;
641 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
642 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
643 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
644 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
645 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
647 red
= VB
->ColorPtr
->data
[i
][0];
648 green
= VB
->ColorPtr
->data
[i
][1];
649 blue
= VB
->ColorPtr
->data
[i
][2];
651 for (y
=ymin
;y
<=ymax
;y
++) {
652 for (x
=xmin
;x
<=xmax
;x
++) {
653 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
654 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
655 GLfloat dist2
= dx
*dx
+ dy
*dy
;
657 alpha
= VB
->ColorPtr
->data
[i
][3];
659 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
660 /* coverage is in [0,256] */
661 alpha
= (alpha
* coverage
) >> 8;
663 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
,
668 PB_CHECK_FLUSH(ctx
,PB
);
677 * Null rasterizer for measuring transformation speed.
679 static void null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
688 /* Definition of the functions for GL_EXT_point_parameters */
690 /* Calculates the distance attenuation formula of a vector of points in
691 * eye space coordinates
693 static void dist3(GLfloat
*out
, GLuint first
, GLuint last
,
694 const GLcontext
*ctx
, const GLvector4f
*v
)
696 GLuint stride
= v
->stride
;
697 GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
700 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) )
702 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
703 out
[i
] = 1/(ctx
->Point
.Params
[0]+
704 dist
* (ctx
->Point
.Params
[1] +
705 dist
* ctx
->Point
.Params
[2]));
709 static void dist2(GLfloat
*out
, GLuint first
, GLuint last
,
710 const GLcontext
*ctx
, const GLvector4f
*v
)
712 GLuint stride
= v
->stride
;
713 GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
716 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) )
718 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
719 out
[i
] = 1/(ctx
->Point
.Params
[0]+
720 dist
* (ctx
->Point
.Params
[1] +
721 dist
* ctx
->Point
.Params
[2]));
726 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
727 const GLcontext
*ctx
, const GLvector4f
*v
);
730 static dist_func eye_dist_tab
[5] = {
739 static void clip_dist(GLfloat
*out
, GLuint first
, GLuint last
,
740 const GLcontext
*ctx
, GLvector4f
*clip
)
742 /* this is never called */
743 gl_problem(NULL
, "clip_dist() called - dead code!\n");
753 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
754 const GLuint stride
= clip_vec
->stride
;
756 for (i
= first
; i
<= last
; i
++ )
758 GLfloat dist
= win
[i
][2];
759 out
[i
] = 1/(ctx
->Point
.Params
[0]+
760 dist
* (ctx
->Point
.Params
[1] +
761 dist
* ctx
->Point
.Params
[2]));
769 * Distance Attenuated General CI points.
771 static void dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
,
774 struct vertex_buffer
*VB
= ctx
->VB
;
775 struct pixel_buffer
*PB
= ctx
->PB
;
778 GLfloat dist
[VB_SIZE
];
779 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
781 if (ctx
->NeedEyeCoords
)
782 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
784 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
786 for (i
=first
;i
<=last
;i
++) {
787 if (VB
->ClipMask
[i
]==0) {
789 GLint x0
, x1
, y0
, y1
;
793 x
= (GLint
) VB
->Win
.data
[i
][0];
794 y
= (GLint
) VB
->Win
.data
[i
][1];
795 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
798 if(dsize
>=ctx
->Point
.Threshold
) {
799 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
801 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
814 x0
= (GLint
) (x
+ 1.5F
) - radius
;
816 y0
= (GLint
) (y
+ 1.5F
) - radius
;
820 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
822 for (iy
=y0
;iy
<=y1
;iy
++) {
823 for (ix
=x0
;ix
<=x1
;ix
++) {
824 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
827 PB_CHECK_FLUSH(ctx
,PB
);
833 * Distance Attenuated General RGBA points.
835 static void dist_atten_general_rgba_points( GLcontext
*ctx
, GLuint first
,
838 struct vertex_buffer
*VB
= ctx
->VB
;
839 struct pixel_buffer
*PB
= ctx
->PB
;
843 GLfloat dist
[VB_SIZE
];
844 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
846 if (ctx
->NeedEyeCoords
)
847 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
849 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
851 for (i
=first
;i
<=last
;i
++) {
852 if (VB
->ClipMask
[i
]==0) {
854 GLint x0
, x1
, y0
, y1
;
858 x
= (GLint
) VB
->Win
.data
[i
][0];
859 y
= (GLint
) VB
->Win
.data
[i
][1];
860 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
862 if (dsize
>= ctx
->Point
.Threshold
) {
863 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
864 alpha
= VB
->ColorPtr
->data
[i
][3];
867 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
868 dsize
/= ctx
->Point
.Threshold
;
869 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
882 x0
= (GLint
) (x
+ 1.5F
) - radius
;
884 y0
= (GLint
) (y
+ 1.5F
) - radius
;
888 PB_SET_COLOR( ctx
, PB
,
889 VB
->ColorPtr
->data
[i
][0],
890 VB
->ColorPtr
->data
[i
][1],
891 VB
->ColorPtr
->data
[i
][2],
894 for (iy
=y0
;iy
<=y1
;iy
++) {
895 for (ix
=x0
;ix
<=x1
;ix
++) {
896 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
899 PB_CHECK_FLUSH(ctx
,PB
);
905 * Distance Attenuated Textured RGBA points.
907 static void dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
,
910 struct vertex_buffer
*VB
= ctx
->VB
;
911 struct pixel_buffer
*PB
= ctx
->PB
;
914 GLfloat dist
[VB_SIZE
];
915 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
917 if (ctx
->NeedEyeCoords
)
918 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
920 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
922 for (i
=first
;i
<=last
;i
++) {
923 if (VB
->ClipMask
[i
]==0) {
925 GLint x0
, x1
, y0
, y1
;
928 GLint red
, green
, blue
, alpha
;
932 x
= (GLint
) VB
->Win
.data
[i
][0];
933 y
= (GLint
) VB
->Win
.data
[i
][1];
934 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
937 if(dsize
>=ctx
->Point
.Threshold
) {
938 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
939 alpha
=VB
->ColorPtr
->data
[i
][3];
941 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
942 dsize
/=ctx
->Point
.Threshold
;
943 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
960 x0
= (GLint
) (x
+ 1.5F
) - radius
;
962 y0
= (GLint
) (y
+ 1.5F
) - radius
;
966 red
= VB
->ColorPtr
->data
[i
][0];
967 green
= VB
->ColorPtr
->data
[i
][1];
968 blue
= VB
->ColorPtr
->data
[i
][2];
970 switch (VB
->TexCoordPtr
[0]->size
) {
972 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
973 VB
->TexCoordPtr
[0]->data
[i
][3]);
974 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
975 VB
->TexCoordPtr
[0]->data
[i
][3]);
976 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
977 VB
->TexCoordPtr
[0]->data
[i
][3]);
980 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
981 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
982 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
985 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
986 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
990 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
995 /* should never get here */
997 gl_problem(ctx
, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1000 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1001 /* Multitextured! This is probably a slow enough path that
1002 there's no reason to specialize the multitexture case. */
1003 switch (VB
->TexCoordPtr
[1]->size
) {
1005 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1006 VB
->TexCoordPtr
[1]->data
[i
][3] );
1007 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1008 VB
->TexCoordPtr
[1]->data
[i
][3] );
1009 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1010 VB
->TexCoordPtr
[1]->data
[i
][3] );
1013 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1014 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1015 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1018 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1019 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1023 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1028 /* should never get here */
1030 gl_problem(ctx
, "unexpected texcoord size in dist_atten_textured_rgba_points()");
1034 /* don't think this is needed
1035 PB_SET_COLOR( red, green, blue, alpha );
1038 for (iy
=y0
;iy
<=y1
;iy
++) {
1039 for (ix
=x0
;ix
<=x1
;ix
++) {
1040 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1041 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1043 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
1047 PB_CHECK_FLUSH(ctx
,PB
);
1053 * Distance Attenuated Antialiased points with or without texture mapping.
1055 static void dist_atten_antialiased_rgba_points( GLcontext
*ctx
,
1056 GLuint first
, GLuint last
)
1058 struct vertex_buffer
*VB
= ctx
->VB
;
1059 struct pixel_buffer
*PB
= ctx
->PB
;
1061 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
1062 GLfloat psize
,dsize
,alphaf
;
1063 GLfloat dist
[VB_SIZE
];
1064 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
1066 if (ctx
->NeedEyeCoords
)
1067 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
1069 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
1071 if (ctx
->Texture
.ReallyEnabled
) {
1072 for (i
=first
;i
<=last
;i
++) {
1073 if (VB
->ClipMask
[i
]==0) {
1074 GLint xmin
, ymin
, xmax
, ymax
;
1076 GLint red
, green
, blue
, alpha
;
1080 dsize
=psize
*dist
[i
];
1081 if(dsize
>=ctx
->Point
.Threshold
) {
1082 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1085 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1086 dsize
/=ctx
->Point
.Threshold
;
1087 alphaf
=(dsize
*dsize
);
1089 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1090 rmax
= radius
+ 0.7071F
;
1093 cscale
= 256.0F
/ (rmax2
-rmin2
);
1095 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1096 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1097 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1098 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1099 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1101 red
= VB
->ColorPtr
->data
[i
][0];
1102 green
= VB
->ColorPtr
->data
[i
][1];
1103 blue
= VB
->ColorPtr
->data
[i
][2];
1105 switch (VB
->TexCoordPtr
[0]->size
) {
1107 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
1108 VB
->TexCoordPtr
[0]->data
[i
][3]);
1109 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
1110 VB
->TexCoordPtr
[0]->data
[i
][3]);
1111 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
1112 VB
->TexCoordPtr
[0]->data
[i
][3]);
1115 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1116 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1117 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
1120 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1121 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1125 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1130 /* should never get here */
1132 gl_problem(ctx
, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1135 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1136 /* Multitextured! This is probably a slow enough path that
1137 there's no reason to specialize the multitexture case. */
1138 switch (VB
->TexCoordPtr
[1]->size
) {
1140 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1141 VB
->TexCoordPtr
[1]->data
[i
][3] );
1142 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1143 VB
->TexCoordPtr
[1]->data
[i
][3] );
1144 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1145 VB
->TexCoordPtr
[1]->data
[i
][3] );
1148 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1149 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1150 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1153 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1154 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1158 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1163 /* should never get here */
1165 gl_problem(ctx
, "unexpected texcoord size in dist_atten_antialiased_rgba_points()");
1169 for (y
=ymin
;y
<=ymax
;y
++) {
1170 for (x
=xmin
;x
<=xmax
;x
++) {
1171 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1172 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1173 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1175 alpha
= VB
->ColorPtr
->data
[i
][3];
1177 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1178 /* coverage is in [0,256] */
1179 alpha
= (alpha
* coverage
) >> 8;
1181 alpha
= (GLint
) (alpha
* alphaf
);
1182 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1183 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1185 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
);
1190 PB_CHECK_FLUSH(ctx
,PB
);
1195 /* Not texture mapped */
1196 for (i
=first
;i
<=last
;i
++) {
1197 if (VB
->ClipMask
[i
]==0) {
1198 GLint xmin
, ymin
, xmax
, ymax
;
1200 GLint red
, green
, blue
, alpha
;
1202 dsize
=psize
*dist
[i
];
1203 if(dsize
>=ctx
->Point
.Threshold
) {
1204 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1207 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1208 dsize
/=ctx
->Point
.Threshold
;
1209 alphaf
=(dsize
*dsize
);
1211 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1212 rmax
= radius
+ 0.7071F
;
1215 cscale
= 256.0F
/ (rmax2
-rmin2
);
1217 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1218 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1219 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1220 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1221 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1223 red
= VB
->ColorPtr
->data
[i
][0];
1224 green
= VB
->ColorPtr
->data
[i
][1];
1225 blue
= VB
->ColorPtr
->data
[i
][2];
1227 for (y
=ymin
;y
<=ymax
;y
++) {
1228 for (x
=xmin
;x
<=xmax
;x
++) {
1229 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1230 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1231 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1233 alpha
= VB
->ColorPtr
->data
[i
][3];
1235 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1236 /* coverage is in [0,256] */
1237 alpha
= (alpha
* coverage
) >> 8;
1239 alpha
= (GLint
) (alpha
* alphaf
);
1240 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
)
1245 PB_CHECK_FLUSH(ctx
,PB
);
1253 * Examine the current context to determine which point drawing function
1256 void gl_set_point_function( GLcontext
*ctx
)
1258 GLboolean rgbmode
= ctx
->Visual
->RGBAflag
;
1260 if (ctx
->RenderMode
==GL_RENDER
) {
1261 if (ctx
->NoRaster
) {
1262 ctx
->Driver
.PointsFunc
= null_points
;
1265 if (ctx
->Driver
.PointsFunc
) {
1266 /* Device driver will draw points. */
1267 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1271 if (!ctx
->Point
.Attenuated
) {
1272 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1273 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1275 else if (ctx
->Texture
.ReallyEnabled
) {
1276 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1277 ctx
->Driver
.PointsFunc
= multitextured_rgba_points
;
1280 ctx
->Driver
.PointsFunc
= textured_rgba_points
;
1283 else if (ctx
->Point
.Size
==1.0) {
1284 /* size=1, any raster ops */
1286 ctx
->Driver
.PointsFunc
= size1_rgba_points
;
1288 ctx
->Driver
.PointsFunc
= size1_ci_points
;
1291 /* every other kind of point rendering */
1293 ctx
->Driver
.PointsFunc
= general_rgba_points
;
1295 ctx
->Driver
.PointsFunc
= general_ci_points
;
1298 else if(ctx
->Point
.SmoothFlag
&& rgbmode
) {
1299 ctx
->Driver
.PointsFunc
= dist_atten_antialiased_rgba_points
;
1301 else if (ctx
->Texture
.ReallyEnabled
) {
1302 ctx
->Driver
.PointsFunc
= dist_atten_textured_rgba_points
;
1305 /* every other kind of point rendering */
1307 ctx
->Driver
.PointsFunc
= dist_atten_general_rgba_points
;
1309 ctx
->Driver
.PointsFunc
= dist_atten_general_ci_points
;
1312 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
1313 ctx
->Driver
.PointsFunc
= gl_feedback_points
;
1316 /* GL_SELECT mode */
1317 ctx
->Driver
.PointsFunc
= gl_select_points
;