This is lines.c in view mode; [Download] [Up]
/* $Id: lines.c,v 1.5 1996/09/27 01:28:56 brianp Exp $ */ /* * Mesa 3-D graphics library * Version: 2.0 * Copyright (C) 1995-1996 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.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 * */ #include "bresenhm.h" #include "context.h" #include "feedback.h" #include "interp.h" #include "lines.h" #include "dlist.h" #include "macros.h" #include "pb.h" #include "types.h" #include "vb.h" 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; 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 = 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 = 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) GL_LINE_RESET_TOKEN ); } else { FEEDBACK_TOKEN( ctx, (GLfloat) GL_LINE_TOKEN ); } if (ctx->Light.ShadeModel==GL_FLAT) { GLfloat color[4]; /* convert color from integer back to a float in [0,1] */ color[0] = (GLfloat) VB->Color[pv][0] * ctx->Visual->InvRedScale; color[1] = (GLfloat) VB->Color[pv][1] * ctx->Visual->InvGreenScale; color[2] = (GLfloat) VB->Color[pv][2] * ctx->Visual->InvBlueScale; color[3] = (GLfloat) VB->Color[pv][3] * ctx->Visual->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 ); } else { GLfloat color[4]; GLint shift = ctx->ColorShift; /* convert color from integer back to a float in [0,1] */ color[0] = (VB->Color[v1][0] >> shift) * ctx->Visual->InvRedScale; color[1] = (VB->Color[v1][1] >> shift) * ctx->Visual->InvGreenScale; color[2] = (VB->Color[v1][2] >> shift) * ctx->Visual->InvBlueScale; color[3] = (VB->Color[v1][3] >> shift) * ctx->Visual->InvAlphaScale; gl_feedback_vertex( ctx, x1,y1,z1,w1, color, (GLfloat) VB->Index[v1], tex1 ); /* convert color from integer back to a float in [0,1] */ color[0] = (VB->Color[v2][0] >> shift) * ctx->Visual->InvRedScale; color[1] = (VB->Color[v2][1] >> shift) * ctx->Visual->InvGreenScale; color[2] = (VB->Color[v2][2] >> shift) * ctx->Visual->InvBlueScale; color[3] = (VB->Color[v2][3] >> shift) * ctx->Visual->InvAlphaScale; gl_feedback_vertex( ctx, x2,y2,z2,w2, color, (GLfloat) VB->Index[v2], 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 shaded, width=1, non-stippled, color index line. */ static void flat_ci_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; struct pixel_buffer *PB = ctx->PB; GLint x1 = (GLint) VB->Win[v1][0]; GLint y1 = (GLint) VB->Win[v1][1]; GLint x2 = (GLint) VB->Win[v2][0]; GLint y2 = (GLint) VB->Win[v2][1]; GLint n; PB_SET_INDEX( ctx, PB, VB->Index[pv] ); /* compute pixel locations */ n = gl_bresenham( ctx, x1, y1, x2, y2, PB->x+PB->count, PB->y+PB->count ); /* interpolate z values */ if (ctx->Depth.Test) { GLdepth *zptr = PB->z + PB->count; GLint z1 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset); GLint z2 = (GLint) (VB->Win[v2][2] + ctx->LineZoffset); GL_INTERPOLATE_Z( n, z1, z2, zptr ); } PB->count += n; PB_CHECK_FLUSH( ctx, PB ); } /* * Flat-shaded, width=1, non-stippled, rgba line. */ static void flat_rgba_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; struct pixel_buffer *PB = ctx->PB; GLint x1 = (GLint) VB->Win[v1][0]; GLint y1 = (GLint) VB->Win[v1][1]; GLint x2 = (GLint) VB->Win[v2][0]; GLint y2 = (GLint) VB->Win[v2][1]; GLint n; /* Note that color components are ints, not fixed point here */ PB_SET_COLOR( ctx, PB, VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2], VB->Color[pv][3] ); /* compute pixel locations */ n = gl_bresenham( ctx, x1, y1, x2, y2, PB->x+PB->count, PB->y+PB->count ); /* interpolate z values */ if (ctx->Depth.Test) { GLdepth *zptr = PB->z + PB->count; GLint z1 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset); GLint z2 = (GLint) (VB->Win[v2][2] + ctx->LineZoffset); GL_INTERPOLATE_Z( n, z1, z2, zptr ); } PB->count += n; PB_CHECK_FLUSH( ctx, PB ); } /* * Smooth-shaded, width=1, non-stippled, color index line. */ static void smooth_ci_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; struct pixel_buffer *PB = ctx->PB; GLint x1 = (GLint) VB->Win[v1][0]; GLint y1 = (GLint) VB->Win[v1][1]; GLint x2 = (GLint) VB->Win[v2][0]; GLint y2 = (GLint) VB->Win[v2][1]; GLint n; /* compute pixel locations */ n = gl_bresenham( ctx, x1, y1, x2, y2, PB->x+PB->count, PB->y+PB->count ); /* interpolate z values */ if (ctx->Depth.Test) { GLdepth *zptr = PB->z + PB->count; GLint z1 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset); GLint z2 = (GLint) (VB->Win[v2][2] + ctx->LineZoffset); GL_INTERPOLATE_Z( n, z1, z2, zptr ); } /* interpolate index */ gl_interpolate_i( n, (GLint) VB->Index[v1], (GLint) VB->Index[v2], (GLint *) PB->i+PB->count ); PB->count += n; PB_CHECK_FLUSH( ctx, PB ); } /* * Smooth-shaded, width=1, non-stippled, RGBA line. */ static void smooth_rgba_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; struct pixel_buffer *PB = ctx->PB; GLint x1 = (GLint) VB->Win[v1][0]; GLint y1 = (GLint) VB->Win[v1][1]; GLint x2 = (GLint) VB->Win[v2][0]; GLint y2 = (GLint) VB->Win[v2][1]; GLint n; /* compute pixel locations */ n = gl_bresenham( ctx, x1, y1, x2, y2, PB->x+PB->count, PB->y+PB->count ); /* interpolate z values */ if (ctx->Depth.Test) { GLdepth *zptr = PB->z + PB->count; GLint z1 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset); GLint z2 = (GLint) (VB->Win[v2][2] + ctx->LineZoffset); GL_INTERPOLATE_Z( n, z1, z2, zptr ); } /* interpolate color, VB->Colors are in fixed point */ gl_interpolate_rgba( n, VB->Color[v1][0], VB->Color[v2][0], PB->r+PB->count, VB->Color[v1][1], VB->Color[v2][1], PB->g+PB->count, VB->Color[v1][2], VB->Color[v2][2], PB->b+PB->count, VB->Color[v1][3], VB->Color[v2][3], PB->a+PB->count ); PB->count += n; PB_CHECK_FLUSH( ctx, PB ); } /* * General CI line: any width, smooth or flat, stippled, any raster ops. */ static void general_ci_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; struct pixel_buffer *PB = ctx->PB; GLint x1, y1, x2, y2; GLint x[MAXPOINTS], y[MAXPOINTS]; GLdepth z[MAXPOINTS]; GLubyte mask[MAXPOINTS]; GLuint index[MAXPOINTS]; GLint i, n; GLint dx, dy; x1 = (GLint) VB->Win[v1][0]; y1 = (GLint) VB->Win[v1][1]; x2 = (GLint) VB->Win[v2][0]; y2 = (GLint) VB->Win[v2][1]; /* compute pixel locations */ if (ctx->Line.StippleFlag) { n = gl_stippled_bresenham( ctx, x1, y1, x2, y2, x, y, mask ); } else { n = gl_bresenham( ctx, x1, y1, x2, y2, x, y ); for (i=0;i<n;i++) { mask[i] = 1; } } if (ctx->Depth.Test) { /* interpolate z */ GLint z1 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset); GLint z2 = (GLint) (VB->Win[v2][2] + ctx->LineZoffset); GL_INTERPOLATE_Z( n, z1, z2, z ); } if (ctx->Light.ShadeModel==GL_FLAT) { GLuint indx = VB->Index[pv]; for (i=0;i<n;i++) { index[i] = indx; } } else { /* interpolate index */ gl_interpolate_i( n, (GLint) VB->Index[v1], (GLint) VB->Index[v2], (GLint *) index ); } /* compute delta x and delta y */ if (x1>x2) { dx = x1 - x2; } else { dx = x2 - x1; } if (y1>y2) { dy = y1 - y2; } else { dy = y2 - y1; } /* render */ if (ctx->Line.Width==2.0F) { /* special case, easy to optimize */ if (dx>dy) { /* X-major: duplicate pixels in Y direction */ for (i=0;i<n;i++) { if (mask[i]) { PB_WRITE_CI_PIXEL( PB, x[i], y[i]-1, z[i], index[i] ); PB_WRITE_CI_PIXEL( PB, x[i], y[i], z[i], index[i] ); } } } else { /* Y-major: duplicate pixels in X direction */ for (i=0;i<n;i++) { if (mask[i]) { PB_WRITE_CI_PIXEL( PB, x[i]-1, y[i], z[i], index[i] ); PB_WRITE_CI_PIXEL( PB, x[i], y[i], z[i], index[i] ); } } } PB_CHECK_FLUSH( ctx, PB ); } else { GLint width, w0, w1; width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH ); w0 = -width / 2; w1 = w0 + width - 1; if (dx>dy) { /* X-major: duplicate pixels in Y direction */ for (i=0;i<n;i++) { if (mask[i]) { GLint yy; GLint y0 = y[i] + w0; GLint y1 = y[i] + w1; for (yy=y0;yy<=y1;yy++) { PB_WRITE_CI_PIXEL( PB, x[i], yy, z[i], index[i] ); } PB_CHECK_FLUSH( ctx, PB ); } } } else { /* Y-major: duplicate pixels in X direction */ for (i=0;i<n;i++) { if (mask[i]) { GLint xx; GLint x0 = x[i] + w0; GLint x1 = x[i] + w1; for (xx=x0;xx<=x1;xx++) { PB_WRITE_CI_PIXEL( PB, xx, y[i], z[i], index[i] ); } PB_CHECK_FLUSH( ctx, PB ); } } } } } /* * General RGBA line: any width, smooth or flat, stippled, any raster ops. */ static void general_rgba_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; struct pixel_buffer *PB = ctx->PB; GLint x1, y1, x2, y2; GLint x[MAXPOINTS], y[MAXPOINTS]; GLdepth z[MAXPOINTS]; GLubyte mask[MAXPOINTS]; GLubyte red[MAXPOINTS], green[MAXPOINTS], blue[MAXPOINTS], alpha[MAXPOINTS]; GLint i, n; GLint dx, dy; x1 = (GLint) VB->Win[v1][0]; y1 = (GLint) VB->Win[v1][1]; x2 = (GLint) VB->Win[v2][0]; y2 = (GLint) VB->Win[v2][1]; /* compute the line */ if (ctx->Line.StippleFlag) { n = gl_stippled_bresenham( ctx, x1, y1, x2, y2, x, y, mask ); } else { n = gl_bresenham( ctx, x1, y1, x2, y2, x, y ); for (i=0;i<n;i++) { mask[i] = 1; } } if (ctx->Depth.Test) { GLint z1 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset); GLint z2 = (GLint) (VB->Win[v2][2] + ctx->LineZoffset); GL_INTERPOLATE_Z( n, z1, z2, z ); } if (ctx->Light.ShadeModel==GL_FLAT) { GLint r, g, b, a; r = VB->Color[pv][0]; /* colors are ints, not fixed point */ g = VB->Color[pv][1]; b = VB->Color[pv][2]; a = VB->Color[pv][3]; for (i=0;i<n;i++) { red[i] = r; green[i] = g; blue[i] = b; alpha[i] = a; } } else { /* interpolate color, VB->Colors are in fixed point */ gl_interpolate_rgba( n, VB->Color[v1][0], VB->Color[v2][0], red, VB->Color[v1][1], VB->Color[v2][1], green, VB->Color[v1][2], VB->Color[v2][2], blue, VB->Color[v1][3], VB->Color[v2][3], alpha ); } /* compute delta x and delta y */ if (x1>x2) { dx = x1 - x2; } else { dx = x2 - x1; } if (y1>y2) { dy = y1 - y2; } else { dy = y2 - y1; } /* render */ if (ctx->Line.Width==2.0F) { /* special case, easy to optimize */ if (dx>dy) { /* X-major: duplicate pixels in Y direction */ for (i=0;i<n;i++) { if (mask[i]) { PB_WRITE_RGBA_PIXEL( PB, x[i], y[i]-1, z[i], red[i], green[i], blue[i], alpha[i] ); PB_WRITE_RGBA_PIXEL( PB, x[i], y[i], z[i], red[i], green[i], blue[i], alpha[i] ); } } } else { /* Y-major: duplicate pixels in X direction */ for (i=0;i<n;i++) { if (mask[i]) { PB_WRITE_RGBA_PIXEL( PB, x[i]-1, y[i], z[i], red[i], green[i], blue[i], alpha[i] ); PB_WRITE_RGBA_PIXEL( PB, x[i], y[i], z[i], red[i], green[i], blue[i], alpha[i] ); } } } PB_CHECK_FLUSH( ctx, PB ); } else { GLint width, w0, w1; width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH ); w0 = -width / 2; w1 = w0 + width - 1; if (dx>dy) { /* X-major: duplicate pixels in Y direction */ for (i=0;i<n;i++) { if (mask[i]) { GLint yy; GLint y0 = y[i] + w0; GLint y1 = y[i] + w1; for (yy=y0;yy<=y1;yy++) { PB_WRITE_RGBA_PIXEL( PB, x[i], yy, z[i], red[i], green[i], blue[i], alpha[i] ); } PB_CHECK_FLUSH( ctx, PB ); } } } else { /* Y-major: duplicate pixels in X direction */ for (i=0;i<n;i++) { if (mask[i]) { GLint xx; GLint x0 = x[i] + w0; GLint x1 = x[i] + w1; for (xx=x0;xx<=x1;xx++) { PB_WRITE_RGBA_PIXEL( PB, xx, y[i], z[i], red[i], green[i], blue[i], alpha[i] ); } PB_CHECK_FLUSH( ctx, PB ); } } } } } /* * Textured RGBA line: any width, smooth or flat, stippled, any raster ops * with texturing. */ static void textured_rgba_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { struct vertex_buffer *VB = ctx->VB; struct pixel_buffer *PB = ctx->PB; GLint x1, y1, x2, y2; GLint x[MAXPOINTS], y[MAXPOINTS]; GLdepth z[MAXPOINTS]; GLubyte mask[MAXPOINTS]; /* Allocate arrays dynamically on Mac */ DEFARRAY(GLubyte,red,MAXPOINTS); DEFARRAY(GLubyte,green,MAXPOINTS); DEFARRAY(GLubyte,blue,MAXPOINTS); DEFARRAY(GLubyte,alpha,MAXPOINTS); DEFARRAY(GLfloat,s,MAXPOINTS); DEFARRAY(GLfloat,t,MAXPOINTS); #if 0 DEFARRAY(GLfloat,u,MAXPOINTS); DEFARRAY(GLfloat,v,MAXPOINTS); #endif GLint i, n; GLint dx, dy; x1 = (GLint) VB->Win[v1][0]; y1 = (GLint) VB->Win[v1][1]; x2 = (GLint) VB->Win[v2][0]; y2 = (GLint) VB->Win[v2][1]; /* compute the line */ if (ctx->Line.StippleFlag) { n = gl_stippled_bresenham( ctx, x1, y1, x2, y2, x, y, mask ); } else { n = gl_bresenham( ctx, x1, y1, x2, y2, x, y ); for (i=0;i<n;i++) { mask[i] = 1; } } if (ctx->Depth.Test) { GLint z1 = (GLint) (VB->Win[v1][2] + ctx->LineZoffset); GLint z2 = (GLint) (VB->Win[v2][2] + ctx->LineZoffset); GL_INTERPOLATE_Z( n, z1, z2, z ); } if (ctx->Light.ShadeModel==GL_FLAT) { GLint r, g, b, a; r = VB->Color[pv][0]; /* colors are ints, not in fixed point */ g = VB->Color[pv][1]; b = VB->Color[pv][2]; a = VB->Color[pv][3]; for (i=0;i<n;i++) { red[i] = r; green[i] = g; blue[i] = b; alpha[i] = a; } } else { /* interpolate color, VB->Colors are in fixed point */ gl_interpolate_rgba( n, VB->Color[v1][0], VB->Color[v2][0], red, VB->Color[v1][1], VB->Color[v2][1], green, VB->Color[v1][2], VB->Color[v2][2], blue, VB->Color[v1][3], VB->Color[v2][3], alpha ); } /* interpolate texture coordinates */ { GLfloat w1 = 1.0F / VB->Clip[v1][3]; GLfloat w2 = 1.0F / VB->Clip[v2][3]; GLfloat s1 = VB->TexCoord[v1][0] * w1; GLfloat s2 = VB->TexCoord[v2][0] * w2; GLfloat t1 = VB->TexCoord[v1][1] * w1; GLfloat t2 = VB->TexCoord[v2][1] * w2; /* don't interpolate r since we don't do 3-D textures, yet */ GLfloat q1 = VB->TexCoord[v1][3] * w1; GLfloat q2 = VB->TexCoord[v2][3] * w2; GLfloat inv_n = 1.0F / (GLfloat) n; GLfloat ds = (s2-s1) * inv_n; GLfloat dt = (t2-t1) * inv_n; GLfloat dq = (q2-q1) * inv_n; for (i=0;i<n;i++) { s[i] = s1 / q1; t[i] = t1 / q1; s1 += ds; t1 += dt; q1 += dq; } } /* compute delta x and delta y */ if (x1>x2) { dx = x1 - x2; } else { dx = x2 - x1; } if (y1>y2) { dy = y1 - y2; } else { dy = y2 - y1; } /* render */ if (ctx->Line.Width==2.0F) { /* special case, easy to optimize */ if (dx>dy) { /* X-major: duplicate pixels in Y direction */ for (i=0;i<n;i++) { if (mask[i]) { PB_WRITE_TEX_PIXEL( PB, x[i], y[i]-1, z[i], red[i], green[i], blue[i], alpha[i], s[i], t[i] ); PB_WRITE_TEX_PIXEL( PB, x[i], y[i], z[i], red[i], green[i], blue[i], alpha[i], s[i], t[i] ); } } } else { /* Y-major: duplicate pixels in X direction */ for (i=0;i<n;i++) { if (mask[i]) { PB_WRITE_TEX_PIXEL( PB, x[i]-1, y[i], z[i], red[i], green[i], blue[i], alpha[i], s[i], t[i] ); PB_WRITE_TEX_PIXEL( PB, x[i], y[i], z[i], red[i], green[i], blue[i], alpha[i], s[i], t[i] ); } } } PB_CHECK_FLUSH( ctx, PB ); } else { GLint width, w0, w1; width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH ); w0 = -width / 2; w1 = w0 + width - 1; if (dx>dy) { /* X-major: duplicate pixels in Y direction */ for (i=0;i<n;i++) { if (mask[i]) { GLint yy; GLint y0 = y[i] + w0; GLint y1 = y[i] + w1; for (yy=y0;yy<=y1;yy++) { PB_WRITE_TEX_PIXEL( PB, x[i], yy, z[i], red[i], green[i], blue[i], alpha[i], s[i], t[i] ); } PB_CHECK_FLUSH( ctx, PB ); } } } else { /* Y-major: duplicate pixels in X direction */ for (i=0;i<n;i++) { if (mask[i]) { GLint xx; GLint x0 = x[i] + w0; GLint x1 = x[i] + w1; for (xx=x0;xx<=x1;xx++) { PB_WRITE_TEX_PIXEL( PB, xx, y[i], z[i], red[i], green[i], blue[i], alpha[i], s[i], t[i] ); } PB_CHECK_FLUSH( ctx, PB ); } } } } /* Deallocate dynamic arrays on Mac */ UNDEFARRAY(red); UNDEFARRAY(green); UNDEFARRAY(blue); UNDEFARRAY(alpha); UNDEFARRAY(s); UNDEFARRAY(t); #if 0 UNDEFARRAY(u); UNDEFARRAY(v); #endif } /* * 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->Driver.LineFunc) { /* Device driver will draw lines. */ ctx->LineFunc = ctx->Driver.LineFunc; } else if (ctx->Texture.Enabled) { ctx->LineFunc = textured_rgba_line; } else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag || ctx->Line.SmoothFlag || ctx->Texture.Enabled) { ctx->LineFunc = rgbmode ? general_rgba_line : general_ci_line; } else { if (ctx->Light.ShadeModel==GL_SMOOTH) { /* Width==1, non-stippled, smooth-shaded, any raster ops */ ctx->LineFunc = rgbmode ? smooth_rgba_line : smooth_ci_line; } else { /* Width==1, non-stippled, flat-shaded, any raster ops */ ctx->LineFunc = rgbmode ? flat_rgba_line : flat_ci_line; } } } else if (ctx->RenderMode==GL_FEEDBACK) { ctx->LineFunc = feedback_line; } else { /* GL_SELECT mode */ ctx->LineFunc = select_line; } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.