s_aalinetemp.h revision c1f859d4
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.1 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_RGBA 67 line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane); 68 line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane); 69 line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane); 70 line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane); 71#endif 72#ifdef DO_INDEX 73 line->span.array->index[i] = (GLint) solve_plane(fx, fy, line->iPlane); 74#endif 75#if defined(DO_ATTRIBS) 76 ATTRIB_LOOP_BEGIN 77 GLfloat (*attribArray)[4] = line->span.array->attribs[attr]; 78 if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0 79 && !ctx->FragmentProgram._Current) { 80 /* texcoord w/ divide by Q */ 81 const GLuint unit = attr - FRAG_ATTRIB_TEX0; 82 const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]); 83 GLuint c; 84 for (c = 0; c < 3; c++) { 85 attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ; 86 } 87 line->span.array->lambda[unit][i] 88 = compute_lambda(line->attrPlane[attr][0], 89 line->attrPlane[attr][1], invQ, 90 line->texWidth[attr], line->texHeight[attr]); 91 } 92 else { 93 /* non-texture attrib */ 94 const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane); 95 GLuint c; 96 for (c = 0; c < 4; c++) { 97 attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW; 98 } 99 } 100 ATTRIB_LOOP_END 101#endif 102 103 if (line->span.end == MAX_WIDTH) { 104#if defined(DO_RGBA) 105 _swrast_write_rgba_span(ctx, &(line->span)); 106#else 107 _swrast_write_index_span(ctx, &(line->span)); 108#endif 109 line->span.end = 0; /* reset counter */ 110 } 111} 112 113 114 115/* 116 * Line setup 117 */ 118static void 119NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) 120{ 121 SWcontext *swrast = SWRAST_CONTEXT(ctx); 122 GLfloat tStart, tEnd; /* segment start, end along line length */ 123 GLboolean inSegment; 124 GLint iLen, i; 125 126 /* Init the LineInfo struct */ 127 struct LineInfo line; 128 line.x0 = v0->attrib[FRAG_ATTRIB_WPOS][0]; 129 line.y0 = v0->attrib[FRAG_ATTRIB_WPOS][1]; 130 line.x1 = v1->attrib[FRAG_ATTRIB_WPOS][0]; 131 line.y1 = v1->attrib[FRAG_ATTRIB_WPOS][1]; 132 line.dx = line.x1 - line.x0; 133 line.dy = line.y1 - line.y0; 134 line.len = SQRTF(line.dx * line.dx + line.dy * line.dy); 135 line.halfWidth = 0.5F * CLAMP(ctx->Line.Width, 136 ctx->Const.MinLineWidthAA, 137 ctx->Const.MaxLineWidthAA); 138 139 if (line.len == 0.0 || IS_INF_OR_NAN(line.len)) 140 return; 141 142 INIT_SPAN(line.span, GL_LINE); 143 line.span.arrayMask = SPAN_XY | SPAN_COVERAGE; 144 line.span.facing = swrast->PointLineFacing; 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->attrib[FRAG_ATTRIB_WPOS][2], v1->attrib[FRAG_ATTRIB_WPOS][2], line.zPlane); 152#endif 153#ifdef DO_RGBA 154 line.span.arrayMask |= SPAN_RGBA; 155 if (ctx->Light.ShadeModel == GL_SMOOTH) { 156 compute_plane(line.x0, line.y0, line.x1, line.y1, 157 v0->color[RCOMP], v1->color[RCOMP], line.rPlane); 158 compute_plane(line.x0, line.y0, line.x1, line.y1, 159 v0->color[GCOMP], v1->color[GCOMP], line.gPlane); 160 compute_plane(line.x0, line.y0, line.x1, line.y1, 161 v0->color[BCOMP], v1->color[BCOMP], line.bPlane); 162 compute_plane(line.x0, line.y0, line.x1, line.y1, 163 v0->color[ACOMP], v1->color[ACOMP], line.aPlane); 164 } 165 else { 166 constant_plane(v1->color[RCOMP], line.rPlane); 167 constant_plane(v1->color[GCOMP], line.gPlane); 168 constant_plane(v1->color[BCOMP], line.bPlane); 169 constant_plane(v1->color[ACOMP], line.aPlane); 170 } 171#endif 172#ifdef DO_INDEX 173 line.span.arrayMask |= SPAN_INDEX; 174 if (ctx->Light.ShadeModel == GL_SMOOTH) { 175 compute_plane(line.x0, line.y0, line.x1, line.y1, 176 v0->attrib[FRAG_ATTRIB_CI][0], 177 v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane); 178 } 179 else { 180 constant_plane(v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane); 181 } 182#endif 183#if defined(DO_ATTRIBS) 184 { 185 const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3]; 186 const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3]; 187 line.span.arrayMask |= SPAN_LAMBDA; 188 compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane); 189 ATTRIB_LOOP_BEGIN 190 GLuint c; 191 if (swrast->_InterpMode[attr] == GL_FLAT) { 192 for (c = 0; c < 4; c++) { 193 constant_plane(v1->attrib[attr][c], line.attrPlane[attr][c]); 194 } 195 } 196 else { 197 for (c = 0; c < 4; c++) { 198 const GLfloat a0 = v0->attrib[attr][c] * invW0; 199 const GLfloat a1 = v1->attrib[attr][c] * invW1; 200 compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1, 201 line.attrPlane[attr][c]); 202 } 203 } 204 line.span.arrayAttribs |= (1 << attr); 205 if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) { 206 const GLuint u = attr - FRAG_ATTRIB_TEX0; 207 const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; 208 const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; 209 line.texWidth[attr] = (GLfloat) texImage->Width; 210 line.texHeight[attr] = (GLfloat) texImage->Height; 211 } 212 ATTRIB_LOOP_END 213 } 214#endif 215 216 tStart = tEnd = 0.0; 217 inSegment = GL_FALSE; 218 iLen = (GLint) line.len; 219 220 if (ctx->Line.StippleFlag) { 221 for (i = 0; i < iLen; i++) { 222 const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; 223 if ((1 << bit) & ctx->Line.StipplePattern) { 224 /* stipple bit is on */ 225 const GLfloat t = (GLfloat) i / (GLfloat) line.len; 226 if (!inSegment) { 227 /* start new segment */ 228 inSegment = GL_TRUE; 229 tStart = t; 230 } 231 else { 232 /* still in the segment, extend it */ 233 tEnd = t; 234 } 235 } 236 else { 237 /* stipple bit is off */ 238 if (inSegment && (tEnd > tStart)) { 239 /* draw the segment */ 240 segment(ctx, &line, NAME(plot), tStart, tEnd); 241 inSegment = GL_FALSE; 242 } 243 else { 244 /* still between segments, do nothing */ 245 } 246 } 247 swrast->StippleCounter++; 248 } 249 250 if (inSegment) { 251 /* draw the final segment of the line */ 252 segment(ctx, &line, NAME(plot), tStart, 1.0F); 253 } 254 } 255 else { 256 /* non-stippled */ 257 segment(ctx, &line, NAME(plot), 0.0, 1.0); 258 } 259 260#if defined(DO_RGBA) 261 _swrast_write_rgba_span(ctx, &(line.span)); 262#else 263 _swrast_write_index_span(ctx, &(line.span)); 264#endif 265} 266 267 268 269 270#undef DO_Z 271#undef DO_RGBA 272#undef DO_INDEX 273#undef DO_ATTRIBS 274#undef NAME 275