Subversion Repositories Kolibri OS

Rev

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

  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. #include "main/glheader.h"
  27. #include "main/context.h"
  28. #include "main/colormac.h"
  29. #include "main/macros.h"
  30. #include "s_aaline.h"
  31. #include "s_context.h"
  32. #include "s_feedback.h"
  33. #include "s_lines.h"
  34. #include "s_span.h"
  35.  
  36.  
  37. /*
  38.  * Init the mask[] array to implement a line stipple.
  39.  */
  40. static void
  41. compute_stipple_mask( struct gl_context *ctx, GLuint len, GLubyte mask[] )
  42. {
  43.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  44.    GLuint i;
  45.  
  46.    for (i = 0; i < len; i++) {
  47.       GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
  48.       if ((1 << bit) & ctx->Line.StipplePattern) {
  49.          mask[i] = GL_TRUE;
  50.       }
  51.       else {
  52.          mask[i] = GL_FALSE;
  53.       }
  54.       swrast->StippleCounter++;
  55.    }
  56. }
  57.  
  58.  
  59. /*
  60.  * To draw a wide line we can simply redraw the span N times, side by side.
  61.  */
  62. static void
  63. draw_wide_line( struct gl_context *ctx, SWspan *span, GLboolean xMajor )
  64. {
  65.    const GLint width = (GLint) CLAMP(ctx->Line.Width,
  66.                                      ctx->Const.MinLineWidth,
  67.                                      ctx->Const.MaxLineWidth);
  68.    GLint start;
  69.  
  70.    ASSERT(span->end < SWRAST_MAX_WIDTH);
  71.  
  72.    if (width & 1)
  73.       start = width / 2;
  74.    else
  75.       start = width / 2 - 1;
  76.  
  77.    if (xMajor) {
  78.       GLint *y = span->array->y;
  79.       GLuint i;
  80.       GLint w;
  81.       for (w = 0; w < width; w++) {
  82.          if (w == 0) {
  83.             for (i = 0; i < span->end; i++)
  84.                y[i] -= start;
  85.          }
  86.          else {
  87.             for (i = 0; i < span->end; i++)
  88.                y[i]++;
  89.          }
  90.          _swrast_write_rgba_span(ctx, span);
  91.       }
  92.    }
  93.    else {
  94.       GLint *x = span->array->x;
  95.       GLuint i;
  96.       GLint w;
  97.       for (w = 0; w < width; w++) {
  98.          if (w == 0) {
  99.             for (i = 0; i < span->end; i++)
  100.                x[i] -= start;
  101.          }
  102.          else {
  103.             for (i = 0; i < span->end; i++)
  104.                x[i]++;
  105.          }
  106.          _swrast_write_rgba_span(ctx, span);
  107.       }
  108.    }
  109. }
  110.  
  111.  
  112.  
  113. /**********************************************************************/
  114. /*****                    Rasterization                           *****/
  115. /**********************************************************************/
  116.  
  117. /* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/
  118. #define NAME simple_no_z_rgba_line
  119. #define INTERP_RGBA
  120. #define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span);
  121. #include "s_linetemp.h"
  122.  
  123.  
  124. /* Z, fog, wide, stipple RGBA line */
  125. #define NAME rgba_line
  126. #define INTERP_RGBA
  127. #define INTERP_Z
  128. #define RENDER_SPAN(span)                                       \
  129.    if (ctx->Line.StippleFlag) {                                 \
  130.       span.arrayMask |= SPAN_MASK;                              \
  131.       compute_stipple_mask(ctx, span.end, span.array->mask);    \
  132.    }                                                            \
  133.    if (ctx->Line.Width > 1.0) {                                 \
  134.       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));         \
  135.    }                                                            \
  136.    else {                                                       \
  137.       _swrast_write_rgba_span(ctx, &span);                      \
  138.    }
  139. #include "s_linetemp.h"
  140.  
  141.  
  142. /* General-purpose line (any/all features). */
  143. #define NAME general_line
  144. #define INTERP_RGBA
  145. #define INTERP_Z
  146. #define INTERP_ATTRIBS
  147. #define RENDER_SPAN(span)                                       \
  148.    if (ctx->Line.StippleFlag) {                                 \
  149.       span.arrayMask |= SPAN_MASK;                              \
  150.       compute_stipple_mask(ctx, span.end, span.array->mask);    \
  151.    }                                                            \
  152.    if (ctx->Line.Width > 1.0) {                                 \
  153.       draw_wide_line(ctx, &span, (GLboolean)(dx > dy));         \
  154.    }                                                            \
  155.    else {                                                       \
  156.       _swrast_write_rgba_span(ctx, &span);                      \
  157.    }
  158. #include "s_linetemp.h"
  159.  
  160.  
  161.  
  162. void
  163. _swrast_add_spec_terms_line(struct gl_context *ctx,
  164.                             const SWvertex *v0, const SWvertex *v1)
  165. {
  166.    SWvertex *ncv0 = (SWvertex *)v0;
  167.    SWvertex *ncv1 = (SWvertex *)v1;
  168.    GLfloat rSum, gSum, bSum;
  169.    GLchan cSave[2][4];
  170.  
  171.    /* save original colors */
  172.    COPY_CHAN4(cSave[0], ncv0->color);
  173.    COPY_CHAN4(cSave[1], ncv1->color);
  174.    /* sum v0 */
  175.    rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[VARYING_SLOT_COL1][0];
  176.    gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[VARYING_SLOT_COL1][1];
  177.    bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[VARYING_SLOT_COL1][2];
  178.    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
  179.    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
  180.    UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
  181.    /* sum v1 */
  182.    rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[VARYING_SLOT_COL1][0];
  183.    gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[VARYING_SLOT_COL1][1];
  184.    bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[VARYING_SLOT_COL1][2];
  185.    UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
  186.    UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
  187.    UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
  188.    /* draw */
  189.    SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
  190.    /* restore original colors */
  191.    COPY_CHAN4(ncv0->color, cSave[0]);
  192.    COPY_CHAN4(ncv1->color, cSave[1]);
  193. }
  194.  
  195.  
  196.  
  197. #ifdef DEBUG
  198.  
  199. /* record the current line function name */
  200. static const char *lineFuncName = NULL;
  201.  
  202. #define USE(lineFunc)                   \
  203. do {                                    \
  204.     lineFuncName = #lineFunc;           \
  205.     /*printf("%s\n", lineFuncName);*/   \
  206.     swrast->Line = lineFunc;            \
  207. } while (0)
  208.  
  209. #else
  210.  
  211. #define USE(lineFunc)  swrast->Line = lineFunc
  212.  
  213. #endif
  214.  
  215.  
  216.  
  217. /**
  218.  * Determine which line drawing function to use given the current
  219.  * rendering context.
  220.  *
  221.  * Please update the summary flag _SWRAST_NEW_LINE if you add or remove
  222.  * tests to this code.
  223.  */
  224. void
  225. _swrast_choose_line( struct gl_context *ctx )
  226. {
  227.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  228.    GLboolean specular = (ctx->Fog.ColorSumEnabled ||
  229.                          (ctx->Light.Enabled &&
  230.                           ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
  231.  
  232.    if (ctx->RenderMode == GL_RENDER) {
  233.       if (ctx->Line.SmoothFlag) {
  234.          /* antialiased lines */
  235.          _swrast_choose_aa_line_function(ctx);
  236.          ASSERT(swrast->Line);
  237.       }
  238.       else if (ctx->Texture._EnabledCoordUnits
  239.                || _swrast_use_fragment_program(ctx)
  240.                || swrast->_FogEnabled
  241.                || specular) {
  242.          USE(general_line);
  243.       }
  244.       else if (ctx->Depth.Test
  245.                || ctx->Line.Width != 1.0
  246.                || ctx->Line.StippleFlag) {
  247.          /* no texture, but Z, fog, width>1, stipple, etc. */
  248. #if CHAN_BITS == 32
  249.          USE(general_line);
  250. #else
  251.          USE(rgba_line);
  252. #endif
  253.       }
  254.       else {
  255.          ASSERT(!ctx->Depth.Test);
  256.          ASSERT(ctx->Line.Width == 1.0);
  257.          /* simple lines */
  258.          USE(simple_no_z_rgba_line);
  259.       }
  260.    }
  261.    else if (ctx->RenderMode == GL_FEEDBACK) {
  262.       USE(_swrast_feedback_line);
  263.    }
  264.    else {
  265.       ASSERT(ctx->RenderMode == GL_SELECT);
  266.       USE(_swrast_select_line);
  267.    }
  268. }
  269.