1 /* $Id: s_pointtemp.h,v 1.4 2001/03/07 05:06:12 brianp 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]);
68 const GLfixed fog
= FloatToFixed( vert
->fog
);
71 const GLint red
= vert
->color
[0];
72 const GLint green
= vert
->color
[1];
73 const GLint blue
= vert
->color
[2];
74 GLint alpha
= vert
->color
[3];
76 const GLint sRed
= vert
->specular
[0];
77 const GLint sGreen
= vert
->specular
[1];
78 const GLint sBlue
= vert
->specular
[2];
81 GLint index
= vert
->index
;
83 #if FLAGS & (ATTENUATE | LARGE | SMOOTH)
91 GLfloat texcoord
[MAX_TEXTURE_UNITS
][4];
93 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
94 if (ctx
->Texture
.Unit
[u
]._ReallyEnabled
) {
95 if (vert
->texcoord
[u
][3] != 1.0 && vert
->texcoord
[u
][3] != 0.0) {
96 texcoord
[u
][0] = vert
->texcoord
[u
][0] / vert
->texcoord
[u
][3];
97 texcoord
[u
][1] = vert
->texcoord
[u
][1] / vert
->texcoord
[u
][3];
98 texcoord
[u
][2] = vert
->texcoord
[u
][2] / vert
->texcoord
[u
][3];
101 texcoord
[u
][0] = vert
->texcoord
[u
][0];
102 texcoord
[u
][1] = vert
->texcoord
[u
][1];
103 texcoord
[u
][2] = vert
->texcoord
[u
][2];
109 #if FLAGS & ATTENUATE
110 if (vert
->pointSize
>= ctx
->Point
.Threshold
) {
111 size
= MIN2(vert
->pointSize
, ctx
->Point
.MaxSize
);
115 GLfloat dsize
= vert
->pointSize
/ ctx
->Point
.Threshold
;
116 size
= MAX2(ctx
->Point
.Threshold
, ctx
->Point
.MinSize
);
117 alphaAtten
= dsize
* dsize
;
119 #elif FLAGS & (LARGE | SMOOTH)
120 size
= ctx
->Point
._Size
;
125 SWcontext
*swctx
= SWRAST_CONTEXT(ctx
);
126 const GLfloat radius
= 0.5 * vert
->pointSize
; /* XXX threshold, alpha */
127 SWvertex v0
, v1
, v2
, v3
;
137 /* lower left corner */
142 /* lower right corner */
147 /* upper right corner */
152 /* upper left corner */
157 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
158 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
159 v0
.texcoord
[unit
][0] = 0.0;
160 v0
.texcoord
[unit
][1] = 0.0;
161 v1
.texcoord
[unit
][0] = 1.0;
162 v1
.texcoord
[unit
][1] = 0.0;
163 v2
.texcoord
[unit
][0] = 1.0;
164 v2
.texcoord
[unit
][1] = 1.0;
165 v3
.texcoord
[unit
][0] = 0.0;
166 v3
.texcoord
[unit
][1] = 1.0;
170 /* XXX if radius < threshold, attenuate alpha? */
172 /* XXX need to implement clipping!!! */
175 swctx
->Triangle(ctx
, &v0
, &v1
, &v2
);
176 swctx
->Triangle(ctx
, &v0
, &v2
, &v3
);
179 #elif FLAGS & (LARGE | ATTENUATE | SMOOTH)
183 const GLfloat radius
= 0.5F
* size
;
185 const GLfloat rmin
= radius
- 0.7071F
; /* 0.7071 = sqrt(2)/2 */
186 const GLfloat rmax
= radius
+ 0.7071F
;
187 const GLfloat rmin2
= MAX2(0.0, rmin
* rmin
);
188 const GLfloat rmax2
= rmax
* rmax
;
189 const GLfloat cscale
= 256.0F
/ (rmax2
- rmin2
);
190 const GLint xmin
= (GLint
) (vert
->win
[0] - radius
);
191 const GLint xmax
= (GLint
) (vert
->win
[0] + radius
);
192 const GLint ymin
= (GLint
) (vert
->win
[1] - radius
);
193 const GLint ymax
= (GLint
) (vert
->win
[1] + radius
);
196 GLint xmin
, xmax
, ymin
, ymax
;
197 GLint iSize
= (GLint
) (size
+ 0.5F
);
199 iSize
= MAX2(1, iSize
);
203 xmin
= (GLint
) (vert
->win
[0] - iRadius
);
204 xmax
= (GLint
) (vert
->win
[0] + iRadius
);
205 ymin
= (GLint
) (vert
->win
[1] - iRadius
);
206 ymax
= (GLint
) (vert
->win
[1] + iRadius
);
210 xmin
= (GLint
) vert
->win
[0] - iRadius
+ 1;
211 xmax
= xmin
+ iSize
- 1;
212 ymin
= (GLint
) vert
->win
[1] - iRadius
+ 1;
213 ymax
= ymin
+ iSize
- 1;
218 for (y
= ymin
; y
<= ymax
; y
++) {
219 for (x
= xmin
; x
<= xmax
; x
++) {
221 /* compute coverage */
222 const GLfloat dx
= x
- vert
->win
[0] + 0.5F
;
223 const GLfloat dy
= y
- vert
->win
[1] + 0.5F
;
224 const GLfloat dist2
= dx
* dx
+ dy
* dy
;
227 alpha
= vert
->color
[3];
229 if (dist2
>= rmin2
) {
230 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
232 /* coverage is in [0,256] */
233 alpha
= (alpha
* coverage
) >> 8;
235 /* 4 fractional index bits */
236 index
= (index
& ~0xf) | (coverage
>> 4); /* XXX verify */
241 #if ((FLAGS & (ATTENUATE | RGBA)) == (ATTENUATE | RGBA))
242 alpha
= (GLint
) (alpha
* alphaAtten
);
246 PB_WRITE_MULTITEX_SPEC_PIXEL(PB
, x
, y
, z
, fog
,
247 red
, green
, blue
, alpha
,
250 #elif FLAGS & TEXTURE
251 if (swrast
->_MultiTextureEnabled
) {
252 PB_WRITE_MULTITEX_PIXEL(PB
, x
, y
, z
, fog
,
253 red
, green
, blue
, alpha
,
256 else if (ctx
->Texture
._ReallyEnabled
) {
257 PB_WRITE_TEX_PIXEL(PB
, x
,y
,z
, fog
,
258 red
, green
, blue
, alpha
,
264 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
,
265 red
, green
, blue
, alpha
);
268 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
, red
, green
, blue
, alpha
);
269 #else /* color index */
270 PB_WRITE_CI_PIXEL(PB
, x
, y
, z
, fog
, index
);
277 PB_CHECK_FLUSH(ctx
,PB
);
280 #else /* LARGE || ATTENUATE || SMOOTH*/
284 GLint x
= (GLint
) vert
->win
[0];
285 GLint y
= (GLint
) vert
->win
[1];
286 #if ((FLAGS & (SPECULAR | TEXTURE)) == (SPECULAR | TEXTURE))
287 PB_WRITE_MULTITEX_SPEC_PIXEL(PB
, x
, y
, z
, fog
,
288 red
, green
, blue
, alpha
,
291 #elif FLAGS & TEXTURE
292 if (swrast
->_MultiTextureEnabled
) {
293 PB_WRITE_MULTITEX_PIXEL(PB
, x
, y
, z
, fog
,
294 red
, green
, blue
, alpha
, texcoord
);
297 PB_WRITE_TEX_PIXEL(PB
, x
, y
, z
, fog
,
298 red
, green
, blue
, alpha
,
299 texcoord
[0][0], texcoord
[0][1], texcoord
[0][2]);
302 /* rgba size 1 point */
303 alpha
= vert
->color
[3];
304 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
, red
, green
, blue
, alpha
);
306 /* color index size 1 point */
307 PB_WRITE_CI_PIXEL(PB
, x
, y
, z
, fog
, index
);
310 #endif /* LARGE || ATTENUATE || SMOOTH */
312 PB_CHECK_FLUSH(ctx
, PB
);