s_aalinetemp.h revision 7117f1b4
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5.3 4 * 5 * Copyright (C) 1999-2007 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 * \param ix - integer fragment window X coordiante 34 * \param iy - integer fragment window Y coordiante 35 */ 36static void 37NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) 38{ 39 const SWcontext *swrast = SWRAST_CONTEXT(ctx); 40 const GLfloat fx = (GLfloat) ix; 41 const GLfloat fy = (GLfloat) iy; 42#ifdef DO_INDEX 43 const GLfloat coverage = compute_coveragei(line, ix, iy); 44#else 45 const GLfloat coverage = compute_coveragef(line, ix, iy); 46#endif 47 const GLuint i = line->span.end; 48 49 (void) swrast; 50 51 if (coverage == 0.0) 52 return; 53 54 line->span.end++; 55 line->span.array->coverage[i] = coverage; 56 line->span.array->x[i] = ix; 57 line->span.array->y[i] = iy; 58 59 /* 60 * Compute Z, color, texture coords, fog for the fragment by 61 * solving the plane equations at (ix,iy). 62 */ 63#ifdef DO_Z 64 line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane); 65#endif 66#ifdef DO_FOG 67 line->span.array->attribs[FRAG_ATTRIB_FOGC][i][0] = solve_plane(fx, fy, line->fPlane); 68#endif 69#ifdef DO_RGBA 70 line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane); 71 line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane); 72 line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane); 73 line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane); 74#endif 75#ifdef DO_INDEX 76 line->span.array->index[i] = (GLint) solve_plane(fx, fy, line->iPlane); 77#endif 78#ifdef DO_SPEC 79 line->span.array->spec[i][RCOMP] = solve_plane_chan(fx, fy, line->srPlane); 80 line->span.array->spec[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane); 81 line->span.array->spec[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane); 82#endif 83#if defined(DO_ATTRIBS) 84 ATTRIB_LOOP_BEGIN 85 GLfloat (*attribArray)[4] = line->span.array->attribs[attr]; 86 GLfloat invQ; 87 if (ctx->FragmentProgram._Active) { 88 invQ = 1.0F; 89 } 90 else { 91 invQ = solve_plane_recip(fx, fy, line->vPlane[attr]); 92 } 93 attribArray[i][0] = solve_plane(fx, fy, line->sPlane[attr]) * invQ; 94 attribArray[i][1] = solve_plane(fx, fy, line->tPlane[attr]) * invQ; 95 attribArray[i][2] = solve_plane(fx, fy, line->uPlane[attr]) * invQ; 96 if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) { 97 const GLuint unit = attr - FRAG_ATTRIB_TEX0; 98 line->span.array->lambda[unit][i] 99 = compute_lambda(line->sPlane[attr], 100 line->tPlane[attr], invQ, 101 line->texWidth[attr], line->texHeight[attr]); 102 } 103 ATTRIB_LOOP_END 104#endif 105 106 if (line->span.end == MAX_WIDTH) { 107#if 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 line.span.facing = swrast->PointLineFacing; 145 146 line.xAdj = line.dx / line.len * line.halfWidth; 147 line.yAdj = line.dy / line.len * line.halfWidth; 148 149#ifdef DO_Z 150 line.span.arrayMask |= SPAN_Z; 151 compute_plane(line.x0, line.y0, line.x1, line.y1, 152 v0->win[2], v1->win[2], line.zPlane); 153#endif 154#ifdef DO_FOG 155 line.span.arrayMask |= SPAN_FOG; 156 compute_plane(line.x0, line.y0, line.x1, line.y1, 157 v0->attrib[FRAG_ATTRIB_FOGC][0], 158 v1->attrib[FRAG_ATTRIB_FOGC][0], 159 line.fPlane); 160#endif 161#ifdef DO_RGBA 162 line.span.arrayMask |= SPAN_RGBA; 163 if (ctx->Light.ShadeModel == GL_SMOOTH) { 164 compute_plane(line.x0, line.y0, line.x1, line.y1, 165 v0->color[RCOMP], v1->color[RCOMP], line.rPlane); 166 compute_plane(line.x0, line.y0, line.x1, line.y1, 167 v0->color[GCOMP], v1->color[GCOMP], line.gPlane); 168 compute_plane(line.x0, line.y0, line.x1, line.y1, 169 v0->color[BCOMP], v1->color[BCOMP], line.bPlane); 170 compute_plane(line.x0, line.y0, line.x1, line.y1, 171 v0->color[ACOMP], v1->color[ACOMP], line.aPlane); 172 } 173 else { 174 constant_plane(v1->color[RCOMP], line.rPlane); 175 constant_plane(v1->color[GCOMP], line.gPlane); 176 constant_plane(v1->color[BCOMP], line.bPlane); 177 constant_plane(v1->color[ACOMP], line.aPlane); 178 } 179#endif 180#ifdef DO_SPEC 181 line.span.arrayMask |= SPAN_SPEC; 182 if (ctx->Light.ShadeModel == GL_SMOOTH) { 183 compute_plane(line.x0, line.y0, line.x1, line.y1, 184 v0->specular[RCOMP], v1->specular[RCOMP], line.srPlane); 185 compute_plane(line.x0, line.y0, line.x1, line.y1, 186 v0->specular[GCOMP], v1->specular[GCOMP], line.sgPlane); 187 compute_plane(line.x0, line.y0, line.x1, line.y1, 188 v0->specular[BCOMP], v1->specular[BCOMP], line.sbPlane); 189 } 190 else { 191 constant_plane(v1->specular[RCOMP], line.srPlane); 192 constant_plane(v1->specular[GCOMP], line.sgPlane); 193 constant_plane(v1->specular[BCOMP], line.sbPlane); 194 } 195#endif 196#ifdef DO_INDEX 197 line.span.arrayMask |= SPAN_INDEX; 198 if (ctx->Light.ShadeModel == GL_SMOOTH) { 199 compute_plane(line.x0, line.y0, line.x1, line.y1, 200 v0->index, v1->index, line.iPlane); 201 } 202 else { 203 constant_plane(v1->index, line.iPlane); 204 } 205#endif 206#if defined(DO_ATTRIBS) 207 { 208 const GLfloat invW0 = v0->win[3]; 209 const GLfloat invW1 = v1->win[3]; 210 line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING); 211 ATTRIB_LOOP_BEGIN 212 const GLfloat s0 = v0->attrib[attr][0] * invW0; 213 const GLfloat s1 = v1->attrib[attr][0] * invW1; 214 const GLfloat t0 = v0->attrib[attr][1] * invW0; 215 const GLfloat t1 = v1->attrib[attr][1] * invW1; 216 const GLfloat r0 = v0->attrib[attr][2] * invW0; 217 const GLfloat r1 = v1->attrib[attr][2] * invW1; 218 const GLfloat q0 = v0->attrib[attr][3] * invW0; 219 const GLfloat q1 = v1->attrib[attr][3] * invW1; 220 compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[attr]); 221 compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[attr]); 222 compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[attr]); 223 compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[attr]); 224 if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) { 225 const GLuint u = attr - FRAG_ATTRIB_TEX0; 226 const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; 227 const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; 228 line.texWidth[attr] = (GLfloat) texImage->Width; 229 line.texHeight[attr] = (GLfloat) texImage->Height; 230 } 231 ATTRIB_LOOP_END 232 } 233#endif 234 235 tStart = tEnd = 0.0; 236 inSegment = GL_FALSE; 237 iLen = (GLint) line.len; 238 239 if (ctx->Line.StippleFlag) { 240 for (i = 0; i < iLen; i++) { 241 const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; 242 if ((1 << bit) & ctx->Line.StipplePattern) { 243 /* stipple bit is on */ 244 const GLfloat t = (GLfloat) i / (GLfloat) line.len; 245 if (!inSegment) { 246 /* start new segment */ 247 inSegment = GL_TRUE; 248 tStart = t; 249 } 250 else { 251 /* still in the segment, extend it */ 252 tEnd = t; 253 } 254 } 255 else { 256 /* stipple bit is off */ 257 if (inSegment && (tEnd > tStart)) { 258 /* draw the segment */ 259 segment(ctx, &line, NAME(plot), tStart, tEnd); 260 inSegment = GL_FALSE; 261 } 262 else { 263 /* still between segments, do nothing */ 264 } 265 } 266 swrast->StippleCounter++; 267 } 268 269 if (inSegment) { 270 /* draw the final segment of the line */ 271 segment(ctx, &line, NAME(plot), tStart, 1.0F); 272 } 273 } 274 else { 275 /* non-stippled */ 276 segment(ctx, &line, NAME(plot), 0.0, 1.0); 277 } 278 279#if defined(DO_RGBA) 280 _swrast_write_rgba_span(ctx, &(line.span)); 281#else 282 _swrast_write_index_span(ctx, &(line.span)); 283#endif 284} 285 286 287 288 289#undef DO_Z 290#undef DO_FOG 291#undef DO_RGBA 292#undef DO_INDEX 293#undef DO_SPEC 294#undef DO_ATTRIBS 295#undef NAME 296