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