-/* $Id: s_lines.c,v 1.25 2002/02/02 21:40:33 brianp Exp $ */
-
/*
* Mesa 3-D graphics library
- * Version: 4.1
*
- * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "glheader.h"
-#include "colormac.h"
-#include "macros.h"
-#include "mmath.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
#include "s_aaline.h"
#include "s_context.h"
-#include "s_depth.h"
#include "s_feedback.h"
#include "s_lines.h"
#include "s_span.h"
* Init the mask[] array to implement a line stipple.
*/
static void
-compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
+compute_stipple_mask( struct gl_context *ctx, GLuint len, GLubyte mask[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint i;
* To draw a wide line we can simply redraw the span N times, side by side.
*/
static void
-draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
+draw_wide_line( struct gl_context *ctx, SWspan *span, GLboolean xMajor )
{
- GLint width, start;
-
- ASSERT(span->end < MAX_WIDTH);
+ const GLint width = (GLint) CLAMP(ctx->Line.Width,
+ ctx->Const.MinLineWidth,
+ ctx->Const.MaxLineWidth);
+ GLint start;
- width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
+ assert(span->end < SWRAST_MAX_WIDTH);
if (width & 1)
start = width / 2;
start = width / 2 - 1;
if (xMajor) {
- GLuint i, w;
+ GLint *y = span->array->y;
+ GLuint i;
+ GLint w;
for (w = 0; w < width; w++) {
if (w == 0) {
for (i = 0; i < span->end; i++)
- span->yArray[i] -= start;
+ y[i] -= start;
}
else {
for (i = 0; i < span->end; i++)
- span->yArray[i]++;
+ y[i]++;
}
- if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
- _mesa_write_texture_span(ctx, span, GL_LINE);
- else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
- _mesa_write_rgba_span(ctx, span, GL_LINE);
- else
- _mesa_write_index_span(ctx, span, GL_LINE);
+ _swrast_write_rgba_span(ctx, span);
}
}
else {
- GLuint i, w;
+ GLint *x = span->array->x;
+ GLuint i;
+ GLint w;
for (w = 0; w < width; w++) {
if (w == 0) {
for (i = 0; i < span->end; i++)
- span->xArray[i] -= start;
+ x[i] -= start;
}
else {
for (i = 0; i < span->end; i++)
- span->xArray[i]++;
+ x[i]++;
}
- if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
- _mesa_write_texture_span(ctx, span, GL_LINE);
- else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
- _mesa_write_rgba_span(ctx, span, GL_LINE);
- else
- _mesa_write_index_span(ctx, span, GL_LINE);
+ _swrast_write_rgba_span(ctx, span);
}
}
}
/***** Rasterization *****/
/**********************************************************************/
-
-/* Flat, color index line */
-static void flat_ci_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_FLAT);
- ASSERT(!ctx->Line.StippleFlag);
- ASSERT(ctx->Line.Width == 1.0F);
-
- INIT_SPAN(span);
- span.arrayMask |= SPAN_XY;
- span.interpMask |= SPAN_INDEX;
- span.index = IntToFixed(vert1->index);
- span.indexStep = 0;
-
-#define INTERP_XY 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.end++; \
- }
-
-#include "s_linetemp.h"
-
- _mesa_write_index_span(ctx, &span, GL_LINE);
-}
-
-
-/* Flat-shaded, RGBA line */
-static void flat_rgba_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_FLAT);
- ASSERT(!ctx->Line.StippleFlag);
- ASSERT(ctx->Line.Width == 1.0F);
-
- INIT_SPAN(span);
- span.arrayMask |= SPAN_XY;
- span.interpMask |= SPAN_RGBA;
- span.red = ChanToFixed(vert1->color[0]);
- span.green = ChanToFixed(vert1->color[1]);
- span.blue = ChanToFixed(vert1->color[2]);
- span.alpha = ChanToFixed(vert1->color[3]);
- span.redStep = 0;
- span.greenStep = 0;
- span.blueStep = 0;
- span.alphaStep = 0;
-
-#define INTERP_XY 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.end++; \
- }
-
-#include "s_linetemp.h"
-
- _mesa_write_rgba_span(ctx, &span, GL_LINE);
-}
-
-
-/* Smooth shaded, color index line */
-static void smooth_ci_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
- ASSERT(!ctx->Line.StippleFlag);
- ASSERT(ctx->Line.Width == 1.0F);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_INDEX);
-
-#define INTERP_XY 1
-#define INTERP_INDEX 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.color.index[span.end] = I; \
- span.end++; \
- }
-
-#include "s_linetemp.h"
-
- _mesa_write_index_span(ctx, &span, GL_LINE);
-}
-
-
-/* Smooth-shaded, RGBA line */
-static void smooth_rgba_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
- ASSERT(!ctx->Line.StippleFlag);
- ASSERT(ctx->Line.Width == 1.0F);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_RGBA);
-
-#define INTERP_XY 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.color.rgba[span.end][RCOMP] = FixedToInt(r0); \
- span.color.rgba[span.end][GCOMP] = FixedToInt(g0); \
- span.color.rgba[span.end][BCOMP] = FixedToInt(b0); \
- span.color.rgba[span.end][ACOMP] = FixedToInt(a0); \
- span.end++; \
- }
-
-#include "s_linetemp.h"
-
- _mesa_write_rgba_span(ctx, &span, GL_LINE);
-}
-
-
-/* Smooth shaded, color index, any width, maybe stippled */
-static void general_smooth_ci_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- GLboolean xMajor = GL_FALSE;
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_INDEX);
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_INDEX 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.zArray[span.end] = Z; \
- span.fogArray[span.end] = fog0; \
- span.color.index[span.end] = I; \
- span.end++; \
- }
-#include "s_linetemp.h"
-
- if (ctx->Line.StippleFlag) {
- span.arrayMask |= SPAN_MASK;
- compute_stipple_mask(ctx, span.end, span.mask);
- }
-
- if (ctx->Line.Width > 1.0) {
- draw_wide_line(ctx, &span, xMajor);
- }
- else {
- _mesa_write_index_span(ctx, &span, GL_LINE);
- }
-}
-
-
-/* Flat shaded, color index, any width, maybe stippled */
-static void general_flat_ci_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- GLboolean xMajor = GL_FALSE;
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG);
- span.interpMask |= SPAN_INDEX;
- span.index = IntToFixed(vert1->index);
- span.indexStep = 0;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.zArray[span.end] = Z; \
- span.fogArray[span.end] = fog0; \
- span.end++; \
- }
-#include "s_linetemp.h"
-
- if (ctx->Line.StippleFlag) {
- span.arrayMask |= SPAN_MASK;
- compute_stipple_mask(ctx, span.end, span.mask);
- }
-
- if (ctx->Line.Width > 1.0) {
- draw_wide_line(ctx, &span, xMajor);
- }
- else {
- _mesa_write_index_span(ctx, &span, GL_LINE);
- }
-}
-
-
-
-static void general_smooth_rgba_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- GLboolean xMajor = GL_FALSE;
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA);
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.zArray[span.end] = Z; \
- span.color.rgba[span.end][RCOMP] = FixedToInt(r0); \
- span.color.rgba[span.end][GCOMP] = FixedToInt(g0); \
- span.color.rgba[span.end][BCOMP] = FixedToInt(b0); \
- span.color.rgba[span.end][ACOMP] = FixedToInt(a0); \
- span.fogArray[span.end] = fog0; \
- span.end++; \
- }
-#include "s_linetemp.h"
-
- if (ctx->Line.StippleFlag) {
- span.arrayMask |= SPAN_MASK;
- compute_stipple_mask(ctx, span.end, span.mask);
- }
-
- if (ctx->Line.Width > 1.0) {
- draw_wide_line(ctx, &span, xMajor);
- }
- else {
- _mesa_write_rgba_span(ctx, &span, GL_LINE);
- }
-}
-
-
-static void general_flat_rgba_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- GLboolean xMajor = GL_FALSE;
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG);
- span.interpMask |= SPAN_RGBA;
- span.red = ChanToFixed(vert1->color[0]);
- span.green = ChanToFixed(vert1->color[1]);
- span.blue = ChanToFixed(vert1->color[2]);
- span.alpha = ChanToFixed(vert1->color[3]);
- span.redStep = 0;
- span.greenStep = 0;
- span.blueStep = 0;
- span.alphaStep = 0;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.zArray[span.end] = Z; \
- span.fogArray[span.end] = fog0; \
- span.end++; \
- }
-#include "s_linetemp.h"
-
- if (ctx->Line.StippleFlag) {
- span.arrayMask |= SPAN_MASK;
- compute_stipple_mask(ctx, span.end, span.mask);
- }
-
- if (ctx->Line.Width > 1.0) {
- draw_wide_line(ctx, &span, xMajor);
- }
- else {
- _mesa_write_rgba_span(ctx, &span, GL_LINE);
- }
-}
-
-
-/* Flat-shaded, textured, any width, maybe stippled */
-static void flat_textured_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- GLboolean xMajor = GL_FALSE;
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
- span.interpMask |= (SPAN_RGBA | SPAN_SPEC);
- span.red = ChanToFixed(vert1->color[0]);
- span.green = ChanToFixed(vert1->color[1]);
- span.blue = ChanToFixed(vert1->color[2]);
- span.alpha = ChanToFixed(vert1->color[3]);
- span.redStep = 0;
- span.greenStep = 0;
- span.blueStep = 0;
- span.alphaStep = 0;
- span.specRed = ChanToFixed(vert1->specular[0]);
- span.specGreen = ChanToFixed(vert1->specular[1]);
- span.specBlue = ChanToFixed(vert1->specular[2]);
- span.specRedStep = 0;
- span.specGreenStep = 0;
- span.specBlueStep = 0;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_TEX 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.zArray[span.end] = Z; \
- span.fogArray[span.end] = fog0; \
- span.texcoords[0][span.end][0] = fragTexcoord[0]; \
- span.texcoords[0][span.end][1] = fragTexcoord[1]; \
- span.texcoords[0][span.end][2] = fragTexcoord[2]; \
- span.lambda[0][span.end] = 0.0; \
- span.end++; \
- }
-#include "s_linetemp.h"
-
- if (ctx->Line.StippleFlag) {
- span.arrayMask |= SPAN_MASK;
- compute_stipple_mask(ctx, span.end, span.mask);
- }
-
- if (ctx->Line.Width > 1.0) {
- draw_wide_line(ctx, &span, xMajor);
- }
- else {
- _mesa_write_texture_span(ctx, &span, GL_LINE);
- }
-}
-
-
-
-/* Smooth-shaded, textured, any width, maybe stippled */
-static void smooth_textured_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- GLboolean xMajor = GL_FALSE;
- struct sw_span span;
-
- ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_TEXTURE | SPAN_LAMBDA);
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_ALPHA 1
-#define INTERP_TEX 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.zArray[span.end] = Z; \
- span.fogArray[span.end] = fog0; \
- span.color.rgba[span.end][RCOMP] = FixedToInt(r0); \
- span.color.rgba[span.end][GCOMP] = FixedToInt(g0); \
- span.color.rgba[span.end][BCOMP] = FixedToInt(b0); \
- span.color.rgba[span.end][ACOMP] = FixedToInt(a0); \
- span.texcoords[0][span.end][0] = fragTexcoord[0]; \
- span.texcoords[0][span.end][1] = fragTexcoord[1]; \
- span.texcoords[0][span.end][2] = fragTexcoord[2]; \
- span.lambda[0][span.end] = 0.0; \
- span.end++; \
- }
+/* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/
+#define NAME simple_no_z_rgba_line
+#define INTERP_RGBA
+#define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span);
#include "s_linetemp.h"
- if (ctx->Line.StippleFlag) {
- span.arrayMask |= SPAN_MASK;
- compute_stipple_mask(ctx, span.end, span.mask);
- }
- if (ctx->Line.Width > 1.0) {
- draw_wide_line(ctx, &span, xMajor);
- }
- else {
- _mesa_write_texture_span(ctx, &span, GL_LINE);
- }
-}
-
-
-/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
- * color interpolation.
- */
-static void smooth_multitextured_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- GLboolean xMajor = GL_FALSE;
- struct sw_span span;
- GLuint u;
-
- ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_TEXTURE | SPAN_LAMBDA);
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_RGB 1
-#define INTERP_SPEC 1
-#define INTERP_ALPHA 1
-#define INTERP_MULTITEX 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.zArray[span.end] = Z; \
- span.fogArray[span.end] = fog0; \
- span.color.rgba[span.end][RCOMP] = FixedToInt(r0); \
- span.color.rgba[span.end][GCOMP] = FixedToInt(g0); \
- span.color.rgba[span.end][BCOMP] = FixedToInt(b0); \
- span.color.rgba[span.end][ACOMP] = FixedToInt(a0); \
- span.specArray[span.end][RCOMP] = FixedToInt(sr0); \
- span.specArray[span.end][GCOMP] = FixedToInt(sb0); \
- span.specArray[span.end][BCOMP] = FixedToInt(sb0); \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u]._ReallyEnabled) { \
- span.texcoords[u][span.end][0] = fragTexcoord[u][0]; \
- span.texcoords[u][span.end][1] = fragTexcoord[u][1]; \
- span.texcoords[u][span.end][2] = fragTexcoord[u][2]; \
- span.lambda[u][span.end] = 0.0; \
- } \
- } \
- span.end++; \
+/* Z, fog, wide, stipple RGBA line */
+#define NAME rgba_line
+#define INTERP_RGBA
+#define INTERP_Z
+#define RENDER_SPAN(span) \
+ if (ctx->Line.StippleFlag) { \
+ span.arrayMask |= SPAN_MASK; \
+ compute_stipple_mask(ctx, span.end, span.array->mask); \
+ } \
+ if (ctx->Line.Width > 1.0) { \
+ draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
+ } \
+ else { \
+ _swrast_write_rgba_span(ctx, &span); \
}
#include "s_linetemp.h"
- if (ctx->Line.StippleFlag) {
- span.arrayMask |= SPAN_MASK;
- compute_stipple_mask(ctx, span.end, span.mask);
- }
- if (ctx->Line.Width > 1.0) {
- draw_wide_line(ctx, &span, xMajor);
- }
- else {
- _mesa_write_texture_span(ctx, &span, GL_LINE);
- }
-}
-
-
-/* Flat-shaded, multitextured, any width, maybe stippled, separate specular
- * color interpolation.
- */
-static void flat_multitextured_line( GLcontext *ctx,
- const SWvertex *vert0,
- const SWvertex *vert1 )
-{
- GLboolean xMajor = GL_FALSE;
- struct sw_span span;
- GLuint u;
-
- ASSERT(ctx->Light.ShadeModel == GL_FLAT);
-
- INIT_SPAN(span);
- span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
- span.interpMask |= (SPAN_RGBA | SPAN_SPEC);
- span.red = ChanToFixed(vert1->color[0]);
- span.green = ChanToFixed(vert1->color[1]);
- span.blue = ChanToFixed(vert1->color[2]);
- span.alpha = ChanToFixed(vert1->color[3]);
- span.redStep = 0;
- span.greenStep = 0;
- span.blueStep = 0;
- span.alphaStep = 0;
- span.specRed = ChanToFixed(vert1->specular[0]);
- span.specGreen = ChanToFixed(vert1->specular[1]);
- span.specBlue = ChanToFixed(vert1->specular[2]);
- span.specRedStep = 0;
- span.specGreenStep = 0;
- span.specBlueStep = 0;
-
-#define SET_XMAJOR 1
-#define INTERP_XY 1
-#define INTERP_Z 1
-#define INTERP_FOG 1
-#define INTERP_MULTITEX 1
-#define PLOT(X,Y) \
- { \
- span.xArray[span.end] = X; \
- span.yArray[span.end] = Y; \
- span.zArray[span.end] = Z; \
- span.fogArray[span.end] = fog0; \
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
- if (ctx->Texture.Unit[u]._ReallyEnabled) { \
- span.texcoords[u][span.end][0] = fragTexcoord[u][0]; \
- span.texcoords[u][span.end][1] = fragTexcoord[u][1]; \
- span.texcoords[u][span.end][2] = fragTexcoord[u][2]; \
- span.lambda[u][span.end] = 0.0; \
- } \
- } \
- span.end++; \
+/* General-purpose line (any/all features). */
+#define NAME general_line
+#define INTERP_RGBA
+#define INTERP_Z
+#define INTERP_ATTRIBS
+#define RENDER_SPAN(span) \
+ if (ctx->Line.StippleFlag) { \
+ span.arrayMask |= SPAN_MASK; \
+ compute_stipple_mask(ctx, span.end, span.array->mask); \
+ } \
+ if (ctx->Line.Width > 1.0) { \
+ draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \
+ } \
+ else { \
+ _swrast_write_rgba_span(ctx, &span); \
}
#include "s_linetemp.h"
- if (ctx->Line.StippleFlag) {
- span.arrayMask |= SPAN_MASK;
- compute_stipple_mask(ctx, span.end, span.mask);
- }
- if (ctx->Line.Width > 1.0) {
- draw_wide_line(ctx, &span, xMajor);
- }
- else {
- _mesa_write_texture_span(ctx, &span, GL_LINE);
- }
-}
-
-void _swrast_add_spec_terms_line( GLcontext *ctx,
- const SWvertex *v0,
- const SWvertex *v1 )
+void
+_swrast_add_spec_terms_line(struct gl_context *ctx,
+ const SWvertex *v0, const SWvertex *v1)
{
SWvertex *ncv0 = (SWvertex *)v0;
SWvertex *ncv1 = (SWvertex *)v1;
- GLchan c[2][4];
- COPY_CHAN4( c[0], ncv0->color );
- COPY_CHAN4( c[1], ncv1->color );
- ACC_3V( ncv0->color, ncv0->specular );
- ACC_3V( ncv1->color, ncv1->specular );
+ GLfloat rSum, gSum, bSum;
+ GLchan cSave[2][4];
+
+ /* save original colors */
+ COPY_CHAN4(cSave[0], ncv0->color);
+ COPY_CHAN4(cSave[1], ncv1->color);
+ /* sum v0 */
+ rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[VARYING_SLOT_COL1][0];
+ gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[VARYING_SLOT_COL1][1];
+ bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[VARYING_SLOT_COL1][2];
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum);
+ /* sum v1 */
+ rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[VARYING_SLOT_COL1][0];
+ gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[VARYING_SLOT_COL1][1];
+ bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[VARYING_SLOT_COL1][2];
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum);
+ UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum);
+ /* draw */
SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
- COPY_CHAN4( ncv0->color, c[0] );
- COPY_CHAN4( ncv1->color, c[1] );
-}
-
-
-#ifdef DEBUG
-extern void
-_mesa_print_line_function(GLcontext *ctx); /* silence compiler warning */
-void
-_mesa_print_line_function(GLcontext *ctx)
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
- printf("Line Func == ");
- if (swrast->Line == flat_ci_line)
- printf("flat_ci_line\n");
- else if (swrast->Line == flat_rgba_line)
- printf("flat_rgba_line\n");
- else if (swrast->Line == smooth_ci_line)
- printf("smooth_ci_line\n");
- else if (swrast->Line == smooth_rgba_line)
- printf("smooth_rgba_line\n");
- else if (swrast->Line == general_smooth_ci_line)
- printf("general_smooth_ci_line\n");
- else if (swrast->Line == general_flat_ci_line)
- printf("general_flat_ci_line\n");
- else if (swrast->Line == general_smooth_rgba_line)
- printf("general_smooth_rgba_line\n");
- else if (swrast->Line == general_flat_rgba_line)
- printf("general_flat_rgba_line\n");
- else if (swrast->Line == flat_textured_line)
- printf("flat_textured_line\n");
- else if (swrast->Line == smooth_textured_line)
- printf("smooth_textured_line\n");
- else if (swrast->Line == smooth_multitextured_line)
- printf("smooth_multitextured_line\n");
- else if (swrast->Line == flat_multitextured_line)
- printf("flat_multitextured_line\n");
- else
- printf("Driver func %p\n", (void *) swrast->Line);
+ /* restore original colors */
+ COPY_CHAN4(ncv0->color, cSave[0]);
+ COPY_CHAN4(ncv1->color, cSave[1]);
}
-#endif
-/*
+/**
* Determine which line drawing function to use given the current
* rendering context.
*
* tests to this code.
*/
void
-_swrast_choose_line( GLcontext *ctx )
+_swrast_choose_line( struct gl_context *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const GLboolean rgbmode = ctx->Visual.rgbMode;
+ GLboolean specular = (ctx->Fog.ColorSumEnabled ||
+ (ctx->Light.Enabled &&
+ ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
if (ctx->RenderMode == GL_RENDER) {
if (ctx->Line.SmoothFlag) {
/* antialiased lines */
_swrast_choose_aa_line_function(ctx);
- ASSERT(swrast->Triangle);
+ assert(swrast->Line);
}
- else if (ctx->Texture._ReallyEnabled) {
- if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY ||
- (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)) {
- /* multi-texture and/or separate specular color */
- if (ctx->Light.ShadeModel == GL_SMOOTH)
- USE(smooth_multitextured_line);
- else
- USE(flat_multitextured_line);
- }
- else {
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
- USE(smooth_textured_line);
- }
- else {
- USE(flat_textured_line);
- }
- }
+ else if (ctx->Texture._EnabledCoordUnits
+ || _swrast_use_fragment_program(ctx)
+ || swrast->_FogEnabled
+ || specular) {
+ USE(general_line);
+ }
+ else if (ctx->Depth.Test
+ || ctx->Line.Width != 1.0F
+ || ctx->Line.StippleFlag) {
+ /* no texture, but Z, fog, width>1, stipple, etc. */
+#if CHAN_BITS == 32
+ USE(general_line);
+#else
+ USE(rgba_line);
+#endif
}
else {
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
- if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
- || ctx->Line.StippleFlag) {
- if (rgbmode)
- USE(general_smooth_rgba_line);
- else
- USE(general_smooth_ci_line);
- }
- else {
- if (rgbmode)
- USE(smooth_rgba_line);
- else
- USE(smooth_ci_line);
- }
- }
- else {
- if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
- || ctx->Line.StippleFlag) {
- if (rgbmode)
- USE(general_flat_rgba_line);
- else
- USE(general_flat_ci_line);
- }
- else {
- if (rgbmode)
- USE(flat_rgba_line);
- else
- USE(flat_ci_line);
- }
- }
+ assert(!ctx->Depth.Test);
+ assert(ctx->Line.Width == 1.0F);
+ /* simple lines */
+ USE(simple_no_z_rgba_line);
}
}
else if (ctx->RenderMode == GL_FEEDBACK) {
- USE(_mesa_feedback_line);
+ USE(_swrast_feedback_line);
}
else {
- ASSERT(ctx->RenderMode == GL_SELECT);
- USE(_mesa_select_line);
+ assert(ctx->RenderMode == GL_SELECT);
+ USE(_swrast_select_line);
}
-
- /*_mesa_print_line_function(ctx);*/
}