1 /* $Id: s_pointtemp.h,v 1.8 2001/05/17 09:32:17 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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.
29 * Point rendering template code.
31 * Set FLAGS = bitwise-OR of the following tokens:
33 * RGBA = do rgba instead of color index
34 * SMOOTH = do antialiasing
35 * TEXTURE = do texture coords
36 * SPECULAR = do separate specular color
37 * LARGE = do points with diameter > 1 pixel
38 * ATTENUATE = compute point size attenuation
39 * SPRITE = GL_MESA_sprite_point
41 * Notes: LARGE and ATTENUATE are exclusive of each other.
42 * TEXTURE requires RGBA
43 * SPECULAR requires TEXTURE
48 * NOTES on antialiased point rasterization:
50 * Let d = distance of fragment center from vertex.
52 * fragment has 100% coverage
53 * else if d > rmax2 then
54 * fragment has 0% coverage
56 * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2)
62 NAME ( GLcontext
*ctx
, const SWvertex
*vert
)
64 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
65 struct pixel_buffer
*PB
= swrast
->PB
;
67 const GLint z
= (GLint
) (vert
->win
[2]);
70 const GLint red
= vert
->color
[0];
71 const GLint green
= vert
->color
[1];
72 const GLint blue
= vert
->color
[2];
73 GLint alpha
= vert
->color
[3];
75 const GLint sRed
= vert
->specular
[0];
76 const GLint sGreen
= vert
->specular
[1];
77 const GLint sBlue
= vert
->specular
[2];
80 GLint index
= vert
->index
;
82 #if FLAGS & (ATTENUATE | LARGE | SMOOTH)
90 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
92 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
93 if (ctx
->Texture
.Unit
[u
]._ReallyEnabled
) {
94 if (vert
->texcoord
[u
][3] != 1.0 && vert
->texcoord
[u
][3] != 0.0) {
95 texcoord
[u
][0] = vert
->texcoord
[u
][0] / vert
->texcoord
[u
][3];
96 texcoord
[u
][1] = vert
->texcoord
[u
][1] / vert
->texcoord
[u
][3];
97 texcoord
[u
][2] = vert
->texcoord
[u
][2] / vert
->texcoord
[u
][3];
100 texcoord
[u
][0] = vert
->texcoord
[u
][0];
101 texcoord
[u
][1] = vert
->texcoord
[u
][1];
102 texcoord
[u
][2] = vert
->texcoord
[u
][2];
108 #if FLAGS & ATTENUATE
109 if (vert
->pointSize
>= ctx
->Point
.Threshold
) {
110 size
= MIN2(vert
->pointSize
, ctx
->Point
.MaxSize
);
114 GLfloat dsize
= vert
->pointSize
/ ctx
->Point
.Threshold
;
115 size
= MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
);
116 alphaAtten
= dsize
* dsize
;
118 #elif FLAGS & (LARGE | SMOOTH)
119 size
= ctx
->Point
._Size
;
124 SWcontext
*swctx
= SWRAST_CONTEXT(ctx
);
125 const GLfloat radius
= 0.5 * vert
->pointSize
; /* XXX threshold, alpha */
126 SWvertex v0
, v1
, v2
, v3
;
135 /* lower left corner */
140 /* lower right corner */
145 /* upper right corner */
150 /* upper left corner */
155 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
156 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
157 v0
.texcoord
[unit
][0] = 0.0;
158 v0
.texcoord
[unit
][1] = 0.0;
159 v1
.texcoord
[unit
][0] = 1.0;
160 v1
.texcoord
[unit
][1] = 0.0;
161 v2
.texcoord
[unit
][0] = 1.0;
162 v2
.texcoord
[unit
][1] = 1.0;
163 v3
.texcoord
[unit
][0] = 0.0;
164 v3
.texcoord
[unit
][1] = 1.0;
168 /* XXX if radius < threshold, attenuate alpha? */
170 /* XXX need to implement clipping!!! */
173 swctx
->Triangle(ctx
, &v0
, &v1
, &v2
);
174 swctx
->Triangle(ctx
, &v0
, &v2
, &v3
);
177 #elif FLAGS & (LARGE | ATTENUATE | SMOOTH)
181 const GLfloat radius
= 0.5F
* size
;
183 const GLfloat rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
184 const GLfloat rmax
= radius
+ 0.7071F
;
185 const GLfloat rmin2
= MAX2(0.0, rmin
* rmin
);
186 const GLfloat rmax2
= rmax
* rmax
;
187 const GLfloat cscale
= 1.0F
/ (rmax2
- rmin2
);
188 const GLint xmin
= (GLint
) (vert
->win
[0] - radius
);
189 const GLint xmax
= (GLint
) (vert
->win
[0] + radius
);
190 const GLint ymin
= (GLint
) (vert
->win
[1] - radius
);
191 const GLint ymax
= (GLint
) (vert
->win
[1] + radius
);
194 GLint xmin
, xmax
, ymin
, ymax
;
195 GLint iSize
= (GLint
) (size
+ 0.5F
);
197 iSize
= MAX2(1, iSize
);
201 xmin
= (GLint
) (vert
->win
[0] - iRadius
);
202 xmax
= (GLint
) (vert
->win
[0] + iRadius
);
203 ymin
= (GLint
) (vert
->win
[1] - iRadius
);
204 ymax
= (GLint
) (vert
->win
[1] + iRadius
);
208 xmin
= (GLint
) vert
->win
[0] - iRadius
+ 1;
209 xmax
= xmin
+ iSize
- 1;
210 ymin
= (GLint
) vert
->win
[1] - iRadius
+ 1;
211 ymax
= ymin
+ iSize
- 1;
216 for (y
= ymin
; y
<= ymax
; y
++) {
217 for (x
= xmin
; x
<= xmax
; x
++) {
219 /* compute coverage */
220 const GLfloat dx
= x
- vert
->win
[0] + 0.5F
;
221 const GLfloat dy
= y
- vert
->win
[1] + 0.5F
;
222 const GLfloat dist2
= dx
* dx
+ dy
* dy
;
225 alpha
= vert
->color
[3];
227 if (dist2
>= rmin2
) {
228 /* compute partial coverage */
229 PB_COVERAGE(PB
, 1.0F
- (dist2
- rmin2
) * cscale
);
233 PB_COVERAGE(PB
, 1.0F
);
238 #if ((FLAGS & (ATTENUATE | RGBA)) == (ATTENUATE | RGBA))
239 alpha
= (GLint
) (alpha
* alphaAtten
);
243 PB_WRITE_MULTITEX_SPEC_PIXEL(PB
, x
, y
, z
, vert
->fog
,
244 red
, green
, blue
, alpha
,
247 #elif FLAGS & TEXTURE
248 if (ctx
->Texture
._ReallyEnabled
> TEXTURE0_ANY
) {
249 PB_WRITE_MULTITEX_PIXEL(PB
, x
, y
, z
, vert
->fog
,
250 red
, green
, blue
, alpha
,
253 else if (ctx
->Texture
._ReallyEnabled
) {
254 PB_WRITE_TEX_PIXEL(PB
, x
,y
,z
, vert
->fog
,
255 red
, green
, blue
, alpha
,
261 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, vert
->fog
,
262 red
, green
, blue
, alpha
);
265 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, vert
->fog
,
266 red
, green
, blue
, alpha
);
267 #else /* color index */
268 PB_WRITE_CI_PIXEL(PB
, x
, y
, z
, vert
->fog
, index
);
277 PB
->haveCoverage
= GL_TRUE
;
280 PB_CHECK_FLUSH(ctx
,PB
);
283 #else /* LARGE || ATTENUATE || SMOOTH*/
287 GLint x
= (GLint
) vert
->win
[0];
288 GLint y
= (GLint
) vert
->win
[1];
289 #if ((FLAGS & (SPECULAR | TEXTURE)) == (SPECULAR | TEXTURE))
290 PB_WRITE_MULTITEX_SPEC_PIXEL(PB
, x
, y
, z
, vert
->fog
,
291 red
, green
, blue
, alpha
,
294 #elif FLAGS & TEXTURE
295 if (ctx
->Texture
._ReallyEnabled
> TEXTURE0_ANY
) {
296 PB_WRITE_MULTITEX_PIXEL(PB
, x
, y
, z
, vert
->fog
,
297 red
, green
, blue
, alpha
, texcoord
);
300 PB_WRITE_TEX_PIXEL(PB
, x
, y
, z
, vert
->fog
,
301 red
, green
, blue
, alpha
,
302 texcoord
[0][0], texcoord
[0][1], texcoord
[0][2]);
305 /* rgba size 1 point */
306 alpha
= vert
->color
[3];
307 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, vert
->fog
, red
, green
, blue
, alpha
);
309 /* color index size 1 point */
310 PB_WRITE_CI_PIXEL(PB
, x
, y
, z
, vert
->fog
, index
);
313 #endif /* LARGE || ATTENUATE || SMOOTH */
315 PB_CHECK_FLUSH(ctx
, PB
);