1 /* $Id: s_aalinetemp.h,v 1.7 2001/03/12 00:48:41 gareth 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 * Antialiased line template.
34 * Function to render each fragment in the AA line.
37 NAME(plot
)(GLcontext
*ctx
, const struct LineInfo
*line
,
38 struct pixel_buffer
*pb
, int ix
, int iy
)
40 const GLfloat fx
= (GLfloat
) ix
;
41 const GLfloat fy
= (GLfloat
) iy
;
42 const GLfloat coverage
= compute_coveragef(line
, ix
, iy
);
45 GLchan red
, green
, blue
, alpha
;
46 GLint frac
, indx
, index
;
47 GLchan specRed
, specGreen
, specBlue
;
48 GLfloat tex
[MAX_TEXTURE_UNITS
][4], lambda
[MAX_TEXTURE_UNITS
];
54 * Compute Z, color, texture coords, fog for the fragment by
55 * solving the plane equations at (ix,iy).
58 z
= (GLdepth
) solve_plane(fx
, fy
, line
->zPlane
);
63 fog
= FloatToFixed( solve_plane(fx
, fy
, line
->fPlane
) );
68 red
= solve_plane_chan(fx
, fy
, line
->rPlane
);
69 green
= solve_plane_chan(fx
, fy
, line
->gPlane
);
70 blue
= solve_plane_chan(fx
, fy
, line
->bPlane
);
71 alpha
= (GLchan
) (solve_plane_chan(fx
, fy
, line
->aPlane
) * coverage
);;
79 frac
= (GLint
) (15.0 * coverage
);
80 indx
= (GLint
) solve_plane(fx
, fy
, line
->iPlane
);
81 index
= (indx
& ~0xf) | frac
;
88 specRed
= solve_plane_chan(fx
, fy
, line
->srPlane
);
89 specGreen
= solve_plane_chan(fx
, fy
, line
->sgPlane
);
90 specBlue
= solve_plane_chan(fx
, fy
, line
->sbPlane
);
98 GLfloat invQ
= solve_plane_recip(fx
, fy
, line
->vPlane
[0]);
99 tex
[0][0] = solve_plane(fx
, fy
, line
->sPlane
[0]) * invQ
;
100 tex
[0][1] = solve_plane(fx
, fy
, line
->tPlane
[0]) * invQ
;
101 tex
[0][2] = solve_plane(fx
, fy
, line
->uPlane
[0]) * invQ
;
102 lambda
[0] = compute_lambda(line
->sPlane
[0], line
->tPlane
[0], invQ
,
103 line
->texWidth
[0], line
->texHeight
[0]);
105 #elif defined(DO_MULTITEX)
108 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
109 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
110 GLfloat invQ
= solve_plane_recip(fx
, fy
, line
->vPlane
[unit
]);
111 tex
[unit
][0] = solve_plane(fx
, fy
, line
->sPlane
[unit
]) * invQ
;
112 tex
[unit
][1] = solve_plane(fx
, fy
, line
->tPlane
[unit
]) * invQ
;
113 tex
[unit
][2] = solve_plane(fx
, fy
, line
->uPlane
[unit
]) * invQ
;
114 lambda
[unit
] = compute_lambda(line
->sPlane
[unit
],
115 line
->tPlane
[unit
], invQ
,
116 line
->texWidth
[unit
], line
->texHeight
[unit
]);
126 #if defined(DO_MULTITEX)
128 PB_WRITE_MULTITEX_SPEC_PIXEL(pb
, ix
, iy
, z
, fog
, red
, green
, blue
, alpha
,
129 specRed
, specGreen
, specBlue
, tex
);
131 PB_WRITE_MULTITEX_PIXEL(pb
, ix
, iy
, z
, fog
, red
, green
, blue
, alpha
, texcoords
);
133 #elif defined(DO_TEX)
134 PB_WRITE_TEX_PIXEL(pb
, ix
, iy
, z
, fog
, red
, green
, blue
, alpha
,
135 tex
[0][0], tex
[0][1], tex
[0][2]);
136 #elif defined(DO_RGBA)
137 PB_WRITE_RGBA_PIXEL(pb
, ix
, iy
, z
, fog
, red
, green
, blue
, alpha
);
138 #elif defined(DO_INDEX)
139 PB_WRITE_CI_PIXEL(pb
, ix
, iy
, z
, fog
, index
);
142 PB_CHECK_FLUSH(ctx
, pb
);
151 NAME(line
)(GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
153 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
154 struct pixel_buffer
*pb
= SWRAST_CONTEXT(ctx
)->PB
;
155 GLfloat tStart
, tEnd
; /* segment start, end along line length */
159 /* Init the LineInfo struct */
160 struct LineInfo line
;
161 line
.x0
= v0
->win
[0];
162 line
.y0
= v0
->win
[1];
163 line
.x1
= v1
->win
[0];
164 line
.y1
= v1
->win
[1];
165 line
.dx
= line
.x1
- line
.x0
;
166 line
.dy
= line
.y1
- line
.y0
;
167 line
.len
= sqrt(line
.dx
* line
.dx
+ line
.dy
* line
.dy
);
168 line
.halfWidth
= 0.5F
* ctx
->Line
.Width
;
169 if (line
.len
== 0.0) {
174 line
.xAdj
= line
.dx
/ line
.len
* line
.halfWidth
;
175 line
.yAdj
= line
.dy
/ line
.len
* line
.halfWidth
;
179 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
180 v0
->win
[2], v1
->win
[2], line
.zPlane
);
183 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
184 v0
->fog
, v1
->fog
, line
.fPlane
);
187 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
188 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
189 v0
->color
[RCOMP
], v1
->color
[RCOMP
], line
.rPlane
);
190 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
191 v0
->color
[GCOMP
], v1
->color
[GCOMP
], line
.gPlane
);
192 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
193 v0
->color
[BCOMP
], v1
->color
[BCOMP
], line
.bPlane
);
194 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
195 v0
->color
[ACOMP
], v1
->color
[ACOMP
], line
.aPlane
);
198 constant_plane(v1
->color
[RCOMP
], line
.rPlane
);
199 constant_plane(v1
->color
[GCOMP
], line
.gPlane
);
200 constant_plane(v1
->color
[BCOMP
], line
.bPlane
);
201 constant_plane(v1
->color
[ACOMP
], line
.aPlane
);
205 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
206 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
207 v0
->specular
[RCOMP
], v1
->specular
[RCOMP
], line
.srPlane
);
208 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
209 v0
->specular
[GCOMP
], v1
->specular
[GCOMP
], line
.sgPlane
);
210 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
211 v0
->specular
[BCOMP
], v1
->specular
[BCOMP
], line
.sbPlane
);
214 constant_plane(v1
->specular
[RCOMP
], line
.srPlane
);
215 constant_plane(v1
->specular
[GCOMP
], line
.sgPlane
);
216 constant_plane(v1
->specular
[BCOMP
], line
.sbPlane
);
220 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
221 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
,
222 v0
->index
, v1
->index
, line
.iPlane
);
225 constant_plane(v1
->index
, line
.iPlane
);
230 const struct gl_texture_object
*obj
= ctx
->Texture
.Unit
[0]._Current
;
231 const struct gl_texture_image
*texImage
= obj
->Image
[obj
->BaseLevel
];
232 const GLfloat invW0
= v0
->win
[3];
233 const GLfloat invW1
= v1
->win
[3];
234 const GLfloat s0
= v0
->texcoord
[0][0] * invW0
;
235 const GLfloat s1
= v1
->texcoord
[0][0] * invW1
;
236 const GLfloat t0
= v0
->texcoord
[0][1] * invW0
;
237 const GLfloat t1
= v1
->texcoord
[0][1] * invW0
;
238 const GLfloat r0
= v0
->texcoord
[0][2] * invW0
;
239 const GLfloat r1
= v1
->texcoord
[0][2] * invW0
;
240 const GLfloat q0
= v0
->texcoord
[0][3] * invW0
;
241 const GLfloat q1
= v1
->texcoord
[0][3] * invW0
;
242 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, s0
, s1
, line
.sPlane
[0]);
243 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, t0
, t1
, line
.tPlane
[0]);
244 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, r0
, r1
, line
.uPlane
[0]);
245 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, q0
, q1
, line
.vPlane
[0]);
246 line
.texWidth
[0] = (GLfloat
) texImage
->Width
;
247 line
.texHeight
[0] = (GLfloat
) texImage
->Height
;
249 #elif defined(DO_MULITEX)
252 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
253 if (ctx
->Texture
.Unit
[u
].ReallyEnabled
) {
254 const struct gl_texture_object
*obj
= ctx
->Texture
.Unit
[u
].Current
;
255 const struct gl_texture_image
*texImage
= obj
->Image
[obj
->BaseLevel
];
256 const GLfloat invW0
= v0
->win
[3];
257 const GLfloat invW1
= v1
->win
[3];
258 GLfloat (*texCoord
)[4] = VB
->TexCoordPtr
[u
]->data
;
259 const GLfloat s0
= v0
->texcoord
[u
][0] * invW0
;
260 const GLfloat s1
= v1
->texcoord
[u
][0] * invW1
;
261 const GLfloat t0
= v0
->texcoord
[u
][1] * invW0
;
262 const GLfloat t1
= v1
->texcoord
[u
][1] * invW0
;
263 const GLfloat r0
= v0
->texcoord
[u
][2] * invW0
;
264 const GLfloat r1
= v1
->texcoord
[u
][2] * invW0
;
265 const GLfloat q0
= v0
->texcoord
[u
][3] * invW0
;
266 const GLfloat q1
= v1
->texcoord
[u
][3] * invW0
;
267 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, s0
, s1
, line
.sPlane
[u
]);
268 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, t0
, t1
, line
.tPlane
[u
]);
269 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, u0
, u1
, line
.uPlane
[u
]);
270 compute_plane(line
.x0
, line
.y0
, line
.x1
, line
.y1
, v0
, v1
, line
.vPlane
[u
]);
271 line
.texWidth
[u
] = (GLfloat
) texImage
->Width
;
272 line
.texHeight
[u
] = (GLfloat
) texImage
->Height
;
279 inSegment
= GL_FALSE
;
280 iLen
= (GLint
) line
.len
;
282 if (ctx
->Line
.StippleFlag
) {
283 for (i
= 0; i
< iLen
; i
++) {
284 const GLuint bit
= (swrast
->StippleCounter
/ ctx
->Line
.StippleFactor
) & 0xf;
285 if ((1 << bit
) & ctx
->Line
.StipplePattern
) {
286 /* stipple bit is on */
287 const GLfloat t
= (GLfloat
) i
/ (GLfloat
) line
.len
;
289 /* start new segment */
294 /* still in the segment, extend it */
299 /* stipple bit is off */
300 if (inSegment
&& (tEnd
> tStart
)) {
301 /* draw the segment */
302 segment(ctx
, &line
, NAME(plot
), pb
, tStart
, tEnd
);
303 inSegment
= GL_FALSE
;
306 /* still between segments, do nothing */
309 swrast
->StippleCounter
++;
313 /* draw the final segment of the line */
314 segment(ctx
, &line
, NAME(plot
), pb
, tStart
, 1.0F
);
319 segment(ctx
, &line
, NAME(plot
), pb
, 0.0, 1.0);