Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  7.0
  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.  * 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[FRAG_ATTRIB_WPOS][0];
  72.    GLint x1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0];
  73.    GLint y0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1];
  74.    GLint y1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][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[FRAG_ATTRIB_WPOS][0] + vert0->attrib[FRAG_ATTRIB_WPOS][1]
  103.                   + vert1->attrib[FRAG_ATTRIB_WPOS][0] + vert1->attrib[FRAG_ATTRIB_WPOS][1];
  104.       if (IS_INF_OR_NAN(tmp))
  105.          return;
  106.    }
  107.  
  108.    /*
  109.    printf("%s():\n", __FUNCTION__);
  110.    printf(" (%f, %f, %f) -> (%f, %f, %f)\n",
  111.           vert0->attrib[FRAG_ATTRIB_WPOS][0],
  112.           vert0->attrib[FRAG_ATTRIB_WPOS][1],
  113.           vert0->attrib[FRAG_ATTRIB_WPOS][2],
  114.           vert1->attrib[FRAG_ATTRIB_WPOS][0],
  115.           vert1->attrib[FRAG_ATTRIB_WPOS][1],
  116.           vert1->attrib[FRAG_ATTRIB_WPOS][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", __FUNCTION__, dx, dy,
  158.           vert0->attrib[FRAG_ATTRIB_COL1][0],
  159.           vert0->attrib[FRAG_ATTRIB_COL1][1],
  160.           vert0->attrib[FRAG_ATTRIB_COL1][2],
  161.           vert0->attrib[FRAG_ATTRIB_COL1][3],
  162.           vert1->attrib[FRAG_ATTRIB_COL1][0],
  163.           vert1->attrib[FRAG_ATTRIB_COL1][1],
  164.           vert1->attrib[FRAG_ATTRIB_COL1][2],
  165.           vert1->attrib[FRAG_ATTRIB_COL1][3]);
  166.    */
  167.  
  168. #ifdef DEPTH_TYPE
  169.    zPtr = (DEPTH_TYPE *) zrb->GetPointer(ctx, 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[FRAG_ATTRIB_WPOS][2]) + FIXED_HALF;
  249.          span.zStep = FloatToFixed(  vert1->attrib[FRAG_ATTRIB_WPOS][2]
  250.                                    - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels;
  251.       }
  252.       else {
  253.          /* don't use fixed point */
  254.          span.z = (GLuint) vert0->attrib[FRAG_ATTRIB_WPOS][2];
  255.          span.zStep = (GLint) ((  vert1->attrib[FRAG_ATTRIB_WPOS][2]
  256.                                 - vert0->attrib[FRAG_ATTRIB_WPOS][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[FRAG_ATTRIB_WPOS][3];
  264.       const GLfloat invw1 = vert1->attrib[FRAG_ATTRIB_WPOS][3];
  265.  
  266.       span.attrStart[FRAG_ATTRIB_WPOS][3] = invw0;
  267.       span.attrStepX[FRAG_ATTRIB_WPOS][3] = (invw1 - invw0) * invLen;
  268.       span.attrStepY[FRAG_ATTRIB_WPOS][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<dy;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
  403.