1 /* $Id: points.c,v 1.3 1999/10/08 09:27:11 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.
26 /* $XFree86: xc/lib/GL/mesa/src/points.c,v 1.4 1999/04/04 00:20:29 dawes Exp $ */
38 #include "GL/xf86glx.h"
55 void gl_PointSize( GLcontext
*ctx
, GLfloat size
)
58 gl_error( ctx
, GL_INVALID_VALUE
, "glPointSize" );
61 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointSize");
63 if (ctx
->Point
.Size
!= size
) {
64 ctx
->Point
.Size
= size
;
65 ctx
->TriangleCaps
&= ~DD_POINT_SIZE
;
66 if (size
!= 1.0) ctx
->TriangleCaps
|= DD_POINT_SIZE
;
67 ctx
->NewState
|= NEW_RASTER_OPS
;
73 void gl_PointParameterfvEXT( GLcontext
*ctx
, GLenum pname
,
74 const GLfloat
*params
)
76 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glPointParameterfvEXT");
77 if(pname
==GL_DISTANCE_ATTENUATION_EXT
) {
78 GLboolean tmp
= ctx
->Point
.Attenuated
;
79 COPY_3V(ctx
->Point
.Params
,params
);
80 ctx
->Point
.Attenuated
= (params
[0] != 1.0 ||
84 if (tmp
!= ctx
->Point
.Attenuated
) {
85 ctx
->Enabled
^= ENABLE_POINT_ATTEN
;
86 ctx
->TriangleCaps
^= DD_POINT_ATTEN
;
87 ctx
->NewState
|= NEW_RASTER_OPS
;
91 gl_error( ctx
, GL_INVALID_VALUE
, "glPointParameterfvEXT" );
95 case GL_POINT_SIZE_MIN_EXT
:
96 ctx
->Point
.MinSize
=*params
;
98 case GL_POINT_SIZE_MAX_EXT
:
99 ctx
->Point
.MaxSize
=*params
;
101 case GL_POINT_FADE_THRESHOLD_SIZE_EXT
:
102 ctx
->Point
.Threshold
=*params
;
105 gl_error( ctx
, GL_INVALID_ENUM
, "glPointParameterfvEXT" );
109 ctx
->NewState
|= NEW_RASTER_OPS
;
113 /**********************************************************************/
114 /***** Rasterization *****/
115 /**********************************************************************/
119 * There are 3 pairs (RGBA, CI) of point rendering functions:
120 * 1. simple: size=1 and no special rasterization functions (fastest)
121 * 2. size1: size=1 and any rasterization functions
122 * 3. general: any size and rasterization functions (slowest)
124 * All point rendering functions take the same two arguments: first and
125 * last which specify that the points specified by VB[first] through
126 * VB[last] are to be rendered.
134 * CI points with size == 1.0
136 void size1_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
138 struct vertex_buffer
*VB
= ctx
->VB
;
139 struct pixel_buffer
*PB
= ctx
->PB
;
141 GLint
*pbx
= PB
->x
, *pby
= PB
->y
;
142 GLdepth
*pbz
= PB
->z
;
144 GLuint pbcount
= PB
->count
;
147 win
= &VB
->Win
.data
[first
][0];
148 for (i
=first
;i
<=last
;i
++) {
149 if (VB
->ClipMask
[i
]==0) {
150 pbx
[pbcount
] = (GLint
) win
[0];
151 pby
[pbcount
] = (GLint
) win
[1];
152 pbz
[pbcount
] = (GLint
) (win
[2] + ctx
->PointZoffset
);
153 pbi
[pbcount
] = VB
->IndexPtr
->data
[i
];
159 PB_CHECK_FLUSH(ctx
, PB
);
165 * RGBA points with size == 1.0
167 static void size1_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
169 struct vertex_buffer
*VB
= ctx
->VB
;
170 struct pixel_buffer
*PB
= ctx
->PB
;
173 for (i
=first
;i
<=last
;i
++) {
174 if (VB
->ClipMask
[i
]==0) {
176 GLint red
, green
, blue
, alpha
;
178 x
= (GLint
) VB
->Win
.data
[i
][0];
179 y
= (GLint
) VB
->Win
.data
[i
][1];
180 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
182 red
= VB
->ColorPtr
->data
[i
][0];
183 green
= VB
->ColorPtr
->data
[i
][1];
184 blue
= VB
->ColorPtr
->data
[i
][2];
185 alpha
= VB
->ColorPtr
->data
[i
][3];
187 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
);
190 PB_CHECK_FLUSH(ctx
,PB
);
198 static void general_ci_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
200 struct vertex_buffer
*VB
= ctx
->VB
;
201 struct pixel_buffer
*PB
= ctx
->PB
;
203 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
204 GLint radius
= isize
>> 1;
206 for (i
=first
;i
<=last
;i
++) {
207 if (VB
->ClipMask
[i
]==0) {
209 GLint x0
, x1
, y0
, y1
;
212 x
= (GLint
) VB
->Win
.data
[i
][0];
213 y
= (GLint
) VB
->Win
.data
[i
][1];
214 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
225 x0
= (GLint
) (x
+ 1.5F
) - radius
;
227 y0
= (GLint
) (y
+ 1.5F
) - radius
;
231 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
233 for (iy
=y0
;iy
<=y1
;iy
++) {
234 for (ix
=x0
;ix
<=x1
;ix
++) {
235 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
238 PB_CHECK_FLUSH(ctx
,PB
);
245 * General RGBA points.
247 static void general_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
249 struct vertex_buffer
*VB
= ctx
->VB
;
250 struct pixel_buffer
*PB
= ctx
->PB
;
252 GLint isize
= (GLint
) (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
253 GLint radius
= isize
>> 1;
255 for (i
=first
;i
<=last
;i
++) {
256 if (VB
->ClipMask
[i
]==0) {
258 GLint x0
, x1
, y0
, y1
;
261 x
= (GLint
) VB
->Win
.data
[i
][0];
262 y
= (GLint
) VB
->Win
.data
[i
][1];
263 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
274 x0
= (GLint
) (x
+ 1.5F
) - radius
;
276 y0
= (GLint
) (y
+ 1.5F
) - radius
;
280 PB_SET_COLOR( ctx
, PB
,
281 VB
->ColorPtr
->data
[i
][0],
282 VB
->ColorPtr
->data
[i
][1],
283 VB
->ColorPtr
->data
[i
][2],
284 VB
->ColorPtr
->data
[i
][3] );
286 for (iy
=y0
;iy
<=y1
;iy
++) {
287 for (ix
=x0
;ix
<=x1
;ix
++) {
288 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
291 PB_CHECK_FLUSH(ctx
,PB
);
300 * Textured RGBA points.
302 static void textured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
304 struct vertex_buffer
*VB
= ctx
->VB
;
305 struct pixel_buffer
*PB
= ctx
->PB
;
308 for (i
=first
;i
<=last
;i
++) {
309 if (VB
->ClipMask
[i
]==0) {
311 GLint x0
, x1
, y0
, y1
;
314 GLint red
, green
, blue
, alpha
;
317 x
= (GLint
) VB
->Win
.data
[i
][0];
318 y
= (GLint
) VB
->Win
.data
[i
][1];
319 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
322 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
337 x0
= (GLint
) (x
+ 1.5F
) - radius
;
339 y0
= (GLint
) (y
+ 1.5F
) - radius
;
343 red
= VB
->ColorPtr
->data
[i
][0];
344 green
= VB
->ColorPtr
->data
[i
][1];
345 blue
= VB
->ColorPtr
->data
[i
][2];
346 alpha
= VB
->ColorPtr
->data
[i
][3];
348 switch (VB
->TexCoordPtr
[0]->size
) {
350 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
351 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
352 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
355 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
356 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
357 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
360 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
361 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
365 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
374 /* don't think this is needed
375 PB_SET_COLOR( red, green, blue, alpha );
378 for (iy
=y0
;iy
<=y1
;iy
++) {
379 for (ix
=x0
;ix
<=x1
;ix
++) {
380 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
383 PB_CHECK_FLUSH(ctx
,PB
);
390 * Multitextured RGBA points.
392 static void multitextured_rgba_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
394 struct vertex_buffer
*VB
= ctx
->VB
;
395 struct pixel_buffer
*PB
= ctx
->PB
;
398 for (i
=first
;i
<=last
;i
++) {
399 if (VB
->ClipMask
[i
]==0) {
401 GLint x0
, x1
, y0
, y1
;
404 GLint red
, green
, blue
, alpha
;
408 x
= (GLint
) VB
->Win
.data
[i
][0];
409 y
= (GLint
) VB
->Win
.data
[i
][1];
410 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
413 (CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
) + 0.5F
);
428 x0
= (GLint
) (x
+ 1.5F
) - radius
;
430 y0
= (GLint
) (y
+ 1.5F
) - radius
;
434 red
= VB
->ColorPtr
->data
[i
][0];
435 green
= VB
->ColorPtr
->data
[i
][1];
436 blue
= VB
->ColorPtr
->data
[i
][2];
437 alpha
= VB
->ColorPtr
->data
[i
][3];
439 switch (VB
->TexCoordPtr
[0]->size
) {
441 s
= VB
->TexCoordPtr
[0]->data
[i
][0]/VB
->TexCoordPtr
[0]->data
[i
][3];
442 t
= VB
->TexCoordPtr
[0]->data
[i
][1]/VB
->TexCoordPtr
[0]->data
[i
][3];
443 u
= VB
->TexCoordPtr
[0]->data
[i
][2]/VB
->TexCoordPtr
[0]->data
[i
][3];
446 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
447 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
448 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
451 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
452 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
456 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
462 switch (VB
->TexCoordPtr
[1]->size
) {
464 s1
= VB
->TexCoordPtr
[1]->data
[i
][0]/VB
->TexCoordPtr
[1]->data
[i
][3];
465 t1
= VB
->TexCoordPtr
[1]->data
[i
][1]/VB
->TexCoordPtr
[1]->data
[i
][3];
466 u1
= VB
->TexCoordPtr
[1]->data
[i
][2]/VB
->TexCoordPtr
[1]->data
[i
][3];
469 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
470 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
471 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
474 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
475 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
479 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
485 for (iy
=y0
;iy
<=y1
;iy
++) {
486 for (ix
=x0
;ix
<=x1
;ix
++) {
487 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
490 PB_CHECK_FLUSH(ctx
,PB
);
499 * Antialiased points with or without texture mapping.
501 static void antialiased_rgba_points( GLcontext
*ctx
,
502 GLuint first
, GLuint last
)
504 struct vertex_buffer
*VB
= ctx
->VB
;
505 struct pixel_buffer
*PB
= ctx
->PB
;
507 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
509 radius
= CLAMP( ctx
->Point
.Size
, MIN_POINT_SIZE
, MAX_POINT_SIZE
) * 0.5F
;
510 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
511 rmax
= radius
+ 0.7071F
;
514 cscale
= 256.0F
/ (rmax2
-rmin2
);
516 if (ctx
->Texture
.ReallyEnabled
) {
517 for (i
=first
;i
<=last
;i
++) {
518 if (VB
->ClipMask
[i
]==0) {
519 GLint xmin
, ymin
, xmax
, ymax
;
521 GLint red
, green
, blue
, alpha
;
525 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
526 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
527 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
528 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
529 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
531 red
= VB
->ColorPtr
->data
[i
][0];
532 green
= VB
->ColorPtr
->data
[i
][1];
533 blue
= VB
->ColorPtr
->data
[i
][2];
535 switch (VB
->TexCoordPtr
[0]->size
) {
537 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
538 VB
->TexCoordPtr
[0]->data
[i
][3]);
539 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
540 VB
->TexCoordPtr
[0]->data
[i
][3]);
541 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
542 VB
->TexCoordPtr
[0]->data
[i
][3]);
545 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
546 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
547 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
550 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
551 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
555 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
561 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
562 /* Multitextured! This is probably a slow enough path that
563 there's no reason to specialize the multitexture case. */
564 switch (VB
->TexCoordPtr
[1]->size
) {
566 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
567 VB
->TexCoordPtr
[1]->data
[i
][3]);
568 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
569 VB
->TexCoordPtr
[1]->data
[i
][3]);
570 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
571 VB
->TexCoordPtr
[1]->data
[i
][3]);
574 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
575 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
576 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
579 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
580 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
584 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
591 for (y
=ymin
;y
<=ymax
;y
++) {
592 for (x
=xmin
;x
<=xmax
;x
++) {
593 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
594 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
595 GLfloat dist2
= dx
*dx
+ dy
*dy
;
597 alpha
= VB
->ColorPtr
->data
[i
][3];
599 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
600 /* coverage is in [0,256] */
601 alpha
= (alpha
* coverage
) >> 8;
603 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
604 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
605 alpha
, s
, t
, u
, s1
, t1
, u1
);
607 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
,
614 PB_CHECK_FLUSH(ctx
,PB
);
619 /* Not texture mapped */
620 for (i
=first
;i
<=last
;i
++) {
621 if (VB
->ClipMask
[i
]==0) {
622 GLint xmin
, ymin
, xmax
, ymax
;
624 GLint red
, green
, blue
, alpha
;
626 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
627 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
628 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
629 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
630 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
632 red
= VB
->ColorPtr
->data
[i
][0];
633 green
= VB
->ColorPtr
->data
[i
][1];
634 blue
= VB
->ColorPtr
->data
[i
][2];
636 for (y
=ymin
;y
<=ymax
;y
++) {
637 for (x
=xmin
;x
<=xmax
;x
++) {
638 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
639 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
640 GLfloat dist2
= dx
*dx
+ dy
*dy
;
642 alpha
= VB
->ColorPtr
->data
[i
][3];
644 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
645 /* coverage is in [0,256] */
646 alpha
= (alpha
* coverage
) >> 8;
648 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
,
653 PB_CHECK_FLUSH(ctx
,PB
);
662 * Null rasterizer for measuring transformation speed.
664 static void null_points( GLcontext
*ctx
, GLuint first
, GLuint last
)
673 /* Definition of the functions for GL_EXT_point_parameters */
675 /* Calculates the distance attenuation formula of a vector of points in
676 * eye space coordinates
678 static void dist3(GLfloat
*out
, GLuint first
, GLuint last
,
679 const GLcontext
*ctx
, const GLvector4f
*v
)
681 GLuint stride
= v
->stride
;
682 GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
685 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) )
687 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]+p
[2]*p
[2]);
688 out
[i
] = 1/(ctx
->Point
.Params
[0]+
689 dist
* (ctx
->Point
.Params
[1] +
690 dist
* ctx
->Point
.Params
[2]));
694 static void dist2(GLfloat
*out
, GLuint first
, GLuint last
,
695 const GLcontext
*ctx
, const GLvector4f
*v
)
697 GLuint stride
= v
->stride
;
698 GLfloat
*p
= VEC_ELT(v
, GLfloat
, first
);
701 for (i
= first
; i
<= last
; i
++, STRIDE_F(p
, stride
) )
703 GLfloat dist
= GL_SQRT(p
[0]*p
[0]+p
[1]*p
[1]);
704 out
[i
] = 1/(ctx
->Point
.Params
[0]+
705 dist
* (ctx
->Point
.Params
[1] +
706 dist
* ctx
->Point
.Params
[2]));
711 typedef void (*dist_func
)(GLfloat
*out
, GLuint first
, GLuint last
,
712 const GLcontext
*ctx
, const GLvector4f
*v
);
715 static dist_func eye_dist_tab
[5] = {
724 static void clip_dist(GLfloat
*out
, GLuint first
, GLuint last
,
725 const GLcontext
*ctx
, GLvector4f
*clip
)
727 /* this is never called */
728 gl_problem(NULL
, "clip_dist() called - dead code!\n");
738 const GLfloat
*from
= (GLfloat
*)clip_vec
->start
;
739 const GLuint stride
= clip_vec
->stride
;
741 for (i
= first
; i
<= last
; i
++ )
743 GLfloat dist
= win
[i
][2];
744 out
[i
] = 1/(ctx
->Point
.Params
[0]+
745 dist
* (ctx
->Point
.Params
[1] +
746 dist
* ctx
->Point
.Params
[2]));
754 * Distance Attenuated General CI points.
756 static void dist_atten_general_ci_points( GLcontext
*ctx
, GLuint first
,
759 struct vertex_buffer
*VB
= ctx
->VB
;
760 struct pixel_buffer
*PB
= ctx
->PB
;
763 GLfloat dist
[VB_SIZE
];
764 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
766 if (ctx
->NeedEyeCoords
)
767 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
769 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
771 for (i
=first
;i
<=last
;i
++) {
772 if (VB
->ClipMask
[i
]==0) {
774 GLint x0
, x1
, y0
, y1
;
778 x
= (GLint
) VB
->Win
.data
[i
][0];
779 y
= (GLint
) VB
->Win
.data
[i
][1];
780 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
783 if(dsize
>=ctx
->Point
.Threshold
) {
784 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
786 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
799 x0
= (GLint
) (x
+ 1.5F
) - radius
;
801 y0
= (GLint
) (y
+ 1.5F
) - radius
;
805 PB_SET_INDEX( ctx
, PB
, VB
->IndexPtr
->data
[i
] );
807 for (iy
=y0
;iy
<=y1
;iy
++) {
808 for (ix
=x0
;ix
<=x1
;ix
++) {
809 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
812 PB_CHECK_FLUSH(ctx
,PB
);
818 * Distance Attenuated General RGBA points.
820 static void dist_atten_general_rgba_points( GLcontext
*ctx
, GLuint first
,
823 struct vertex_buffer
*VB
= ctx
->VB
;
824 struct pixel_buffer
*PB
= ctx
->PB
;
828 GLfloat dist
[VB_SIZE
];
829 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
831 if (ctx
->NeedEyeCoords
)
832 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
834 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
836 for (i
=first
;i
<=last
;i
++) {
837 if (VB
->ClipMask
[i
]==0) {
839 GLint x0
, x1
, y0
, y1
;
843 x
= (GLint
) VB
->Win
.data
[i
][0];
844 y
= (GLint
) VB
->Win
.data
[i
][1];
845 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
847 if (dsize
>= ctx
->Point
.Threshold
) {
848 isize
= (GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
849 alpha
= VB
->ColorPtr
->data
[i
][3];
852 isize
= (GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
853 dsize
/= ctx
->Point
.Threshold
;
854 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
867 x0
= (GLint
) (x
+ 1.5F
) - radius
;
869 y0
= (GLint
) (y
+ 1.5F
) - radius
;
873 PB_SET_COLOR( ctx
, PB
,
874 VB
->ColorPtr
->data
[i
][0],
875 VB
->ColorPtr
->data
[i
][1],
876 VB
->ColorPtr
->data
[i
][2],
879 for (iy
=y0
;iy
<=y1
;iy
++) {
880 for (ix
=x0
;ix
<=x1
;ix
++) {
881 PB_WRITE_PIXEL( PB
, ix
, iy
, z
);
884 PB_CHECK_FLUSH(ctx
,PB
);
890 * Distance Attenuated Textured RGBA points.
892 static void dist_atten_textured_rgba_points( GLcontext
*ctx
, GLuint first
,
895 struct vertex_buffer
*VB
= ctx
->VB
;
896 struct pixel_buffer
*PB
= ctx
->PB
;
899 GLfloat dist
[VB_SIZE
];
900 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
902 if (ctx
->NeedEyeCoords
)
903 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
905 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
907 for (i
=first
;i
<=last
;i
++) {
908 if (VB
->ClipMask
[i
]==0) {
910 GLint x0
, x1
, y0
, y1
;
913 GLint red
, green
, blue
, alpha
;
917 x
= (GLint
) VB
->Win
.data
[i
][0];
918 y
= (GLint
) VB
->Win
.data
[i
][1];
919 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
922 if(dsize
>=ctx
->Point
.Threshold
) {
923 isize
=(GLint
) (MIN2(dsize
,ctx
->Point
.MaxSize
)+0.5F
);
924 alpha
=VB
->ColorPtr
->data
[i
][3];
926 isize
=(GLint
) (MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)+0.5F
);
927 dsize
/=ctx
->Point
.Threshold
;
928 alpha
= (GLint
) (VB
->ColorPtr
->data
[i
][3]* (dsize
*dsize
));
945 x0
= (GLint
) (x
+ 1.5F
) - radius
;
947 y0
= (GLint
) (y
+ 1.5F
) - radius
;
951 red
= VB
->ColorPtr
->data
[i
][0];
952 green
= VB
->ColorPtr
->data
[i
][1];
953 blue
= VB
->ColorPtr
->data
[i
][2];
955 switch (VB
->TexCoordPtr
[0]->size
) {
957 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
958 VB
->TexCoordPtr
[0]->data
[i
][3]);
959 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
960 VB
->TexCoordPtr
[0]->data
[i
][3]);
961 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
962 VB
->TexCoordPtr
[0]->data
[i
][3]);
965 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
966 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
967 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
970 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
971 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
975 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
981 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
982 /* Multitextured! This is probably a slow enough path that
983 there's no reason to specialize the multitexture case. */
984 switch (VB
->TexCoordPtr
[1]->size
) {
986 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
987 VB
->TexCoordPtr
[1]->data
[i
][3] );
988 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
989 VB
->TexCoordPtr
[1]->data
[i
][3] );
990 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
991 VB
->TexCoordPtr
[1]->data
[i
][3] );
994 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
995 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
996 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
999 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1000 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1004 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1011 /* don't think this is needed
1012 PB_SET_COLOR( red, green, blue, alpha );
1015 for (iy
=y0
;iy
<=y1
;iy
++) {
1016 for (ix
=x0
;ix
<=x1
;ix
++) {
1017 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1018 PB_WRITE_MULTITEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1020 PB_WRITE_TEX_PIXEL( PB
, ix
, iy
, z
, red
, green
, blue
, alpha
, s
, t
, u
);
1024 PB_CHECK_FLUSH(ctx
,PB
);
1030 * Distance Attenuated Antialiased points with or without texture mapping.
1032 static void dist_atten_antialiased_rgba_points( GLcontext
*ctx
,
1033 GLuint first
, GLuint last
)
1035 struct vertex_buffer
*VB
= ctx
->VB
;
1036 struct pixel_buffer
*PB
= ctx
->PB
;
1038 GLfloat radius
, rmin
, rmax
, rmin2
, rmax2
, cscale
;
1039 GLfloat psize
,dsize
,alphaf
;
1040 GLfloat dist
[VB_SIZE
];
1041 psize
=CLAMP(ctx
->Point
.Size
,MIN_POINT_SIZE
,MAX_POINT_SIZE
);
1043 if (ctx
->NeedEyeCoords
)
1044 (eye_dist_tab
[VB
->EyePtr
->size
])( dist
, first
, last
, ctx
, VB
->EyePtr
);
1046 clip_dist( dist
, first
, last
, ctx
, VB
->ClipPtr
);
1048 if (ctx
->Texture
.ReallyEnabled
) {
1049 for (i
=first
;i
<=last
;i
++) {
1050 if (VB
->ClipMask
[i
]==0) {
1051 GLint xmin
, ymin
, xmax
, ymax
;
1053 GLint red
, green
, blue
, alpha
;
1057 dsize
=psize
*dist
[i
];
1058 if(dsize
>=ctx
->Point
.Threshold
) {
1059 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1062 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1063 dsize
/=ctx
->Point
.Threshold
;
1064 alphaf
=(dsize
*dsize
);
1066 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1067 rmax
= radius
+ 0.7071F
;
1070 cscale
= 256.0F
/ (rmax2
-rmin2
);
1072 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1073 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1074 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1075 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1076 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1078 red
= VB
->ColorPtr
->data
[i
][0];
1079 green
= VB
->ColorPtr
->data
[i
][1];
1080 blue
= VB
->ColorPtr
->data
[i
][2];
1082 switch (VB
->TexCoordPtr
[0]->size
) {
1084 s
= (VB
->TexCoordPtr
[0]->data
[i
][0]/
1085 VB
->TexCoordPtr
[0]->data
[i
][3]);
1086 t
= (VB
->TexCoordPtr
[0]->data
[i
][1]/
1087 VB
->TexCoordPtr
[0]->data
[i
][3]);
1088 u
= (VB
->TexCoordPtr
[0]->data
[i
][2]/
1089 VB
->TexCoordPtr
[0]->data
[i
][3]);
1092 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1093 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1094 u
= VB
->TexCoordPtr
[0]->data
[i
][2];
1097 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1098 t
= VB
->TexCoordPtr
[0]->data
[i
][1];
1102 s
= VB
->TexCoordPtr
[0]->data
[i
][0];
1108 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1109 /* Multitextured! This is probably a slow enough path that
1110 there's no reason to specialize the multitexture case. */
1111 switch (VB
->TexCoordPtr
[1]->size
) {
1113 s1
= ( VB
->TexCoordPtr
[1]->data
[i
][0] /
1114 VB
->TexCoordPtr
[1]->data
[i
][3] );
1115 t1
= ( VB
->TexCoordPtr
[1]->data
[i
][1] /
1116 VB
->TexCoordPtr
[1]->data
[i
][3] );
1117 u1
= ( VB
->TexCoordPtr
[1]->data
[i
][2] /
1118 VB
->TexCoordPtr
[1]->data
[i
][3] );
1121 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1122 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1123 u1
= VB
->TexCoordPtr
[1]->data
[i
][2];
1126 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1127 t1
= VB
->TexCoordPtr
[1]->data
[i
][1];
1131 s1
= VB
->TexCoordPtr
[1]->data
[i
][0];
1138 for (y
=ymin
;y
<=ymax
;y
++) {
1139 for (x
=xmin
;x
<=xmax
;x
++) {
1140 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1141 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1142 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1144 alpha
= VB
->ColorPtr
->data
[i
][3];
1146 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1147 /* coverage is in [0,256] */
1148 alpha
= (alpha
* coverage
) >> 8;
1150 alpha
= (GLint
) (alpha
* alphaf
);
1151 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1152 PB_WRITE_MULTITEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
, s1
, t1
, u1
);
1154 PB_WRITE_TEX_PIXEL( PB
, x
,y
,z
, red
, green
, blue
, alpha
, s
, t
, u
);
1159 PB_CHECK_FLUSH(ctx
,PB
);
1164 /* Not texture mapped */
1165 for (i
=first
;i
<=last
;i
++) {
1166 if (VB
->ClipMask
[i
]==0) {
1167 GLint xmin
, ymin
, xmax
, ymax
;
1169 GLint red
, green
, blue
, alpha
;
1171 dsize
=psize
*dist
[i
];
1172 if(dsize
>=ctx
->Point
.Threshold
) {
1173 radius
=(MIN2(dsize
,ctx
->Point
.MaxSize
)*0.5F
);
1176 radius
=(MAX2(ctx
->Point
.Threshold
,ctx
->Point
.MinSize
)*0.5F
);
1177 dsize
/=ctx
->Point
.Threshold
;
1178 alphaf
=(dsize
*dsize
);
1180 rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
1181 rmax
= radius
+ 0.7071F
;
1184 cscale
= 256.0F
/ (rmax2
-rmin2
);
1186 xmin
= (GLint
) (VB
->Win
.data
[i
][0] - radius
);
1187 xmax
= (GLint
) (VB
->Win
.data
[i
][0] + radius
);
1188 ymin
= (GLint
) (VB
->Win
.data
[i
][1] - radius
);
1189 ymax
= (GLint
) (VB
->Win
.data
[i
][1] + radius
);
1190 z
= (GLint
) (VB
->Win
.data
[i
][2] + ctx
->PointZoffset
);
1192 red
= VB
->ColorPtr
->data
[i
][0];
1193 green
= VB
->ColorPtr
->data
[i
][1];
1194 blue
= VB
->ColorPtr
->data
[i
][2];
1196 for (y
=ymin
;y
<=ymax
;y
++) {
1197 for (x
=xmin
;x
<=xmax
;x
++) {
1198 GLfloat dx
= x
/*+0.5F*/ - VB
->Win
.data
[i
][0];
1199 GLfloat dy
= y
/*+0.5F*/ - VB
->Win
.data
[i
][1];
1200 GLfloat dist2
= dx
*dx
+ dy
*dy
;
1202 alpha
= VB
->ColorPtr
->data
[i
][3];
1204 GLint coverage
= (GLint
) (256.0F
-(dist2
-rmin2
)*cscale
);
1205 /* coverage is in [0,256] */
1206 alpha
= (alpha
* coverage
) >> 8;
1208 alpha
= (GLint
) (alpha
* alphaf
);
1209 PB_WRITE_RGBA_PIXEL( PB
, x
, y
, z
, red
, green
, blue
, alpha
)
1214 PB_CHECK_FLUSH(ctx
,PB
);
1222 * Examine the current context to determine which point drawing function
1225 void gl_set_point_function( GLcontext
*ctx
)
1227 GLboolean rgbmode
= ctx
->Visual
->RGBAflag
;
1229 if (ctx
->RenderMode
==GL_RENDER
) {
1230 if (ctx
->NoRaster
) {
1231 ctx
->Driver
.PointsFunc
= null_points
;
1234 if (ctx
->Driver
.PointsFunc
) {
1235 /* Device driver will draw points. */
1236 ctx
->IndirectTriangles
&= ~DD_POINT_SW_RASTERIZE
;
1240 if (!ctx
->Point
.Attenuated
) {
1241 if (ctx
->Point
.SmoothFlag
&& rgbmode
) {
1242 ctx
->Driver
.PointsFunc
= antialiased_rgba_points
;
1244 else if (ctx
->Texture
.ReallyEnabled
) {
1245 if (ctx
->Texture
.ReallyEnabled
>= TEXTURE1_1D
) {
1246 ctx
->Driver
.PointsFunc
= multitextured_rgba_points
;
1249 ctx
->Driver
.PointsFunc
= textured_rgba_points
;
1252 else if (ctx
->Point
.Size
==1.0) {
1253 /* size=1, any raster ops */
1255 ctx
->Driver
.PointsFunc
= size1_rgba_points
;
1257 ctx
->Driver
.PointsFunc
= size1_ci_points
;
1260 /* every other kind of point rendering */
1262 ctx
->Driver
.PointsFunc
= general_rgba_points
;
1264 ctx
->Driver
.PointsFunc
= general_ci_points
;
1267 else if(ctx
->Point
.SmoothFlag
&& rgbmode
) {
1268 ctx
->Driver
.PointsFunc
= dist_atten_antialiased_rgba_points
;
1270 else if (ctx
->Texture
.ReallyEnabled
) {
1271 ctx
->Driver
.PointsFunc
= dist_atten_textured_rgba_points
;
1274 /* every other kind of point rendering */
1276 ctx
->Driver
.PointsFunc
= dist_atten_general_rgba_points
;
1278 ctx
->Driver
.PointsFunc
= dist_atten_general_ci_points
;
1281 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
1282 ctx
->Driver
.PointsFunc
= gl_feedback_points
;
1285 /* GL_SELECT mode */
1286 ctx
->Driver
.PointsFunc
= gl_select_points
;