Merge commit 'origin/gallium-0.1'
[mesa.git] / src / mesa / main / texgen.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2008 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
25 /**
26 * \file texgen.c
27 *
28 * glTexGen-related functions
29 */
30
31
32 #include "main/glheader.h"
33 #include "main/context.h"
34 #include "main/enums.h"
35 #include "main/macros.h"
36 #include "main/texgen.h"
37 #include "math/m_matrix.h"
38
39
40
41 void GLAPIENTRY
42 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
43 {
44 GET_CURRENT_CONTEXT(ctx);
45 struct gl_texture_unit *texUnit;
46 ASSERT_OUTSIDE_BEGIN_END(ctx);
47
48 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
49 _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
50 _mesa_lookup_enum_by_nr(coord),
51 _mesa_lookup_enum_by_nr(pname),
52 *params,
53 _mesa_lookup_enum_by_nr((GLenum) (GLint) *params));
54
55 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
56 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
57 return;
58 }
59
60 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
61
62 switch (coord) {
63 case GL_S:
64 if (pname==GL_TEXTURE_GEN_MODE) {
65 GLenum mode = (GLenum) (GLint) *params;
66 GLbitfield bits;
67 switch (mode) {
68 case GL_OBJECT_LINEAR:
69 bits = TEXGEN_OBJ_LINEAR;
70 break;
71 case GL_EYE_LINEAR:
72 bits = TEXGEN_EYE_LINEAR;
73 break;
74 case GL_REFLECTION_MAP_NV:
75 bits = TEXGEN_REFLECTION_MAP_NV;
76 break;
77 case GL_NORMAL_MAP_NV:
78 bits = TEXGEN_NORMAL_MAP_NV;
79 break;
80 case GL_SPHERE_MAP:
81 bits = TEXGEN_SPHERE_MAP;
82 break;
83 default:
84 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
85 return;
86 }
87 if (texUnit->GenModeS == mode)
88 return;
89 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
90 texUnit->GenModeS = mode;
91 texUnit->_GenBitS = bits;
92 }
93 else if (pname==GL_OBJECT_PLANE) {
94 if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
95 return;
96 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
97 COPY_4FV(texUnit->ObjectPlaneS, params);
98 }
99 else if (pname==GL_EYE_PLANE) {
100 GLfloat tmp[4];
101 /* Transform plane equation by the inverse modelview matrix */
102 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
103 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
104 }
105 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
106 if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
107 return;
108 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
109 COPY_4FV(texUnit->EyePlaneS, tmp);
110 }
111 else {
112 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
113 return;
114 }
115 break;
116 case GL_T:
117 if (pname==GL_TEXTURE_GEN_MODE) {
118 GLenum mode = (GLenum) (GLint) *params;
119 GLbitfield bitt;
120 switch (mode) {
121 case GL_OBJECT_LINEAR:
122 bitt = TEXGEN_OBJ_LINEAR;
123 break;
124 case GL_EYE_LINEAR:
125 bitt = TEXGEN_EYE_LINEAR;
126 break;
127 case GL_REFLECTION_MAP_NV:
128 bitt = TEXGEN_REFLECTION_MAP_NV;
129 break;
130 case GL_NORMAL_MAP_NV:
131 bitt = TEXGEN_NORMAL_MAP_NV;
132 break;
133 case GL_SPHERE_MAP:
134 bitt = TEXGEN_SPHERE_MAP;
135 break;
136 default:
137 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
138 return;
139 }
140 if (texUnit->GenModeT == mode)
141 return;
142 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
143 texUnit->GenModeT = mode;
144 texUnit->_GenBitT = bitt;
145 }
146 else if (pname==GL_OBJECT_PLANE) {
147 if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
148 return;
149 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
150 COPY_4FV(texUnit->ObjectPlaneT, params);
151 }
152 else if (pname==GL_EYE_PLANE) {
153 GLfloat tmp[4];
154 /* Transform plane equation by the inverse modelview matrix */
155 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
156 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
157 }
158 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
159 if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
160 return;
161 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
162 COPY_4FV(texUnit->EyePlaneT, tmp);
163 }
164 else {
165 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
166 return;
167 }
168 break;
169 case GL_R:
170 if (pname==GL_TEXTURE_GEN_MODE) {
171 GLenum mode = (GLenum) (GLint) *params;
172 GLbitfield bitr;
173 switch (mode) {
174 case GL_OBJECT_LINEAR:
175 bitr = TEXGEN_OBJ_LINEAR;
176 break;
177 case GL_REFLECTION_MAP_NV:
178 bitr = TEXGEN_REFLECTION_MAP_NV;
179 break;
180 case GL_NORMAL_MAP_NV:
181 bitr = TEXGEN_NORMAL_MAP_NV;
182 break;
183 case GL_EYE_LINEAR:
184 bitr = TEXGEN_EYE_LINEAR;
185 break;
186 default:
187 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
188 return;
189 }
190 if (texUnit->GenModeR == mode)
191 return;
192 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
193 texUnit->GenModeR = mode;
194 texUnit->_GenBitR = bitr;
195 }
196 else if (pname==GL_OBJECT_PLANE) {
197 if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
198 return;
199 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
200 COPY_4FV(texUnit->ObjectPlaneR, params);
201 }
202 else if (pname==GL_EYE_PLANE) {
203 GLfloat tmp[4];
204 /* Transform plane equation by the inverse modelview matrix */
205 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
206 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
207 }
208 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
209 if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
210 return;
211 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
212 COPY_4FV(texUnit->EyePlaneR, tmp);
213 }
214 else {
215 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
216 return;
217 }
218 break;
219 case GL_Q:
220 if (pname==GL_TEXTURE_GEN_MODE) {
221 GLenum mode = (GLenum) (GLint) *params;
222 GLbitfield bitq;
223 switch (mode) {
224 case GL_OBJECT_LINEAR:
225 bitq = TEXGEN_OBJ_LINEAR;
226 break;
227 case GL_EYE_LINEAR:
228 bitq = TEXGEN_EYE_LINEAR;
229 break;
230 default:
231 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
232 return;
233 }
234 if (texUnit->GenModeQ == mode)
235 return;
236 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
237 texUnit->GenModeQ = mode;
238 texUnit->_GenBitQ = bitq;
239 }
240 else if (pname==GL_OBJECT_PLANE) {
241 if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
242 return;
243 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
244 COPY_4FV(texUnit->ObjectPlaneQ, params);
245 }
246 else if (pname==GL_EYE_PLANE) {
247 GLfloat tmp[4];
248 /* Transform plane equation by the inverse modelview matrix */
249 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
250 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
251 }
252 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
253 if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
254 return;
255 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
256 COPY_4FV(texUnit->EyePlaneQ, tmp);
257 }
258 else {
259 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
260 return;
261 }
262 break;
263 default:
264 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
265 return;
266 }
267
268 if (ctx->Driver.TexGen)
269 ctx->Driver.TexGen( ctx, coord, pname, params );
270 }
271
272
273 void GLAPIENTRY
274 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
275 {
276 GLfloat p[4];
277 p[0] = (GLfloat) params[0];
278 if (pname == GL_TEXTURE_GEN_MODE) {
279 p[1] = p[2] = p[3] = 0.0F;
280 }
281 else {
282 p[1] = (GLfloat) params[1];
283 p[2] = (GLfloat) params[2];
284 p[3] = (GLfloat) params[3];
285 }
286 _mesa_TexGenfv(coord, pname, p);
287 }
288
289
290 void GLAPIENTRY
291 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
292 {
293 GLfloat p = (GLfloat) param;
294 _mesa_TexGenfv( coord, pname, &p );
295 }
296
297
298 void GLAPIENTRY
299 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
300 {
301 GLfloat p[4];
302 p[0] = (GLfloat) params[0];
303 if (pname == GL_TEXTURE_GEN_MODE) {
304 p[1] = p[2] = p[3] = 0.0F;
305 }
306 else {
307 p[1] = (GLfloat) params[1];
308 p[2] = (GLfloat) params[2];
309 p[3] = (GLfloat) params[3];
310 }
311 _mesa_TexGenfv( coord, pname, p );
312 }
313
314
315 void GLAPIENTRY
316 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
317 {
318 _mesa_TexGenfv(coord, pname, &param);
319 }
320
321
322 void GLAPIENTRY
323 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
324 {
325 _mesa_TexGeniv( coord, pname, &param );
326 }
327
328
329
330 void GLAPIENTRY
331 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
332 {
333 const struct gl_texture_unit *texUnit;
334 GET_CURRENT_CONTEXT(ctx);
335 ASSERT_OUTSIDE_BEGIN_END(ctx);
336
337 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
338 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)");
339 return;
340 }
341
342 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
343
344 switch (coord) {
345 case GL_S:
346 if (pname==GL_TEXTURE_GEN_MODE) {
347 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
348 }
349 else if (pname==GL_OBJECT_PLANE) {
350 COPY_4V( params, texUnit->ObjectPlaneS );
351 }
352 else if (pname==GL_EYE_PLANE) {
353 COPY_4V( params, texUnit->EyePlaneS );
354 }
355 else {
356 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
357 return;
358 }
359 break;
360 case GL_T:
361 if (pname==GL_TEXTURE_GEN_MODE) {
362 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
363 }
364 else if (pname==GL_OBJECT_PLANE) {
365 COPY_4V( params, texUnit->ObjectPlaneT );
366 }
367 else if (pname==GL_EYE_PLANE) {
368 COPY_4V( params, texUnit->EyePlaneT );
369 }
370 else {
371 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
372 return;
373 }
374 break;
375 case GL_R:
376 if (pname==GL_TEXTURE_GEN_MODE) {
377 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
378 }
379 else if (pname==GL_OBJECT_PLANE) {
380 COPY_4V( params, texUnit->ObjectPlaneR );
381 }
382 else if (pname==GL_EYE_PLANE) {
383 COPY_4V( params, texUnit->EyePlaneR );
384 }
385 else {
386 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
387 return;
388 }
389 break;
390 case GL_Q:
391 if (pname==GL_TEXTURE_GEN_MODE) {
392 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
393 }
394 else if (pname==GL_OBJECT_PLANE) {
395 COPY_4V( params, texUnit->ObjectPlaneQ );
396 }
397 else if (pname==GL_EYE_PLANE) {
398 COPY_4V( params, texUnit->EyePlaneQ );
399 }
400 else {
401 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
402 return;
403 }
404 break;
405 default:
406 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
407 return;
408 }
409 }
410
411
412
413 void GLAPIENTRY
414 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
415 {
416 const struct gl_texture_unit *texUnit;
417 GET_CURRENT_CONTEXT(ctx);
418 ASSERT_OUTSIDE_BEGIN_END(ctx);
419
420 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
421 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)");
422 return;
423 }
424
425 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
426
427 switch (coord) {
428 case GL_S:
429 if (pname==GL_TEXTURE_GEN_MODE) {
430 params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
431 }
432 else if (pname==GL_OBJECT_PLANE) {
433 COPY_4V( params, texUnit->ObjectPlaneS );
434 }
435 else if (pname==GL_EYE_PLANE) {
436 COPY_4V( params, texUnit->EyePlaneS );
437 }
438 else {
439 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
440 return;
441 }
442 break;
443 case GL_T:
444 if (pname==GL_TEXTURE_GEN_MODE) {
445 params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
446 }
447 else if (pname==GL_OBJECT_PLANE) {
448 COPY_4V( params, texUnit->ObjectPlaneT );
449 }
450 else if (pname==GL_EYE_PLANE) {
451 COPY_4V( params, texUnit->EyePlaneT );
452 }
453 else {
454 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
455 return;
456 }
457 break;
458 case GL_R:
459 if (pname==GL_TEXTURE_GEN_MODE) {
460 params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
461 }
462 else if (pname==GL_OBJECT_PLANE) {
463 COPY_4V( params, texUnit->ObjectPlaneR );
464 }
465 else if (pname==GL_EYE_PLANE) {
466 COPY_4V( params, texUnit->EyePlaneR );
467 }
468 else {
469 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
470 return;
471 }
472 break;
473 case GL_Q:
474 if (pname==GL_TEXTURE_GEN_MODE) {
475 params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
476 }
477 else if (pname==GL_OBJECT_PLANE) {
478 COPY_4V( params, texUnit->ObjectPlaneQ );
479 }
480 else if (pname==GL_EYE_PLANE) {
481 COPY_4V( params, texUnit->EyePlaneQ );
482 }
483 else {
484 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
485 return;
486 }
487 break;
488 default:
489 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
490 return;
491 }
492 }
493
494
495
496 void GLAPIENTRY
497 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
498 {
499 const struct gl_texture_unit *texUnit;
500 GET_CURRENT_CONTEXT(ctx);
501 ASSERT_OUTSIDE_BEGIN_END(ctx);
502
503 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
504 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)");
505 return;
506 }
507
508 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
509
510 switch (coord) {
511 case GL_S:
512 if (pname==GL_TEXTURE_GEN_MODE) {
513 params[0] = texUnit->GenModeS;
514 }
515 else if (pname==GL_OBJECT_PLANE) {
516 params[0] = (GLint) texUnit->ObjectPlaneS[0];
517 params[1] = (GLint) texUnit->ObjectPlaneS[1];
518 params[2] = (GLint) texUnit->ObjectPlaneS[2];
519 params[3] = (GLint) texUnit->ObjectPlaneS[3];
520 }
521 else if (pname==GL_EYE_PLANE) {
522 params[0] = (GLint) texUnit->EyePlaneS[0];
523 params[1] = (GLint) texUnit->EyePlaneS[1];
524 params[2] = (GLint) texUnit->EyePlaneS[2];
525 params[3] = (GLint) texUnit->EyePlaneS[3];
526 }
527 else {
528 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
529 return;
530 }
531 break;
532 case GL_T:
533 if (pname==GL_TEXTURE_GEN_MODE) {
534 params[0] = texUnit->GenModeT;
535 }
536 else if (pname==GL_OBJECT_PLANE) {
537 params[0] = (GLint) texUnit->ObjectPlaneT[0];
538 params[1] = (GLint) texUnit->ObjectPlaneT[1];
539 params[2] = (GLint) texUnit->ObjectPlaneT[2];
540 params[3] = (GLint) texUnit->ObjectPlaneT[3];
541 }
542 else if (pname==GL_EYE_PLANE) {
543 params[0] = (GLint) texUnit->EyePlaneT[0];
544 params[1] = (GLint) texUnit->EyePlaneT[1];
545 params[2] = (GLint) texUnit->EyePlaneT[2];
546 params[3] = (GLint) texUnit->EyePlaneT[3];
547 }
548 else {
549 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
550 return;
551 }
552 break;
553 case GL_R:
554 if (pname==GL_TEXTURE_GEN_MODE) {
555 params[0] = texUnit->GenModeR;
556 }
557 else if (pname==GL_OBJECT_PLANE) {
558 params[0] = (GLint) texUnit->ObjectPlaneR[0];
559 params[1] = (GLint) texUnit->ObjectPlaneR[1];
560 params[2] = (GLint) texUnit->ObjectPlaneR[2];
561 params[3] = (GLint) texUnit->ObjectPlaneR[3];
562 }
563 else if (pname==GL_EYE_PLANE) {
564 params[0] = (GLint) texUnit->EyePlaneR[0];
565 params[1] = (GLint) texUnit->EyePlaneR[1];
566 params[2] = (GLint) texUnit->EyePlaneR[2];
567 params[3] = (GLint) texUnit->EyePlaneR[3];
568 }
569 else {
570 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
571 return;
572 }
573 break;
574 case GL_Q:
575 if (pname==GL_TEXTURE_GEN_MODE) {
576 params[0] = texUnit->GenModeQ;
577 }
578 else if (pname==GL_OBJECT_PLANE) {
579 params[0] = (GLint) texUnit->ObjectPlaneQ[0];
580 params[1] = (GLint) texUnit->ObjectPlaneQ[1];
581 params[2] = (GLint) texUnit->ObjectPlaneQ[2];
582 params[3] = (GLint) texUnit->ObjectPlaneQ[3];
583 }
584 else if (pname==GL_EYE_PLANE) {
585 params[0] = (GLint) texUnit->EyePlaneQ[0];
586 params[1] = (GLint) texUnit->EyePlaneQ[1];
587 params[2] = (GLint) texUnit->EyePlaneQ[2];
588 params[3] = (GLint) texUnit->EyePlaneQ[3];
589 }
590 else {
591 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
592 return;
593 }
594 break;
595 default:
596 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
597 return;
598 }
599 }
600
601