Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
5
 *
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:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
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
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.
23
 */
24
 
25
 
26
/*
27
 * Line Rasterizer Template
28
 *
29
 * This file is #include'd to generate custom line rasterizers.
30
 *
31
 * The following macros may be defined to indicate what auxillary information
32
 * must be interplated along the line:
33
 *    INTERP_Z        - if defined, interpolate Z values
34
 *    INTERP_ATTRIBS  - if defined, interpolate attribs (texcoords, varying, etc)
35
 *
36
 * When one can directly address pixels in the color buffer the following
37
 * macros can be defined and used to directly compute pixel addresses during
38
 * rasterization (see pixelPtr):
39
 *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
40
 *    BYTES_PER_ROW       - number of bytes per row in the color buffer
41
 *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
42
 *                          Y==0 at bottom of screen and increases upward.
43
 *
44
 * Similarly, for direct depth buffer access, this type is used for depth
45
 * buffer addressing:
46
 *    DEPTH_TYPE          - either GLushort or GLuint
47
 *
48
 * Optionally, one may provide one-time setup code
49
 *    SETUP_CODE    - code which is to be executed once per line
50
 *
51
 * To actually "plot" each pixel the PLOT macro must be defined...
52
 *    PLOT(X,Y) - code to plot a pixel.  Example:
53
 *                if (Z < *zPtr) {
54
 *                   *zPtr = Z;
55
 *                   color = pack_rgb( FixedToInt(r0), FixedToInt(g0),
56
 *                                     FixedToInt(b0) );
57
 *                   put_pixel( X, Y, color );
58
 *                }
59
 *
60
 * This code was designed for the origin to be in the lower-left corner.
61
 *
62
 */
63
 
64
 
65
static void
66
NAME( struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1 )
67
{
68
   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
69
   SWspan span;
70
   GLuint interpFlags = 0;
71
   GLint x0 = (GLint) vert0->attrib[VARYING_SLOT_POS][0];
72
   GLint x1 = (GLint) vert1->attrib[VARYING_SLOT_POS][0];
73
   GLint y0 = (GLint) vert0->attrib[VARYING_SLOT_POS][1];
74
   GLint y1 = (GLint) vert1->attrib[VARYING_SLOT_POS][1];
75
   GLint dx, dy;
76
   GLint numPixels;
77
   GLint xstep, ystep;
78
#if defined(DEPTH_TYPE)
79
   const GLint depthBits = ctx->DrawBuffer->Visual.depthBits;
80
   const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
81
   struct gl_renderbuffer *zrb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
82
#define FixedToDepth(F)  ((F) >> fixedToDepthShift)
83
   GLint zPtrXstep, zPtrYstep;
84
   DEPTH_TYPE *zPtr;
85
#elif defined(INTERP_Z)
86
   const GLint depthBits = ctx->DrawBuffer->Visual.depthBits;
87
#endif
88
#ifdef PIXEL_ADDRESS
89
   PIXEL_TYPE *pixelPtr;
90
   GLint pixelXstep, pixelYstep;
91
#endif
92
 
93
#ifdef SETUP_CODE
94
   SETUP_CODE
95
#endif
96
 
97
   (void) swrast;
98
 
99
   /* Cull primitives with malformed coordinates.
100
    */
101
   {
102
      GLfloat tmp = vert0->attrib[VARYING_SLOT_POS][0] + vert0->attrib[VARYING_SLOT_POS][1]
103
                  + vert1->attrib[VARYING_SLOT_POS][0] + vert1->attrib[VARYING_SLOT_POS][1];
104
      if (IS_INF_OR_NAN(tmp))
105
	 return;
106
   }
107
 
108
   /*
109
   printf("%s():\n", __func__);
110
   printf(" (%f, %f, %f) -> (%f, %f, %f)\n",
111
          vert0->attrib[VARYING_SLOT_POS][0],
112
          vert0->attrib[VARYING_SLOT_POS][1],
113
          vert0->attrib[VARYING_SLOT_POS][2],
114
          vert1->attrib[VARYING_SLOT_POS][0],
115
          vert1->attrib[VARYING_SLOT_POS][1],
116
          vert1->attrib[VARYING_SLOT_POS][2]);
117
   printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
118
          vert0->color[0], vert0->color[1], vert0->color[2],
119
          vert1->color[0], vert1->color[1], vert1->color[2]);
120
   printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
121
          vert0->specular[0], vert0->specular[1], vert0->specular[2],
122
          vert1->specular[0], vert1->specular[1], vert1->specular[2]);
123
   */
124
 
125
/*
126
 * Despite being clipped to the view volume, the line's window coordinates
127
 * may just lie outside the window bounds.  That is, if the legal window
128
 * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H.
129
 * This quick and dirty code nudges the endpoints inside the window if
130
 * necessary.
131
 */
132
#ifdef CLIP_HACK
133
   {
134
      GLint w = ctx->DrawBuffer->Width;
135
      GLint h = ctx->DrawBuffer->Height;
136
      if ((x0==w) | (x1==w)) {
137
         if ((x0==w) & (x1==w))
138
           return;
139
         x0 -= x0==w;
140
         x1 -= x1==w;
141
      }
142
      if ((y0==h) | (y1==h)) {
143
         if ((y0==h) & (y1==h))
144
           return;
145
         y0 -= y0==h;
146
         y1 -= y1==h;
147
      }
148
   }
149
#endif
150
 
151
   dx = x1 - x0;
152
   dy = y1 - y0;
153
   if (dx == 0 && dy == 0)
154
      return;
155
 
156
   /*
157
   printf("%s %d,%d  %g %g %g %g  %g %g %g %g\n", __func__, dx, dy,
158
          vert0->attrib[VARYING_SLOT_COL1][0],
159
          vert0->attrib[VARYING_SLOT_COL1][1],
160
          vert0->attrib[VARYING_SLOT_COL1][2],
161
          vert0->attrib[VARYING_SLOT_COL1][3],
162
          vert1->attrib[VARYING_SLOT_COL1][0],
163
          vert1->attrib[VARYING_SLOT_COL1][1],
164
          vert1->attrib[VARYING_SLOT_COL1][2],
165
          vert1->attrib[VARYING_SLOT_COL1][3]);
166
   */
167
 
168
#ifdef DEPTH_TYPE
169
   zPtr = (DEPTH_TYPE *) _swrast_pixel_address(zrb, x0, y0);
170
#endif
171
#ifdef PIXEL_ADDRESS
172
   pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0);
