Fix typo (& instead of &&) to fix olympic.c bug
[mesa.git] / src / mesa / main / api_eval.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 5.1
5 *
6 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29 #include "glheader.h"
30 #include "api_eval.h"
31 #include "context.h"
32 #include "macros.h"
33 #include "math/m_eval.h"
34
35 static void do_EvalCoord1f(GLcontext* ctx, GLfloat u)
36 {
37
38 /** Color Index **/
39 if (ctx->Eval.Map1Index)
40 {
41 GLfloat findex;
42 struct gl_1d_map *map = &ctx->EvalMap.Map1Index;
43 GLfloat uu = (u - map->u1) * map->du;
44 _math_horner_bezier_curve(map->Points, &findex, uu, 1, map->Order);
45 glIndexi( (GLint) findex );
46 }
47
48 /** Color **/
49 if (ctx->Eval.Map1Color4) {
50 GLfloat fcolor[4];
51 struct gl_1d_map *map = &ctx->EvalMap.Map1Color4;
52 GLfloat uu = (u - map->u1) * map->du;
53 _math_horner_bezier_curve(map->Points, fcolor, uu, 4, map->Order);
54 glColor4fv( fcolor );
55 }
56
57 /** Normal Vector **/
58 if (ctx->Eval.Map1Normal) {
59 GLfloat normal[3];
60 struct gl_1d_map *map = &ctx->EvalMap.Map1Normal;
61 GLfloat uu = (u - map->u1) * map->du;
62 _math_horner_bezier_curve(map->Points, normal, uu, 3, map->Order);
63 glNormal3fv( normal );
64 }
65
66 /** Texture Coordinates **/
67 if (ctx->Eval.Map1TextureCoord4) {
68 GLfloat texcoord[4];
69 struct gl_1d_map *map = &ctx->EvalMap.Map1Texture4;
70 GLfloat uu = (u - map->u1) * map->du;
71 _math_horner_bezier_curve(map->Points, texcoord, uu, 4, map->Order);
72 glTexCoord4fv( texcoord );
73 }
74 else if (ctx->Eval.Map1TextureCoord3) {
75 GLfloat texcoord[4];
76 struct gl_1d_map *map = &ctx->EvalMap.Map1Texture3;
77 GLfloat uu = (u - map->u1) * map->du;
78 _math_horner_bezier_curve(map->Points, texcoord, uu, 3, map->Order);
79 glTexCoord3fv( texcoord );
80 }
81 else if (ctx->Eval.Map1TextureCoord2) {
82 GLfloat texcoord[4];
83 struct gl_1d_map *map = &ctx->EvalMap.Map1Texture2;
84 GLfloat uu = (u - map->u1) * map->du;
85 _math_horner_bezier_curve(map->Points, texcoord, uu, 2, map->Order);
86 glTexCoord2fv( texcoord );
87 }
88 else if (ctx->Eval.Map1TextureCoord1) {
89 GLfloat texcoord[4];
90 struct gl_1d_map *map = &ctx->EvalMap.Map1Texture1;
91 GLfloat uu = (u - map->u1) * map->du;
92 _math_horner_bezier_curve(map->Points, texcoord, uu, 1, map->Order);
93 glTexCoord1fv( texcoord );
94 }
95
96 /** Vertex **/
97 if (ctx->Eval.Map1Vertex4)
98 {
99 GLfloat vertex[4];
100 struct gl_1d_map *map = &ctx->EvalMap.Map1Vertex4;
101 GLfloat uu = (u - map->u1) * map->du;
102 _math_horner_bezier_curve(map->Points, vertex, uu, 4, map->Order);
103 glVertex4fv( vertex );
104 }
105 else if (ctx->Eval.Map1Vertex3)
106 {
107 GLfloat vertex[4];
108 struct gl_1d_map *map = &ctx->EvalMap.Map1Vertex3;
109 GLfloat uu = (u - map->u1) * map->du;
110 _math_horner_bezier_curve(map->Points, vertex, uu, 3, map->Order);
111 glVertex3fv( vertex );
112 }
113 }
114
115 #define CROSS_PROD(n, u, v) \
116 (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \
117 (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \
118 (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]
119
120
121 static void do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v )
122 {
123 /** Color Index **/
124 if (ctx->Eval.Map2Index) {
125 GLfloat findex;
126 struct gl_2d_map *map = &ctx->EvalMap.Map2Index;
127 GLfloat uu = (u - map->u1) * map->du;
128 GLfloat vv = (v - map->v1) * map->dv;
129 _math_horner_bezier_surf(map->Points, &findex, uu, vv, 1,
130 map->Uorder, map->Vorder);
131 glIndexi( (GLuint) (GLint) findex );
132 }
133
134 /** Color **/
135 if (ctx->Eval.Map2Color4) {
136 GLfloat fcolor[4];
137 struct gl_2d_map *map = &ctx->EvalMap.Map2Color4;
138 GLfloat uu = (u - map->u1) * map->du;
139 GLfloat vv = (v - map->v1) * map->dv;
140 _math_horner_bezier_surf(map->Points, fcolor, uu, vv, 4,
141 map->Uorder, map->Vorder);
142 glColor4fv( fcolor );
143 }
144
145 /** Normal **/
146 if (ctx->Eval.Map2Normal &&
147 (!ctx->Eval.AutoNormal || (!ctx->Eval.Map2Vertex3 &&
148 !ctx->Eval.Map2Vertex4))) {
149 GLfloat normal[3];
150 struct gl_2d_map *map = &ctx->EvalMap.Map2Normal;
151 GLfloat uu = (u - map->u1) * map->du;
152 GLfloat vv = (v - map->v1) * map->dv;
153 _math_horner_bezier_surf(map->Points, normal, uu, vv, 3,
154 map->Uorder, map->Vorder);
155 glNormal3fv( normal );
156 }
157
158 /** Texture Coordinates **/
159 if (ctx->Eval.Map2TextureCoord4) {
160 GLfloat texcoord[4];
161 struct gl_2d_map *map = &ctx->EvalMap.Map2Texture4;
162 GLfloat uu = (u - map->u1) * map->du;
163 GLfloat vv = (v - map->v1) * map->dv;
164 _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 4,
165 map->Uorder, map->Vorder);
166 glTexCoord4fv( texcoord );
167 }
168 else if (ctx->Eval.Map2TextureCoord3) {
169 GLfloat texcoord[4];
170 struct gl_2d_map *map = &ctx->EvalMap.Map2Texture3;
171 GLfloat uu = (u - map->u1) * map->du;
172 GLfloat vv = (v - map->v1) * map->dv;
173 _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 3,
174 map->Uorder, map->Vorder);
175 glTexCoord3fv( texcoord );
176 }
177 else if (ctx->Eval.Map2TextureCoord2) {
178 GLfloat texcoord[4];
179 struct gl_2d_map *map = &ctx->EvalMap.Map2Texture2;
180 GLfloat uu = (u - map->u1) * map->du;
181 GLfloat vv = (v - map->v1) * map->dv;
182 _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 2,
183 map->Uorder, map->Vorder);
184 glTexCoord2fv( texcoord );
185 }
186 else if (ctx->Eval.Map2TextureCoord1) {
187 GLfloat texcoord[4];
188 struct gl_2d_map *map = &ctx->EvalMap.Map2Texture1;
189 GLfloat uu = (u - map->u1) * map->du;
190 GLfloat vv = (v - map->v1) * map->dv;
191 _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 1,
192 map->Uorder, map->Vorder);
193 glTexCoord1fv( texcoord );
194 }
195
196 /** Vertex **/
197 if(ctx->Eval.Map2Vertex4) {
198 GLfloat vertex[4];
199 GLfloat normal[3];
200 struct gl_2d_map *map = &ctx->EvalMap.Map2Vertex4;
201 GLfloat uu = (u - map->u1) * map->du;
202 GLfloat vv = (v - map->v1) * map->dv;
203
204 if (ctx->Eval.AutoNormal) {
205 GLfloat du[4], dv[4];
206
207 _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 4,
208 map->Uorder, map->Vorder);
209
210 CROSS_PROD(normal, du, dv);
211 NORMALIZE_3FV(normal);
212 }
213 else {
214 _math_horner_bezier_surf(map->Points, vertex, uu, vv, 4,
215 map->Uorder, map->Vorder);
216 }
217 }
218 else if (ctx->Eval.Map2Vertex3) {
219 GLfloat vertex[4];
220 struct gl_2d_map *map = &ctx->EvalMap.Map2Vertex3;
221 GLfloat uu = (u - map->u1) * map->du;
222 GLfloat vv = (v - map->v1) * map->dv;
223 if (ctx->Eval.AutoNormal) {
224 GLfloat du[3], dv[3];
225 GLfloat normal[3];
226 _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 3,
227 map->Uorder, map->Vorder);
228 CROSS_PROD(normal, du, dv);
229 NORMALIZE_3FV(normal);
230 glNormal3fv( normal );
231 glVertex3fv( vertex );
232 }
233 else {
234 _math_horner_bezier_surf(map->Points, vertex, uu, vv, 3,
235 map->Uorder, map->Vorder);
236 glVertex3fv( vertex );
237 }
238 }
239 }
240
241
242 void _mesa_EvalPoint1( GLint i )
243 {
244 GET_CURRENT_CONTEXT( ctx );
245 GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) /
246 (GLfloat) ctx->Eval.MapGrid1un);
247 GLfloat u = i * du + ctx->Eval.MapGrid1u1;
248
249 glEvalCoord1f( u );
250 }
251
252
253 void _mesa_EvalPoint2( GLint i, GLint j )
254 {
255 GET_CURRENT_CONTEXT( ctx );
256 GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) /
257 (GLfloat) ctx->Eval.MapGrid2un);
258 GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) /
259 (GLfloat) ctx->Eval.MapGrid2vn);
260 GLfloat u = i * du + ctx->Eval.MapGrid2u1;
261 GLfloat v = j * dv + ctx->Eval.MapGrid2v1;
262
263 glEvalCoord2f( u, v );
264 }
265
266 /* Wierd thing about eval is that it doesn't affect 'current' values.
267 * This technique of saving and resetting current values requires
268 * that:
269 *
270 * 1) Current values are updated immediately in the glColor,
271 * etc. functions.
272 *
273 * 2) Hardware color values are stored seperately from ctx->Current,
274 * for example in dma buffers, or direct emit to registers.
275 */
276 void _mesa_EvalCoord1f( GLfloat u )
277 {
278 GET_CURRENT_CONTEXT( ctx );
279 GLfloat normal[3], texcoord[4], color[4];
280 GLuint index;
281
282 COPY_3FV( normal, ctx->Current.Attrib[VERT_ATTRIB_NORMAL] );
283 COPY_4FV( texcoord, ctx->Current.Attrib[VERT_ATTRIB_TEX0] );
284 COPY_4FV( color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
285 index = ctx->Current.Index;
286
287 do_EvalCoord1f( ctx, u );
288
289 COPY_3FV( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], normal );
290 COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_TEX0], texcoord );
291 COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color );
292 ctx->Current.Index = index;
293 }
294
295 void _mesa_EvalCoord2f( GLfloat u, GLfloat v )
296 {
297 GET_CURRENT_CONTEXT( ctx );
298 GLfloat normal[3], texcoord[4], color[4];
299 GLuint index;
300
301 COPY_3FV( normal, ctx->Current.Attrib[VERT_ATTRIB_NORMAL] );
302 COPY_4FV( texcoord, ctx->Current.Attrib[VERT_ATTRIB_TEX0] );
303 COPY_4FV( color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
304 index = ctx->Current.Index;
305
306 do_EvalCoord2f( ctx, u, v );
307
308 COPY_3FV( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], normal );
309 COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_TEX0], texcoord );
310 COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color );
311 ctx->Current.Index = index;
312 }
313
314 void _mesa_EvalCoord1fv( const GLfloat *u )
315 {
316 glEvalCoord1f( u[0] );
317 }
318
319 void _mesa_EvalCoord2fv( const GLfloat *u )
320 {
321 glEvalCoord2f( u[0], u[1] );
322 }