s_aalinetemp.h revision 8662c5d98febd8efaf5f8ee47d34c7fcfd597ce3
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.3 4 * 5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/* 27 * Antialiased line template. 28 */ 29 30 31/* 32 * Function to render each fragment in the AA line. 33 */ 34static void 35NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) 36{ 37 const GLfloat fx = (GLfloat) ix; 38 const GLfloat fy = (GLfloat) iy; 39#ifdef DO_INDEX 40 const GLfloat coverage = compute_coveragei(line, ix, iy); 41#else 42 const GLfloat coverage = compute_coveragef(line, ix, iy); 43#endif 44 const GLuint i = line->span.end; 45 46 if (coverage == 0.0) 47 return; 48 49 line->span.end++; 50 line->span.array->coverage[i] = coverage; 51 line->span.array->x[i] = ix; 52 line->span.array->y[i] = iy; 53 54 /* 55 * Compute Z, color, texture coords, fog for the fragment by 56 * solving the plane equations at (ix,iy). 57 */ 58#ifdef DO_Z 59 line->span.array->z[i] = (GLdepth) IROUND(solve_plane(fx, fy, line->zPlane)); 60#endif 61#ifdef DO_FOG 62 line->span.array->fog[i] = solve_plane(fx, fy, line->fPlane); 63#endif 64#ifdef DO_RGBA 65 line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane); 66 line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane); 67 line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane); 68 line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane); 69#endif 70#ifdef DO_INDEX 71 line->span.array->index[i] = (GLint) solve_plane(fx, fy, line->iPlane); 72#endif 73#ifdef DO_SPEC 74 line->span.array->spec[i][RCOMP] = solve_plane_chan(fx, fy, line->srPlane); 75 line->span.array->spec[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane); 76 line->span.array->spec[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane); 77#endif 78#ifdef DO_TEX 79 { 80 const GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[0]); 81 line->span.array->texcoords[0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ; 82 line->span.array->texcoords[0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ; 83 line->span.array->texcoords[0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ; 84 line->span.array->lambda[0][i] = compute_lambda(line->sPlane[0], line->tPlane[0], invQ, 85 line->texWidth[0], line->texHeight[0]); 86 } 87#elif defined(DO_MULTITEX) 88 { 89 GLuint unit; 90 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 91 if (ctx->Texture.Unit[unit]._ReallyEnabled) { 92 const GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[unit]); 93 line->span.array->texcoords[unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ; 94 line->span.array->texcoords[unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ; 95 line->span.array->texcoords[unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ; 96 line->span.array->lambda[unit][i] = compute_lambda(line->sPlane[unit], 97 line->tPlane[unit], invQ, 98 line->texWidth[unit], line->texHeight[unit]); 99 } 100 } 101 } 102#endif 103 104 if (line->span.end == MAX_WIDTH) { 105#if defined(DO_TEX) || defined(DO_MULTITEX) 106 _swrast_write_texture_span(ctx, &(line->span)); 107#elif defined(DO_RGBA) 108 _swrast_write_rgba_span(ctx, &(line->span)); 109#else 110 _swrast_write_index_span(ctx, &(line->span)); 111#endif 112 line->span.end = 0; /* reset counter */ 113 } 114} 115 116 117 118/* 119 * Line setup 120 */ 121static void 122NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) 123{ 124 SWcontext *swrast = SWRAST_CONTEXT(ctx); 125 GLfloat tStart, tEnd; /* segment start, end along line length */ 126 GLboolean inSegment; 127 GLint iLen, i; 128 129 /* Init the LineInfo struct */ 130 struct LineInfo line; 131 line.x0 = v0->win[0]; 132 line.y0 = v0->win[1]; 133 line.x1 = v1->win[0]; 134 line.y1 = v1->win[1]; 135 line.dx = line.x1 - line.x0; 136 line.dy = line.y1 - line.y0; 137 line.len = SQRTF(line.dx * line.dx + line.dy * line.dy); 138 line.halfWidth = 0.5F * ctx->Line.Width; 139 140 if (line.len == 0.0 || IS_INF_OR_NAN(line.len)) 141 return; 142 143 INIT_SPAN(line.span, GL_LINE, 0, 0, SPAN_XY | SPAN_COVERAGE); 144 145 line.xAdj = line.dx / line.len * line.halfWidth; 146 line.yAdj = line.dy / line.len * line.halfWidth; 147 148#ifdef DO_Z 149 line.span.arrayMask |= SPAN_Z; 150 compute_plane(line.x0, line.y0, line.x1, line.y1, 151 v0->win[2], v1->win[2], line.zPlane); 152#endif 153#ifdef DO_FOG 154 line.span.arrayMask |= SPAN_FOG; 155 compute_plane(line.x0, line.y0, line.x1, line.y1, 156 v0->fog, v1->fog, line.fPlane); 157#endif 158#ifdef DO_RGBA 159 line.span.arrayMask |= SPAN_RGBA; 160 if (ctx->Light.ShadeModel == GL_SMOOTH) { 161 compute_plane(line.x0, line.y0, line.x1, line.y1, 162 v0->color[RCOMP], v1->color[RCOMP], line.rPlane); 163 compute_plane(line.x0, line.y0, line.x1, line.y1, 164 v0->color[GCOMP], v1->color[GCOMP], line.gPlane); 165 compute_plane(line.x0, line.y0, line.x1, line.y1, 166 v0->color[BCOMP], v1->color[BCOMP], line.bPlane); 167 compute_plane(line.x0, line.y0, line.x1, line.y1, 168 v0->color[ACOMP], v1->color[ACOMP], line.aPlane); 169 } 170 else { 171 constant_plane(v1->color[RCOMP], line.rPlane); 172 constant_plane(v1->color[GCOMP], line.gPlane); 173 constant_plane(v1->color[BCOMP], line.bPlane); 174 constant_plane(v1->color[ACOMP], line.aPlane); 175 } 176#endif 177#ifdef DO_SPEC 178 line.span.arrayMask |= SPAN_SPEC; 179 if (ctx->Light.ShadeModel == GL_SMOOTH) { 180 compute_plane(line.x0, line.y0, line.x1, line.y1, 181 v0->specular[RCOMP], v1->specular[RCOMP], line.srPlane); 182 compute_plane(line.x0, line.y0, line.x1, line.y1, 183 v0->specular[GCOMP], v1->specular[GCOMP], line.sgPlane); 184 compute_plane(line.x0, line.y0, line.x1, line.y1, 185 v0->specular[BCOMP], v1->specular[BCOMP], line.sbPlane); 186 } 187 else { 188 constant_plane(v1->specular[RCOMP], line.srPlane); 189 constant_plane(v1->specular[GCOMP], line.sgPlane); 190 constant_plane(v1->specular[BCOMP], line.sbPlane); 191 } 192#endif 193#ifdef DO_INDEX 194 line.span.arrayMask |= SPAN_INDEX; 195 if (ctx->Light.ShadeModel == GL_SMOOTH) { 196 compute_plane(line.x0, line.y0, line.x1, line.y1, 197 v0->index, v1->index, line.iPlane); 198 } 199 else { 200 constant_plane(v1->index, line.iPlane); 201 } 202#endif 203#ifdef DO_TEX 204 { 205 const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; 206 const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; 207 const GLfloat invW0 = v0->win[3]; 208 const GLfloat invW1 = v1->win[3]; 209 const GLfloat s0 = v0->texcoord[0][0] * invW0; 210 const GLfloat s1 = v1->texcoord[0][0] * invW1; 211 const GLfloat t0 = v0->texcoord[0][1] * invW0; 212 const GLfloat t1 = v1->texcoord[0][1] * invW1; 213 const GLfloat r0 = v0->texcoord[0][2] * invW0; 214 const GLfloat r1 = v1->texcoord[0][2] * invW1; 215 const GLfloat q0 = v0->texcoord[0][3] * invW0; 216 const GLfloat q1 = v1->texcoord[0][3] * invW1; 217 line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); 218 compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[0]); 219 compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[0]); 220 compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[0]); 221 compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[0]); 222 line.texWidth[0] = (GLfloat) texImage->Width; 223 line.texHeight[0] = (GLfloat) texImage->Height; 224 } 225#elif defined(DO_MULTITEX) 226 { 227 GLuint u; 228 line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); 229 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 230 if (ctx->Texture.Unit[u]._ReallyEnabled) { 231 const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; 232 const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; 233 const GLfloat invW0 = v0->win[3]; 234 const GLfloat invW1 = v1->win[3]; 235 const GLfloat s0 = v0->texcoord[u][0] * invW0; 236 const GLfloat s1 = v1->texcoord[u][0] * invW1; 237 const GLfloat t0 = v0->texcoord[u][1] * invW0; 238 const GLfloat t1 = v1->texcoord[u][1] * invW1; 239 const GLfloat r0 = v0->texcoord[u][2] * invW0; 240 const GLfloat r1 = v1->texcoord[u][2] * invW1; 241 const GLfloat q0 = v0->texcoord[u][3] * invW0; 242 const GLfloat q1 = v1->texcoord[u][3] * invW1; 243 compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[u]); 244 compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[u]); 245 compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[u]); 246 compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[u]); 247 line.texWidth[u] = (GLfloat) texImage->Width; 248 line.texHeight[u] = (GLfloat) texImage->Height; 249 } 250 } 251 } 252#endif 253 254 tStart = tEnd = 0.0; 255 inSegment = GL_FALSE; 256 iLen = (GLint) line.len; 257 258 if (ctx->Line.StippleFlag) { 259 for (i = 0; i < iLen; i++) { 260 const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; 261 if ((1 << bit) & ctx->Line.StipplePattern) { 262 /* stipple bit is on */ 263 const GLfloat t = (GLfloat) i / (GLfloat) line.len; 264 if (!inSegment) { 265 /* start new segment */ 266 inSegment = GL_TRUE; 267 tStart = t; 268 } 269 else { 270 /* still in the segment, extend it */ 271 tEnd = t; 272 } 273 } 274 else { 275 /* stipple bit is off */ 276 if (inSegment && (tEnd > tStart)) { 277 /* draw the segment */ 278 segment(ctx, &line, NAME(plot), tStart, tEnd); 279 inSegment = GL_FALSE; 280 } 281 else { 282 /* still between segments, do nothing */ 283 } 284 } 285 swrast->StippleCounter++; 286 } 287 288 if (inSegment) { 289 /* draw the final segment of the line */ 290 segment(ctx, &line, NAME(plot), tStart, 1.0F); 291 } 292 } 293 else { 294 /* non-stippled */ 295 segment(ctx, &line, NAME(plot), 0.0, 1.0); 296 } 297 298#if defined(DO_TEX) || defined(DO_MULTITEX) 299 _swrast_write_texture_span(ctx, &(line.span)); 300#elif defined(DO_RGBA) 301 _swrast_write_rgba_span(ctx, &(line.span)); 302#else 303 _swrast_write_index_span(ctx, &(line.span)); 304#endif 305} 306 307 308 309 310#undef DO_Z 311#undef DO_FOG 312#undef DO_RGBA 313#undef DO_INDEX 314#undef DO_SPEC 315#undef DO_TEX 316#undef DO_MULTITEX 317#undef NAME 318