Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Mesa 3-D graphics library |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 3 | * |
Brian | dd34fe8 | 2007-02-05 10:10:01 -0700 | [diff] [blame] | 4 | * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 5 | * |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 7 | * copy of this software and associated documentation files (the "Software"), |
| 8 | * to deal in the Software without restriction, including without limitation |
| 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 10 | * and/or sell copies of the Software, and to permit persons to whom the |
| 11 | * Software is furnished to do so, subject to the following conditions: |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 12 | * |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 13 | * The above copyright notice and this permission notice shall be included |
| 14 | * in all copies or substantial portions of the Software. |
Gareth Hughes | 22144ab | 2001-03-12 00:48:37 +0000 | [diff] [blame] | 15 | * |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
Kenneth Graunke | 3d8d5b2 | 2013-04-21 13:46:48 -0700 | [diff] [blame] | 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| 20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 22 | * OTHER DEALINGS IN THE SOFTWARE. |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 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 | |
Matt Turner | 04aa8b5 | 2015-07-12 23:15:10 -0700 | [diff] [blame] | 47 | if (coverage == 0.0F) |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 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]; |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 69 | if (attr >= VARYING_SLOT_TEX0 && attr < VARYING_SLOT_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 */ |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 72 | const GLuint unit = attr - VARYING_SLOT_TEX0; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 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; |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 115 | line.x0 = v0->attrib[VARYING_SLOT_POS][0]; |
| 116 | line.y0 = v0->attrib[VARYING_SLOT_POS][1]; |
| 117 | line.x1 = v1->attrib[VARYING_SLOT_POS][0]; |
| 118 | line.y1 = v1->attrib[VARYING_SLOT_POS][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 | 56ccdf7 | 2012-09-03 12:19:15 -0600 | [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 | |
Matt Turner | 04aa8b5 | 2015-07-12 23:15:10 -0700 | [diff] [blame] | 126 | if (line.len == 0.0F || 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, |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 138 | v0->attrib[VARYING_SLOT_POS][2], v1->attrib[VARYING_SLOT_POS][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 | { |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 159 | const GLfloat invW0 = v0->attrib[VARYING_SLOT_POS][3]; |
| 160 | const GLfloat invW1 = v1->attrib[VARYING_SLOT_POS][3]; |
Brian | 9e8a961 | 2007-05-20 12:27:39 -0600 | [diff] [blame] | 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); |
Paul Berry | eed6baf | 2013-02-23 09:00:58 -0800 | [diff] [blame] | 179 | if (attr >= VARYING_SLOT_TEX0 && attr < VARYING_SLOT_VAR0) { |
| 180 | const GLuint u = attr - VARYING_SLOT_TEX0; |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 181 | const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; |
Brian Paul | 05279fa | 2015-01-02 16:56:12 -0700 | [diff] [blame] | 182 | const struct gl_texture_image *texImage = |
| 183 | _mesa_base_tex_image(obj); |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 184 | line.texWidth[attr] = (GLfloat) texImage->Width; |
Brian | eca456b | 2007-04-24 16:57:38 -0600 | [diff] [blame] | 185 | line.texHeight[attr] = (GLfloat) texImage->Height; |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 186 | } |
Brian | 0bdf216 | 2007-04-23 21:21:52 -0600 | [diff] [blame] | 187 | ATTRIB_LOOP_END |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 188 | } |
| 189 | #endif |
| 190 | |
| 191 | tStart = tEnd = 0.0; |
| 192 | inSegment = GL_FALSE; |
| 193 | iLen = (GLint) line.len; |
| 194 | |
| 195 | if (ctx->Line.StippleFlag) { |
| 196 | for (i = 0; i < iLen; i++) { |
| 197 | const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; |
| 198 | if ((1 << bit) & ctx->Line.StipplePattern) { |
| 199 | /* stipple bit is on */ |
| 200 | const GLfloat t = (GLfloat) i / (GLfloat) line.len; |
| 201 | if (!inSegment) { |
| 202 | /* start new segment */ |
| 203 | inSegment = GL_TRUE; |
| 204 | tStart = t; |
| 205 | } |
| 206 | else { |
| 207 | /* still in the segment, extend it */ |
| 208 | tEnd = t; |
| 209 | } |
| 210 | } |
| 211 | else { |
| 212 | /* stipple bit is off */ |
| 213 | if (inSegment && (tEnd > tStart)) { |
| 214 | /* draw the segment */ |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 215 | segment(ctx, &line, NAME(plot), tStart, tEnd); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 216 | inSegment = GL_FALSE; |
| 217 | } |
| 218 | else { |
| 219 | /* still between segments, do nothing */ |
| 220 | } |
| 221 | } |
| 222 | swrast->StippleCounter++; |
| 223 | } |
Brian Paul | 426628c | 2001-01-29 23:38:41 +0000 | [diff] [blame] | 224 | |
| 225 | if (inSegment) { |
| 226 | /* draw the final segment of the line */ |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 227 | segment(ctx, &line, NAME(plot), tStart, 1.0F); |
Brian Paul | 426628c | 2001-01-29 23:38:41 +0000 | [diff] [blame] | 228 | } |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 229 | } |
| 230 | else { |
| 231 | /* non-stippled */ |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 232 | segment(ctx, &line, NAME(plot), 0.0, 1.0); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 233 | } |
Brian Paul | 733a4b6 | 2002-02-02 17:24:11 +0000 | [diff] [blame] | 234 | |
Brian Paul | 45bc887 | 2003-03-25 02:23:44 +0000 | [diff] [blame] | 235 | _swrast_write_rgba_span(ctx, &(line.span)); |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | |
| 239 | |
| 240 | |
| 241 | #undef DO_Z |
Brian | eca456b | 2007-04-24 16:57:38 -0600 | [diff] [blame] | 242 | #undef DO_ATTRIBS |
Brian Paul | 7798374 | 2000-11-05 23:15:16 +0000 | [diff] [blame] | 243 | #undef NAME |