lines.c revision f19cba049d7af1824ddc0236e4ff1e910d6002a7
18b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli/* $Id: lines.c,v 1.12 2000/07/14 14:04:07 brianp Exp $ */
2c68cb64496485710cdb5b8480f8fee287058c93farmvixl
3c68cb64496485710cdb5b8480f8fee287058c93farmvixl/*
4c68cb64496485710cdb5b8480f8fee287058c93farmvixl * Mesa 3-D graphics library
5c68cb64496485710cdb5b8480f8fee287058c93farmvixl * Version:  3.3
6c68cb64496485710cdb5b8480f8fee287058c93farmvixl *
7c68cb64496485710cdb5b8480f8fee287058c93farmvixl * Copyright (C) 1999  Brian Paul   All Rights Reserved.
8c68cb64496485710cdb5b8480f8fee287058c93farmvixl *
9c68cb64496485710cdb5b8480f8fee287058c93farmvixl * Permission is hereby granted, free of charge, to any person obtaining a
10c68cb64496485710cdb5b8480f8fee287058c93farmvixl * copy of this software and associated documentation files (the "Software"),
11c68cb64496485710cdb5b8480f8fee287058c93farmvixl * to deal in the Software without restriction, including without limitation
12c68cb64496485710cdb5b8480f8fee287058c93farmvixl * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13c68cb64496485710cdb5b8480f8fee287058c93farmvixl * and/or sell copies of the Software, and to permit persons to whom the
14c68cb64496485710cdb5b8480f8fee287058c93farmvixl * Software is furnished to do so, subject to the following conditions:
15c68cb64496485710cdb5b8480f8fee287058c93farmvixl *
16c68cb64496485710cdb5b8480f8fee287058c93farmvixl * The above copyright notice and this permission notice shall be included
17c68cb64496485710cdb5b8480f8fee287058c93farmvixl * in all copies or substantial portions of the Software.
18c68cb64496485710cdb5b8480f8fee287058c93farmvixl *
19c68cb64496485710cdb5b8480f8fee287058c93farmvixl * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20c68cb64496485710cdb5b8480f8fee287058c93farmvixl * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21c68cb64496485710cdb5b8480f8fee287058c93farmvixl * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22c68cb64496485710cdb5b8480f8fee287058c93farmvixl * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23c68cb64496485710cdb5b8480f8fee287058c93farmvixl * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24c68cb64496485710cdb5b8480f8fee287058c93farmvixl * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25c68cb64496485710cdb5b8480f8fee287058c93farmvixl */
26c68cb64496485710cdb5b8480f8fee287058c93farmvixl
27c68cb64496485710cdb5b8480f8fee287058c93farmvixl
28c68cb64496485710cdb5b8480f8fee287058c93farmvixl#ifdef PC_HEADER
29c68cb64496485710cdb5b8480f8fee287058c93farmvixl#include "all.h"
3078973f258039f6e96eba85f1b5ecdb14b3c51dbbPierre Langlois#else
31b68bacb75c1ab265fc539afa93964c7f51f35589Alexandre Rames#include "glheader.h"
321f9074de150536670464a85ef8e0ede60d26e3f9Alexandre Rames#include "context.h"
3388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include "depth.h"
34c68cb64496485710cdb5b8480f8fee287058c93farmvixl#include "feedback.h"
35c68cb64496485710cdb5b8480f8fee287058c93farmvixl#include "lines.h"
36c68cb64496485710cdb5b8480f8fee287058c93farmvixl#include "macros.h"
37c68cb64496485710cdb5b8480f8fee287058c93farmvixl#include "mmath.h"
38c68cb64496485710cdb5b8480f8fee287058c93farmvixl#include "pb.h"
39f2f550c0bfd0f15a4d1c51ff06ec898536f14205Alexandre Rames#include "texstate.h"
40f2f550c0bfd0f15a4d1c51ff06ec898536f14205Alexandre Rames#include "types.h"
41f2f550c0bfd0f15a4d1c51ff06ec898536f14205Alexandre Rames#include "vb.h"
42919e3fe28a5024c53ede42922092bbc32e89dcb8Alexandre Rames#endif
43c68cb64496485710cdb5b8480f8fee287058c93farmvixl
44c68cb64496485710cdb5b8480f8fee287058c93farmvixl
45c68cb64496485710cdb5b8480f8fee287058c93farmvixl
46c68cb64496485710cdb5b8480f8fee287058c93farmvixlvoid
47745a8558eec037d49b276e040ef18513d7451c36Jacob Bramley_mesa_LineWidth( GLfloat width )
4831dd2ae90d5e82871667fbf3ee2697a155e7c3acAlex Gilday{
4931dd2ae90d5e82871667fbf3ee2697a155e7c3acAlex Gilday   GET_CURRENT_CONTEXT(ctx);
50745a8558eec037d49b276e040ef18513d7451c36Jacob Bramley   if (width<=0.0) {
51745a8558eec037d49b276e040ef18513d7451c36Jacob Bramley      gl_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
52745a8558eec037d49b276e040ef18513d7451c36Jacob Bramley      return;
53390876fd572a28333d843671e30b5cb71c45f6e4Jacob Bramley   }
54390876fd572a28333d843671e30b5cb71c45f6e4Jacob Bramley   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLineWidth");
55745a8558eec037d49b276e040ef18513d7451c36Jacob Bramley
5631dd2ae90d5e82871667fbf3ee2697a155e7c3acAlex Gilday   if (ctx->Line.Width != width) {
5788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois      ctx->Line.Width = width;
58c68cb64496485710cdb5b8480f8fee287058c93farmvixl      ctx->TriangleCaps &= ~DD_LINE_WIDTH;
59c68cb64496485710cdb5b8480f8fee287058c93farmvixl      if (width != 1.0) ctx->TriangleCaps |= DD_LINE_WIDTH;
60c68cb64496485710cdb5b8480f8fee287058c93farmvixl      ctx->NewState |= NEW_RASTER_OPS;
61c68cb64496485710cdb5b8480f8fee287058c93farmvixl      if (ctx->Driver.LineWidth)
6288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois         (*ctx->Driver.LineWidth)(ctx, width);
6388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   }
6488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
6588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
66c68cb64496485710cdb5b8480f8fee287058c93farmvixl
6788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
6888c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisvoid
6988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois_mesa_LineStipple( GLint factor, GLushort pattern )
7088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois{
7188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   GET_CURRENT_CONTEXT(ctx);
7288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLineStipple");
7388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   ctx->Line.StippleFactor = CLAMP( factor, 1, 256 );
7488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   ctx->Line.StipplePattern = pattern;
7588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   ctx->NewState |= NEW_RASTER_OPS;
7688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
77c68cb64496485710cdb5b8480f8fee287058c93farmvixl   if (ctx->Driver.LineStipple)
78c68cb64496485710cdb5b8480f8fee287058c93farmvixl      ctx->Driver.LineStipple( ctx, factor, pattern );
79c68cb64496485710cdb5b8480f8fee287058c93farmvixl}
806a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames
81c68cb64496485710cdb5b8480f8fee287058c93farmvixl
82c68cb64496485710cdb5b8480f8fee287058c93farmvixl
83c68cb64496485710cdb5b8480f8fee287058c93farmvixl/**********************************************************************/
84c68cb64496485710cdb5b8480f8fee287058c93farmvixl/*****                    Rasterization                           *****/
856a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames/**********************************************************************/
866a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames
876a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames
886a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames/*
896a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames * There are 4 pairs (RGBA, CI) of line drawing functions:
906a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames *   1. simple:  width=1 and no special rasterization functions (fastest)
916a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames *   2. flat:  width=1, non-stippled, flat-shaded, any raster operations
926a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames *   3. smooth:  width=1, non-stippled, smooth-shaded, any raster operations
936a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames *   4. general:  any other kind of line (slowest)
946a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames */
956a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames
966a049f97861bd71c69d81f643e42308d28c5de31Alexandre Rames
9788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois/*
98c68cb64496485710cdb5b8480f8fee287058c93farmvixl * All line drawing functions have the same arguments:
99c68cb64496485710cdb5b8480f8fee287058c93farmvixl * v1, v2 - indexes of first and second endpoints into vertex buffer arrays
100c68cb64496485710cdb5b8480f8fee287058c93farmvixl * pv     - provoking vertex: which vertex color/index to use for flat shading.
10188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois */
10288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
10388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
10488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
10588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
10688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
10788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
10888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#if MAX_WIDTH > MAX_HEIGHT
109c68cb64496485710cdb5b8480f8fee287058c93farmvixl#  define MAXPOINTS MAX_WIDTH
110c68cb64496485710cdb5b8480f8fee287058c93farmvixl#else
1115d85018e08776bbf182bcb36edf6fbb764023a5fVincent Belliard#  define MAXPOINTS MAX_HEIGHT
1125d85018e08776bbf182bcb36edf6fbb764023a5fVincent Belliard#endif
113c68cb64496485710cdb5b8480f8fee287058c93farmvixl
1145d85018e08776bbf182bcb36edf6fbb764023a5fVincent Belliard
1155d85018e08776bbf182bcb36edf6fbb764023a5fVincent Belliard/* Flat, color index line */
11688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstatic void flat_ci_line( GLcontext *ctx,
11788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                          GLuint vert0, GLuint vert1, GLuint pvert )
118c68cb64496485710cdb5b8480f8fee287058c93farmvixl{
119c68cb64496485710cdb5b8480f8fee287058c93farmvixl   PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
120c68cb64496485710cdb5b8480f8fee287058c93farmvixl
121c68cb64496485710cdb5b8480f8fee287058c93farmvixl#define INTERP_XY 1
122c68cb64496485710cdb5b8480f8fee287058c93farmvixl#define PLOT(X,Y)  PB_WRITE_PIXEL(ctx->PB, X, Y, 0);
123c68cb64496485710cdb5b8480f8fee287058c93farmvixl
12488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#include "linetemp.h"
12588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
12686eb8871a7c87e6ef75066c3deaedfc9dbd3c4afAlexandre Rames   gl_flush_pb(ctx);
12786eb8871a7c87e6ef75066c3deaedfc9dbd3c4afAlexandre Rames}
12886eb8871a7c87e6ef75066c3deaedfc9dbd3c4afAlexandre Rames
12986eb8871a7c87e6ef75066c3deaedfc9dbd3c4afAlexandre Rames
13086eb8871a7c87e6ef75066c3deaedfc9dbd3c4afAlexandre Rames
13186eb8871a7c87e6ef75066c3deaedfc9dbd3c4afAlexandre Rames/* Flat, color index line with Z interpolation/testing */
13286eb8871a7c87e6ef75066c3deaedfc9dbd3c4afAlexandre Ramesstatic void flat_ci_z_line( GLcontext *ctx,
13386eb8871a7c87e6ef75066c3deaedfc9dbd3c4afAlexandre Rames                            GLuint vert0, GLuint vert1, GLuint pvert )
1343e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard{
1353e1b899f48c1328ac748b1f5fa78f417f7ec6581Vincent Belliard   PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
13688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
137c68cb64496485710cdb5b8480f8fee287058c93farmvixl#define INTERP_XY 1
138c68cb64496485710cdb5b8480f8fee287058c93farmvixl#define INTERP_Z 1
1398b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#define PLOT(X,Y)  PB_WRITE_PIXEL(ctx->PB, X, Y, Z);
1408b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli
1418b57c86886020cf0a5331823be4789ee558764e2Georgia Kouveli#include "linetemp.h"
14288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
14388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   gl_flush_pb(ctx);
14488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
14588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
14688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
14788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
14888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois/* Flat-shaded, RGBA line */
14988c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstatic void flat_rgba_line( GLcontext *ctx,
150c68cb64496485710cdb5b8480f8fee287058c93farmvixl                            GLuint vert0, GLuint vert1, GLuint pvert )
151c68cb64496485710cdb5b8480f8fee287058c93farmvixl{
152c68cb64496485710cdb5b8480f8fee287058c93farmvixl   const GLubyte *color = ctx->VB->ColorPtr->data[pvert];
153329ccf9105e1f360633f5c6bd229915ad1d1b14bYi Kong   PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
154c68cb64496485710cdb5b8480f8fee287058c93farmvixl
155c68cb64496485710cdb5b8480f8fee287058c93farmvixl#define INTERP_XY 1
156c68cb64496485710cdb5b8480f8fee287058c93farmvixl#define PLOT(X,Y)   PB_WRITE_PIXEL(ctx->PB, X, Y, 0);
157c68cb64496485710cdb5b8480f8fee287058c93farmvixl
158c68cb64496485710cdb5b8480f8fee287058c93farmvixl#include "linetemp.h"
15988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
16088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   gl_flush_pb(ctx);
16188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois}
16288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
16388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
16488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
16588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois/* Flat-shaded, RGBA line with Z interpolation/testing */
16688c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisstatic void flat_rgba_z_line( GLcontext *ctx,
16788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois                              GLuint vert0, GLuint vert1, GLuint pvert )
16888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois{
16988c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   const GLubyte *color = ctx->VB->ColorPtr->data[pvert];
17088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois   PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
17188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois
17288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define INTERP_XY 1
17388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois#define INTERP_Z 1
174c68cb64496485710cdb5b8480f8fee287058c93farmvixl#define PLOT(X,Y)   PB_WRITE_PIXEL(ctx->PB, X, Y, Z);
175c68cb64496485710cdb5b8480f8fee287058c93farmvixl
176c68cb64496485710cdb5b8480f8fee287058c93farmvixl#include "linetemp.h"
177c68cb64496485710cdb5b8480f8fee287058c93farmvixl
178c68cb64496485710cdb5b8480f8fee287058c93farmvixl   gl_flush_pb(ctx);
179c68cb64496485710cdb5b8480f8fee287058c93farmvixl}
180c68cb64496485710cdb5b8480f8fee287058c93farmvixl
181c68cb64496485710cdb5b8480f8fee287058c93farmvixl
182c68cb64496485710cdb5b8480f8fee287058c93farmvixl
183c68cb64496485710cdb5b8480f8fee287058c93farmvixl/* Smooth shaded, color index line */
184c68cb64496485710cdb5b8480f8fee287058c93farmvixlstatic void smooth_ci_line( GLcontext *ctx,
185c68cb64496485710cdb5b8480f8fee287058c93farmvixl                            GLuint vert0, GLuint vert1, GLuint pvert )
186c68cb64496485710cdb5b8480f8fee287058c93farmvixl{
187c68cb64496485710cdb5b8480f8fee287058c93farmvixl   GLint count = ctx->PB->count;
188c68cb64496485710cdb5b8480f8fee287058c93farmvixl   GLint *pbx = ctx->PB->x;
189c68cb64496485710cdb5b8480f8fee287058c93farmvixl   GLint *pby = ctx->PB->y;
190c68cb64496485710cdb5b8480f8fee287058c93farmvixl   GLuint *pbi = ctx->PB->index;
191c68cb64496485710cdb5b8480f8fee287058c93farmvixl   (void) pvert;
192
193   ctx->PB->mono = GL_FALSE;
194
195#define INTERP_XY 1
196#define INTERP_INDEX 1
197
198#define PLOT(X,Y)		\
199	pbx[count] = X;		\
200	pby[count] = Y;		\
201	pbi[count] = I;		\
202	count++;
203
204#include "linetemp.h"
205
206   ctx->PB->count = count;
207   gl_flush_pb(ctx);
208}
209
210
211
212/* Smooth shaded, color index line with Z interpolation/testing */
213static void smooth_ci_z_line( GLcontext *ctx,
214                              GLuint vert0, GLuint vert1, GLuint pvert )
215{
216   GLint count = ctx->PB->count;
217   GLint *pbx = ctx->PB->x;
218   GLint *pby = ctx->PB->y;
219   GLdepth *pbz = ctx->PB->z;
220   GLuint *pbi = ctx->PB->index;
221   (void) pvert;
222
223   ctx->PB->mono = GL_FALSE;
224
225#define INTERP_XY 1
226#define INTERP_Z 1
227#define INTERP_INDEX 1
228
229#define PLOT(X,Y)		\
230	pbx[count] = X;		\
231	pby[count] = Y;		\
232	pbz[count] = Z;		\
233	pbi[count] = I;		\
234	count++;
235
236#include "linetemp.h"
237
238   ctx->PB->count = count;
239   gl_flush_pb(ctx);
240}
241
242
243
244/* Smooth-shaded, RGBA line */
245static void smooth_rgba_line( GLcontext *ctx,
246                       	      GLuint vert0, GLuint vert1, GLuint pvert )
247{
248   GLint count = ctx->PB->count;
249   GLint *pbx = ctx->PB->x;
250   GLint *pby = ctx->PB->y;
251   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
252   (void) pvert;
253
254   ctx->PB->mono = GL_FALSE;
255
256#define INTERP_XY 1
257#define INTERP_RGB 1
258#define INTERP_ALPHA 1
259
260#define PLOT(X,Y)			\
261	pbx[count] = X;			\
262	pby[count] = Y;			\
263	pbrgba[count][RCOMP] = FixedToInt(r0);	\
264	pbrgba[count][GCOMP] = FixedToInt(g0);	\
265	pbrgba[count][BCOMP] = FixedToInt(b0);	\
266	pbrgba[count][ACOMP] = FixedToInt(a0);	\
267	count++;
268
269#include "linetemp.h"
270
271   ctx->PB->count = count;
272   gl_flush_pb(ctx);
273}
274
275
276
277/* Smooth-shaded, RGBA line with Z interpolation/testing */
278static void smooth_rgba_z_line( GLcontext *ctx,
279                       	        GLuint vert0, GLuint vert1, GLuint pvert )
280{
281   GLint count = ctx->PB->count;
282   GLint *pbx = ctx->PB->x;
283   GLint *pby = ctx->PB->y;
284   GLdepth *pbz = ctx->PB->z;
285   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
286   (void) pvert;
287
288   ctx->PB->mono = GL_FALSE;
289
290#define INTERP_XY 1
291#define INTERP_Z 1
292#define INTERP_RGB 1
293#define INTERP_ALPHA 1
294
295#define PLOT(X,Y)			\
296	pbx[count] = X;			\
297	pby[count] = Y;			\
298	pbz[count] = Z;			\
299	pbrgba[count][RCOMP] = FixedToInt(r0);	\
300	pbrgba[count][GCOMP] = FixedToInt(g0);	\
301	pbrgba[count][BCOMP] = FixedToInt(b0);	\
302	pbrgba[count][ACOMP] = FixedToInt(a0);	\
303	count++;
304
305#include "linetemp.h"
306
307   ctx->PB->count = count;
308   gl_flush_pb(ctx);
309}
310
311
312#define CHECK_FULL(count)			\
313	if (count >= PB_SIZE-MAX_WIDTH) {	\
314	   ctx->PB->count = count;		\
315	   gl_flush_pb(ctx);			\
316	   count = ctx->PB->count;		\
317	}
318
319
320
321/* Smooth shaded, color index, any width, maybe stippled */
322static void general_smooth_ci_line( GLcontext *ctx,
323                           	    GLuint vert0, GLuint vert1, GLuint pvert )
324{
325   GLint count = ctx->PB->count;
326   GLint *pbx = ctx->PB->x;
327   GLint *pby = ctx->PB->y;
328   GLdepth *pbz = ctx->PB->z;
329   GLuint *pbi = ctx->PB->index;
330   (void) pvert;
331
332   ctx->PB->mono = GL_FALSE;
333
334   if (ctx->Line.StippleFlag) {
335      /* stippled */
336#define INTERP_XY 1
337#define INTERP_Z 1
338#define INTERP_INDEX 1
339#define WIDE 1
340#define STIPPLE 1
341#define PLOT(X,Y)		\
342	pbx[count] = X;		\
343	pby[count] = Y;		\
344	pbz[count] = Z;		\
345	pbi[count] = I;		\
346	count++;		\
347	CHECK_FULL(count);
348#include "linetemp.h"
349   }
350   else {
351      /* unstippled */
352      if (ctx->Line.Width==2.0F) {
353         /* special case: unstippled and width=2 */
354#define INTERP_XY 1
355#define INTERP_Z 1
356#define INTERP_INDEX 1
357#define XMAJOR_PLOT(X,Y)			\
358	pbx[count] = X;  pbx[count+1] = X;	\
359	pby[count] = Y;  pby[count+1] = Y+1;	\
360	pbz[count] = Z;  pbz[count+1] = Z;	\
361	pbi[count] = I;  pbi[count+1] = I;	\
362	count += 2;				\
363	CHECK_FULL(count);
364#define YMAJOR_PLOT(X,Y)			\
365	pbx[count] = X;  pbx[count+1] = X+1;	\
366	pby[count] = Y;  pby[count+1] = Y;	\
367	pbz[count] = Z;  pbz[count+1] = Z;	\
368	pbi[count] = I;  pbi[count+1] = I;	\
369	count += 2;				\
370	CHECK_FULL(count);
371#include "linetemp.h"
372      }
373      else {
374         /* unstippled, any width */
375#define INTERP_XY 1
376#define INTERP_Z 1
377#define INTERP_INDEX 1
378#define WIDE 1
379#define PLOT(X,Y)		\
380	pbx[count] = X;		\
381	pby[count] = Y;		\
382	pbz[count] = Z;		\
383	pbi[count] = I;		\
384	count++;		\
385	CHECK_FULL(count);
386#include "linetemp.h"
387      }
388   }
389
390   ctx->PB->count = count;
391   gl_flush_pb(ctx);
392}
393
394
395/* Flat shaded, color index, any width, maybe stippled */
396static void general_flat_ci_line( GLcontext *ctx,
397                                  GLuint vert0, GLuint vert1, GLuint pvert )
398{
399   GLint count;
400   GLint *pbx = ctx->PB->x;
401   GLint *pby = ctx->PB->y;
402   GLdepth *pbz = ctx->PB->z;
403   PB_SET_INDEX( ctx->PB, ctx->VB->IndexPtr->data[pvert] );
404   count = ctx->PB->count;
405
406   if (ctx->Line.StippleFlag) {
407      /* stippled, any width */
408#define INTERP_XY 1
409#define INTERP_Z 1
410#define WIDE 1
411#define STIPPLE 1
412#define PLOT(X,Y)		\
413	pbx[count] = X;		\
414	pby[count] = Y;		\
415	pbz[count] = Z;		\
416	count++;		\
417	CHECK_FULL(count);
418#include "linetemp.h"
419   }
420   else {
421      /* unstippled */
422      if (ctx->Line.Width==2.0F) {
423         /* special case: unstippled and width=2 */
424#define INTERP_XY 1
425#define INTERP_Z 1
426#define XMAJOR_PLOT(X,Y)			\
427	pbx[count] = X;  pbx[count+1] = X;	\
428	pby[count] = Y;  pby[count+1] = Y+1;	\
429	pbz[count] = Z;  pbz[count+1] = Z;	\
430	count += 2;				\
431	CHECK_FULL(count);
432#define YMAJOR_PLOT(X,Y)			\
433	pbx[count] = X;  pbx[count+1] = X+1;	\
434	pby[count] = Y;  pby[count+1] = Y;	\
435	pbz[count] = Z;  pbz[count+1] = Z;	\
436	count += 2;				\
437	CHECK_FULL(count);
438#include "linetemp.h"
439      }
440      else {
441         /* unstippled, any width */
442#define INTERP_XY 1
443#define INTERP_Z 1
444#define WIDE 1
445#define PLOT(X,Y)		\
446	pbx[count] = X;		\
447	pby[count] = Y;		\
448	pbz[count] = Z;		\
449	count++;		\
450	CHECK_FULL(count);
451#include "linetemp.h"
452      }
453   }
454
455   ctx->PB->count = count;
456   gl_flush_pb(ctx);
457}
458
459
460
461static void general_smooth_rgba_line( GLcontext *ctx,
462                                      GLuint vert0, GLuint vert1, GLuint pvert)
463{
464   GLint count = ctx->PB->count;
465   GLint *pbx = ctx->PB->x;
466   GLint *pby = ctx->PB->y;
467   GLdepth *pbz = ctx->PB->z;
468   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
469   (void) pvert;
470
471   ctx->PB->mono = GL_FALSE;
472
473   if (ctx->Line.StippleFlag) {
474      /* stippled */
475#define INTERP_XY 1
476#define INTERP_Z 1
477#define INTERP_RGB 1
478#define INTERP_ALPHA 1
479#define WIDE 1
480#define STIPPLE 1
481#define PLOT(X,Y)				\
482	pbx[count] = X;				\
483	pby[count] = Y;				\
484	pbz[count] = Z;				\
485	pbrgba[count][RCOMP] = FixedToInt(r0);	\
486	pbrgba[count][GCOMP] = FixedToInt(g0);	\
487	pbrgba[count][BCOMP] = FixedToInt(b0);	\
488	pbrgba[count][ACOMP] = FixedToInt(a0);	\
489	count++;				\
490	CHECK_FULL(count);
491#include "linetemp.h"
492   }
493   else {
494      /* unstippled */
495      if (ctx->Line.Width==2.0F) {
496         /* special case: unstippled and width=2 */
497#define INTERP_XY 1
498#define INTERP_Z 1
499#define INTERP_RGB 1
500#define INTERP_ALPHA 1
501#define XMAJOR_PLOT(X,Y)				\
502	pbx[count] = X;  pbx[count+1] = X;		\
503	pby[count] = Y;  pby[count+1] = Y+1;		\
504	pbz[count] = Z;  pbz[count+1] = Z;		\
505	pbrgba[count][RCOMP] = FixedToInt(r0);		\
506	pbrgba[count][GCOMP] = FixedToInt(g0);		\
507	pbrgba[count][BCOMP] = FixedToInt(b0);		\
508	pbrgba[count][ACOMP] = FixedToInt(a0);		\
509	pbrgba[count+1][RCOMP] = FixedToInt(r0);	\
510	pbrgba[count+1][GCOMP] = FixedToInt(g0);	\
511	pbrgba[count+1][BCOMP] = FixedToInt(b0);	\
512	pbrgba[count+1][ACOMP] = FixedToInt(a0);	\
513	count += 2;					\
514	CHECK_FULL(count);
515#define YMAJOR_PLOT(X,Y)				\
516	pbx[count] = X;  pbx[count+1] = X+1;		\
517	pby[count] = Y;  pby[count+1] = Y;		\
518	pbz[count] = Z;  pbz[count+1] = Z;		\
519	pbrgba[count][RCOMP] = FixedToInt(r0);		\
520	pbrgba[count][GCOMP] = FixedToInt(g0);		\
521	pbrgba[count][BCOMP] = FixedToInt(b0);		\
522	pbrgba[count][ACOMP] = FixedToInt(a0);		\
523	pbrgba[count+1][RCOMP] = FixedToInt(r0);	\
524	pbrgba[count+1][GCOMP] = FixedToInt(g0);	\
525	pbrgba[count+1][BCOMP] = FixedToInt(b0);	\
526	pbrgba[count+1][ACOMP] = FixedToInt(a0);	\
527	count += 2;					\
528	CHECK_FULL(count);
529#include "linetemp.h"
530      }
531      else {
532         /* unstippled, any width */
533#define INTERP_XY 1
534#define INTERP_Z 1
535#define INTERP_RGB 1
536#define INTERP_ALPHA 1
537#define WIDE 1
538#define PLOT(X,Y)				\
539	pbx[count] = X;				\
540	pby[count] = Y;				\
541	pbz[count] = Z;				\
542	pbrgba[count][RCOMP] = FixedToInt(r0);	\
543	pbrgba[count][GCOMP] = FixedToInt(g0);	\
544	pbrgba[count][BCOMP] = FixedToInt(b0);	\
545	pbrgba[count][ACOMP] = FixedToInt(a0);	\
546	count++;				\
547	CHECK_FULL(count);
548#include "linetemp.h"
549      }
550   }
551
552   ctx->PB->count = count;
553   gl_flush_pb(ctx);
554}
555
556
557static void general_flat_rgba_line( GLcontext *ctx,
558                                    GLuint vert0, GLuint vert1, GLuint pvert )
559{
560   const GLubyte *color = ctx->VB->ColorPtr->data[pvert];
561   PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
562
563   if (ctx->Line.StippleFlag) {
564      /* stippled */
565#define INTERP_XY 1
566#define INTERP_Z 1
567#define WIDE 1
568#define STIPPLE 1
569#define PLOT(X,Y)  PB_WRITE_PIXEL(ctx->PB, X, Y, Z);
570#include "linetemp.h"
571   }
572   else {
573      /* unstippled */
574      if (ctx->Line.Width==2.0F) {
575         /* special case: unstippled and width=2 */
576#define INTERP_XY 1
577#define INTERP_Z 1
578#define XMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z); \
579                         PB_WRITE_PIXEL(ctx->PB, X, Y+1, Z);
580#define YMAJOR_PLOT(X,Y)  PB_WRITE_PIXEL(ctx->PB, X, Y, Z); \
581                          PB_WRITE_PIXEL(ctx->PB, X+1, Y, Z);
582#include "linetemp.h"
583      }
584      else {
585         /* unstippled, any width */
586#define INTERP_XY 1
587#define INTERP_Z 1
588#define WIDE 1
589#define PLOT(X,Y) PB_WRITE_PIXEL(ctx->PB, X, Y, Z);
590#include "linetemp.h"
591      }
592   }
593
594   gl_flush_pb(ctx);
595}
596
597
598/* Flat-shaded, textured, any width, maybe stippled */
599static void flat_textured_line( GLcontext *ctx,
600                                GLuint vert0, GLuint vert1, GLuint pv )
601{
602   GLint count;
603   GLint *pbx = ctx->PB->x;
604   GLint *pby = ctx->PB->y;
605   GLdepth *pbz = ctx->PB->z;
606   GLfloat *pbs = ctx->PB->s[0];
607   GLfloat *pbt = ctx->PB->t[0];
608   GLfloat *pbu = ctx->PB->u[0];
609   GLubyte *color = ctx->VB->ColorPtr->data[pv];
610   PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
611   count = ctx->PB->count;
612
613   if (ctx->Line.StippleFlag) {
614      /* stippled */
615#define INTERP_XY 1
616#define INTERP_Z 1
617#define INTERP_STUV0 1
618#define WIDE 1
619#define STIPPLE 1
620#define PLOT(X,Y)			\
621	{				\
622	   pbx[count] = X;		\
623	   pby[count] = Y;		\
624	   pbz[count] = Z;		\
625	   pbs[count] = s;		\
626	   pbt[count] = t;		\
627	   pbu[count] = u;		\
628	   count++;			\
629	   CHECK_FULL(count);		\
630	}
631#include "linetemp.h"
632   }
633   else {
634      /* unstippled */
635#define INTERP_XY 1
636#define INTERP_Z 1
637#define INTERP_STUV0 1
638#define WIDE 1
639#define PLOT(X,Y)			\
640	{				\
641	   pbx[count] = X;		\
642	   pby[count] = Y;		\
643	   pbz[count] = Z;		\
644	   pbs[count] = s;		\
645	   pbt[count] = t;		\
646	   pbu[count] = u;		\
647	   count++;			\
648	   CHECK_FULL(count);		\
649	}
650#include "linetemp.h"
651   }
652
653   ctx->PB->count = count;
654   gl_flush_pb(ctx);
655}
656
657
658
659/* Smooth-shaded, textured, any width, maybe stippled */
660static void smooth_textured_line( GLcontext *ctx,
661                                  GLuint vert0, GLuint vert1, GLuint pvert )
662{
663   GLint count = ctx->PB->count;
664   GLint *pbx = ctx->PB->x;
665   GLint *pby = ctx->PB->y;
666   GLdepth *pbz = ctx->PB->z;
667   GLfloat *pbs = ctx->PB->s[0];
668   GLfloat *pbt = ctx->PB->t[0];
669   GLfloat *pbu = ctx->PB->u[0];
670   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
671   (void) pvert;
672
673   ctx->PB->mono = GL_FALSE;
674
675   if (ctx->Line.StippleFlag) {
676      /* stippled */
677#define INTERP_XY 1
678#define INTERP_Z 1
679#define INTERP_RGB 1
680#define INTERP_ALPHA 1
681#define INTERP_STUV0 1
682#define WIDE 1
683#define STIPPLE 1
684#define PLOT(X,Y)					\
685	{						\
686	   pbx[count] = X;				\
687	   pby[count] = Y;				\
688	   pbz[count] = Z;				\
689	   pbs[count] = s;				\
690	   pbt[count] = t;				\
691	   pbu[count] = u;				\
692	   pbrgba[count][RCOMP] = FixedToInt(r0);	\
693	   pbrgba[count][GCOMP] = FixedToInt(g0);	\
694	   pbrgba[count][BCOMP] = FixedToInt(b0);	\
695	   pbrgba[count][ACOMP] = FixedToInt(a0);	\
696	   count++;					\
697	   CHECK_FULL(count);				\
698	}
699#include "linetemp.h"
700   }
701   else {
702      /* unstippled */
703#define INTERP_XY 1
704#define INTERP_Z 1
705#define INTERP_RGB 1
706#define INTERP_ALPHA 1
707#define INTERP_STUV0 1
708#define WIDE 1
709#define PLOT(X,Y)					\
710	{						\
711	   pbx[count] = X;				\
712	   pby[count] = Y;				\
713	   pbz[count] = Z;				\
714	   pbs[count] = s;				\
715	   pbt[count] = t;				\
716	   pbu[count] = u;				\
717	   pbrgba[count][RCOMP] = FixedToInt(r0);	\
718	   pbrgba[count][GCOMP] = FixedToInt(g0);	\
719	   pbrgba[count][BCOMP] = FixedToInt(b0);	\
720	   pbrgba[count][ACOMP] = FixedToInt(a0);	\
721	   count++;					\
722	   CHECK_FULL(count);				\
723	}
724#include "linetemp.h"
725   }
726
727   ctx->PB->count = count;
728   gl_flush_pb(ctx);
729}
730
731
732/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
733 * color interpolation.
734 */
735static void smooth_multitextured_line( GLcontext *ctx,
736                                   GLuint vert0, GLuint vert1, GLuint pvert )
737{
738   GLint count = ctx->PB->count;
739   GLint *pbx = ctx->PB->x;
740   GLint *pby = ctx->PB->y;
741   GLdepth *pbz = ctx->PB->z;
742   GLfloat *pbs = ctx->PB->s[0];
743   GLfloat *pbt = ctx->PB->t[0];
744   GLfloat *pbu = ctx->PB->u[0];
745   GLfloat *pbs1 = ctx->PB->s[1];
746   GLfloat *pbt1 = ctx->PB->t[1];
747   GLfloat *pbu1 = ctx->PB->u[1];
748   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
749   GLubyte (*pbspec)[3] = ctx->PB->spec;
750   (void) pvert;
751
752   ctx->PB->mono = GL_FALSE;
753
754   if (ctx->Line.StippleFlag) {
755      /* stippled */
756#define INTERP_XY 1
757#define INTERP_Z 1
758#define INTERP_RGB 1
759#define INTERP_SPEC 1
760#define INTERP_ALPHA 1
761#define INTERP_STUV0 1
762#define INTERP_STUV1 1
763#define WIDE 1
764#define STIPPLE 1
765#define PLOT(X,Y)					\
766	{						\
767	   pbx[count] = X;				\
768	   pby[count] = Y;				\
769	   pbz[count] = Z;				\
770	   pbs[count] = s;				\
771	   pbt[count] = t;				\
772	   pbu[count] = u;				\
773	   pbs1[count] = s1;				\
774	   pbt1[count] = t1;				\
775	   pbu1[count] = u1;				\
776	   pbrgba[count][RCOMP] = FixedToInt(r0);	\
777	   pbrgba[count][GCOMP] = FixedToInt(g0);	\
778	   pbrgba[count][BCOMP] = FixedToInt(b0);	\
779	   pbrgba[count][ACOMP] = FixedToInt(a0);	\
780	   pbspec[count][RCOMP] = FixedToInt(sr0);	\
781	   pbspec[count][GCOMP] = FixedToInt(sg0);	\
782	   pbspec[count][BCOMP] = FixedToInt(sb0);	\
783	   count++;					\
784	   CHECK_FULL(count);				\
785	}
786#include "linetemp.h"
787   }
788   else {
789      /* unstippled */
790#define INTERP_XY 1
791#define INTERP_Z 1
792#define INTERP_RGB 1
793#define INTERP_SPEC 1
794#define INTERP_ALPHA 1
795#define INTERP_STUV0 1
796#define INTERP_STUV1 1
797#define WIDE 1
798#define PLOT(X,Y)					\
799	{						\
800	   pbx[count] = X;				\
801	   pby[count] = Y;				\
802	   pbz[count] = Z;				\
803	   pbs[count] = s;				\
804	   pbt[count] = t;				\
805	   pbu[count] = u;				\
806	   pbs1[count] = s1;				\
807	   pbt1[count] = t1;				\
808	   pbu1[count] = u1;				\
809	   pbrgba[count][RCOMP] = FixedToInt(r0);	\
810	   pbrgba[count][GCOMP] = FixedToInt(g0);	\
811	   pbrgba[count][BCOMP] = FixedToInt(b0);	\
812	   pbrgba[count][ACOMP] = FixedToInt(a0);	\
813	   pbspec[count][RCOMP] = FixedToInt(sr0);	\
814	   pbspec[count][GCOMP] = FixedToInt(sg0);	\
815	   pbspec[count][BCOMP] = FixedToInt(sb0);	\
816	   count++;					\
817	   CHECK_FULL(count);				\
818	}
819#include "linetemp.h"
820   }
821
822   ctx->PB->count = count;
823   gl_flush_pb(ctx);
824}
825
826
827/* Flat-shaded, multitextured, any width, maybe stippled, separate specular
828 * color interpolation.
829 */
830static void flat_multitextured_line( GLcontext *ctx,
831                                     GLuint vert0, GLuint vert1, GLuint pvert )
832{
833   GLint count = ctx->PB->count;
834   GLint *pbx = ctx->PB->x;
835   GLint *pby = ctx->PB->y;
836   GLdepth *pbz = ctx->PB->z;
837   GLfloat *pbs = ctx->PB->s[0];
838   GLfloat *pbt = ctx->PB->t[0];
839   GLfloat *pbu = ctx->PB->u[0];
840   GLfloat *pbs1 = ctx->PB->s[1];
841   GLfloat *pbt1 = ctx->PB->t[1];
842   GLfloat *pbu1 = ctx->PB->u[1];
843   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
844   GLubyte (*pbspec)[3] = ctx->PB->spec;
845   GLubyte *color = ctx->VB->ColorPtr->data[pvert];
846   GLubyte sRed   = ctx->VB->Specular ? ctx->VB->Specular[pvert][0] : 0;
847   GLubyte sGreen = ctx->VB->Specular ? ctx->VB->Specular[pvert][1] : 0;
848   GLubyte sBlue  = ctx->VB->Specular ? ctx->VB->Specular[pvert][2] : 0;
849
850   (void) pvert;
851
852   ctx->PB->mono = GL_FALSE;
853
854   if (ctx->Line.StippleFlag) {
855      /* stippled */
856#define INTERP_XY 1
857#define INTERP_Z 1
858#define INTERP_ALPHA 1
859#define INTERP_STUV0 1
860#define INTERP_STUV1 1
861#define WIDE 1
862#define STIPPLE 1
863#define PLOT(X,Y)					\
864	{						\
865	   pbx[count] = X;				\
866	   pby[count] = Y;				\
867	   pbz[count] = Z;				\
868	   pbs[count] = s;				\
869	   pbt[count] = t;				\
870	   pbu[count] = u;				\
871	   pbs1[count] = s1;				\
872	   pbt1[count] = t1;				\
873	   pbu1[count] = u1;				\
874	   pbrgba[count][RCOMP] = color[0];		\
875	   pbrgba[count][GCOMP] = color[1];		\
876	   pbrgba[count][BCOMP] = color[2];		\
877	   pbrgba[count][ACOMP] = color[3];		\
878	   pbspec[count][RCOMP] = sRed;			\
879	   pbspec[count][GCOMP] = sGreen;		\
880	   pbspec[count][BCOMP] = sBlue;		\
881	   count++;					\
882	   CHECK_FULL(count);				\
883	}
884#include "linetemp.h"
885   }
886   else {
887      /* unstippled */
888#define INTERP_XY 1
889#define INTERP_Z 1
890#define INTERP_ALPHA 1
891#define INTERP_STUV0 1
892#define INTERP_STUV1 1
893#define WIDE 1
894#define PLOT(X,Y)					\
895	{						\
896	   pbx[count] = X;				\
897	   pby[count] = Y;				\
898	   pbz[count] = Z;				\
899	   pbs[count] = s;				\
900	   pbt[count] = t;				\
901	   pbu[count] = u;				\
902	   pbs1[count] = s1;				\
903	   pbt1[count] = t1;				\
904	   pbu1[count] = u1;				\
905	   pbrgba[count][RCOMP] = color[0];		\
906	   pbrgba[count][GCOMP] = color[1];		\
907	   pbrgba[count][BCOMP] = color[2];		\
908	   pbrgba[count][ACOMP] = color[3];		\
909	   pbspec[count][RCOMP] = sRed;			\
910	   pbspec[count][GCOMP] = sGreen;		\
911	   pbspec[count][BCOMP] = sBlue;		\
912	   count++;					\
913	   CHECK_FULL(count);				\
914	}
915#include "linetemp.h"
916   }
917
918   ctx->PB->count = count;
919   gl_flush_pb(ctx);
920}
921
922
923
924
925/*
926 * Antialiased RGBA line
927 *
928 * This AA line function isn't terribly efficient but it's pretty
929 * straight-forward to understand.  Also, it doesn't exactly conform
930 * to the specification.
931 */
932static void aa_rgba_line( GLcontext *ctx,
933                          GLuint vert0, GLuint vert1, GLuint pvert )
934{
935#define INTERP_RGBA 1
936#define PLOT(x, y)  { PB_WRITE_RGBA_PIXEL( pb, (x), (y), z, red, green, blue, coverage ); }
937#include "lnaatemp.h"
938}
939
940/*
941 * Antialiased Textured RGBA line
942 *
943 * This AA line function isn't terribly efficient but it's pretty
944 * straight-forward to understand.  Also, it doesn't exactly conform
945 * to the specification.
946 */
947static void aa_tex_rgba_line( GLcontext *ctx,
948                              GLuint vert0, GLuint vert1, GLuint pvert )
949{
950#define INTERP_RGBA 1
951#define INTERP_STUV0 1
952#define PLOT(x, y)							\
953   {									\
954      PB_WRITE_TEX_PIXEL( pb, (x), (y), z, red, green, blue, coverage,	\
955                          s, t, u );					\
956   }
957#include "lnaatemp.h"
958}
959
960
961/*
962 * Antialiased Multitextured RGBA line
963 *
964 * This AA line function isn't terribly efficient but it's pretty
965 * straight-forward to understand.  Also, it doesn't exactly conform
966 * to the specification.
967 */
968static void aa_multitex_rgba_line( GLcontext *ctx,
969                                   GLuint vert0, GLuint vert1, GLuint pvert )
970{
971#define INTERP_RGBA 1
972#define INTERP_SPEC 1
973#define INTERP_STUV0 1
974#define INTERP_STUV1 1
975#define PLOT(x, y)							\
976   {									\
977      PB_WRITE_MULTITEX_SPEC_PIXEL( pb, (x), (y), z,			\
978            red, green, blue, coverage, specRed, specGreen, specBlue,	\
979            s, t, u, s1, t1, u1 );					\
980   }
981#include "lnaatemp.h"
982}
983
984
985/*
986 * Antialiased CI line.  Same comments for RGBA antialiased lines apply.
987 */
988static void aa_ci_line( GLcontext *ctx,
989                        GLuint vert0, GLuint vert1, GLuint pvert )
990{
991#define INTERP_INDEX 1
992#define PLOT(x, y)						\
993   {								\
994      PB_WRITE_CI_PIXEL( pb, (x), (y), z, index + coverage );	\
995   }
996#include "lnaatemp.h"
997}
998
999
1000/*
1001 * Null rasterizer for measuring transformation speed.
1002 */
1003static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
1004{
1005   (void) ctx;
1006   (void) v1;
1007   (void) v2;
1008   (void) pv;
1009}
1010
1011
1012
1013#ifdef DEBUG
1014void
1015_mesa_print_line_function(GLcontext *ctx)
1016{
1017   printf("Line Func == ");
1018   if (ctx->Driver.LineFunc == flat_ci_line)
1019      printf("flat_ci_line\n");
1020   else if (ctx->Driver.LineFunc == flat_ci_z_line)
1021      printf("flat_ci_z_line\n");
1022   else if (ctx->Driver.LineFunc == flat_rgba_line)
1023      printf("flat_rgba_line\n");
1024   else if (ctx->Driver.LineFunc == flat_rgba_z_line)
1025      printf("flat_rgba_z_line\n");
1026   else if (ctx->Driver.LineFunc == smooth_ci_line)
1027      printf("smooth_ci_line\n");
1028   else if (ctx->Driver.LineFunc == smooth_ci_z_line)
1029      printf("smooth_ci_z_line\n");
1030   else if (ctx->Driver.LineFunc == smooth_rgba_line)
1031      printf("smooth_rgba_line\n");
1032   else if (ctx->Driver.LineFunc == smooth_rgba_z_line)
1033      printf("smooth_rgba_z_line\n");
1034   else if (ctx->Driver.LineFunc == general_smooth_ci_line)
1035      printf("general_smooth_ci_line\n");
1036   else if (ctx->Driver.LineFunc == general_flat_ci_line)
1037      printf("general_flat_ci_line\n");
1038   else if (ctx->Driver.LineFunc == general_smooth_rgba_line)
1039      printf("general_smooth_rgba_line\n");
1040   else if (ctx->Driver.LineFunc == general_flat_rgba_line)
1041      printf("general_flat_rgba_line\n");
1042   else if (ctx->Driver.LineFunc == flat_textured_line)
1043      printf("flat_textured_line\n");
1044   else if (ctx->Driver.LineFunc == smooth_textured_line)
1045      printf("smooth_textured_line\n");
1046   else if (ctx->Driver.LineFunc == smooth_multitextured_line)
1047      printf("smooth_multitextured_line\n");
1048   else if (ctx->Driver.LineFunc == flat_multitextured_line)
1049      printf("flat_multitextured_line\n");
1050   else if (ctx->Driver.LineFunc == aa_rgba_line)
1051      printf("aa_rgba_line\n");
1052   else if (ctx->Driver.LineFunc == aa_tex_rgba_line)
1053      printf("aa_tex_rgba_line\n");
1054   else if (ctx->Driver.LineFunc == aa_multitex_rgba_line)
1055      printf("aa_multitex_rgba_line\n");
1056   else if (ctx->Driver.LineFunc == aa_ci_line)
1057      printf("aa_ci_line\n");
1058   else if (ctx->Driver.LineFunc == null_line)
1059      printf("null_line\n");
1060   else
1061      printf("Driver func %p\n", ctx->Driver.PointsFunc);
1062}
1063#endif
1064
1065
1066
1067/*
1068 * Determine which line drawing function to use given the current
1069 * rendering context.
1070 */
1071void gl_set_line_function( GLcontext *ctx )
1072{
1073   GLboolean rgbmode = ctx->Visual->RGBAflag;
1074   /* TODO: antialiased lines */
1075
1076   if (ctx->RenderMode==GL_RENDER) {
1077      if (ctx->NoRaster) {
1078         ctx->Driver.LineFunc = null_line;
1079         return;
1080      }
1081      if (ctx->Driver.LineFunc) {
1082         /* Device driver will draw lines. */
1083	 return;
1084      }
1085
1086      if (ctx->Line.SmoothFlag) {
1087         /* antialiased lines */
1088         if (rgbmode) {
1089            if (ctx->Texture.ReallyEnabled) {
1090               if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
1091                  || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR)
1092                  /* Multitextured! */
1093                  ctx->Driver.LineFunc = aa_multitex_rgba_line;
1094               else
1095                  ctx->Driver.LineFunc = aa_tex_rgba_line;
1096            } else {
1097               ctx->Driver.LineFunc = aa_rgba_line;
1098            }
1099         }
1100         else {
1101            ctx->Driver.LineFunc = aa_ci_line;
1102         }
1103      }
1104      else if (ctx->Texture.ReallyEnabled) {
1105         if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
1106             || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
1107            /* multi-texture and/or separate specular color */
1108            if (ctx->Light.ShadeModel==GL_SMOOTH)
1109               ctx->Driver.LineFunc = smooth_multitextured_line;
1110            else
1111               ctx->Driver.LineFunc = flat_multitextured_line;
1112         }
1113         else {
1114            if (ctx->Light.ShadeModel==GL_SMOOTH) {
1115                ctx->Driver.LineFunc = smooth_textured_line;
1116            }
1117            else {
1118                ctx->Driver.LineFunc = flat_textured_line;
1119            }
1120         }
1121      }
1122      else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag
1123               || ctx->Line.SmoothFlag) {
1124         if (ctx->Light.ShadeModel==GL_SMOOTH) {
1125            if (rgbmode)
1126               ctx->Driver.LineFunc = general_smooth_rgba_line;
1127            else
1128               ctx->Driver.LineFunc = general_smooth_ci_line;
1129         }
1130         else {
1131            if (rgbmode)
1132               ctx->Driver.LineFunc = general_flat_rgba_line;
1133            else
1134               ctx->Driver.LineFunc = general_flat_ci_line;
1135         }
1136      }
1137      else {
1138	 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1139	    /* Width==1, non-stippled, smooth-shaded */
1140            if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
1141               if (rgbmode)
1142                  ctx->Driver.LineFunc = smooth_rgba_z_line;
1143               else
1144                  ctx->Driver.LineFunc = smooth_ci_z_line;
1145            }
1146            else {
1147               if (rgbmode)
1148                  ctx->Driver.LineFunc = smooth_rgba_line;
1149               else
1150                  ctx->Driver.LineFunc = smooth_ci_line;
1151            }
1152	 }
1153         else {
1154	    /* Width==1, non-stippled, flat-shaded */
1155            if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
1156               if (rgbmode)
1157                  ctx->Driver.LineFunc = flat_rgba_z_line;
1158               else
1159                  ctx->Driver.LineFunc = flat_ci_z_line;
1160            }
1161            else {
1162               if (rgbmode)
1163                  ctx->Driver.LineFunc = flat_rgba_line;
1164               else
1165                  ctx->Driver.LineFunc = flat_ci_line;
1166            }
1167         }
1168      }
1169   }
1170   else if (ctx->RenderMode==GL_FEEDBACK) {
1171      ctx->Driver.LineFunc = gl_feedback_line;
1172   }
1173   else {
1174      /* GL_SELECT mode */
1175      ctx->Driver.LineFunc = gl_select_line;
1176   }
1177
1178   /*_mesa_print_line_function(ctx);*/
1179}
1180