xref: /reactos/dll/opengl/mesa/triangle.c (revision 5f2bebf7)
1*5f2bebf7SJérôme Gardou /* $Id: triangle.c,v 1.31 1998/02/03 23:46:00 brianp Exp $ */
2*5f2bebf7SJérôme Gardou 
3*5f2bebf7SJérôme Gardou /*
4*5f2bebf7SJérôme Gardou  * Mesa 3-D graphics library
5*5f2bebf7SJérôme Gardou  * Version:  2.4
6*5f2bebf7SJérôme Gardou  * Copyright (C) 1995-1997  Brian Paul
7*5f2bebf7SJérôme Gardou  *
8*5f2bebf7SJérôme Gardou  * This library is free software; you can redistribute it and/or
9*5f2bebf7SJérôme Gardou  * modify it under the terms of the GNU Library General Public
10*5f2bebf7SJérôme Gardou  * License as published by the Free Software Foundation; either
11*5f2bebf7SJérôme Gardou  * version 2 of the License, or (at your option) any later version.
12*5f2bebf7SJérôme Gardou  *
13*5f2bebf7SJérôme Gardou  * This library is distributed in the hope that it will be useful,
14*5f2bebf7SJérôme Gardou  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*5f2bebf7SJérôme Gardou  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16*5f2bebf7SJérôme Gardou  * Library General Public License for more details.
17*5f2bebf7SJérôme Gardou  *
18*5f2bebf7SJérôme Gardou  * You should have received a copy of the GNU Library General Public
19*5f2bebf7SJérôme Gardou  * License along with this library; if not, write to the Free
20*5f2bebf7SJérôme Gardou  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*5f2bebf7SJérôme Gardou  */
22*5f2bebf7SJérôme Gardou 
23*5f2bebf7SJérôme Gardou 
24*5f2bebf7SJérôme Gardou /*
25*5f2bebf7SJérôme Gardou  * $Log: triangle.c,v $
26*5f2bebf7SJérôme Gardou  * Revision 1.31  1998/02/03 23:46:00  brianp
27*5f2bebf7SJérôme Gardou  * fixed a few problems with condition expressions for Amiga StormC compiler
28*5f2bebf7SJérôme Gardou  *
29*5f2bebf7SJérôme Gardou  * Revision 1.30  1997/08/27 01:20:05  brianp
30*5f2bebf7SJérôme Gardou  * moved texture completeness test out one level (Karl Anders Oygard)
31*5f2bebf7SJérôme Gardou  *
32*5f2bebf7SJérôme Gardou  * Revision 1.29  1997/07/24 01:26:05  brianp
33*5f2bebf7SJérôme Gardou  * changed precompiled header symbol from PCH to PC_HEADER
34*5f2bebf7SJérôme Gardou  *
35*5f2bebf7SJérôme Gardou  * Revision 1.28  1997/07/21 22:18:10  brianp
36*5f2bebf7SJérôme Gardou  * fixed bug in compute_lambda() thanks to Magnus Lundin
37*5f2bebf7SJérôme Gardou  *
38*5f2bebf7SJérôme Gardou  * Revision 1.27  1997/06/23 00:40:03  brianp
39*5f2bebf7SJérôme Gardou  * added a DEFARRAY/UNDEFARRAY for the Mac
40*5f2bebf7SJérôme Gardou  *
41*5f2bebf7SJérôme Gardou  * Revision 1.26  1997/06/20 02:51:38  brianp
42*5f2bebf7SJérôme Gardou  * changed color components from GLfixed to GLubyte
43*5f2bebf7SJérôme Gardou  *
44*5f2bebf7SJérôme Gardou  * Revision 1.25  1997/06/03 01:38:22  brianp
45*5f2bebf7SJérôme Gardou  * fixed divide by zero problem in feedback function (William Mitchell)
46*5f2bebf7SJérôme Gardou  *
47*5f2bebf7SJérôme Gardou  * Revision 1.24  1997/05/28 03:26:49  brianp
48*5f2bebf7SJérôme Gardou  * added precompiled header (PCH) support
49*5f2bebf7SJérôme Gardou  *
50*5f2bebf7SJérôme Gardou  * Revision 1.23  1997/05/17 03:40:55  brianp
51*5f2bebf7SJérôme Gardou  * refined textured triangle selection code (Mats Lofkvist)
52*5f2bebf7SJérôme Gardou  *
53*5f2bebf7SJérôme Gardou  * Revision 1.22  1997/05/03 00:51:02  brianp
54*5f2bebf7SJérôme Gardou  * removed calls to gl_texturing_enabled()
55*5f2bebf7SJérôme Gardou  *
56*5f2bebf7SJérôme Gardou  * Revision 1.21  1997/04/14 21:38:15  brianp
57*5f2bebf7SJérôme Gardou  * fixed a typo (dtdx instead of dudx) in lambda_textured_triangle()
58*5f2bebf7SJérôme Gardou  *
59*5f2bebf7SJérôme Gardou  * Revision 1.20  1997/04/14 02:00:39  brianp
60*5f2bebf7SJérôme Gardou  * #include "texstate.h" instead of "texture.h"
61*5f2bebf7SJérôme Gardou  *
62*5f2bebf7SJérôme Gardou  * Revision 1.19  1997/04/12 12:27:16  brianp
63*5f2bebf7SJérôme Gardou  * replaced ctx->TriangleFunc with ctx->Driver.TriangleFunc
64*5f2bebf7SJérôme Gardou  *
65*5f2bebf7SJérôme Gardou  * Revision 1.18  1997/04/02 03:12:06  brianp
66*5f2bebf7SJérôme Gardou  * replaced ctx->IdentityTexMat with ctx->TextureMatrixType
67*5f2bebf7SJérôme Gardou  *
68*5f2bebf7SJérôme Gardou  * Revision 1.17  1997/03/13 03:05:31  brianp
69*5f2bebf7SJérôme Gardou  * removed unused shift variable in feedback_triangle()
70*5f2bebf7SJérôme Gardou  *
71*5f2bebf7SJérôme Gardou  * Revision 1.16  1997/03/08 02:04:27  brianp
72*5f2bebf7SJérôme Gardou  * better implementation of feedback function
73*5f2bebf7SJérôme Gardou  *
74*5f2bebf7SJérôme Gardou  * Revision 1.15  1997/03/04 18:54:13  brianp
75*5f2bebf7SJérôme Gardou  * renamed mipmap_textured_triangle() to lambda_textured_triangle()
76*5f2bebf7SJérôme Gardou  * better comments about lambda and mipmapping
77*5f2bebf7SJérôme Gardou  *
78*5f2bebf7SJérôme Gardou  * Revision 1.14  1997/02/20 23:47:35  brianp
79*5f2bebf7SJérôme Gardou  * triangle feedback colors were wrong when using smooth shading
80*5f2bebf7SJérôme Gardou  *
81*5f2bebf7SJérôme Gardou  * Revision 1.13  1997/02/19 10:24:26  brianp
82*5f2bebf7SJérôme Gardou  * use a GLdouble instead of a GLfloat for wwvvInv (perspective correction)
83*5f2bebf7SJérôme Gardou  *
84*5f2bebf7SJérôme Gardou  * Revision 1.12  1997/02/09 19:53:43  brianp
85*5f2bebf7SJérôme Gardou  * now use TEXTURE_xD enable constants
86*5f2bebf7SJérôme Gardou  *
87*5f2bebf7SJérôme Gardou  * Revision 1.11  1997/02/09 18:51:02  brianp
88*5f2bebf7SJérôme Gardou  * added GL_EXT_texture3D support
89*5f2bebf7SJérôme Gardou  *
90*5f2bebf7SJérôme Gardou  * Revision 1.10  1997/01/16 03:36:43  brianp
91*5f2bebf7SJérôme Gardou  * added #include "texture.h"
92*5f2bebf7SJérôme Gardou  *
93*5f2bebf7SJérôme Gardou  * Revision 1.9  1997/01/09 19:50:49  brianp
94*5f2bebf7SJérôme Gardou  * now call gl_texturing_enabled()
95*5f2bebf7SJérôme Gardou  *
96*5f2bebf7SJérôme Gardou  * Revision 1.8  1996/12/20 20:23:30  brianp
97*5f2bebf7SJérôme Gardou  * the test for using general_textured_triangle() was wrong
98*5f2bebf7SJérôme Gardou  *
99*5f2bebf7SJérôme Gardou  * Revision 1.7  1996/12/12 22:37:30  brianp
100*5f2bebf7SJérôme Gardou  * projective textures didn't work right
101*5f2bebf7SJérôme Gardou  *
102*5f2bebf7SJérôme Gardou  * Revision 1.6  1996/11/08 02:21:21  brianp
103*5f2bebf7SJérôme Gardou  * added null drawing function for GL_NO_RASTER
104*5f2bebf7SJérôme Gardou  *
105*5f2bebf7SJérôme Gardou  * Revision 1.4  1996/09/27 01:30:37  brianp
106*5f2bebf7SJérôme Gardou  * removed unneeded INTERP_ALPHA from flat_rgba_triangle()
107*5f2bebf7SJérôme Gardou  *
108*5f2bebf7SJérôme Gardou  * Revision 1.3  1996/09/15 14:19:16  brianp
109*5f2bebf7SJérôme Gardou  * now use GLframebuffer and GLvisual
110*5f2bebf7SJérôme Gardou  *
111*5f2bebf7SJérôme Gardou  * Revision 1.2  1996/09/15 01:48:58  brianp
112*5f2bebf7SJérôme Gardou  * removed #define NULL 0
113*5f2bebf7SJérôme Gardou  *
114*5f2bebf7SJérôme Gardou  * Revision 1.1  1996/09/13 01:38:16  brianp
115*5f2bebf7SJérôme Gardou  * Initial revision
116*5f2bebf7SJérôme Gardou  *
117*5f2bebf7SJérôme Gardou  */
118*5f2bebf7SJérôme Gardou 
119*5f2bebf7SJérôme Gardou 
120*5f2bebf7SJérôme Gardou /*
121*5f2bebf7SJérôme Gardou  * Triangle rasterizers
122*5f2bebf7SJérôme Gardou  */
123*5f2bebf7SJérôme Gardou 
124*5f2bebf7SJérôme Gardou 
125*5f2bebf7SJérôme Gardou #ifdef PC_HEADER
126*5f2bebf7SJérôme Gardou #include "all.h"
127*5f2bebf7SJérôme Gardou #else
128*5f2bebf7SJérôme Gardou #include <assert.h>
129*5f2bebf7SJérôme Gardou #include <math.h>
130*5f2bebf7SJérôme Gardou #include <stdio.h>
131*5f2bebf7SJérôme Gardou #include "depth.h"
132*5f2bebf7SJérôme Gardou #include "feedback.h"
133*5f2bebf7SJérôme Gardou #include "macros.h"
134*5f2bebf7SJérôme Gardou #include "span.h"
135*5f2bebf7SJérôme Gardou #include "texstate.h"
136*5f2bebf7SJérôme Gardou #include "triangle.h"
137*5f2bebf7SJérôme Gardou #include "types.h"
138*5f2bebf7SJérôme Gardou #include "vb.h"
139*5f2bebf7SJérôme Gardou #endif
140*5f2bebf7SJérôme Gardou 
141*5f2bebf7SJérôme Gardou 
142*5f2bebf7SJérôme Gardou /*
143*5f2bebf7SJérôme Gardou  * Put triangle in feedback buffer.
144*5f2bebf7SJérôme Gardou  */
feedback_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)145*5f2bebf7SJérôme Gardou static void feedback_triangle( GLcontext *ctx,
146*5f2bebf7SJérôme Gardou                                GLuint v0, GLuint v1, GLuint v2, GLuint pv )
147*5f2bebf7SJérôme Gardou {
148*5f2bebf7SJérôme Gardou    struct vertex_buffer *VB = ctx->VB;
149*5f2bebf7SJérôme Gardou    GLfloat color[4];
150*5f2bebf7SJérôme Gardou    GLuint i;
151*5f2bebf7SJérôme Gardou    GLfloat invRedScale   = ctx->Visual->InvRedScale;
152*5f2bebf7SJérôme Gardou    GLfloat invGreenScale = ctx->Visual->InvGreenScale;
153*5f2bebf7SJérôme Gardou    GLfloat invBlueScale  = ctx->Visual->InvBlueScale;
154*5f2bebf7SJérôme Gardou    GLfloat invAlphaScale = ctx->Visual->InvAlphaScale;
155*5f2bebf7SJérôme Gardou 
156*5f2bebf7SJérôme Gardou    FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN );
157*5f2bebf7SJérôme Gardou    FEEDBACK_TOKEN( ctx, (GLfloat) 3 );        /* three vertices */
158*5f2bebf7SJérôme Gardou 
159*5f2bebf7SJérôme Gardou    if (ctx->Light.ShadeModel==GL_FLAT) {
160*5f2bebf7SJérôme Gardou       /* flat shading - same color for each vertex */
161*5f2bebf7SJérôme Gardou       color[0] = (GLfloat) VB->Color[pv][0] * invRedScale;
162*5f2bebf7SJérôme Gardou       color[1] = (GLfloat) VB->Color[pv][1] * invGreenScale;
163*5f2bebf7SJérôme Gardou       color[2] = (GLfloat) VB->Color[pv][2] * invBlueScale;
164*5f2bebf7SJérôme Gardou       color[3] = (GLfloat) VB->Color[pv][3] * invAlphaScale;
165*5f2bebf7SJérôme Gardou    }
166*5f2bebf7SJérôme Gardou 
167*5f2bebf7SJérôme Gardou    for (i=0;i<3;i++) {
168*5f2bebf7SJérôme Gardou       GLfloat x, y, z, w;
169*5f2bebf7SJérôme Gardou       GLfloat tc[4];
170*5f2bebf7SJérôme Gardou       GLuint v;
171*5f2bebf7SJérôme Gardou       GLfloat invq;
172*5f2bebf7SJérôme Gardou 
173*5f2bebf7SJérôme Gardou       if (i==0)       v = v0;
174*5f2bebf7SJérôme Gardou       else if (i==1)  v = v1;
175*5f2bebf7SJérôme Gardou       else            v = v2;
176*5f2bebf7SJérôme Gardou 
177*5f2bebf7SJérôme Gardou       x = VB->Win[v][0];
178*5f2bebf7SJérôme Gardou       y = VB->Win[v][1];
179*5f2bebf7SJérôme Gardou       z = VB->Win[v][2] / DEPTH_SCALE;
180*5f2bebf7SJérôme Gardou       w = VB->Clip[v][3];
181*5f2bebf7SJérôme Gardou 
182*5f2bebf7SJérôme Gardou       if (ctx->Light.ShadeModel==GL_SMOOTH) {
183*5f2bebf7SJérôme Gardou          /* smooth shading - different color for each vertex */
184*5f2bebf7SJérôme Gardou          color[0] = VB->Color[v][0] * invRedScale;
185*5f2bebf7SJérôme Gardou          color[1] = VB->Color[v][1] * invGreenScale;
186*5f2bebf7SJérôme Gardou          color[2] = VB->Color[v][2] * invBlueScale;
187*5f2bebf7SJérôme Gardou          color[3] = VB->Color[v][3] * invAlphaScale;
188*5f2bebf7SJérôme Gardou       }
189*5f2bebf7SJérôme Gardou 
190*5f2bebf7SJérôme Gardou       invq = (VB->TexCoord[v][3]==0.0) ? 1.0 : (1.0F / VB->TexCoord[v][3]);
191*5f2bebf7SJérôme Gardou       tc[0] = VB->TexCoord[v][0] * invq;
192*5f2bebf7SJérôme Gardou       tc[1] = VB->TexCoord[v][1] * invq;
193*5f2bebf7SJérôme Gardou       tc[2] = VB->TexCoord[v][2] * invq;
194*5f2bebf7SJérôme Gardou       tc[3] = VB->TexCoord[v][3];
195*5f2bebf7SJérôme Gardou 
196*5f2bebf7SJérôme Gardou       gl_feedback_vertex( ctx, x, y, z, w, color, (GLfloat) VB->Index[v], tc );
197*5f2bebf7SJérôme Gardou    }
198*5f2bebf7SJérôme Gardou }
199*5f2bebf7SJérôme Gardou 
200*5f2bebf7SJérôme Gardou 
201*5f2bebf7SJérôme Gardou 
202*5f2bebf7SJérôme Gardou /*
203*5f2bebf7SJérôme Gardou  * Put triangle in selection buffer.
204*5f2bebf7SJérôme Gardou  */
select_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)205*5f2bebf7SJérôme Gardou static void select_triangle( GLcontext *ctx,
206*5f2bebf7SJérôme Gardou                              GLuint v0, GLuint v1, GLuint v2, GLuint pv )
207*5f2bebf7SJérôme Gardou {
208*5f2bebf7SJérôme Gardou    struct vertex_buffer *VB = ctx->VB;
209*5f2bebf7SJérôme Gardou 
210*5f2bebf7SJérôme Gardou    gl_update_hitflag( ctx, VB->Win[v0][2] / DEPTH_SCALE );
211*5f2bebf7SJérôme Gardou    gl_update_hitflag( ctx, VB->Win[v1][2] / DEPTH_SCALE );
212*5f2bebf7SJérôme Gardou    gl_update_hitflag( ctx, VB->Win[v2][2] / DEPTH_SCALE );
213*5f2bebf7SJérôme Gardou }
214*5f2bebf7SJérôme Gardou 
215*5f2bebf7SJérôme Gardou 
216*5f2bebf7SJérôme Gardou 
217*5f2bebf7SJérôme Gardou /*
218*5f2bebf7SJérôme Gardou  * Render a flat-shaded color index triangle.
219*5f2bebf7SJérôme Gardou  */
flat_ci_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)220*5f2bebf7SJérôme Gardou static void flat_ci_triangle( GLcontext *ctx,
221*5f2bebf7SJérôme Gardou                               GLuint v0, GLuint v1, GLuint v2, GLuint pv )
222*5f2bebf7SJérôme Gardou {
223*5f2bebf7SJérôme Gardou #define INTERP_Z 1
224*5f2bebf7SJérôme Gardou 
225*5f2bebf7SJérôme Gardou #define SETUP_CODE				\
226*5f2bebf7SJérôme Gardou    GLuint index = VB->Index[pv];		\
227*5f2bebf7SJérôme Gardou    if (!VB->MonoColor) {			\
228*5f2bebf7SJérôme Gardou       /* set the color index */			\
229*5f2bebf7SJérôme Gardou       (*ctx->Driver.Index)( ctx, index );	\
230*5f2bebf7SJérôme Gardou    }
231*5f2bebf7SJérôme Gardou 
232*5f2bebf7SJérôme Gardou #define INNER_LOOP( LEFT, RIGHT, Y )				\
233*5f2bebf7SJérôme Gardou 	{							\
234*5f2bebf7SJérôme Gardou 	   GLint i, n = RIGHT-LEFT;				\
235*5f2bebf7SJérôme Gardou 	   GLdepth zspan[MAX_WIDTH];				\
236*5f2bebf7SJérôme Gardou 	   if (n>0) {						\
237*5f2bebf7SJérôme Gardou 	      for (i=0;i<n;i++) {				\
238*5f2bebf7SJérôme Gardou 		 zspan[i] = ffz;			    \
239*5f2bebf7SJérôme Gardou 		 ffz += fdzdx;					\
240*5f2bebf7SJérôme Gardou 	      }							\
241*5f2bebf7SJérôme Gardou 	      gl_write_monoindex_span( ctx, n, LEFT, Y,		\
242*5f2bebf7SJérôme Gardou 	                            zspan, index, GL_POLYGON );	\
243*5f2bebf7SJérôme Gardou 	   }							\
244*5f2bebf7SJérôme Gardou 	}
245*5f2bebf7SJérôme Gardou 
246*5f2bebf7SJérôme Gardou #include "tritemp.h"
247*5f2bebf7SJérôme Gardou }
248*5f2bebf7SJérôme Gardou 
249*5f2bebf7SJérôme Gardou 
250*5f2bebf7SJérôme Gardou 
251*5f2bebf7SJérôme Gardou /*
252*5f2bebf7SJérôme Gardou  * Render a smooth-shaded color index triangle.
253*5f2bebf7SJérôme Gardou  */
smooth_ci_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)254*5f2bebf7SJérôme Gardou static void smooth_ci_triangle( GLcontext *ctx,
255*5f2bebf7SJérôme Gardou                                 GLuint v0, GLuint v1, GLuint v2, GLuint pv )
256*5f2bebf7SJérôme Gardou {
257*5f2bebf7SJérôme Gardou #define INTERP_Z 1
258*5f2bebf7SJérôme Gardou #define INTERP_INDEX 1
259*5f2bebf7SJérôme Gardou 
260*5f2bebf7SJérôme Gardou #define INNER_LOOP( LEFT, RIGHT, Y )				\
261*5f2bebf7SJérôme Gardou 	{							\
262*5f2bebf7SJérôme Gardou 	   GLint i, n = RIGHT-LEFT;				\
263*5f2bebf7SJérôme Gardou 	   GLdepth zspan[MAX_WIDTH];				\
264*5f2bebf7SJérôme Gardou            GLuint index[MAX_WIDTH];				\
265*5f2bebf7SJérôme Gardou 	   if (n>0) {						\
266*5f2bebf7SJérôme Gardou 	      for (i=0;i<n;i++) {				\
267*5f2bebf7SJérôme Gardou 		 zspan[i] = ffz;                    \
268*5f2bebf7SJérôme Gardou                  index[i] = FixedToInt(ffi);			\
269*5f2bebf7SJérôme Gardou 		 ffz += fdzdx;					\
270*5f2bebf7SJérôme Gardou 		 ffi += fdidx;					\
271*5f2bebf7SJérôme Gardou 	      }							\
272*5f2bebf7SJérôme Gardou 	      gl_write_index_span( ctx, n, LEFT, Y, zspan,	\
273*5f2bebf7SJérôme Gardou 	                           index, GL_POLYGON );		\
274*5f2bebf7SJérôme Gardou 	   }							\
275*5f2bebf7SJérôme Gardou 	}
276*5f2bebf7SJérôme Gardou 
277*5f2bebf7SJérôme Gardou #include "tritemp.h"
278*5f2bebf7SJérôme Gardou }
279*5f2bebf7SJérôme Gardou 
280*5f2bebf7SJérôme Gardou 
281*5f2bebf7SJérôme Gardou 
282*5f2bebf7SJérôme Gardou /*
283*5f2bebf7SJérôme Gardou  * Render a flat-shaded RGBA triangle.
284*5f2bebf7SJérôme Gardou  */
flat_rgba_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)285*5f2bebf7SJérôme Gardou static void flat_rgba_triangle( GLcontext *ctx,
286*5f2bebf7SJérôme Gardou                                 GLuint v0, GLuint v1, GLuint v2, GLuint pv )
287*5f2bebf7SJérôme Gardou {
288*5f2bebf7SJérôme Gardou #define INTERP_Z 1
289*5f2bebf7SJérôme Gardou 
290*5f2bebf7SJérôme Gardou #define SETUP_CODE				\
291*5f2bebf7SJérôme Gardou    if (!VB->MonoColor) {			\
292*5f2bebf7SJérôme Gardou       /* set the color */			\
293*5f2bebf7SJérôme Gardou       GLubyte r = VB->Color[pv][0];		\
294*5f2bebf7SJérôme Gardou       GLubyte g = VB->Color[pv][1];		\
295*5f2bebf7SJérôme Gardou       GLubyte b = VB->Color[pv][2];		\
296*5f2bebf7SJérôme Gardou       GLubyte a = VB->Color[pv][3];		\
297*5f2bebf7SJérôme Gardou       (*ctx->Driver.Color)( ctx, r, g, b, a );	\
298*5f2bebf7SJérôme Gardou    }
299*5f2bebf7SJérôme Gardou 
300*5f2bebf7SJérôme Gardou #define INNER_LOOP( LEFT, RIGHT, Y )				\
301*5f2bebf7SJérôme Gardou 	{							\
302*5f2bebf7SJérôme Gardou 	   GLint i, n = RIGHT-LEFT;				\
303*5f2bebf7SJérôme Gardou 	   GLdepth zspan[MAX_WIDTH];				\
304*5f2bebf7SJérôme Gardou 	   if (n>0) {						\
305*5f2bebf7SJérôme Gardou 	      for (i=0;i<n;i++) {				\
306*5f2bebf7SJérôme Gardou 		 zspan[i] = ffz;                \
307*5f2bebf7SJérôme Gardou 		 ffz += fdzdx;					\
308*5f2bebf7SJérôme Gardou 	      }							\
309*5f2bebf7SJérôme Gardou               gl_write_monocolor_span( ctx, n, LEFT, Y, zspan,	\
310*5f2bebf7SJérôme Gardou                              VB->Color[pv][0], VB->Color[pv][1],\
311*5f2bebf7SJérôme Gardou                              VB->Color[pv][2], VB->Color[pv][3],\
312*5f2bebf7SJérôme Gardou 			     GL_POLYGON );			\
313*5f2bebf7SJérôme Gardou 	   }							\
314*5f2bebf7SJérôme Gardou 	}
315*5f2bebf7SJérôme Gardou 
316*5f2bebf7SJérôme Gardou #include "tritemp.h"
317*5f2bebf7SJérôme Gardou }
318*5f2bebf7SJérôme Gardou 
319*5f2bebf7SJérôme Gardou 
320*5f2bebf7SJérôme Gardou 
321*5f2bebf7SJérôme Gardou /*
322*5f2bebf7SJérôme Gardou  * Render a smooth-shaded RGBA triangle.
323*5f2bebf7SJérôme Gardou  */
smooth_rgba_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)324*5f2bebf7SJérôme Gardou static void smooth_rgba_triangle( GLcontext *ctx,
325*5f2bebf7SJérôme Gardou                                   GLuint v0, GLuint v1, GLuint v2, GLuint pv )
326*5f2bebf7SJérôme Gardou {
327*5f2bebf7SJérôme Gardou #define INTERP_Z 1
328*5f2bebf7SJérôme Gardou #define INTERP_RGB 1
329*5f2bebf7SJérôme Gardou #define INTERP_ALPHA 1
330*5f2bebf7SJérôme Gardou 
331*5f2bebf7SJérôme Gardou #define INNER_LOOP( LEFT, RIGHT, Y )				\
332*5f2bebf7SJérôme Gardou 	{							\
333*5f2bebf7SJérôme Gardou 	   GLint i, n = RIGHT-LEFT;				\
334*5f2bebf7SJérôme Gardou 	   GLdepth zspan[MAX_WIDTH];				\
335*5f2bebf7SJérôme Gardou 	   GLubyte red[MAX_WIDTH], green[MAX_WIDTH];		\
336*5f2bebf7SJérôme Gardou 	   GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];		\
337*5f2bebf7SJérôme Gardou 	   if (n>0) {						\
338*5f2bebf7SJérôme Gardou 	      for (i=0;i<n;i++) {				\
339*5f2bebf7SJérôme Gardou 		 zspan[i] = ffz;			            \
340*5f2bebf7SJérôme Gardou 		 red[i]   = FixedToInt(ffr);			\
341*5f2bebf7SJérôme Gardou 		 green[i] = FixedToInt(ffg);			\
342*5f2bebf7SJérôme Gardou 		 blue[i]  = FixedToInt(ffb);			\
343*5f2bebf7SJérôme Gardou 		 alpha[i] = FixedToInt(ffa);			\
344*5f2bebf7SJérôme Gardou 		 ffz += fdzdx;					\
345*5f2bebf7SJérôme Gardou 		 ffr += fdrdx;					\
346*5f2bebf7SJérôme Gardou 		 ffg += fdgdx;					\
347*5f2bebf7SJérôme Gardou 		 ffb += fdbdx;					\
348*5f2bebf7SJérôme Gardou 		 ffa += fdadx;					\
349*5f2bebf7SJérôme Gardou 	      }							\
350*5f2bebf7SJérôme Gardou 	      gl_write_color_span( ctx, n, LEFT, Y, zspan,	\
351*5f2bebf7SJérôme Gardou 	                           red, green, blue, alpha,	\
352*5f2bebf7SJérôme Gardou 				   GL_POLYGON );		\
353*5f2bebf7SJérôme Gardou 	   }							\
354*5f2bebf7SJérôme Gardou 	}
355*5f2bebf7SJérôme Gardou 
356*5f2bebf7SJérôme Gardou #include "tritemp.h"
357*5f2bebf7SJérôme Gardou }
358*5f2bebf7SJérôme Gardou 
359*5f2bebf7SJérôme Gardou 
360*5f2bebf7SJérôme Gardou 
361*5f2bebf7SJérôme Gardou /*
362*5f2bebf7SJérôme Gardou  * Render an RGB, GL_DECAL, textured triangle.
363*5f2bebf7SJérôme Gardou  * Interpolate S,T only w/out mipmapping or perspective correction.
364*5f2bebf7SJérôme Gardou  */
simple_textured_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)365*5f2bebf7SJérôme Gardou static void simple_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
366*5f2bebf7SJérôme Gardou                                       GLuint v2, GLuint pv )
367*5f2bebf7SJérôme Gardou {
368*5f2bebf7SJérôme Gardou #define INTERP_ST 1
369*5f2bebf7SJérôme Gardou #define S_SCALE twidth
370*5f2bebf7SJérôme Gardou #define T_SCALE theight
371*5f2bebf7SJérôme Gardou #define SETUP_CODE							\
372*5f2bebf7SJérôme Gardou    GLfloat twidth = (GLfloat) ctx->Texture.Current2D->Image[0]->Width;	\
373*5f2bebf7SJérôme Gardou    GLfloat theight = (GLfloat) ctx->Texture.Current2D->Image[0]->Height;\
374*5f2bebf7SJérôme Gardou    GLint twidth_log2 = ctx->Texture.Current2D->Image[0]->WidthLog2;	\
375*5f2bebf7SJérôme Gardou    GLubyte *texture = ctx->Texture.Current2D->Image[0]->Data;		\
376*5f2bebf7SJérôme Gardou    GLint smask = ctx->Texture.Current2D->Image[0]->Width - 1;		\
377*5f2bebf7SJérôme Gardou    GLint tmask = ctx->Texture.Current2D->Image[0]->Height - 1;
378*5f2bebf7SJérôme Gardou 
379*5f2bebf7SJérôme Gardou #define INNER_LOOP( LEFT, RIGHT, Y )				\
380*5f2bebf7SJérôme Gardou 	{							\
381*5f2bebf7SJérôme Gardou 	   GLint i, n = RIGHT-LEFT;				\
382*5f2bebf7SJérôme Gardou 	   GLubyte red[MAX_WIDTH], green[MAX_WIDTH];		\
383*5f2bebf7SJérôme Gardou 	   GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];		\
384*5f2bebf7SJérôme Gardou 	   if (n>0) {						\
385*5f2bebf7SJérôme Gardou 	      for (i=0;i<n;i++) {				\
386*5f2bebf7SJérôme Gardou                  GLint s = FixedToInt(ffs) & smask;		\
387*5f2bebf7SJérôme Gardou                  GLint t = FixedToInt(fft) & tmask;		\
388*5f2bebf7SJérôme Gardou                  GLint pos = (t << twidth_log2) + s;		\
389*5f2bebf7SJérôme Gardou                  pos = pos + pos  + pos;  /* multiply by 3 */	\
390*5f2bebf7SJérôme Gardou                  red[i]   = texture[pos];			\
391*5f2bebf7SJérôme Gardou                  green[i] = texture[pos+1];			\
392*5f2bebf7SJérôme Gardou                  blue[i]  = texture[pos+2];			\
393*5f2bebf7SJérôme Gardou                  alpha[i] = 255;				\
394*5f2bebf7SJérôme Gardou 		 ffs += fdsdx;					\
395*5f2bebf7SJérôme Gardou 		 fft += fdtdx;					\
396*5f2bebf7SJérôme Gardou 	      }							\
397*5f2bebf7SJérôme Gardou               (*ctx->Driver.WriteColorSpan)( ctx, n, LEFT, Y,	\
398*5f2bebf7SJérôme Gardou                              red, green, blue, alpha, NULL );	\
399*5f2bebf7SJérôme Gardou 	   }							\
400*5f2bebf7SJérôme Gardou 	}
401*5f2bebf7SJérôme Gardou 
402*5f2bebf7SJérôme Gardou #include "tritemp.h"
403*5f2bebf7SJérôme Gardou }
404*5f2bebf7SJérôme Gardou 
405*5f2bebf7SJérôme Gardou 
406*5f2bebf7SJérôme Gardou 
407*5f2bebf7SJérôme Gardou /*
408*5f2bebf7SJérôme Gardou  * Render an RGB, GL_DECAL, textured triangle.
409*5f2bebf7SJérôme Gardou  * Interpolate S,T, GL_LESS depth test, w/out mipmapping or
410*5f2bebf7SJérôme Gardou  * perspective correction.
411*5f2bebf7SJérôme Gardou  */
simple_z_textured_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)412*5f2bebf7SJérôme Gardou static void simple_z_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
413*5f2bebf7SJérôme Gardou                                       GLuint v2, GLuint pv )
414*5f2bebf7SJérôme Gardou {
415*5f2bebf7SJérôme Gardou #define INTERP_Z 1
416*5f2bebf7SJérôme Gardou #define INTERP_ST 1
417*5f2bebf7SJérôme Gardou #define S_SCALE twidth
418*5f2bebf7SJérôme Gardou #define T_SCALE theight
419*5f2bebf7SJérôme Gardou #define SETUP_CODE							\
420*5f2bebf7SJérôme Gardou    GLfloat twidth = (GLfloat) ctx->Texture.Current2D->Image[0]->Width;	\
421*5f2bebf7SJérôme Gardou    GLfloat theight = (GLfloat) ctx->Texture.Current2D->Image[0]->Height;\
422*5f2bebf7SJérôme Gardou    GLint twidth_log2 = ctx->Texture.Current2D->Image[0]->WidthLog2;	\
423*5f2bebf7SJérôme Gardou    GLubyte *texture = ctx->Texture.Current2D->Image[0]->Data;		\
424*5f2bebf7SJérôme Gardou    GLint smask = ctx->Texture.Current2D->Image[0]->Width - 1;		\
425*5f2bebf7SJérôme Gardou    GLint tmask = ctx->Texture.Current2D->Image[0]->Height - 1;
426*5f2bebf7SJérôme Gardou 
427*5f2bebf7SJérôme Gardou #define INNER_LOOP( LEFT, RIGHT, Y )				\
428*5f2bebf7SJérôme Gardou 	{							\
429*5f2bebf7SJérôme Gardou 	   GLint i, n = RIGHT-LEFT;				\
430*5f2bebf7SJérôme Gardou 	   GLubyte red[MAX_WIDTH], green[MAX_WIDTH];		\
431*5f2bebf7SJérôme Gardou 	   GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];		\
432*5f2bebf7SJérôme Gardou            GLubyte mask[MAX_WIDTH];				\
433*5f2bebf7SJérôme Gardou 	   if (n>0) {						\
434*5f2bebf7SJérôme Gardou 	      for (i=0;i<n;i++) {				\
435*5f2bebf7SJérôme Gardou                  GLdepth z = ffz;           \
436*5f2bebf7SJérôme Gardou                  if (z < zRow[i]) {				\
437*5f2bebf7SJérôme Gardou                     GLint s = FixedToInt(ffs) & smask;		\
438*5f2bebf7SJérôme Gardou                     GLint t = FixedToInt(fft) & tmask;		\
439*5f2bebf7SJérôme Gardou                     GLint pos = (t << twidth_log2) + s;		\
440*5f2bebf7SJérôme Gardou                     pos = pos + pos  + pos;  /* multiply by 3 */\
441*5f2bebf7SJérôme Gardou                     red[i]   = texture[pos];			\
442*5f2bebf7SJérôme Gardou                     green[i] = texture[pos+1];			\
443*5f2bebf7SJérôme Gardou                     blue[i]  = texture[pos+2];			\
444*5f2bebf7SJérôme Gardou                     alpha[i] = 255;				\
445*5f2bebf7SJérôme Gardou                     zRow[i] = z;				\
446*5f2bebf7SJérôme Gardou                     mask[i] = 1;				\
447*5f2bebf7SJérôme Gardou                  }						\
448*5f2bebf7SJérôme Gardou                  else {						\
449*5f2bebf7SJérôme Gardou                     mask[i] = 0;				\
450*5f2bebf7SJérôme Gardou                  }						\
451*5f2bebf7SJérôme Gardou 		 ffz += fdzdx;					\
452*5f2bebf7SJérôme Gardou 		 ffs += fdsdx;					\
453*5f2bebf7SJérôme Gardou 		 fft += fdtdx;					\
454*5f2bebf7SJérôme Gardou 	      }							\
455*5f2bebf7SJérôme Gardou               (*ctx->Driver.WriteColorSpan)( ctx, n, LEFT, Y,	\
456*5f2bebf7SJérôme Gardou                              red, green, blue, alpha, mask );	\
457*5f2bebf7SJérôme Gardou 	   }							\
458*5f2bebf7SJérôme Gardou 	}
459*5f2bebf7SJérôme Gardou 
460*5f2bebf7SJérôme Gardou #include "tritemp.h"
461*5f2bebf7SJérôme Gardou }
462*5f2bebf7SJérôme Gardou 
463*5f2bebf7SJérôme Gardou 
464*5f2bebf7SJérôme Gardou 
465*5f2bebf7SJérôme Gardou /*
466*5f2bebf7SJérôme Gardou  * Render a smooth-shaded, textured, RGBA triangle.
467*5f2bebf7SJérôme Gardou  * Interpolate S,T,U with perspective correction, w/out mipmapping.
468*5f2bebf7SJérôme Gardou  * Note: we use texture coordinates S,T,U,V instead of S,T,R,Q because
469*5f2bebf7SJérôme Gardou  * R is already used for red.
470*5f2bebf7SJérôme Gardou  */
general_textured_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)471*5f2bebf7SJérôme Gardou static void general_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
472*5f2bebf7SJérôme Gardou                                        GLuint v2, GLuint pv )
473*5f2bebf7SJérôme Gardou {
474*5f2bebf7SJérôme Gardou #define INTERP_Z 1
475*5f2bebf7SJérôme Gardou #define INTERP_RGB 1
476*5f2bebf7SJérôme Gardou #define INTERP_ALPHA 1
477*5f2bebf7SJérôme Gardou #define INTERP_STW 1
478*5f2bebf7SJérôme Gardou #define INTERP_UV 1
479*5f2bebf7SJérôme Gardou #define SETUP_CODE						\
480*5f2bebf7SJérôme Gardou    GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);	\
481*5f2bebf7SJérôme Gardou    GLint r, g, b, a;						\
482*5f2bebf7SJérôme Gardou    if (flat_shade) {						\
483*5f2bebf7SJérôme Gardou       r = VB->Color[pv][0];					\
484*5f2bebf7SJérôme Gardou       g = VB->Color[pv][1];					\
485*5f2bebf7SJérôme Gardou       b = VB->Color[pv][2];					\
486*5f2bebf7SJérôme Gardou       a = VB->Color[pv][3];					\
487*5f2bebf7SJérôme Gardou    }
488*5f2bebf7SJérôme Gardou #define INNER_LOOP( LEFT, RIGHT, Y )				\
489*5f2bebf7SJérôme Gardou 	{							\
490*5f2bebf7SJérôme Gardou 	   GLint i, n = RIGHT-LEFT;				\
491*5f2bebf7SJérôme Gardou 	   GLdepth zspan[MAX_WIDTH];				\
492*5f2bebf7SJérôme Gardou 	   GLubyte red[MAX_WIDTH], green[MAX_WIDTH];		\
493*5f2bebf7SJérôme Gardou 	   GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];		\
494*5f2bebf7SJérôme Gardou            GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH];	\
495*5f2bebf7SJérôme Gardou 	   if (n>0) {						\
496*5f2bebf7SJérôme Gardou               if (flat_shade) {					\
497*5f2bebf7SJérôme Gardou                  for (i=0;i<n;i++) {				\
498*5f2bebf7SJérôme Gardou 		    GLdouble wwvvInv = 1.0 / (ww*vv);		\
499*5f2bebf7SJérôme Gardou 		    zspan[i] = ffz;		        \
500*5f2bebf7SJérôme Gardou 		    red[i]   = r;				\
501*5f2bebf7SJérôme Gardou 		    green[i] = g;				\
502*5f2bebf7SJérôme Gardou 		    blue[i]  = b;				\
503*5f2bebf7SJérôme Gardou 		    alpha[i] = a;				\
504*5f2bebf7SJérôme Gardou 		    s[i] = ss*wwvvInv;				\
505*5f2bebf7SJérôme Gardou 		    t[i] = tt*wwvvInv;				\
506*5f2bebf7SJérôme Gardou 		    u[i] = uu*wwvvInv;				\
507*5f2bebf7SJérôme Gardou 		    ffz += fdzdx;				\
508*5f2bebf7SJérôme Gardou 		    ss += dsdx;					\
509*5f2bebf7SJérôme Gardou 		    tt += dtdx;					\
510*5f2bebf7SJérôme Gardou 		    uu += dudx;					\
511*5f2bebf7SJérôme Gardou 		    vv += dvdx;					\
512*5f2bebf7SJérôme Gardou 		    ww += dwdx;					\
513*5f2bebf7SJérôme Gardou 		 }						\
514*5f2bebf7SJérôme Gardou               }							\
515*5f2bebf7SJérôme Gardou               else {						\
516*5f2bebf7SJérôme Gardou                  for (i=0;i<n;i++) {				\
517*5f2bebf7SJérôme Gardou 		    GLdouble wwvvInv = 1.0 / (ww*vv);		\
518*5f2bebf7SJérôme Gardou 		    zspan[i] = ffz;	                    \
519*5f2bebf7SJérôme Gardou 		    red[i]   = FixedToInt(ffr);			\
520*5f2bebf7SJérôme Gardou 		    green[i] = FixedToInt(ffg);			\
521*5f2bebf7SJérôme Gardou 		    blue[i]  = FixedToInt(ffb);			\
522*5f2bebf7SJérôme Gardou 		    alpha[i] = FixedToInt(ffa);			\
523*5f2bebf7SJérôme Gardou 		    s[i] = ss*wwvvInv;				\
524*5f2bebf7SJérôme Gardou 		    t[i] = tt*wwvvInv;				\
525*5f2bebf7SJérôme Gardou 		    u[i] = uu*wwvvInv;				\
526*5f2bebf7SJérôme Gardou 		    ffz += fdzdx;				\
527*5f2bebf7SJérôme Gardou 		    ffr += fdrdx;				\
528*5f2bebf7SJérôme Gardou 		    ffg += fdgdx;				\
529*5f2bebf7SJérôme Gardou 		    ffb += fdbdx;				\
530*5f2bebf7SJérôme Gardou 		    ffa += fdadx;				\
531*5f2bebf7SJérôme Gardou 		    ss += dsdx;					\
532*5f2bebf7SJérôme Gardou 		    tt += dtdx;					\
533*5f2bebf7SJérôme Gardou 		    uu += dudx;					\
534*5f2bebf7SJérôme Gardou 		    ww += dwdx;					\
535*5f2bebf7SJérôme Gardou 		    vv += dvdx;					\
536*5f2bebf7SJérôme Gardou 		 }						\
537*5f2bebf7SJérôme Gardou               }							\
538*5f2bebf7SJérôme Gardou 	      gl_write_texture_span( ctx, n, LEFT, Y, zspan,	\
539*5f2bebf7SJérôme Gardou                                      s, t, u, NULL, 		\
540*5f2bebf7SJérôme Gardou 	                             red, green, blue, alpha,	\
541*5f2bebf7SJérôme Gardou 				     GL_POLYGON );		\
542*5f2bebf7SJérôme Gardou 	   }							\
543*5f2bebf7SJérôme Gardou 	}
544*5f2bebf7SJérôme Gardou 
545*5f2bebf7SJérôme Gardou #include "tritemp.h"
546*5f2bebf7SJérôme Gardou }
547*5f2bebf7SJérôme Gardou 
548*5f2bebf7SJérôme Gardou 
549*5f2bebf7SJérôme Gardou 
550*5f2bebf7SJérôme Gardou /*
551*5f2bebf7SJérôme Gardou  * Compute the lambda value (texture level value) for a fragment.
552*5f2bebf7SJérôme Gardou  */
compute_lambda(GLfloat s,GLfloat t,GLfloat dsdx,GLfloat dsdy,GLfloat dtdx,GLfloat dtdy,GLfloat w,GLfloat dwdx,GLfloat dwdy,GLfloat width,GLfloat height)553*5f2bebf7SJérôme Gardou static GLfloat compute_lambda( GLfloat s, GLfloat t,
554*5f2bebf7SJérôme Gardou                                GLfloat dsdx, GLfloat dsdy,
555*5f2bebf7SJérôme Gardou                                GLfloat dtdx, GLfloat dtdy,
556*5f2bebf7SJérôme Gardou                                GLfloat w, GLfloat dwdx, GLfloat dwdy,
557*5f2bebf7SJérôme Gardou                                GLfloat width, GLfloat height )
558*5f2bebf7SJérôme Gardou {
559*5f2bebf7SJérôme Gardou    /* TODO: this function can probably be optimized a bit */
560*5f2bebf7SJérôme Gardou    GLfloat invw = 1.0 / w;
561*5f2bebf7SJérôme Gardou    GLfloat dudx, dudy, dvdx, dvdy;
562*5f2bebf7SJérôme Gardou    GLfloat r1, r2, rho2;
563*5f2bebf7SJérôme Gardou 
564*5f2bebf7SJérôme Gardou    dudx = (dsdx - s*dwdx) * invw * width;
565*5f2bebf7SJérôme Gardou    dudy = (dsdy - s*dwdy) * invw * width;
566*5f2bebf7SJérôme Gardou    dvdx = (dtdx - t*dwdx) * invw * height;
567*5f2bebf7SJérôme Gardou    dvdy = (dtdy - t*dwdy) * invw * height;
568*5f2bebf7SJérôme Gardou 
569*5f2bebf7SJérôme Gardou    r1 = dudx * dudx + dudy * dudy;
570*5f2bebf7SJérôme Gardou    r2 = dvdx * dvdx + dvdy * dvdy;
571*5f2bebf7SJérôme Gardou 
572*5f2bebf7SJérôme Gardou    /* rho2 = MAX2(r1,r2); */
573*5f2bebf7SJérôme Gardou    rho2 = r1 + r2;
574*5f2bebf7SJérôme Gardou    if (rho2 <= 0.0F) {
575*5f2bebf7SJérôme Gardou       return 0.0F;
576*5f2bebf7SJérôme Gardou    }
577*5f2bebf7SJérôme Gardou    else {
578*5f2bebf7SJérôme Gardou       /* return log base 2 of rho */
579*5f2bebf7SJérôme Gardou       return log(rho2) * 1.442695 * 0.5;       /* 1.442695 = 1/log(2) */
580*5f2bebf7SJérôme Gardou    }
581*5f2bebf7SJérôme Gardou }
582*5f2bebf7SJérôme Gardou 
583*5f2bebf7SJérôme Gardou 
584*5f2bebf7SJérôme Gardou 
585*5f2bebf7SJérôme Gardou /*
586*5f2bebf7SJérôme Gardou  * Render a smooth-shaded, textured, RGBA triangle.
587*5f2bebf7SJérôme Gardou  * Interpolate S,T,U with perspective correction and compute lambda for
588*5f2bebf7SJérôme Gardou  * each fragment.  Lambda is used to determine whether to use the
589*5f2bebf7SJérôme Gardou  * minification or magnification filter.  If minification and using
590*5f2bebf7SJérôme Gardou  * mipmaps, lambda is also used to select the texture level of detail.
591*5f2bebf7SJérôme Gardou  */
lambda_textured_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)592*5f2bebf7SJérôme Gardou static void lambda_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
593*5f2bebf7SJérôme Gardou                                       GLuint v2, GLuint pv )
594*5f2bebf7SJérôme Gardou {
595*5f2bebf7SJérôme Gardou #define INTERP_Z 1
596*5f2bebf7SJérôme Gardou #define INTERP_RGB 1
597*5f2bebf7SJérôme Gardou #define INTERP_ALPHA 1
598*5f2bebf7SJérôme Gardou #define INTERP_STW 1
599*5f2bebf7SJérôme Gardou #define INTERP_UV 1
600*5f2bebf7SJérôme Gardou 
601*5f2bebf7SJérôme Gardou #define SETUP_CODE							\
602*5f2bebf7SJérôme Gardou    GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);		\
603*5f2bebf7SJérôme Gardou    GLint r, g, b, a;							\
604*5f2bebf7SJérôme Gardou    GLfloat twidth, theight;						\
605*5f2bebf7SJérôme Gardou    if (ctx->Texture.Enabled & TEXTURE_2D) {			\
606*5f2bebf7SJérôme Gardou       twidth = (GLfloat) ctx->Texture.Current2D->Image[0]->Width;	\
607*5f2bebf7SJérôme Gardou       theight = (GLfloat) ctx->Texture.Current2D->Image[0]->Height;	\
608*5f2bebf7SJérôme Gardou    }									\
609*5f2bebf7SJérôme Gardou    else {								\
610*5f2bebf7SJérôme Gardou       twidth = (GLfloat) ctx->Texture.Current1D->Image[0]->Width;	\
611*5f2bebf7SJérôme Gardou       theight = 1.0;							\
612*5f2bebf7SJérôme Gardou    }									\
613*5f2bebf7SJérôme Gardou    if (flat_shade) {							\
614*5f2bebf7SJérôme Gardou       r = VB->Color[pv][0];						\
615*5f2bebf7SJérôme Gardou       g = VB->Color[pv][1];						\
616*5f2bebf7SJérôme Gardou       b = VB->Color[pv][2];						\
617*5f2bebf7SJérôme Gardou       a = VB->Color[pv][3];						\
618*5f2bebf7SJérôme Gardou    }
619*5f2bebf7SJérôme Gardou 
620*5f2bebf7SJérôme Gardou #define INNER_LOOP( LEFT, RIGHT, Y )					\
621*5f2bebf7SJérôme Gardou 	{								\
622*5f2bebf7SJérôme Gardou 	   GLint i, n = RIGHT-LEFT;					\
623*5f2bebf7SJérôme Gardou 	   GLdepth zspan[MAX_WIDTH];					\
624*5f2bebf7SJérôme Gardou 	   GLubyte red[MAX_WIDTH], green[MAX_WIDTH];			\
625*5f2bebf7SJérôme Gardou 	   GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];			\
626*5f2bebf7SJérôme Gardou            GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH];		\
627*5f2bebf7SJérôme Gardou 	   DEFARRAY(GLfloat,lambda,MAX_WIDTH);				\
628*5f2bebf7SJérôme Gardou 	   if (n>0) {							\
629*5f2bebf7SJérôme Gardou 	      if (flat_shade) {						\
630*5f2bebf7SJérôme Gardou 		 for (i=0;i<n;i++) {					\
631*5f2bebf7SJérôme Gardou 		    GLdouble wwvvInv = 1.0 / (ww*vv);			\
632*5f2bebf7SJérôme Gardou 		    zspan[i] = ffz;			        \
633*5f2bebf7SJérôme Gardou 		    red[i]   = r;					\
634*5f2bebf7SJérôme Gardou 		    green[i] = g;					\
635*5f2bebf7SJérôme Gardou 		    blue[i]  = b;					\
636*5f2bebf7SJérôme Gardou 		    alpha[i] = a;					\
637*5f2bebf7SJérôme Gardou 		    s[i] = ss*wwvvInv;					\
638*5f2bebf7SJérôme Gardou 		    t[i] = tt*wwvvInv;					\
639*5f2bebf7SJérôme Gardou 		    u[i] = uu*wwvvInv;					\
640*5f2bebf7SJérôme Gardou 		    lambda[i] = compute_lambda( s[i], t[i],		\
641*5f2bebf7SJérôme Gardou 						dsdx, dsdy,		\
642*5f2bebf7SJérôme Gardou 						dtdx, dtdy, ww,		\
643*5f2bebf7SJérôme Gardou 						dwdx, dwdy,		\
644*5f2bebf7SJérôme Gardou 						twidth, theight );	\
645*5f2bebf7SJérôme Gardou 		    ffz += fdzdx;					\
646*5f2bebf7SJérôme Gardou 		    ss += dsdx;						\
647*5f2bebf7SJérôme Gardou 		    tt += dtdx;						\
648*5f2bebf7SJérôme Gardou 		    uu += dudx;						\
649*5f2bebf7SJérôme Gardou 		    vv += dvdx;						\
650*5f2bebf7SJérôme Gardou 		    ww += dwdx;						\
651*5f2bebf7SJérôme Gardou 		 }							\
652*5f2bebf7SJérôme Gardou               }								\
653*5f2bebf7SJérôme Gardou               else {							\
654*5f2bebf7SJérôme Gardou 		 for (i=0;i<n;i++) {					\
655*5f2bebf7SJérôme Gardou 		    GLdouble wwvvInv = 1.0 / (ww*vv);			\
656*5f2bebf7SJérôme Gardou 		    zspan[i] = ffz;			                \
657*5f2bebf7SJérôme Gardou 		    red[i]   = FixedToInt(ffr);				\
658*5f2bebf7SJérôme Gardou 		    green[i] = FixedToInt(ffg);				\
659*5f2bebf7SJérôme Gardou 		    blue[i]  = FixedToInt(ffb);				\
660*5f2bebf7SJérôme Gardou 		    alpha[i] = FixedToInt(ffa);				\
661*5f2bebf7SJérôme Gardou 		    s[i] = ss*wwvvInv;					\
662*5f2bebf7SJérôme Gardou 		    t[i] = tt*wwvvInv;					\
663*5f2bebf7SJérôme Gardou 		    u[i] = uu*wwvvInv;					\
664*5f2bebf7SJérôme Gardou 		    lambda[i] = compute_lambda( s[i], t[i],		\
665*5f2bebf7SJérôme Gardou 						dsdx, dsdy,		\
666*5f2bebf7SJérôme Gardou 						dtdx, dtdy, ww,		\
667*5f2bebf7SJérôme Gardou 						dwdx, dwdy,		\
668*5f2bebf7SJérôme Gardou 						twidth, theight );	\
669*5f2bebf7SJérôme Gardou 		    ffz += fdzdx;					\
670*5f2bebf7SJérôme Gardou 		    ffr += fdrdx;					\
671*5f2bebf7SJérôme Gardou 		    ffg += fdgdx;					\
672*5f2bebf7SJérôme Gardou 		    ffb += fdbdx;					\
673*5f2bebf7SJérôme Gardou 		    ffa += fdadx;					\
674*5f2bebf7SJérôme Gardou 		    ss += dsdx;						\
675*5f2bebf7SJérôme Gardou 		    tt += dtdx;						\
676*5f2bebf7SJérôme Gardou 		    uu += dudx;						\
677*5f2bebf7SJérôme Gardou 		    vv += dvdx;						\
678*5f2bebf7SJérôme Gardou 		    ww += dwdx;						\
679*5f2bebf7SJérôme Gardou 		 }							\
680*5f2bebf7SJérôme Gardou               }								\
681*5f2bebf7SJérôme Gardou 	      gl_write_texture_span( ctx, n, LEFT, Y, zspan,		\
682*5f2bebf7SJérôme Gardou                                      s, t, u, lambda,	 		\
683*5f2bebf7SJérôme Gardou 	                             red, green, blue, alpha,		\
684*5f2bebf7SJérôme Gardou 				     GL_POLYGON );			\
685*5f2bebf7SJérôme Gardou 	   }								\
686*5f2bebf7SJérôme Gardou 	   UNDEFARRAY(lambda);						\
687*5f2bebf7SJérôme Gardou 	}
688*5f2bebf7SJérôme Gardou 
689*5f2bebf7SJérôme Gardou #include "tritemp.h"
690*5f2bebf7SJérôme Gardou }
691*5f2bebf7SJérôme Gardou 
692*5f2bebf7SJérôme Gardou 
693*5f2bebf7SJérôme Gardou 
694*5f2bebf7SJérôme Gardou /*
695*5f2bebf7SJérôme Gardou  * Null rasterizer for measuring transformation speed.
696*5f2bebf7SJérôme Gardou  */
null_triangle(GLcontext * ctx,GLuint v0,GLuint v1,GLuint v2,GLuint pv)697*5f2bebf7SJérôme Gardou static void null_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
698*5f2bebf7SJérôme Gardou                            GLuint v2, GLuint pv )
699*5f2bebf7SJérôme Gardou {
700*5f2bebf7SJérôme Gardou }
701*5f2bebf7SJérôme Gardou 
702*5f2bebf7SJérôme Gardou 
703*5f2bebf7SJérôme Gardou 
704*5f2bebf7SJérôme Gardou /*
705*5f2bebf7SJérôme Gardou  * Determine which triangle rendering function to use given the current
706*5f2bebf7SJérôme Gardou  * rendering context.
707*5f2bebf7SJérôme Gardou  */
gl_set_triangle_function(GLcontext * ctx)708*5f2bebf7SJérôme Gardou void gl_set_triangle_function( GLcontext *ctx )
709*5f2bebf7SJérôme Gardou {
710*5f2bebf7SJérôme Gardou    GLboolean rgbmode = ctx->Visual->RGBAflag;
711*5f2bebf7SJérôme Gardou 
712*5f2bebf7SJérôme Gardou    if (ctx->RenderMode==GL_RENDER) {
713*5f2bebf7SJérôme Gardou       if (ctx->NoRaster) {
714*5f2bebf7SJérôme Gardou          ctx->Driver.TriangleFunc = null_triangle;
715*5f2bebf7SJérôme Gardou          return;
716*5f2bebf7SJérôme Gardou       }
717*5f2bebf7SJérôme Gardou       if (ctx->Driver.TriangleFunc) {
718*5f2bebf7SJérôme Gardou          /* Device driver will draw triangles. */
719*5f2bebf7SJérôme Gardou       }
720*5f2bebf7SJérôme Gardou       else if (ctx->Texture.Enabled
721*5f2bebf7SJérôme Gardou                && ctx->Texture.Current
722*5f2bebf7SJérôme Gardou                && ctx->Texture.Current->Complete) {
723*5f2bebf7SJérôme Gardou          if (   (ctx->Texture.Enabled==TEXTURE_2D)
724*5f2bebf7SJérôme Gardou              && ctx->Texture.Current2D->MinFilter==GL_NEAREST
725*5f2bebf7SJérôme Gardou              && ctx->Texture.Current2D->MagFilter==GL_NEAREST
726*5f2bebf7SJérôme Gardou              && ctx->Texture.Current2D->WrapS==GL_REPEAT
727*5f2bebf7SJérôme Gardou              && ctx->Texture.Current2D->WrapT==GL_REPEAT
728*5f2bebf7SJérôme Gardou              && ctx->Texture.Current2D->Image[0]->Format==GL_RGB
729*5f2bebf7SJérôme Gardou              && ctx->Texture.Current2D->Image[0]->Border==0
730*5f2bebf7SJérôme Gardou              && (ctx->Texture.EnvMode==GL_DECAL
731*5f2bebf7SJérôme Gardou                  || ctx->Texture.EnvMode==GL_REPLACE)
732*5f2bebf7SJérôme Gardou              && ctx->Hint.PerspectiveCorrection==GL_FASTEST
733*5f2bebf7SJérôme Gardou              && ctx->TextureMatrixType==MATRIX_IDENTITY
734*5f2bebf7SJérôme Gardou              && ((ctx->RasterMask==DEPTH_BIT
735*5f2bebf7SJérôme Gardou                   && ctx->Depth.Func==GL_LESS
736*5f2bebf7SJérôme Gardou                   && ctx->Depth.Mask==GL_TRUE)
737*5f2bebf7SJérôme Gardou                  || ctx->RasterMask==0)
738*5f2bebf7SJérôme Gardou              && ctx->Polygon.StippleFlag==GL_FALSE
739*5f2bebf7SJérôme Gardou              && ctx->Visual->EightBitColor) {
740*5f2bebf7SJérôme Gardou             if (ctx->RasterMask==DEPTH_BIT) {
741*5f2bebf7SJérôme Gardou                ctx->Driver.TriangleFunc = simple_z_textured_triangle;
742*5f2bebf7SJérôme Gardou             }
743*5f2bebf7SJérôme Gardou             else {
744*5f2bebf7SJérôme Gardou                ctx->Driver.TriangleFunc = simple_textured_triangle;
745*5f2bebf7SJérôme Gardou             }
746*5f2bebf7SJérôme Gardou          }
747*5f2bebf7SJérôme Gardou          else {
748*5f2bebf7SJérôme Gardou             GLboolean needLambda = GL_TRUE;
749*5f2bebf7SJérôme Gardou             /* if mag filter == min filter we're not mipmapping */
750*5f2bebf7SJérôme Gardou             if (ctx->Texture.Enabled & TEXTURE_2D) {
751*5f2bebf7SJérôme Gardou                if (ctx->Texture.Current2D->MinFilter==
752*5f2bebf7SJérôme Gardou                    ctx->Texture.Current2D->MagFilter) {
753*5f2bebf7SJérôme Gardou                   needLambda = GL_FALSE;
754*5f2bebf7SJérôme Gardou                }
755*5f2bebf7SJérôme Gardou             }
756*5f2bebf7SJérôme Gardou             else if (ctx->Texture.Enabled & TEXTURE_1D) {
757*5f2bebf7SJérôme Gardou                if (ctx->Texture.Current1D->MinFilter==
758*5f2bebf7SJérôme Gardou                    ctx->Texture.Current1D->MagFilter) {
759*5f2bebf7SJérôme Gardou                   needLambda = GL_FALSE;
760*5f2bebf7SJérôme Gardou                }
761*5f2bebf7SJérôme Gardou             }
762*5f2bebf7SJérôme Gardou             if (needLambda)
763*5f2bebf7SJérôme Gardou                ctx->Driver.TriangleFunc = lambda_textured_triangle;
764*5f2bebf7SJérôme Gardou             else
765*5f2bebf7SJérôme Gardou                ctx->Driver.TriangleFunc = general_textured_triangle;
766*5f2bebf7SJérôme Gardou          }
767*5f2bebf7SJérôme Gardou       }
768*5f2bebf7SJérôme Gardou       else {
769*5f2bebf7SJérôme Gardou 	 if (ctx->Light.ShadeModel==GL_SMOOTH) {
770*5f2bebf7SJérôme Gardou 	    /* smooth shaded, no texturing, stippled or some raster ops */
771*5f2bebf7SJérôme Gardou             if (rgbmode)
772*5f2bebf7SJérôme Gardou                ctx->Driver.TriangleFunc = smooth_rgba_triangle;
773*5f2bebf7SJérôme Gardou             else
774*5f2bebf7SJérôme Gardou                ctx->Driver.TriangleFunc = smooth_ci_triangle;
775*5f2bebf7SJérôme Gardou 	 }
776*5f2bebf7SJérôme Gardou 	 else {
777*5f2bebf7SJérôme Gardou 	    /* flat shaded, no texturing, stippled or some raster ops */
778*5f2bebf7SJérôme Gardou             if (rgbmode)
779*5f2bebf7SJérôme Gardou                ctx->Driver.TriangleFunc = flat_rgba_triangle;
780*5f2bebf7SJérôme Gardou             else
781*5f2bebf7SJérôme Gardou                ctx->Driver.TriangleFunc = flat_ci_triangle;
782*5f2bebf7SJérôme Gardou 	 }
783*5f2bebf7SJérôme Gardou       }
784*5f2bebf7SJérôme Gardou    }
785*5f2bebf7SJérôme Gardou    else if (ctx->RenderMode==GL_FEEDBACK) {
786*5f2bebf7SJérôme Gardou       ctx->Driver.TriangleFunc = feedback_triangle;
787*5f2bebf7SJérôme Gardou    }
788*5f2bebf7SJérôme Gardou    else {
789*5f2bebf7SJérôme Gardou       /* GL_SELECT mode */
790*5f2bebf7SJérôme Gardou       ctx->Driver.TriangleFunc = select_triangle;
791*5f2bebf7SJérôme Gardou    }
792*5f2bebf7SJérôme Gardou }
793*5f2bebf7SJérôme Gardou 
794