reactos/dll/opengl/mesa/lines.c

979 lines
24 KiB
C
Raw Normal View History

/* $Id: lines.c,v 1.19 1998/02/03 23:46:00 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 2.4
* Copyright (C) 1995-1997 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* $Log: lines.c,v $
* Revision 1.19 1998/02/03 23:46:00 brianp
* fixed a few problems with condition expressions for Amiga StormC compiler
*
* Revision 1.18 1997/07/24 01:24:11 brianp
* changed precompiled header symbol from PCH to PC_HEADER
*
* Revision 1.17 1997/07/05 16:03:51 brianp
* fixed PB overflow problem
*
* Revision 1.16 1997/06/20 02:01:49 brianp
* changed color components from GLfixed to GLubyte
*
* Revision 1.15 1997/06/03 01:38:22 brianp
* fixed divide by zero problem in feedback function (William Mitchell)
*
* Revision 1.14 1997/05/28 03:25:26 brianp
* added precompiled header (PCH) support
*
* Revision 1.13 1997/05/03 00:51:02 brianp
* removed calls to gl_texturing_enabled()
*
* Revision 1.12 1997/04/14 02:00:39 brianp
* #include "texstate.h" instead of "texture.h"
*
* Revision 1.11 1997/04/12 12:25:01 brianp
* replaced ctx->LineFunc with ctx->Driver.LineFunc, fixed PB->count bug
*
* Revision 1.10 1997/03/16 02:07:31 brianp
* now use linetemp.h in line drawing functions
*
* Revision 1.9 1997/03/08 02:04:27 brianp
* better implementation of feedback function
*
* Revision 1.8 1997/02/09 18:44:20 brianp
* added GL_EXT_texture3D support
*
* Revision 1.7 1997/01/09 19:48:00 brianp
* now call gl_texturing_enabled()
*
* Revision 1.6 1996/11/08 02:21:21 brianp
* added null drawing function for GL_NO_RASTER
*
* Revision 1.5 1996/09/27 01:28:56 brianp
* removed unused variables
*
* Revision 1.4 1996/09/25 02:01:54 brianp
* new texture coord interpolation
*
* Revision 1.3 1996/09/15 14:18:10 brianp
* now use GLframebuffer and GLvisual
*
* Revision 1.2 1996/09/15 01:48:58 brianp
* removed #define NULL 0
*
* Revision 1.1 1996/09/13 01:38:16 brianp
* Initial revision
*
*/
#ifdef PC_HEADER
#include "all.h"
#else
#include "context.h"
#include "depth.h"
#include "feedback.h"
#include "lines.h"
#include "dlist.h"
#include "macros.h"
#include "pb.h"
#include "texstate.h"
#include "types.h"
#include "vb.h"
#include <wine/debug.h>
#endif
WINE_DEFAULT_DEBUG_CHANNEL(opengl32);
void gl_LineWidth( GLcontext *ctx, GLfloat width )
{
if (width<=0.0) {
gl_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
return;
}
if (INSIDE_BEGIN_END(ctx)) {
gl_error( ctx, GL_INVALID_OPERATION, "glLineWidth" );
return;
}
ctx->Line.Width = width;
ctx->NewState |= NEW_RASTER_OPS;
}
void gl_LineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
{
if (INSIDE_BEGIN_END(ctx)) {
gl_error( ctx, GL_INVALID_OPERATION, "glLineStipple" );
return;
}
ctx->Line.StippleFactor = CLAMP( factor, 1, 256 );
ctx->Line.StipplePattern = pattern;
ctx->NewState |= NEW_RASTER_OPS;
}
/**********************************************************************/
/***** 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.
*/
static void feedback_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
{
struct vertex_buffer *VB = ctx->VB;
GLfloat x1, y1, z1, w1;
GLfloat x2, y2, z2, w2;
GLfloat tex1[4], tex2[4], invq;
GLfloat invRedScale = ctx->Visual->InvRedScale;
GLfloat invGreenScale = ctx->Visual->InvGreenScale;
GLfloat invBlueScale = ctx->Visual->InvBlueScale;
GLfloat invAlphaScale = ctx->Visual->InvAlphaScale;
x1 = VB->Win[v1][0];
y1 = VB->Win[v1][1];
z1 = VB->Win[v1][2] / DEPTH_SCALE;
w1 = VB->Clip[v1][3];
x2 = VB->Win[v2][0];
y2 = VB->Win[v2][1];
z2 = VB->Win[v2][2] / DEPTH_SCALE;
w2 = VB->Clip[v2][3];
invq = (VB->TexCoord[v1][3]==0.0) ? 1.0 : (1.0F / VB->TexCoord[v1][3]);
tex1[0] = VB->TexCoord[v1][0] * invq;
tex1[1] = VB->TexCoord[v1][1] * invq;
tex1[2] = VB->TexCoord[v1][2] * invq;
tex1[3] = VB->TexCoord[v1][3];
invq = (VB->TexCoord[v2][3]==0.0) ? 1.0 : (1.0F / VB->TexCoord[v2][3]);
tex2[0] = VB->TexCoord[v2][0] * invq;
tex2[1] = VB->TexCoord[v2][1] * invq;
tex2[2] = VB->TexCoord[v2][2] * invq;
tex2[3] = VB->TexCoord[v2][3];
if (ctx->StippleCounter==0) {
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_LINE_RESET_TOKEN );
}
else {
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_LINE_TOKEN );
}
{
GLfloat color[4];
/* convert color from integer to a float in [0,1] */
color[0] = (GLfloat) VB->Color[pv][0] * invRedScale;
color[1] = (GLfloat) VB->Color[pv][1] * invGreenScale;
color[2] = (GLfloat) VB->Color[pv][2] * invBlueScale;
color[3] = (GLfloat) VB->Color[pv][3] * invAlphaScale;
gl_feedback_vertex( ctx, x1,y1,z1,w1, color,
(GLfloat) VB->Index[pv], tex1 );
gl_feedback_vertex( ctx, x2,y2,z2,w2, color,
(GLfloat) VB->Index[pv], tex2 );
}
ctx->StippleCounter++;
}
static void select_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
{
gl_update_hitflag( ctx, ctx->VB->Win[v1][2] / DEPTH_SCALE );
gl_update_hitflag( ctx, ctx->VB->Win[v2][2] / DEPTH_SCALE );
}
#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 )
{
GLint count;
GLint *pbx = ctx->PB->x;
GLint *pby = ctx->PB->y;
PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[pvert] );
count = ctx->PB->count;
#define INTERP_XY 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
count++;
#include "linetemp.h"
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* Flat, color index line with Z interpolation/testing */
static void flat_ci_z_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;
PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[pvert] );
count = ctx->PB->count;
#define INTERP_XY 1
#define INTERP_Z 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbz[count] = Z; \
count++;
#include "linetemp.h"
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* Flat-shaded, RGBA line */
static void flat_rgba_line( GLcontext *ctx,
GLuint vert0, GLuint vert1, GLuint pvert )
{
GLint count;
GLint *pbx = ctx->PB->x;
GLint *pby = ctx->PB->y;
GLubyte *color = ctx->VB->Color[pvert];
PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
count = ctx->PB->count;
#define INTERP_XY 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
count++;
#include "linetemp.h"
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* Flat-shaded, RGBA line with Z interpolation/testing */
static void flat_rgba_z_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;
GLubyte *color = ctx->VB->Color[pvert];
PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
count = ctx->PB->count;
#define INTERP_XY 1
#define INTERP_Z 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbz[count] = Z; \
count++;
#include "linetemp.h"
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* 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->i;
#define INTERP_XY 1
#define INTERP_INDEX 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbi[count] = I; \
count++;
#include "linetemp.h"
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* 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->i;
#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 "linetemp.h"
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* 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;
GLubyte *pbr = ctx->PB->r;
GLubyte *pbg = ctx->PB->g;
GLubyte *pbb = ctx->PB->b;
GLubyte *pba = ctx->PB->a;
#define INTERP_XY 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbr[count] = FixedToInt(r0); \
pbg[count] = FixedToInt(g0); \
pbb[count] = FixedToInt(b0); \
pba[count] = FixedToInt(a0); \
count++;
#include "linetemp.h"
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* 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;
GLubyte *pbr = ctx->PB->r;
GLubyte *pbg = ctx->PB->g;
GLubyte *pbb = ctx->PB->b;
GLubyte *pba = ctx->PB->a;
#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; \
pbr[count] = FixedToInt(r0); \
pbg[count] = FixedToInt(g0); \
pbb[count] = FixedToInt(b0); \
pba[count] = FixedToInt(a0); \
count++;
#include "linetemp.h"
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
#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;
GLuint *pbi = ctx->PB->i;
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; \
pbi[count] = I; \
count++; \
CHECK_FULL(count);
#include "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; \
pbi[count] = I; pbi[count+1] = I; \
count += 2;
#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; \
pbi[count] = I; pbi[count+1] = I; \
count += 2;
#include "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; \
count++; \
CHECK_FULL(count);
#include "linetemp.h"
}
}
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* 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;
PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[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; \
count++; \
CHECK_FULL(count);
#include "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; \
count += 2;
#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; \
count += 2;
#include "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; \
count++; \
CHECK_FULL(count);
#include "linetemp.h"
}
}
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
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;
GLubyte *pbr = ctx->PB->r;
GLubyte *pbg = ctx->PB->g;
GLubyte *pbb = ctx->PB->b;
GLubyte *pba = ctx->PB->a;
TRACE("Line %3.1f, %3.1f, %3.1f (r%u, g%u, b%u) --> %3.1f, %3.1f, %3.1f (r%u, g%u, b%u)\n",
ctx->VB->Win[vert0][0], ctx->VB->Win[vert0][1], ctx->VB->Win[vert0][2], ctx->VB->Color[vert0][0], ctx->VB->Color[vert0][1], ctx->VB->Color[vert0][2],
ctx->VB->Win[vert1][0], ctx->VB->Win[vert1][1], ctx->VB->Win[vert1][2], ctx->VB->Color[vert1][0], ctx->VB->Color[vert1][1], ctx->VB->Color[vert1][2]);
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; \
pbr[count] = FixedToInt(r0); \
pbg[count] = FixedToInt(g0); \
pbb[count] = FixedToInt(b0); \
pba[count] = FixedToInt(a0); \
count++; \
CHECK_FULL(count);
#include "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; \
pbr[count] = FixedToInt(r0); pbr[count+1] = FixedToInt(r0); \
pbg[count] = FixedToInt(g0); pbg[count+1] = FixedToInt(g0); \
pbb[count] = FixedToInt(b0); pbb[count+1] = FixedToInt(b0); \
pba[count] = FixedToInt(a0); pba[count+1] = FixedToInt(a0); \
count += 2;
#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; \
pbr[count] = FixedToInt(r0); pbr[count+1] = FixedToInt(r0); \
pbg[count] = FixedToInt(g0); pbg[count+1] = FixedToInt(g0); \
pbb[count] = FixedToInt(b0); pbb[count+1] = FixedToInt(b0); \
pba[count] = FixedToInt(a0); pba[count+1] = FixedToInt(a0); \
count += 2;
#include "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; \
pbr[count] = FixedToInt(r0); \
pbg[count] = FixedToInt(g0); \
pbb[count] = FixedToInt(b0); \
pba[count] = FixedToInt(a0); \
count++; \
CHECK_FULL(count);
#include "linetemp.h"
}
}
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
static void general_flat_rgba_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;
GLubyte *color = ctx->VB->Color[pvert];
PB_SET_COLOR( ctx, 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 WIDE 1
#define STIPPLE 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbz[count] = Z; \
count++; \
CHECK_FULL(count);
#include "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; \
count += 2;
#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; \
count += 2;
#include "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; \
count++; \
CHECK_FULL(count);
#include "linetemp.h"
}
}
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* 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;
GLfloat *pbs = ctx->PB->s;
GLfloat *pbt = ctx->PB->t;
GLfloat *pbu = ctx->PB->u;
GLubyte *color = ctx->VB->Color[pv];
PB_SET_COLOR( ctx, 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_STW 1
#define INTERP_UV 1
#define WIDE 1
#define STIPPLE 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbz[count] = Z; \
pbs[count] = s0 / w0; \
pbt[count] = t0 / w0; \
pbu[count] = u0 / w0; \
count++; \
CHECK_FULL(count);
#include "linetemp.h"
}
else {
/* unstippled */
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_STW 1
#define INTERP_UV 1
#define WIDE 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbz[count] = Z; \
pbs[count] = s0 / w0; \
pbt[count] = t0 / w0; \
pbu[count] = u0 / w0; \
count++; \
CHECK_FULL(count);
#include "linetemp.h"
}
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/* Smooth-shaded, textured, any width, maybe stippled */
static void smooth_textured_line( GLcontext *ctx,
GLuint vert0, GLuint vert1, GLuint pv )
{
GLint count = ctx->PB->count;
GLint *pbx = ctx->PB->x;
GLint *pby = ctx->PB->y;
GLdepth *pbz = ctx->PB->z;
GLfloat *pbs = ctx->PB->s;
GLfloat *pbt = ctx->PB->t;
GLfloat *pbu = ctx->PB->u;
GLubyte *pbr = ctx->PB->r;
GLubyte *pbg = ctx->PB->g;
GLubyte *pbb = ctx->PB->b;
GLubyte *pba = ctx->PB->a;
if (ctx->Line.StippleFlag) {
/* stippled */
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_STW 1
#define INTERP_UV 1
#define WIDE 1
#define STIPPLE 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbz[count] = Z; \
pbs[count] = s0 / w0; \
pbt[count] = t0 / w0; \
pbu[count] = u0 / w0; \
pbr[count] = FixedToInt(r0); \
pbg[count] = FixedToInt(g0); \
pbb[count] = FixedToInt(b0); \
pba[count] = FixedToInt(a0); \
count++; \
CHECK_FULL(count);
#include "linetemp.h"
}
else {
/* unstippled */
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_STW 1
#define INTERP_UV 1
#define WIDE 1
#define PLOT(X,Y) \
pbx[count] = X; \
pby[count] = Y; \
pbz[count] = Z; \
pbs[count] = s0 / w0; \
pbt[count] = t0 / w0; \
pbu[count] = u0 / w0; \
pbr[count] = FixedToInt(r0); \
pbg[count] = FixedToInt(g0); \
pbb[count] = FixedToInt(b0); \
pba[count] = FixedToInt(a0); \
count++; \
CHECK_FULL(count);
#include "linetemp.h"
}
ctx->PB->count = count;
PB_CHECK_FLUSH( ctx, ctx->PB );
}
/*
* Null rasterizer for measuring transformation speed.
*/
static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
{
}
/*
* Determine which line drawing function to use given the current
* rendering context.
*/
void gl_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. */
ctx->Driver.LineFunc = ctx->Driver.LineFunc;
}
else if (ctx->Texture.Enabled) {
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 || ctx->Texture.Enabled) {
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 && ctx->Hint.Fog==GL_NICEST)) {
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 && ctx->Hint.Fog==GL_NICEST)) {
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 = feedback_line;
}
else {
/* GL_SELECT mode */
ctx->Driver.LineFunc = select_line;
}
}