s_lines.c revision 9e8a961dd7d7b717a9fb4ecdea1c1b60ea355efe
143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/* 243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * Mesa 3-D graphics library 343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * Version: 6.5.3 443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * 543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * 743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * Permission is hereby granted, free of charge, to any person obtaining a 843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * copy of this software and associated documentation files (the "Software"), 943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * to deal in the Software without restriction, including without limitation 1043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * and/or sell copies of the Software, and to permit persons to whom the 1243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * Software is furnished to do so, subject to the following conditions: 1343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * 1443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * The above copyright notice and this permission notice shall be included 1543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * in all copies or substantial portions of the Software. 1643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * 1743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com */ 2443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 2543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 2643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "glheader.h" 2743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "context.h" 2843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "colormac.h" 2943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "macros.h" 3043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_aaline.h" 3143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_context.h" 3243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_depth.h" 3343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_feedback.h" 3443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_lines.h" 3543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_span.h" 3643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 3743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 3843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/* 3943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * Init the mask[] array to implement a line stipple. 4043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com */ 4143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comstatic void 4243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comcompute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] ) 4343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com{ 4443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com SWcontext *swrast = SWRAST_CONTEXT(ctx); 4543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com GLuint i; 4643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 4743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com for (i = 0; i < len; i++) { 4843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; 4943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com if ((1 << bit) & ctx->Line.StipplePattern) { 5043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com mask[i] = GL_TRUE; 5143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 5243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com else { 5343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com mask[i] = GL_FALSE; 5443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 5543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com swrast->StippleCounter++; 5643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 5743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com} 5843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 5943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 6043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/* 6143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * To draw a wide line we can simply redraw the span N times, side by side. 6243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com */ 6343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comstatic void 6443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comdraw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor ) 6543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com{ 66e1d94437585dad1c195d7cf095f8a5a8219d196askia.committer@gmail.com GLint width, start; 6743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 6843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com ASSERT(span->end < MAX_WIDTH); 6943d6d80b49b05c4eec400c8393445397653d9654reed@google.com 7043d6d80b49b05c4eec400c8393445397653d9654reed@google.com width = (GLint) CLAMP( ctx->Line._Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH ); 7143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 7243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com if (width & 1) 7343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com start = width / 2; 7443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com else 7543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com start = width / 2 - 1; 7643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 7743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com if (xMajor) { 7843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com GLint *y = span->array->y; 7943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com GLuint i; 8043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com GLint w; 8143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com for (w = 0; w < width; w++) { 8243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com if (w == 0) { 8343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com for (i = 0; i < span->end; i++) 8443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com y[i] -= start; 8543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 8643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com else { 8743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com for (i = 0; i < span->end; i++) 8843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com y[i]++; 8943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 9043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com if (ctx->Visual.rgbMode) 9143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com _swrast_write_rgba_span(ctx, span); 9243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com else 9343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com _swrast_write_index_span(ctx, span); 9443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 9543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 9643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com else { 9743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com GLint *x = span->array->x; 9843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com GLuint i; 9943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com GLint w; 10043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com for (w = 0; w < width; w++) { 1016719d604856e45c789c46703204ae10046e0b448reed@google.com if (w == 0) { 1026719d604856e45c789c46703204ae10046e0b448reed@google.com for (i = 0; i < span->end; i++) 103efadb4b63c428b4f99399c097879981e6efa8870reed@google.com x[i] -= start; 104efadb4b63c428b4f99399c097879981e6efa8870reed@google.com } 105efadb4b63c428b4f99399c097879981e6efa8870reed@google.com else { 10643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com for (i = 0; i < span->end; i++) 10743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com x[i]++; 10843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 10943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com if (ctx->Visual.rgbMode) 11043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com _swrast_write_rgba_span(ctx, span); 11143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com else 11243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com _swrast_write_index_span(ctx, span); 11343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 11443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 11543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com} 11643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 11743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 11843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 11943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/**********************************************************************/ 12043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/***** Rasterization *****/ 12143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/**********************************************************************/ 12243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 12343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/* Simple color index line (no stipple, width=1, no Z, no fog, no tex)*/ 12443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define NAME simple_no_z_ci_line 12543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define INTERP_INDEX 12643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define RENDER_SPAN(span) _swrast_write_index_span(ctx, &span) 12743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_linetemp.h" 12843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 12943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/ 13043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define NAME simple_no_z_rgba_line 13143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define INTERP_RGBA 13243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span); 13343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_linetemp.h" 13443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 13543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 13643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/* Z, fog, wide, stipple color index line */ 13743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define NAME ci_line 13843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define INTERP_INDEX 13943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define INTERP_Z 14043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define INTERP_ATTRIBS /* for fog */ 14143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define RENDER_SPAN(span) \ 14243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com if (ctx->Line.StippleFlag) { \ 14343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com span.arrayMask |= SPAN_MASK; \ 14443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com compute_stipple_mask(ctx, span.end, span.array->mask); \ 14543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } \ 14643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com if (ctx->Line._Width > 1.0) { \ 14743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ 14843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } \ 14943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com else { \ 15043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com _swrast_write_index_span(ctx, &span); \ 15143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com } 15243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "s_linetemp.h" 15343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 15443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com 15543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/* Z, fog, wide, stipple RGBA line */ 15643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#define NAME rgba_line 157#define INTERP_RGBA 158#define INTERP_Z 159#define RENDER_SPAN(span) \ 160 if (ctx->Line.StippleFlag) { \ 161 span.arrayMask |= SPAN_MASK; \ 162 compute_stipple_mask(ctx, span.end, span.array->mask); \ 163 } \ 164 if (ctx->Line._Width > 1.0) { \ 165 draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ 166 } \ 167 else { \ 168 _swrast_write_rgba_span(ctx, &span); \ 169 } 170#include "s_linetemp.h" 171 172 173/* General-purpose line (any/all features). */ 174#define NAME general_line 175#define INTERP_RGBA 176#define INTERP_Z 177#define INTERP_ATTRIBS 178#define RENDER_SPAN(span) \ 179 if (ctx->Line.StippleFlag) { \ 180 span.arrayMask |= SPAN_MASK; \ 181 compute_stipple_mask(ctx, span.end, span.array->mask); \ 182 } \ 183 if (ctx->Line._Width > 1.0) { \ 184 draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ 185 } \ 186 else { \ 187 _swrast_write_rgba_span(ctx, &span); \ 188 } 189#include "s_linetemp.h" 190 191 192 193void 194_swrast_add_spec_terms_line(GLcontext *ctx, 195 const SWvertex *v0, const SWvertex *v1) 196{ 197 SWvertex *ncv0 = (SWvertex *)v0; 198 SWvertex *ncv1 = (SWvertex *)v1; 199 GLfloat rSum, gSum, bSum; 200 GLchan cSave[2][4]; 201 202 /* save original colors */ 203 COPY_CHAN4(cSave[0], ncv0->color); 204 COPY_CHAN4(cSave[1], ncv1->color); 205 /* sum v0 */ 206 rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0]; 207 gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1]; 208 bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2]; 209 UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); 210 UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); 211 UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); 212 /* sum v1 */ 213 rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0]; 214 gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1]; 215 bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2]; 216 UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum); 217 UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum); 218 UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum); 219 /* draw */ 220 SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 ); 221 /* restore original colors */ 222 COPY_CHAN4( ncv0->attrib[FRAG_ATTRIB_COL0], cSave[0] ); 223 COPY_CHAN4( ncv1->attrib[FRAG_ATTRIB_COL0], cSave[1] ); 224} 225 226 227 228#ifdef DEBUG 229 230/* record the current line function name */ 231static const char *lineFuncName = NULL; 232 233#define USE(lineFunc) \ 234do { \ 235 lineFuncName = #lineFunc; \ 236 /*_mesa_printf("%s\n", lineFuncName);*/ \ 237 swrast->Line = lineFunc; \ 238} while (0) 239 240#else 241 242#define USE(lineFunc) swrast->Line = lineFunc 243 244#endif 245 246 247 248/** 249 * Determine which line drawing function to use given the current 250 * rendering context. 251 * 252 * Please update the summary flag _SWRAST_NEW_LINE if you add or remove 253 * tests to this code. 254 */ 255void 256_swrast_choose_line( GLcontext *ctx ) 257{ 258 SWcontext *swrast = SWRAST_CONTEXT(ctx); 259 const GLboolean rgbmode = ctx->Visual.rgbMode; 260 GLboolean specular = (ctx->Fog.ColorSumEnabled || 261 (ctx->Light.Enabled && 262 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); 263 264 if (ctx->RenderMode == GL_RENDER) { 265 if (ctx->Line.SmoothFlag) { 266 /* antialiased lines */ 267 _swrast_choose_aa_line_function(ctx); 268 ASSERT(swrast->Line); 269 } 270 else if (ctx->Texture._EnabledCoordUnits 271 || ctx->FragmentProgram._Current 272 || swrast->_FogEnabled 273 || specular) { 274 USE(general_line); 275 } 276 else if (ctx->Depth.Test 277 || ctx->Line._Width != 1.0 278 || ctx->Line.StippleFlag) { 279 /* no texture, but Z, fog, width>1, stipple, etc. */ 280 if (rgbmode) 281 USE(rgba_line); 282 else 283 USE(ci_line); 284 } 285 else { 286 ASSERT(!ctx->Depth.Test); 287 /* simple lines */ 288 if (rgbmode) 289 USE(simple_no_z_rgba_line); 290 else 291 USE(simple_no_z_ci_line); 292 } 293 } 294 else if (ctx->RenderMode == GL_FEEDBACK) { 295 USE(_swrast_feedback_line); 296 } 297 else { 298 ASSERT(ctx->RenderMode == GL_SELECT); 299 USE(_swrast_select_line); 300 } 301} 302