Subversion Repositories shark

Rev

Rev 135 | Details | Compare with Previous | Last modification | View Log | RSS feed

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