summaryrefslogtreecommitdiffstats
path: root/src/mesa/swrast/s_lines.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/swrast/s_lines.c')
-rw-r--r--src/mesa/swrast/s_lines.c1173
1 files changed, 1173 insertions, 0 deletions
diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c
new file mode 100644
index 00000000000..75a01cf12eb
--- /dev/null
+++ b/src/mesa/swrast/s_lines.c
@@ -0,0 +1,1173 @@
+/* $Id: s_lines.c,v 1.1 2000/10/31 18:00:04 keithw Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.5
+ *
+ * Copyright (C) 1999-2000 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"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of 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.
+ */
+
+
+#include "glheader.h"
+#include "feedback.h"
+#include "macros.h"
+#include "mmath.h"
+#include "vb.h"
+
+#include "s_pb.h"
+#include "s_depth.h"
+
+
+
+/**********************************************************************/
+/***** Rasterization *****/
+/**********************************************************************/
+
+
+/*
+ * There are 4 pairs (RGBA, CI) of line drawing functions:
+ * 1. simple: width=1 and no special rasterization functions (fastest)
+ * 2. flat: width=1, non-stippled, flat-shaded, any raster operations
+ * 3. smooth: width=1, non-stippled, smooth-shaded, any raster operations
+ * 4. general: any other kind of line (slowest)
+ */
+
+
+/*
+ * All line drawing functions have the same arguments:
+ * v1, v2 - indexes of first and second endpoints into vertex buffer arrays
+ * pv - provoking vertex: which vertex color/index to use for flat shading.
+ */
+
+
+
+
+
+
+#if MAX_WIDTH > MAX_HEIGHT
+# define MAXPOINTS MAX_WIDTH
+#else
+# define MAXPOINTS MAX_HEIGHT
+#endif
+
+
+/* Flat, color index line */
+static void flat_ci_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
+
+#define INTERP_XY 1
+#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, 0, 0);
+
+#include "s_linetemp.h"
+
+ gl_flush_pb(ctx);
+}
+
+
+
+/* Flat, color index line with Z interpolation/testing */
+static void flat_ci_z_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0);
+
+#include "s_linetemp.h"
+
+ gl_flush_pb(ctx);
+}
+
+
+
+/* Flat-shaded, RGBA line */
+static void flat_rgba_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ const GLchan *color = ctx->VB->ColorPtr->data[pvert];
+ PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
+
+#define INTERP_XY 1
+#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, 0, 0);
+
+#include "s_linetemp.h"
+
+ gl_flush_pb(ctx);
+}
+
+
+
+/* Flat-shaded, RGBA line with Z interpolation/testing */
+static void flat_rgba_z_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ const GLchan *color = ctx->VB->ColorPtr->data[pvert];
+ PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0);
+
+#include "s_linetemp.h"
+
+ gl_flush_pb(ctx);
+}
+
+
+
+/* Smooth shaded, color index line */
+static void smooth_ci_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLuint *pbi = ctx->PB->index;
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+#define INTERP_XY 1
+#define INTERP_INDEX 1
+
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbi[count] = I; \
+ count++;
+
+#include "s_linetemp.h"
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+
+/* Smooth shaded, color index line with Z interpolation/testing */
+static void smooth_ci_z_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLuint *pbi = ctx->PB->index;
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbi[count] = I; \
+ count++;
+
+#include "s_linetemp.h"
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+
+/* Smooth-shaded, RGBA line */
+static void smooth_rgba_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLchan (*pbrgba)[4] = ctx->PB->rgba;
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+#define INTERP_XY 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ count++;
+
+#include "s_linetemp.h"
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+
+/* Smooth-shaded, RGBA line with Z interpolation/testing */
+static void smooth_rgba_z_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLfixed *pbfog = ctx->PB->fog;
+ GLchan (*pbrgba)[4] = ctx->PB->rgba;
+
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ count++;
+
+#include "s_linetemp.h"
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+#define CHECK_FULL(count) \
+ if (count >= PB_SIZE-MAX_WIDTH) { \
+ ctx->PB->count = count; \
+ gl_flush_pb(ctx); \
+ count = ctx->PB->count; \
+ }
+
+
+
+/* Smooth shaded, color index, any width, maybe stippled */
+static void general_smooth_ci_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLfixed *pbfog = ctx->PB->fog;
+ GLuint *pbi = ctx->PB->index;
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+ if (ctx->Line.StippleFlag) {
+ /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbi[count] = I; \
+ count++; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled */
+ if (ctx->Line.Width==2.0F) {
+ /* special case: unstippled and width=2 */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define XMAJOR_PLOT(X,Y) \
+ pbx[count] = X; pbx[count+1] = X; \
+ pby[count] = Y; pby[count+1] = Y+1; \
+ pbz[count] = Z; pbz[count+1] = Z; \
+ pbfog[count] = fog0; pbfog[count+1] = fog0; \
+ pbi[count] = I; pbi[count+1] = I; \
+ count += 2; \
+ CHECK_FULL(count);
+#define YMAJOR_PLOT(X,Y) \
+ pbx[count] = X; pbx[count+1] = X+1; \
+ pby[count] = Y; pby[count+1] = Y; \
+ pbz[count] = Z; pbz[count+1] = Z; \
+ pbfog[count] = fog0; pbfog[count+1] = fog0; \
+ pbi[count] = I; pbi[count+1] = I; \
+ count += 2; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define WIDE 1
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbi[count] = I; \
+ pbfog[count] = fog0; \
+ count++; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ }
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+/* Flat shaded, color index, any width, maybe stippled */
+static void general_flat_ci_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLfixed *pbfog = ctx->PB->fog;
+ PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
+ count = ctx->PB->count;
+
+ if (ctx->Line.StippleFlag) {
+ /* stippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ count++; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled */
+ if (ctx->Line.Width==2.0F) {
+ /* special case: unstippled and width=2 */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define XMAJOR_PLOT(X,Y) \
+ pbx[count] = X; pbx[count+1] = X; \
+ pby[count] = Y; pby[count+1] = Y+1; \
+ pbz[count] = Z; pbz[count+1] = Z; \
+ pbfog[count] = fog0; pbfog[count+1] = fog0; \
+ count += 2; \
+ CHECK_FULL(count);
+#define YMAJOR_PLOT(X,Y) \
+ pbx[count] = X; pbx[count+1] = X+1; \
+ pby[count] = Y; pby[count+1] = Y; \
+ pbz[count] = Z; pbz[count+1] = Z; \
+ pbfog[count] = fog0; pbfog[count+1] = fog0; \
+ count += 2; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define WIDE 1
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ count++; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ }
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+
+static void general_smooth_rgba_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert)
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLfixed *pbfog = ctx->PB->fog;
+ GLchan (*pbrgba)[4] = ctx->PB->rgba;
+
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+ if (ctx->Line.StippleFlag) {
+ /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ count++; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled */
+ if (ctx->Line.Width==2.0F) {
+ /* special case: unstippled and width=2 */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define XMAJOR_PLOT(X,Y) \
+ pbx[count] = X; pbx[count+1] = X; \
+ pby[count] = Y; pby[count+1] = Y+1; \
+ pbz[count] = Z; pbz[count+1] = Z; \
+ pbfog[count] = fog0; pbfog[count+1] = fog0; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ pbrgba[count+1][RCOMP] = FixedToInt(r0); \
+ pbrgba[count+1][GCOMP] = FixedToInt(g0); \
+ pbrgba[count+1][BCOMP] = FixedToInt(b0); \
+ pbrgba[count+1][ACOMP] = FixedToInt(a0); \
+ count += 2; \
+ CHECK_FULL(count);
+#define YMAJOR_PLOT(X,Y) \
+ pbx[count] = X; pbx[count+1] = X+1; \
+ pby[count] = Y; pby[count+1] = Y; \
+ pbz[count] = Z; pbz[count+1] = Z; \
+ pbfog[count] = fog0; pbfog[count+1] = fog0; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ pbrgba[count+1][RCOMP] = FixedToInt(r0); \
+ pbrgba[count+1][GCOMP] = FixedToInt(g0); \
+ pbrgba[count+1][BCOMP] = FixedToInt(b0); \
+ pbrgba[count+1][ACOMP] = FixedToInt(a0); \
+ count += 2; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define WIDE 1
+#define PLOT(X,Y) \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ count++; \
+ CHECK_FULL(count);
+#include "s_linetemp.h"
+ }
+ }
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+static void general_flat_rgba_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ const GLchan *color = ctx->VB->ColorPtr->data[pvert];
+ PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
+
+ if (ctx->Line.StippleFlag) {
+ /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0);
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled */
+ if (ctx->Line.Width==2.0F) {
+ /* special case: unstippled and width=2 */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define XMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0); \
+ PB_WRITE_PIXEL(ctx->PB, X, Y+1, Z, fog0);
+#define YMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0); \
+ PB_WRITE_PIXEL(ctx->PB, X+1, Y, Z, fog0);
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define WIDE 1
+#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z, fog0);
+#include "s_linetemp.h"
+ }
+ }
+
+ gl_flush_pb(ctx);
+}
+
+
+/* Flat-shaded, textured, any width, maybe stippled */
+static void flat_textured_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pv )
+{
+ GLint count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLfixed *pbfog = ctx->PB->fog;
+ GLfloat *pbs = ctx->PB->s[0];
+ GLfloat *pbt = ctx->PB->t[0];
+ GLfloat *pbu = ctx->PB->u[0];
+ GLchan *color = ctx->VB->ColorPtr->data[pv];
+ PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
+ count = ctx->PB->count;
+
+ if (ctx->Line.StippleFlag) {
+ /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_TEX 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y) \
+ { \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbs[count] = fragTexcoord[0];\
+ pbt[count] = fragTexcoord[1];\
+ pbu[count] = fragTexcoord[2];\
+ count++; \
+ CHECK_FULL(count); \
+ }
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_TEX 1
+#define WIDE 1
+#define PLOT(X,Y) \
+ { \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbs[count] = fragTexcoord[0];\
+ pbt[count] = fragTexcoord[1];\
+ pbu[count] = fragTexcoord[2];\
+ count++; \
+ CHECK_FULL(count); \
+ }
+#include "s_linetemp.h"
+ }
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+
+/* Smooth-shaded, textured, any width, maybe stippled */
+static void smooth_textured_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLfixed *pbfog = ctx->PB->fog;
+ GLfloat *pbs = ctx->PB->s[0];
+ GLfloat *pbt = ctx->PB->t[0];
+ GLfloat *pbu = ctx->PB->u[0];
+ GLchan (*pbrgba)[4] = ctx->PB->rgba;
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+ if (ctx->Line.StippleFlag) {
+ /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define INTERP_TEX 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y) \
+ { \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbs[count] = fragTexcoord[0]; \
+ pbt[count] = fragTexcoord[1]; \
+ pbu[count] = fragTexcoord[2]; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ count++; \
+ CHECK_FULL(count); \
+ }
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define INTERP_TEX 1
+#define WIDE 1
+#define PLOT(X,Y) \
+ { \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbs[count] = fragTexcoord[0]; \
+ pbt[count] = fragTexcoord[1]; \
+ pbu[count] = fragTexcoord[2]; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ count++; \
+ CHECK_FULL(count); \
+ }
+#include "s_linetemp.h"
+ }
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
+ * color interpolation.
+ */
+static void smooth_multitextured_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLfixed *pbfog = ctx->PB->fog;
+ GLchan (*pbrgba)[4] = ctx->PB->rgba;
+ GLchan (*pbspec)[3] = ctx->PB->spec;
+
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+ if (ctx->Line.StippleFlag) {
+ /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_SPEC 1
+#define INTERP_ALPHA 1
+#define INTERP_MULTITEX 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y) \
+ { \
+ GLuint u; \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ pbspec[count][RCOMP] = FixedToInt(sr0); \
+ pbspec[count][GCOMP] = FixedToInt(sg0); \
+ pbspec[count][BCOMP] = FixedToInt(sb0); \
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
+ if (ctx->Texture.Unit[u].ReallyEnabled) { \
+ ctx->PB->s[u][0] = fragTexcoord[u][0]; \
+ ctx->PB->s[u][1] = fragTexcoord[u][1]; \
+ ctx->PB->s[u][2] = fragTexcoord[u][2]; \
+ ctx->PB->s[u][3] = fragTexcoord[u][3]; \
+ } \
+ } \
+ count++; \
+ CHECK_FULL(count); \
+ }
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_SPEC 1
+#define INTERP_ALPHA 1
+#define INTERP_MULTITEX 1
+#define WIDE 1
+#define PLOT(X,Y) \
+ { \
+ GLuint u; \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbrgba[count][RCOMP] = FixedToInt(r0); \
+ pbrgba[count][GCOMP] = FixedToInt(g0); \
+ pbrgba[count][BCOMP] = FixedToInt(b0); \
+ pbrgba[count][ACOMP] = FixedToInt(a0); \
+ pbspec[count][RCOMP] = FixedToInt(sr0); \
+ pbspec[count][GCOMP] = FixedToInt(sg0); \
+ pbspec[count][BCOMP] = FixedToInt(sb0); \
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
+ if (ctx->Texture.Unit[u].ReallyEnabled) { \
+ ctx->PB->s[u][0] = fragTexcoord[u][0]; \
+ ctx->PB->s[u][1] = fragTexcoord[u][1]; \
+ ctx->PB->s[u][2] = fragTexcoord[u][2]; \
+ ctx->PB->s[u][3] = fragTexcoord[u][3]; \
+ } \
+ } \
+ count++; \
+ CHECK_FULL(count); \
+ }
+#include "s_linetemp.h"
+ }
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+/* Flat-shaded, multitextured, any width, maybe stippled, separate specular
+ * color interpolation.
+ */
+static void flat_multitextured_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+ GLint count = ctx->PB->count;
+ GLint *pbx = ctx->PB->x;
+ GLint *pby = ctx->PB->y;
+ GLdepth *pbz = ctx->PB->z;
+ GLfixed *pbfog = ctx->PB->fog;
+ GLchan (*pbrgba)[4] = ctx->PB->rgba;
+ GLchan (*pbspec)[3] = ctx->PB->spec;
+ GLchan *color = ctx->VB->ColorPtr->data[pvert];
+ GLchan sRed = ctx->VB->SecondaryColorPtr->data ? ctx->VB->SecondaryColorPtr->data[pvert][0] : 0;
+ GLchan sGreen = ctx->VB->SecondaryColorPtr->data ? ctx->VB->SecondaryColorPtr->data[pvert][1] : 0;
+ GLchan sBlue = ctx->VB->SecondaryColorPtr->data ? ctx->VB->SecondaryColorPtr->data[pvert][2] : 0;
+
+ (void) pvert;
+
+ ctx->PB->mono = GL_FALSE;
+
+ if (ctx->Line.StippleFlag) {
+ /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_ALPHA 1
+#define INTERP_MULTITEX 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y) \
+ { \
+ GLuint u; \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbrgba[count][RCOMP] = color[0]; \
+ pbrgba[count][GCOMP] = color[1]; \
+ pbrgba[count][BCOMP] = color[2]; \
+ pbrgba[count][ACOMP] = color[3]; \
+ pbspec[count][RCOMP] = sRed; \
+ pbspec[count][GCOMP] = sGreen; \
+ pbspec[count][BCOMP] = sBlue; \
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
+ if (ctx->Texture.Unit[u].ReallyEnabled) { \
+ ctx->PB->s[u][0] = fragTexcoord[u][0]; \
+ ctx->PB->s[u][1] = fragTexcoord[u][1]; \
+ ctx->PB->s[u][2] = fragTexcoord[u][2]; \
+ ctx->PB->s[u][3] = fragTexcoord[u][3]; \
+ } \
+ } \
+ count++; \
+ CHECK_FULL(count); \
+ }
+#include "s_linetemp.h"
+ }
+ else {
+ /* unstippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_ALPHA 1
+#define INTERP_MULTITEX 1
+#define WIDE 1
+#define PLOT(X,Y) \
+ { \
+ GLuint u; \
+ pbx[count] = X; \
+ pby[count] = Y; \
+ pbz[count] = Z; \
+ pbfog[count] = fog0; \
+ pbrgba[count][RCOMP] = color[0]; \
+ pbrgba[count][GCOMP] = color[1]; \
+ pbrgba[count][BCOMP] = color[2]; \
+ pbrgba[count][ACOMP] = color[3]; \
+ pbspec[count][RCOMP] = sRed; \
+ pbspec[count][GCOMP] = sGreen; \
+ pbspec[count][BCOMP] = sBlue; \
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
+ if (ctx->Texture.Unit[u].ReallyEnabled) { \
+ ctx->PB->s[u][0] = fragTexcoord[u][0]; \
+ ctx->PB->s[u][1] = fragTexcoord[u][1]; \
+ ctx->PB->s[u][2] = fragTexcoord[u][2]; \
+ ctx->PB->s[u][3] = fragTexcoord[u][3]; \
+ } \
+ } \
+ count++; \
+ CHECK_FULL(count); \
+ }
+#include "s_linetemp.h"
+ }
+
+ ctx->PB->count = count;
+ gl_flush_pb(ctx);
+}
+
+
+
+
+/*
+ * Antialiased RGBA line
+ *
+ * This AA line function isn't terribly efficient but it's pretty
+ * straight-forward to understand. Also, it doesn't exactly conform
+ * to the specification.
+ */
+static void aa_rgba_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+#define INTERP_RGBA 1
+#define PLOT(x, y) \
+ { \
+ PB_WRITE_RGBA_PIXEL( pb, (x), (y), z, fog0, \
+ red, green, blue, coverage ); \
+ }
+#include "s_lnaatemp.h"
+}
+
+/*
+ * Antialiased Textured RGBA line
+ *
+ * This AA line function isn't terribly efficient but it's pretty
+ * straight-forward to understand. Also, it doesn't exactly conform
+ * to the specification.
+ */
+static void aa_tex_rgba_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+#define INTERP_RGBA 1
+#define INTERP_TEX 1
+#define PLOT(x, y) \
+ { \
+ PB_WRITE_TEX_PIXEL( pb, (x), (y), z, fog0, \
+ red, green, blue, coverage, \
+ fragTexcoord[0], fragTexcoord[1], fragTexcoord[2] ); \
+ }
+#include "s_lnaatemp.h"
+}
+
+
+/*
+ * Antialiased Multitextured RGBA line
+ *
+ * This AA line function isn't terribly efficient but it's pretty
+ * straight-forward to understand. Also, it doesn't exactly conform
+ * to the specification.
+ */
+static void aa_multitex_rgba_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+#define INTERP_RGBA 1
+#define INTERP_SPEC 1
+#define INTERP_MULTITEX 1
+#define PLOT(x, y) \
+ { \
+ PB_WRITE_MULTITEX_SPEC_PIXEL( pb, (x), (y), z, fog0, \
+ red, green, blue, coverage, specRed, specGreen, specBlue, \
+ fragTexcoord ); \
+ }
+#include "s_lnaatemp.h"
+}
+
+
+/*
+ * Antialiased CI line. Same comments for RGBA antialiased lines apply.
+ */
+static void aa_ci_line( GLcontext *ctx,
+ GLuint vert0, GLuint vert1, GLuint pvert )
+{
+#define INTERP_INDEX 1
+#define PLOT(x, y) \
+ { \
+ PB_WRITE_CI_PIXEL( pb, (x), (y), z, fog0, index + coverage ); \
+ }
+#include "s_lnaatemp.h"
+}
+
+
+/*
+ * Null rasterizer for measuring transformation speed.
+ */
+static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+ (void) ctx;
+ (void) v1;
+ (void) v2;
+ (void) pv;
+}
+
+
+
+#ifdef DEBUG
+void
+_mesa_print_line_function(GLcontext *ctx)
+{
+ printf("Line Func == ");
+ if (ctx->Driver.LineFunc == flat_ci_line)
+ printf("flat_ci_line\n");
+ else if (ctx->Driver.LineFunc == flat_ci_z_line)
+ printf("flat_ci_z_line\n");
+ else if (ctx->Driver.LineFunc == flat_rgba_line)
+ printf("flat_rgba_line\n");
+ else if (ctx->Driver.LineFunc == flat_rgba_z_line)
+ printf("flat_rgba_z_line\n");
+ else if (ctx->Driver.LineFunc == smooth_ci_line)
+ printf("smooth_ci_line\n");
+ else if (ctx->Driver.LineFunc == smooth_ci_z_line)
+ printf("smooth_ci_z_line\n");
+ else if (ctx->Driver.LineFunc == smooth_rgba_line)
+ printf("smooth_rgba_line\n");
+ else if (ctx->Driver.LineFunc == smooth_rgba_z_line)
+ printf("smooth_rgba_z_line\n");
+ else if (ctx->Driver.LineFunc == general_smooth_ci_line)
+ printf("general_smooth_ci_line\n");
+ else if (ctx->Driver.LineFunc == general_flat_ci_line)
+ printf("general_flat_ci_line\n");
+ else if (ctx->Driver.LineFunc == general_smooth_rgba_line)
+ printf("general_smooth_rgba_line\n");
+ else if (ctx->Driver.LineFunc == general_flat_rgba_line)
+ printf("general_flat_rgba_line\n");
+ else if (ctx->Driver.LineFunc == flat_textured_line)
+ printf("flat_textured_line\n");
+ else if (ctx->Driver.LineFunc == smooth_textured_line)
+ printf("smooth_textured_line\n");
+ else if (ctx->Driver.LineFunc == smooth_multitextured_line)
+ printf("smooth_multitextured_line\n");
+ else if (ctx->Driver.LineFunc == flat_multitextured_line)
+ printf("flat_multitextured_line\n");
+ else if (ctx->Driver.LineFunc == aa_rgba_line)
+ printf("aa_rgba_line\n");
+ else if (ctx->Driver.LineFunc == aa_tex_rgba_line)
+ printf("aa_tex_rgba_line\n");
+ else if (ctx->Driver.LineFunc == aa_multitex_rgba_line)
+ printf("aa_multitex_rgba_line\n");
+ else if (ctx->Driver.LineFunc == aa_ci_line)
+ printf("aa_ci_line\n");
+ else if (ctx->Driver.LineFunc == null_line)
+ printf("null_line\n");
+ else
+ printf("Driver func %p\n", ctx->Driver.LineFunc);
+}
+#endif
+
+
+
+/*
+ * Determine which line drawing function to use given the current
+ * rendering context.
+ *
+ * Please update the summary flag _SWRAST_NEW_LINE if you add or remove
+ * tests to this code.
+ */
+void
+_swrast_set_line_function( GLcontext *ctx )
+{
+ GLboolean rgbmode = ctx->Visual.RGBAflag;
+ /* TODO: antialiased lines */
+
+ if (ctx->RenderMode==GL_RENDER) {
+ if (ctx->NoRaster) {
+ ctx->Driver.LineFunc = null_line;
+ return;
+ }
+ if (ctx->Driver.LineFunc) {
+ /* Device driver will draw lines. */
+ return;
+ }
+
+ if (ctx->Line.SmoothFlag) {
+ /* antialiased lines */
+ if (rgbmode) {
+ if (ctx->Texture.ReallyEnabled) {
+ if (ctx->Texture.MultiTextureEnabled
+ || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR
+ || ctx->Fog.ColorSumEnabled)
+ /* Multitextured! */
+ ctx->Driver.LineFunc = aa_multitex_rgba_line;
+ else
+ ctx->Driver.LineFunc = aa_tex_rgba_line;
+ } else {
+ ctx->Driver.LineFunc = aa_rgba_line;
+ }
+ }
+ else {
+ ctx->Driver.LineFunc = aa_ci_line;
+ }
+ }
+ else if (ctx->Texture.ReallyEnabled) {
+ if (ctx->Texture.MultiTextureEnabled
+ || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR
+ || ctx->Fog.ColorSumEnabled) {
+ /* multi-texture and/or separate specular color */
+ if (ctx->Light.ShadeModel==GL_SMOOTH)
+ ctx->Driver.LineFunc = smooth_multitextured_line;
+ else
+ ctx->Driver.LineFunc = flat_multitextured_line;
+ }
+ else {
+ if (ctx->Light.ShadeModel==GL_SMOOTH) {
+ ctx->Driver.LineFunc = smooth_textured_line;
+ }
+ else {
+ ctx->Driver.LineFunc = flat_textured_line;
+ }
+ }
+ }
+ else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag
+ || ctx->Line.SmoothFlag) {
+ if (ctx->Light.ShadeModel==GL_SMOOTH) {
+ if (rgbmode)
+ ctx->Driver.LineFunc = general_smooth_rgba_line;
+ else
+ ctx->Driver.LineFunc = general_smooth_ci_line;
+ }
+ else {
+ if (rgbmode)
+ ctx->Driver.LineFunc = general_flat_rgba_line;
+ else
+ ctx->Driver.LineFunc = general_flat_ci_line;
+ }
+ }
+ else {
+ if (ctx->Light.ShadeModel==GL_SMOOTH) {
+ /* Width==1, non-stippled, smooth-shaded */
+ if (ctx->Depth.Test || ctx->Fog.Enabled) {
+ if (rgbmode)
+ ctx->Driver.LineFunc = smooth_rgba_z_line;
+ else
+ ctx->Driver.LineFunc = smooth_ci_z_line;
+ }
+ else {
+ if (rgbmode)
+ ctx->Driver.LineFunc = smooth_rgba_line;
+ else
+ ctx->Driver.LineFunc = smooth_ci_line;
+ }
+ }
+ else {
+ /* Width==1, non-stippled, flat-shaded */
+ if (ctx->Depth.Test || ctx->Fog.Enabled) {
+ if (rgbmode)
+ ctx->Driver.LineFunc = flat_rgba_z_line;
+ else
+ ctx->Driver.LineFunc = flat_ci_z_line;
+ }
+ else {
+ if (rgbmode)
+ ctx->Driver.LineFunc = flat_rgba_line;
+ else
+ ctx->Driver.LineFunc = flat_ci_line;
+ }
+ }
+ }
+ }
+ else if (ctx->RenderMode==GL_FEEDBACK) {
+ ctx->Driver.LineFunc = gl_feedback_line;
+ }
+ else {
+ /* GL_SELECT mode */
+ ctx->Driver.LineFunc = gl_select_line;
+ }
+
+ /*_mesa_print_line_function(ctx);*/
+}