mirror of
https://github.com/reactos/reactos.git
synced 2024-10-30 11:35:58 +00:00
5f2bebf7a5
With this commit, we now use a forked version of MESA which only supports OpenGL 1.1, like the windows implementation does. It exposes : - The same pixel formats - The same set of extensions - Nothing more All of this without taking 10% of your build time. If you need a more modern option, look at the MESA package from Rapps, which is (and must be) maintained outside of this code tree. CORE-7499
979 lines
24 KiB
C
979 lines
24 KiB
C
/* $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;
|
|
}
|
|
}
|
|
|