173
#endif
174
 
175
   if (dx<0) {
176
      dx = -dx;   /* make positive */
177
      xstep = -1;
178
#ifdef DEPTH_TYPE
179
      zPtrXstep = -((GLint)sizeof(DEPTH_TYPE));
180
#endif
181
#ifdef PIXEL_ADDRESS
182
      pixelXstep = -((GLint)sizeof(PIXEL_TYPE));
183
#endif
184
   }
185
   else {
186
      xstep = 1;
187
#ifdef DEPTH_TYPE
188
      zPtrXstep = ((GLint)sizeof(DEPTH_TYPE));
189
#endif
190
#ifdef PIXEL_ADDRESS
191
      pixelXstep = ((GLint)sizeof(PIXEL_TYPE));
192
#endif
193
   }
194
 
195
   if (dy<0) {
196
      dy = -dy;   /* make positive */
197
      ystep = -1;
198
#ifdef DEPTH_TYPE
199
      zPtrYstep = -((GLint) (ctx->DrawBuffer->Width * sizeof(DEPTH_TYPE)));
200
#endif
201
#ifdef PIXEL_ADDRESS
202
      pixelYstep = BYTES_PER_ROW;
203
#endif
204
   }
205
   else {
206
      ystep = 1;
207
#ifdef DEPTH_TYPE
208
      zPtrYstep = (GLint) (ctx->DrawBuffer->Width * sizeof(DEPTH_TYPE));
209
#endif
210
#ifdef PIXEL_ADDRESS
211
      pixelYstep = -(BYTES_PER_ROW);
212
#endif
213
   }
214
 
215
   assert(dx >= 0);
216
   assert(dy >= 0);
217
 
218
   numPixels = MAX2(dx, dy);
219
 
220
   /*
221
    * Span setup: compute start and step values for all interpolated values.
222
    */
223
   interpFlags |= SPAN_RGBA;
224
   if (ctx->Light.ShadeModel == GL_SMOOTH) {
225
      span.red   = ChanToFixed(vert0->color[0]);
226
      span.green = ChanToFixed(vert0->color[1]);
227
      span.blue  = ChanToFixed(vert0->color[2]);
228
      span.alpha = ChanToFixed(vert0->color[3]);
229
      span.redStep   = (ChanToFixed(vert1->color[0]) - span.red  ) / numPixels;
230
      span.greenStep = (ChanToFixed(vert1->color[1]) - span.green) / numPixels;
231
      span.blueStep  = (ChanToFixed(vert1->color[2]) - span.blue ) / numPixels;
232
      span.alphaStep = (ChanToFixed(vert1->color[3]) - span.alpha) / numPixels;
233
   }
234
   else {
235
      span.red   = ChanToFixed(vert1->color[0]);
236
      span.green = ChanToFixed(vert1->color[1]);
237
      span.blue  = ChanToFixed(vert1->color[2]);
238
      span.alpha = ChanToFixed(vert1->color[3]);
239
      span.redStep   = 0;
240
      span.greenStep = 0;
241
      span.blueStep  = 0;
242
      span.alphaStep = 0;
243
   }
244
#if defined(INTERP_Z) || defined(DEPTH_TYPE)
245
   interpFlags |= SPAN_Z;
