#include "glheader.h"
#include "context.h"
#include "colormac.h"
#include "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"
static void
compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint i;
for (i = 0; i < len; i++) {
GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
if ((1 << bit) & ctx->Line.StipplePattern) {
mask[i] = GL_TRUE;
}
else {
mask[i] = GL_FALSE;
}
swrast->StippleCounter++;
}
}
static void
draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor )
{
GLint width, start;
ASSERT(span->end < MAX_WIDTH);
width = (GLint) CLAMP( ctx->Line._Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
if (width & 1)
start = width / 2;
else
start = width / 2 - 1;
if (xMajor) {
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++)
y[i] -= start;
}
else {
for (i = 0; i < span->end; i++)
y[i]++;
}
if (ctx->Visual.rgbMode)
_swrast_write_rgba_span(ctx, span);
else
_swrast_write_index_span(ctx, span);
}
}
else {
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++)
x[i] -= start;
}
else {
for (i = 0; i < span->end; i++)
x[i]++;
}
if (ctx->Visual.rgbMode)
_swrast_write_rgba_span(ctx, span);
else
_swrast_write_index_span(ctx, span);
}
}
}
#define NAME simple_ci_line
#define INTERP_INDEX
#define RENDER_SPAN(span) _swrast_write_index_span(ctx, &span)
#include "s_linetemp.h"
#define NAME simple_rgba_line
#define INTERP_RGBA
#define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span);
#include "s_linetemp.h"
#define NAME general_ci_line
#define INTERP_INDEX
#define INTERP_Z
#define INTERP_FOG
#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_index_span(ctx, &span); \
}
#include "s_linetemp.h"
#define NAME general_rgba_line
#define INTERP_RGBA
#define INTERP_Z
#define INTERP_FOG
#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"
#define NAME textured_line
#define INTERP_RGBA
#define INTERP_SPEC
#define INTERP_Z
#define INTERP_FOG
#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"
void
_swrast_add_spec_terms_line( GLcontext *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 );
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);
void
_mesa_print_line_function(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
_mesa_printf("Line Func == ");
if (swrast->Line == simple_ci_line)
_mesa_printf("simple_ci_line\n");
else if (swrast->Line == simple_rgba_line)
_mesa_printf("simple_rgba_line\n");
else if (swrast->Line == general_ci_line)
_mesa_printf("general_ci_line\n");
else if (swrast->Line == general_rgba_line)
_mesa_printf("general_rgba_line\n");
else if (swrast->Line == textured_line)
_mesa_printf("textured_line\n");
else
_mesa_printf("Driver func %p\n", (void *(*)()) swrast->Line);
}
#endif
#ifdef DEBUG
static const char *lineFuncName = NULL;
#define USE(lineFunc) \
do { \
lineFuncName = #lineFunc; \
\
swrast->Line = lineFunc; \
} while (0)
#else
#define USE(lineFunc) swrast->Line = lineFunc
#endif
void
_swrast_choose_line( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLboolean rgbmode = ctx->Visual.rgbMode;
if (ctx->RenderMode == GL_RENDER) {
if (ctx->Line.SmoothFlag) {
_swrast_choose_aa_line_function(ctx);
ASSERT(swrast->Line);
}
else if (ctx->Texture._EnabledCoordUnits
|| ctx->FragmentProgram._Current) {
USE(textured_line);
}
else if (ctx->Depth.Test || swrast->_FogEnabled || ctx->Line._Width != 1.0
|| ctx->Line.StippleFlag) {
if (rgbmode)
USE(general_rgba_line);
else
USE(general_ci_line);
}
else {
if (rgbmode)
USE(simple_rgba_line);
else
USE(simple_ci_line);
}
}
else if (ctx->RenderMode == GL_FEEDBACK) {
USE(_swrast_feedback_line);
}
else {
ASSERT(ctx->RenderMode == GL_SELECT);
USE(_swrast_select_line);
}
}