ed2ab0ca5e38982c338af8ef5195ef6acdef16d7
1 /* $Id: s_pointtemp.h,v 1.1 2001/01/03 22:17:16 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 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
= vert
->win
[0] - iRadius
;
204 xmax
= vert
->win
[0] + iRadius
;
205 ymin
= vert
->win
[1] - iRadius
;
206 ymax
= 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];
223 const GLfloat dy
= y
- vert
->win
[1];
224 const GLfloat dist2
= dx
* dx
+ dy
* dy
;
226 alpha
= vert
->color
[3];
227 if (dist2
>= rmin2
) {
228 GLint coverage
= (GLint
) (256.0F
- (dist2
- rmin2
) * cscale
);
230 /* coverage is in [0,256] */
231 alpha
= (alpha
* coverage
) >> 8;
233 /* 4 fractional index bits */
234 index
= (index
& ~f
) | (coverage
>> 4); /* XXX verify */
239 #if ((FLAGS & (ATTENUATE | RGBA)) == (ATTENUATE | RGBA))
240 alpha
= (GLint
) (alpha
* alphaAtten
);
244 PB_WRITE_MULTITEX_SPEC_PIXEL(PB
, x
, y
, z
, fog
,
245 red
, green
, blue
, alpha
,
249 #elif FLAGS & TEXTURE
250 if (swrast
->_MultiTextureEnabled
) {
251 PB_WRITE_MULTITEX_PIXEL(PB
, x
, y
, z
, fog
,
252 red
, green
, blue
, alpha
,
256 PB_WRITE_TEX_PIXEL(PB
, x
,y
,z
, fog
,
257 red
, green
, blue
, alpha
,
263 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
, red
, green
, blue
, alpha
);
264 #else /* color index */
265 PB_WRITE_CI_PIXEL(PB
, x
, y
, z
, fog
, index
);
272 PB_CHECK_FLUSH(ctx
,PB
);
275 #else /* LARGE || ATTENUATE || SMOOTH*/
279 GLint x
= vert
->win
[0];
280 GLint y
= vert
->win
[1];
281 #if ((FLAGS & (SPECULAR | TEXTURE)) == (SPECULAR | TEXTURE))
282 PB_WRITE_MULTITEX_SPEC_PIXEL(PB
, x
, y
, z
, fog
,
283 red
, green
, blue
, alpha
,
286 #elif FLAGS & TEXTURE
287 if (swrast
->_MultiTextureEnabled
) {
288 PB_WRITE_MULTITEX_PIXEL(PB
, x
, y
, z
, fog
,
289 red
, green
, blue
, alpha
, texcoord
);
292 PB_WRITE_TEX_PIXEL(PB
, x
, y
, z
, fog
,
293 red
, green
, blue
, alpha
,
294 texcoord
[0][0], texcoord
[0][1], texcoord
[0][2]);
297 /* rgba size 1 point */
298 alpha
= vert
->color
[3];
299 PB_WRITE_RGBA_PIXEL(PB
, x
, y
, z
, fog
, red
, green
, blue
, alpha
);
301 /* color index size 1 point */
302 PB_WRITE_CI_PIXEL(PB
, x
, y
, z
, fog
, index
);
305 #endif /* LARGE || ATTENUATE || SMOOTH */
307 PB_CHECK_FLUSH(ctx
, PB
);