246
   {
247
      if (depthBits <= 16) {
248
         span.z = FloatToFixed(vert0->attrib[VARYING_SLOT_POS][2]) + FIXED_HALF;
249
         span.zStep = FloatToFixed(  vert1->attrib[VARYING_SLOT_POS][2]
250
                                   - vert0->attrib[VARYING_SLOT_POS][2]) / numPixels;
251
      }
252
      else {
253
         /* don't use fixed point */
254
         span.z = (GLuint) vert0->attrib[VARYING_SLOT_POS][2];
255
         span.zStep = (GLint) ((  vert1->attrib[VARYING_SLOT_POS][2]
256
                                - vert0->attrib[VARYING_SLOT_POS][2]) / numPixels);
257
      }
258
   }
259
#endif
260
#if defined(INTERP_ATTRIBS)
261
   {
262
      const GLfloat invLen = 1.0F / numPixels;
263
      const GLfloat invw0 = vert0->attrib[VARYING_SLOT_POS][3];
264
      const GLfloat invw1 = vert1->attrib[VARYING_SLOT_POS][3];
265
 
266
      span.attrStart[VARYING_SLOT_POS][3] = invw0;
267
      span.attrStepX[VARYING_SLOT_POS][3] = (invw1 - invw0) * invLen;
268
      span.attrStepY[VARYING_SLOT_POS][3] = 0.0;
269
 
270
      ATTRIB_LOOP_BEGIN
271
         if (swrast->_InterpMode[attr] == GL_FLAT) {
272
            COPY_4V(span.attrStart[attr], vert1->attrib[attr]);
273
            ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0);
274
         }
275
         else {
276
            GLuint c;
277
            for (c = 0; c < 4; c++) {
278
               float da;
279
               span.attrStart[attr][c] = invw0 * vert0->attrib[attr][c];
280
               da = (invw1 * vert1->attrib[attr][c]) - span.attrStart[attr][c];
281
               span.attrStepX[attr][c] = da * invLen;
282
            }
283
         }
284
         ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0);
285
      ATTRIB_LOOP_END
286
   }
287
#endif
288
 
289
   INIT_SPAN(span, GL_LINE);
290
   span.end = numPixels;
291
   span.interpMask = interpFlags;
292
   span.arrayMask = SPAN_XY;
293
 
294
   span.facing = swrast->PointLineFacing;
295
 
296
 
297
   /*
298
    * Draw
299
    */
300
 
301
   if (dx > dy) {
302
      /*** X-major line ***/
303
      GLint i;
304
      GLint errorInc = dy+dy;
305
      GLint error = errorInc-dx;
306
      GLint errorDec = error-dx;
307
 
308
      for (i = 0; i < dx; i++) {
309
#ifdef DEPTH_TYPE
310
         GLuint Z = FixedToDepth(span.z);
311
#endif
312
#ifdef PLOT
313
         PLOT( x0, y0 );
314
#else
315
         span.array->x[i] = x0;
316
         span.array->y[i] = y0;
317
#endif
318
         x0 += xstep;
319
#ifdef DEPTH_TYPE
320
         zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep);
321
         span.z += span.zStep;
322
#endif
323
#ifdef PIXEL_ADDRESS
324
         pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
325
#endif
326
         if (error < 0) {
327
            error += errorInc;
328
         }
329
         else {
330
            error += errorDec;
331
            y0 += ystep;
332
#ifdef DEPTH_TYPE
333
            zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep);
334
#endif
335
#ifdef PIXEL_ADDRESS
336
            pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
337
#endif
338
         }
339
      }
340
   }
341
   else {
342
      /*** Y-major line ***/
343
      GLint i;
344
      GLint errorInc = dx+dx;
345
      GLint error = errorInc-dy;
346
      GLint errorDec = error-dy;
347
 
348
      for (i=0;i
349
#ifdef DEPTH_TYPE
350
         GLuint Z = FixedToDepth(span.z);
351
#endif
352
#ifdef PLOT
353
         PLOT( x0, y0 );
354
#else
355
         span.array->x[i] = x0;
356
         span.array->y[i] = y0;
357
#endif
358
         y0 += ystep;
359
#ifdef DEPTH_TYPE
360
         zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep);
361
         span.z += span.zStep;
362
#endif
363
#ifdef PIXEL_ADDRESS
364
         pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
365
#endif
366
         if (error<0) {
367
            error += errorInc;
368
         }
369
         else {
370
            error += errorDec;
371
            x0 += xstep;
372
#ifdef DEPTH_TYPE
373
            zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep);
374
#endif
375
#ifdef PIXEL_ADDRESS
376
            pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
377
#endif
378
         }
379
      }
380
   }
381
 
382
#ifdef RENDER_SPAN
383
   RENDER_SPAN( span );
384
#endif
385
 
386
   (void)span;
387
 
388
}
389
 
390
 
391
#undef NAME
392
#undef INTERP_Z
393
#undef INTERP_ATTRIBS
394
#undef PIXEL_ADDRESS
395
#undef PIXEL_TYPE
396
#undef DEPTH_TYPE
397
#undef BYTES_PER_ROW
398
#undef SETUP_CODE
399
#undef PLOT
400
#undef CLIP_HACK
401
#undef FixedToDepth
402
#undef RENDER_SPAN