Subversion Repositories Kolibri OS

Rev

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