Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Mesa 3-D graphics library |
Brian | 5237f86 | 2007-05-25 16:22:15 -0600 | [diff] [blame] | 3 | * Version: 7.1 |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 4 | * |
Brian | dd34fe8 | 2007-02-05 10:10:01 -0700 | [diff] [blame] | 5 | * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 6 | * |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 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: |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 13 | * |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 14 | * The above copyright notice and this permission notice shall be included |
| 15 | * in all copies or substantial portions of the Software. |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 16 | * |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 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. |
Brian Paul | a803b0c | 2004-12-18 22:03:07 +0000 | [diff] [blame] | 33 | * \param ix - integer fragment window X coordiante |
| 34 | * \param iy - integer fragment window Y coordiante |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 35 | */ |
| 36 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 37 | NAME(plot)(struct gl_context *ctx, struct LineInfo *line, int ix, int iy) |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 38 | { |
Brian | dd34fe8 | 2007-02-05 10:10:01 -0700 | [diff] [blame] | 39 | const SWcontext *swrast = SWRAST_CONTEXT(ctx); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 40 | const GLfloat fx = (GLfloat) ix; |
| 41 | const GLfloat fy = (GLfloat) iy; |
| 42 | const GLfloat coverage = compute_coveragef(line, ix, iy); |
Brian Paul | 77df887 | 2002-08-07 00:45:07 +0000 | [diff] [blame] | 43 | const GLuint i = line->span.end; |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 44 | |
Brian | dd34fe8 | 2007-02-05 10:10:01 -0700 | [diff] [blame] | 45 | (void) swrast; |
| 46 | |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 47 | if (coverage == 0.0) |
| 48 | return; |
| 49 | |
Brian Paul | 77df887 | 2002-08-07 00:45:07 +0000 | [diff] [blame] | 50 | line->span.end++; |
| 51 | line->span.array->coverage[i] = coverage; |
| 52 | line->span.array->x[i] = ix; |
| 53 | line->span.array->y[i] = iy; |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 54 | |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 55 | /* |
| 56 | * Compute Z, color, texture coords, fog for the fragment by |
| 57 | * solving the plane equations at (ix,iy). |
| 58 | */ |
| 59 | #ifdef DO_Z |
Brian Paul | 3e37baf | 2005-09-21 02:47:32 +0000 | [diff] [blame] | 60 | line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 61 | #endif |
Brian Paul | 77df887 | 2002-08-07 00:45:07 +0000 | [diff] [blame] | 62 | line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane); |
| 63 | line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane); |
| 64 | line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane); |
| 65 | line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane); |
Brian | eca456b | 2007-04-24 16:57:38 -0600 | [diff] [blame] | 66 | #if defined(DO_ATTRIBS) |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 67 | ATTRIB_LOOP_BEGIN |
| 68 | GLfloat (*attribArray)[4] = line->span.array->attribs[attr]; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 69 | if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0 |
Chad Versace | 1c0f1dd | 2012-01-25 19:38:10 -0800 | [diff] [blame] | 70 | && !_swrast_use_fragment_program(ctx)) { |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 71 | /* texcoord w/ divide by Q */ |
| 72 | const GLuint unit = attr - FRAG_ATTRIB_TEX0; |
| 73 | const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]); |
| 74 | GLuint c; |
| 75 | for (c = 0; c < 3; c++) { |
| 76 | attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ; |
| 77 | } |
| 78 | line->span.array->lambda[unit][i] |
| 79 | = compute_lambda(line->attrPlane[attr][0], |
| 80 | line->attrPlane[attr][1], invQ, |
| 81 | line->texWidth[attr], line->texHeight[attr]); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 82 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 83 | else { |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 84 | /* non-texture attrib */ |
| 85 | const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane); |
| 86 | GLuint c; |
| 87 | for (c = 0; c < 4; c++) { |
| 88 | attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW; |
| 89 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 90 | } |
| 91 | ATTRIB_LOOP_END |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 92 | #endif |
| 93 | |
Brian Paul | 47d88ef | 2012-02-20 11:07:00 -0700 | [diff] [blame^] | 94 | if (line->span.end == SWRAST_MAX_WIDTH) { |
Brian Paul | 45bc887 | 2003-03-25 02:23:44 +0000 | [diff] [blame] | 95 | _swrast_write_rgba_span(ctx, &(line->span)); |
Brian Paul | 77df887 | 2002-08-07 00:45:07 +0000 | [diff] [blame] | 96 | line->span.end = 0; /* reset counter */ |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 97 | } |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | |
| 101 | |
| 102 | /* |
| 103 | * Line setup |
| 104 | */ |
| 105 | static void |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 106 | NAME(line)(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1) |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 107 | { |
| 108 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 109 | GLfloat tStart, tEnd; /* segment start, end along line length */ |
| 110 | GLboolean inSegment; |
| 111 | GLint iLen, i; |
| 112 | |
| 113 | /* Init the LineInfo struct */ |
| 114 | struct LineInfo line; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 115 | line.x0 = v0->attrib[FRAG_ATTRIB_WPOS][0]; |
| 116 | line.y0 = v0->attrib[FRAG_ATTRIB_WPOS][1]; |
| 117 | line.x1 = v1->attrib[FRAG_ATTRIB_WPOS][0]; |
| 118 | line.y1 = v1->attrib[FRAG_ATTRIB_WPOS][1]; |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 119 | line.dx = line.x1 - line.x0; |
| 120 | line.dy = line.y1 - line.y0; |
Brian Paul | f9b1e52 | 2003-03-04 16:33:53 +0000 | [diff] [blame] | 121 | line.len = SQRTF(line.dx * line.dx + line.dy * line.dy); |
Brian | af2aa8e | 2007-07-21 10:06:18 -0600 | [diff] [blame] | 122 | line.halfWidth = 0.5F * CLAMP(ctx->Line.Width, |
| 123 | ctx->Const.MinLineWidthAA, |
| 124 | ctx->Const.MaxLineWidthAA); |
Brian Paul | dbed202 | 2001-05-10 17:41:41 +0000 | [diff] [blame] | 125 | |
Keith Whitwell | ef4f5b3 | 2001-12-05 10:24:31 +0000 | [diff] [blame] | 126 | if (line.len == 0.0 || IS_INF_OR_NAN(line.len)) |
Brian Paul | dbed202 | 2001-05-10 17:41:41 +0000 | [diff] [blame] | 127 | return; |
| 128 | |
Brian | f4b103d | 2007-06-29 21:52:18 -0600 | [diff] [blame] | 129 | INIT_SPAN(line.span, GL_LINE); |
| 130 | line.span.arrayMask = SPAN_XY | SPAN_COVERAGE; |
Brian | fcd7c37 | 2007-11-30 13:01:57 -0700 | [diff] [blame] | 131 | line.span.facing = swrast->PointLineFacing; |
Brian Paul | dbed202 | 2001-05-10 17:41:41 +0000 | [diff] [blame] | 132 | line.xAdj = line.dx / line.len * line.halfWidth; |
| 133 | line.yAdj = line.dy / line.len * line.halfWidth; |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 134 | |
| 135 | #ifdef DO_Z |
Brian Paul | 77df887 | 2002-08-07 00:45:07 +0000 | [diff] [blame] | 136 | line.span.arrayMask |= SPAN_Z; |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 137 | compute_plane(line.x0, line.y0, line.x1, line.y1, |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 138 | v0->attrib[FRAG_ATTRIB_WPOS][2], v1->attrib[FRAG_ATTRIB_WPOS][2], line.zPlane); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 139 | #endif |
Brian Paul | 77df887 | 2002-08-07 00:45:07 +0000 | [diff] [blame] | 140 | line.span.arrayMask |= SPAN_RGBA; |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 141 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
| 142 | compute_plane(line.x0, line.y0, line.x1, line.y1, |
| 143 | v0->color[RCOMP], v1->color[RCOMP], line.rPlane); |
| 144 | compute_plane(line.x0, line.y0, line.x1, line.y1, |
| 145 | v0->color[GCOMP], v1->color[GCOMP], line.gPlane); |
| 146 | compute_plane(line.x0, line.y0, line.x1, line.y1, |
| 147 | v0->color[BCOMP], v1->color[BCOMP], line.bPlane); |
| 148 | compute_plane(line.x0, line.y0, line.x1, line.y1, |
| 149 | v0->color[ACOMP], v1->color[ACOMP], line.aPlane); |
| 150 | } |
| 151 | else { |
Keith Whitwell | 58e9917 | 2001-01-05 02:26:48 +0000 | [diff] [blame] | 152 | constant_plane(v1->color[RCOMP], line.rPlane); |
| 153 | constant_plane(v1->color[GCOMP], line.gPlane); |
| 154 | constant_plane(v1->color[BCOMP], line.bPlane); |
| 155 | constant_plane(v1->color[ACOMP], line.aPlane); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 156 | } |
Brian | eca456b | 2007-04-24 16:57:38 -0600 | [diff] [blame] | 157 | #if defined(DO_ATTRIBS) |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 158 | { |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 159 | const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3]; |
| 160 | const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3]; |
| 161 | line.span.arrayMask |= SPAN_LAMBDA; |
| 162 | compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane); |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 163 | ATTRIB_LOOP_BEGIN |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 164 | GLuint c; |
Brian | 5237f86 | 2007-05-25 16:22:15 -0600 | [diff] [blame] | 165 | if (swrast->_InterpMode[attr] == GL_FLAT) { |
| 166 | for (c = 0; c < 4; c++) { |
| 167 | constant_plane(v1->attrib[attr][c], line.attrPlane[attr][c]); |
| 168 | } |
| 169 | } |
| 170 | else { |
| 171 | for (c = 0; c < 4; c++) { |
| 172 | const GLfloat a0 = v0->attrib[attr][c] * invW0; |
| 173 | const GLfloat a1 = v1->attrib[attr][c] * invW1; |
| 174 | compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1, |
| 175 | line.attrPlane[attr][c]); |
| 176 | } |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 177 | } |
Brian Paul | 706400f | 2012-01-12 09:54:04 -0700 | [diff] [blame] | 178 | line.span.arrayAttribs |= BITFIELD64_BIT(attr); |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 179 | if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) { |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 180 | const GLuint u = attr - FRAG_ATTRIB_TEX0; |
| 181 | const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; |
| 182 | const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; |
| 183 | line.texWidth[attr] = (GLfloat) texImage->Width; |
Brian | eca456b | 2007-04-24 16:57:38 -0600 | [diff] [blame] | 184 | line.texHeight[attr] = (GLfloat) texImage->Height; |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 185 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 186 | ATTRIB_LOOP_END |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 187 | } |
| 188 | #endif |
| 189 | |
| 190 | tStart = tEnd = 0.0; |
| 191 | inSegment = GL_FALSE; |
| 192 | iLen = (GLint) line.len; |
| 193 | |
| 194 | if (ctx->Line.StippleFlag) { |
| 195 | for (i = 0; i < iLen; i++) { |
| 196 | const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; |
| 197 | if ((1 << bit) & ctx->Line.StipplePattern) { |
| 198 | /* stipple bit is on */ |
| 199 | const GLfloat t = (GLfloat) i / (GLfloat) line.len; |
| 200 | if (!inSegment) { |
| 201 | /* start new segment */ |
| 202 | inSegment = GL_TRUE; |
| 203 | tStart = t; |
| 204 | } |
| 205 | else { |
| 206 | /* still in the segment, extend it */ |
| 207 | tEnd = t; |
| 208 | } |
| 209 | } |
| 210 | else { |
| 211 | /* stipple bit is off */ |
| 212 | if (inSegment && (tEnd > tStart)) { |
| 213 | /* draw the segment */ |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 214 | segment(ctx, &line, NAME(plot), tStart, tEnd); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 215 | inSegment = GL_FALSE; |
| 216 | } |
| 217 | else { |
| 218 | /* still between segments, do nothing */ |
| 219 | } |
| 220 | } |
| 221 | swrast->StippleCounter++; |
| 222 | } |
Brian Paul | 426628c | 2001-01-29 23:38:41 +0000 | [diff] [blame] | 223 | |
| 224 | if (inSegment) { |
| 225 | /* draw the final segment of the line */ |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 226 | segment(ctx, &line, NAME(plot), tStart, 1.0F); |
Brian Paul | 426628c | 2001-01-29 23:38:41 +0000 | [diff] [blame] | 227 | } |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 228 | } |
| 229 | else { |
| 230 | /* non-stippled */ |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 231 | segment(ctx, &line, NAME(plot), 0.0, 1.0); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 232 | } |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 233 | |
Brian Paul | 45bc887 | 2003-03-25 02:23:44 +0000 | [diff] [blame] | 234 | _swrast_write_rgba_span(ctx, &(line.span)); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 235 | } |
| 236 | |
| 237 | |
| 238 | |
| 239 | |
| 240 | #undef DO_Z |
Brian | eca456b | 2007-04-24 16:57:38 -0600 | [diff] [blame] | 241 | #undef DO_ATTRIBS |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 242 | #undef NAME |