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