fix for GL_COMPILE_AND_EXECUTE bug
[mesa.git] / src / mesa / main / texstate.c
1 /* $Id: texstate.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28
29 #ifdef PC_HEADER
30 #include "all.h"
31 #else
32 #include <assert.h>
33 #include <stdio.h>
34 #include "context.h"
35 #include "enums.h"
36 #include "macros.h"
37 #include "matrix.h"
38 #include "texobj.h"
39 #include "texstate.h"
40 #include "texture.h"
41 #include "types.h"
42 #include "xform.h"
43 #ifdef XFree86Server
44 #include "GL/xf86glx.h"
45 #endif
46 #endif
47
48
49
50 #ifdef SPECIALCAST
51 /* Needed for an Amiga compiler */
52 #define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
53 #define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
54 #else
55 /* all other compilers */
56 #define ENUM_TO_FLOAT(X) ((GLfloat)(X))
57 #define ENUM_TO_DOUBLE(X) ((GLdouble)(X))
58 #endif
59
60
61
62
63 /**********************************************************************/
64 /* Texture Environment */
65 /**********************************************************************/
66
67
68 void gl_TexEnvfv( GLcontext *ctx,
69 GLenum target, GLenum pname, const GLfloat *param )
70 {
71 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
72
73 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexEnv");
74
75 if (target!=GL_TEXTURE_ENV) {
76 gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(target)" );
77 return;
78 }
79
80 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
81 fprintf(stderr, "glTexEnv %s %s %.1f(%s) ...\n",
82 gl_lookup_enum_by_nr(target),
83 gl_lookup_enum_by_nr(pname),
84 *param,
85 gl_lookup_enum_by_nr((GLenum) (GLint) *param));
86
87
88 if (pname==GL_TEXTURE_ENV_MODE) {
89 GLenum mode = (GLenum) (GLint) *param;
90 switch (mode) {
91 case GL_MODULATE:
92 case GL_BLEND:
93 case GL_DECAL:
94 case GL_REPLACE:
95 /* A small optimization for drivers */
96 if (texUnit->EnvMode == mode)
97 return;
98
99 if (MESA_VERBOSE & (VERBOSE_STATE|VERBOSE_TEXTURE))
100 fprintf(stderr, "glTexEnv: old mode %s, new mode %s\n",
101 gl_lookup_enum_by_nr(texUnit->EnvMode),
102 gl_lookup_enum_by_nr(mode));
103
104 texUnit->EnvMode = mode;
105 ctx->NewState |= NEW_TEXTURE_ENV;
106 break;
107 default:
108 gl_error( ctx, GL_INVALID_VALUE, "glTexEnv(param)" );
109 return;
110 }
111 }
112 else if (pname==GL_TEXTURE_ENV_COLOR) {
113 texUnit->EnvColor[0] = CLAMP( param[0], 0.0, 1.0 );
114 texUnit->EnvColor[1] = CLAMP( param[1], 0.0, 1.0 );
115 texUnit->EnvColor[2] = CLAMP( param[2], 0.0, 1.0 );
116 texUnit->EnvColor[3] = CLAMP( param[3], 0.0, 1.0 );
117 }
118 else {
119 gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
120 return;
121 }
122
123 /* Tell device driver about the new texture environment */
124 if (ctx->Driver.TexEnv) {
125 (*ctx->Driver.TexEnv)( ctx, pname, param );
126 }
127 }
128
129
130
131
132
133 void gl_GetTexEnvfv( GLcontext *ctx,
134 GLenum target, GLenum pname, GLfloat *params )
135 {
136 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
137 if (target!=GL_TEXTURE_ENV) {
138 gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
139 return;
140 }
141 switch (pname) {
142 case GL_TEXTURE_ENV_MODE:
143 *params = ENUM_TO_FLOAT(texUnit->EnvMode);
144 break;
145 case GL_TEXTURE_ENV_COLOR:
146 COPY_4FV( params, texUnit->EnvColor );
147 break;
148 default:
149 gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
150 }
151 }
152
153
154 void gl_GetTexEnviv( GLcontext *ctx,
155 GLenum target, GLenum pname, GLint *params )
156 {
157 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
158 if (target!=GL_TEXTURE_ENV) {
159 gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
160 return;
161 }
162 switch (pname) {
163 case GL_TEXTURE_ENV_MODE:
164 *params = (GLint) texUnit->EnvMode;
165 break;
166 case GL_TEXTURE_ENV_COLOR:
167 params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
168 params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
169 params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
170 params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
171 break;
172 default:
173 gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
174 }
175 }
176
177
178
179
180 /**********************************************************************/
181 /* Texture Parameters */
182 /**********************************************************************/
183
184
185 void gl_TexParameterfv( GLcontext *ctx,
186 GLenum target, GLenum pname, const GLfloat *params )
187 {
188 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
189 GLenum eparam = (GLenum) (GLint) params[0];
190 struct gl_texture_object *texObj;
191
192 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
193 fprintf(stderr, "texPARAM %s %s %d...\n",
194 gl_lookup_enum_by_nr(target),
195 gl_lookup_enum_by_nr(pname),
196 eparam);
197
198
199 switch (target) {
200 case GL_TEXTURE_1D:
201 texObj = texUnit->CurrentD[1];
202 break;
203 case GL_TEXTURE_2D:
204 texObj = texUnit->CurrentD[2];
205 break;
206 case GL_TEXTURE_3D_EXT:
207 texObj = texUnit->CurrentD[3];
208 break;
209 default:
210 gl_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
211 return;
212 }
213
214 switch (pname) {
215 case GL_TEXTURE_MIN_FILTER:
216 /* A small optimization */
217 if (texObj->MinFilter == eparam)
218 return;
219
220 if (eparam==GL_NEAREST || eparam==GL_LINEAR
221 || eparam==GL_NEAREST_MIPMAP_NEAREST
222 || eparam==GL_LINEAR_MIPMAP_NEAREST
223 || eparam==GL_NEAREST_MIPMAP_LINEAR
224 || eparam==GL_LINEAR_MIPMAP_LINEAR) {
225 texObj->MinFilter = eparam;
226 ctx->NewState |= NEW_TEXTURING;
227 }
228 else {
229 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
230 return;
231 }
232 break;
233 case GL_TEXTURE_MAG_FILTER:
234 /* A small optimization */
235 if (texObj->MagFilter == eparam)
236 return;
237
238 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
239 texObj->MagFilter = eparam;
240 ctx->NewState |= NEW_TEXTURING;
241 }
242 else {
243 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
244 return;
245 }
246 break;
247 case GL_TEXTURE_WRAP_S:
248 if (texObj->WrapS == eparam)
249 return;
250
251 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
252 texObj->WrapS = eparam;
253 ctx->NewState |= NEW_TEXTURING;
254 }
255 else {
256 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
257 return;
258 }
259 break;
260 case GL_TEXTURE_WRAP_T:
261 if (texObj->WrapT == eparam)
262 return;
263
264 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
265 texObj->WrapT = eparam;
266 ctx->NewState |= NEW_TEXTURING;
267 }
268 else {
269 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
270 return;
271 }
272 break;
273 case GL_TEXTURE_WRAP_R_EXT:
274 if (texObj->WrapR == eparam)
275 return;
276
277 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
278 texObj->WrapR = eparam;
279 ctx->NewState |= NEW_TEXTURING;
280 }
281 else {
282 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
283 }
284 break;
285 case GL_TEXTURE_BORDER_COLOR:
286 texObj->BorderColor[0] = CLAMP((GLint)(params[0]*255.0), 0, 255);
287 texObj->BorderColor[1] = CLAMP((GLint)(params[1]*255.0), 0, 255);
288 texObj->BorderColor[2] = CLAMP((GLint)(params[2]*255.0), 0, 255);
289 texObj->BorderColor[3] = CLAMP((GLint)(params[3]*255.0), 0, 255);
290 break;
291 case GL_TEXTURE_MIN_LOD:
292 texObj->MinLod = params[0];
293 ctx->NewState |= NEW_TEXTURING;
294 break;
295 case GL_TEXTURE_MAX_LOD:
296 texObj->MaxLod = params[0];
297 ctx->NewState |= NEW_TEXTURING;
298 break;
299 case GL_TEXTURE_BASE_LEVEL:
300 if (params[0] < 0.0) {
301 gl_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
302 return;
303 }
304 texObj->BaseLevel = (GLint) params[0];
305 ctx->NewState |= NEW_TEXTURING;
306 break;
307 case GL_TEXTURE_MAX_LEVEL:
308 if (params[0] < 0.0) {
309 gl_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
310 return;
311 }
312 texObj->MaxLevel = (GLint) params[0];
313 ctx->NewState |= NEW_TEXTURING;
314 break;
315 case GL_TEXTURE_PRIORITY:
316 /* (keithh@netcomuk.co.uk) */
317 texObj->Priority = CLAMP( params[0], 0.0, 1.0 );
318 break;
319 default:
320 gl_error( ctx, GL_INVALID_ENUM, "glTexParameter(pname)" );
321 return;
322 }
323
324 gl_put_texobj_on_dirty_list( ctx, texObj );
325
326 if (ctx->Driver.TexParameter) {
327 (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
328 }
329 }
330
331
332
333 void gl_GetTexLevelParameterfv( GLcontext *ctx, GLenum target, GLint level,
334 GLenum pname, GLfloat *params )
335 {
336 GLint iparam;
337 gl_GetTexLevelParameteriv( ctx, target, level, pname, &iparam );
338 *params = (GLfloat) iparam;
339 }
340
341
342
343 void gl_GetTexLevelParameteriv( GLcontext *ctx, GLenum target, GLint level,
344 GLenum pname, GLint *params )
345 {
346 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
347 const struct gl_texture_image *img = NULL;
348 GLuint dimensions;
349
350 if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
351 gl_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
352 return;
353 }
354
355 switch (target) {
356 case GL_TEXTURE_1D:
357 img = texUnit->CurrentD[1]->Image[level];
358 dimensions = 1;
359 break;
360 case GL_TEXTURE_2D:
361 img = texUnit->CurrentD[2]->Image[level];
362 dimensions = 2;
363 break;
364 case GL_TEXTURE_3D:
365 img = texUnit->CurrentD[3]->Image[level];
366 dimensions = 3;
367 break;
368 case GL_PROXY_TEXTURE_1D:
369 img = ctx->Texture.Proxy1D->Image[level];
370 dimensions = 1;
371 break;
372 case GL_PROXY_TEXTURE_2D:
373 img = ctx->Texture.Proxy2D->Image[level];
374 dimensions = 2;
375 break;
376 case GL_PROXY_TEXTURE_3D:
377 img = ctx->Texture.Proxy3D->Image[level];
378 dimensions = 3;
379 break;
380 default:
381 gl_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
382 return;
383 }
384
385 if (!img) {
386 if (pname == GL_TEXTURE_COMPONENTS)
387 *params = 1;
388 else
389 *params = 0;
390 return;
391 }
392
393 switch (pname) {
394 case GL_TEXTURE_WIDTH:
395 *params = img->Width;
396 return;
397 case GL_TEXTURE_HEIGHT:
398 if (dimensions > 1) {
399 *params = img->Height;
400 }
401 else {
402 gl_error( ctx, GL_INVALID_ENUM,
403 "glGetTexLevelParameter[if]v(pname=GL_TEXTURE_HEIGHT)" );
404 }
405 return;
406 case GL_TEXTURE_DEPTH:
407 if (dimensions > 2) {
408 *params = img->Depth;
409 }
410 else {
411 gl_error( ctx, GL_INVALID_ENUM,
412 "glGetTexLevelParameter[if]v(pname=GL_TEXTURE_DEPTH)" );
413 }
414 return;
415 case GL_TEXTURE_COMPONENTS:
416 *params = img->IntFormat;
417 return;
418 case GL_TEXTURE_BORDER:
419 *params = img->Border;
420 return;
421 case GL_TEXTURE_RED_SIZE:
422 *params = img->RedBits;
423 return;
424 case GL_TEXTURE_GREEN_SIZE:
425 *params = img->GreenBits;
426 return;
427 case GL_TEXTURE_BLUE_SIZE:
428 *params = img->BlueBits;
429 return;
430 case GL_TEXTURE_ALPHA_SIZE:
431 *params = img->AlphaBits;
432 return;
433 case GL_TEXTURE_INTENSITY_SIZE:
434 *params = img->IntensityBits;
435 return;
436 case GL_TEXTURE_LUMINANCE_SIZE:
437 *params = img->LuminanceBits;
438 return;
439 case GL_TEXTURE_INDEX_SIZE_EXT:
440 *params = img->IndexBits;
441 return;
442 default:
443 gl_error( ctx, GL_INVALID_ENUM,
444 "glGetTexLevelParameter[if]v(pname)" );
445 }
446 }
447
448
449
450
451 void gl_GetTexParameterfv( GLcontext *ctx,
452 GLenum target, GLenum pname, GLfloat *params )
453 {
454 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
455 struct gl_texture_object *obj;
456
457 switch (target) {
458 case GL_TEXTURE_1D:
459 obj = texUnit->CurrentD[1];
460 break;
461 case GL_TEXTURE_2D:
462 obj = texUnit->CurrentD[2];
463 break;
464 case GL_TEXTURE_3D_EXT:
465 obj = texUnit->CurrentD[3];
466 break;
467 default:
468 gl_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
469 return;
470 }
471
472 switch (pname) {
473 case GL_TEXTURE_MAG_FILTER:
474 *params = ENUM_TO_FLOAT(obj->MagFilter);
475 break;
476 case GL_TEXTURE_MIN_FILTER:
477 *params = ENUM_TO_FLOAT(obj->MinFilter);
478 break;
479 case GL_TEXTURE_WRAP_S:
480 *params = ENUM_TO_FLOAT(obj->WrapS);
481 break;
482 case GL_TEXTURE_WRAP_T:
483 *params = ENUM_TO_FLOAT(obj->WrapT);
484 break;
485 case GL_TEXTURE_WRAP_R_EXT:
486 *params = ENUM_TO_FLOAT(obj->WrapR);
487 break;
488 case GL_TEXTURE_BORDER_COLOR:
489 params[0] = obj->BorderColor[0] / 255.0F;
490 params[1] = obj->BorderColor[1] / 255.0F;
491 params[2] = obj->BorderColor[2] / 255.0F;
492 params[3] = obj->BorderColor[3] / 255.0F;
493 break;
494 case GL_TEXTURE_RESIDENT:
495 *params = ENUM_TO_FLOAT(GL_TRUE);
496 break;
497 case GL_TEXTURE_PRIORITY:
498 *params = obj->Priority;
499 break;
500 case GL_TEXTURE_MIN_LOD:
501 *params = obj->MinLod;
502 break;
503 case GL_TEXTURE_MAX_LOD:
504 *params = obj->MaxLod;
505 break;
506 case GL_TEXTURE_BASE_LEVEL:
507 *params = obj->BaseLevel;
508 break;
509 case GL_TEXTURE_MAX_LEVEL:
510 *params = obj->MaxLevel;
511 break;
512 default:
513 gl_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
514 }
515 }
516
517
518 void gl_GetTexParameteriv( GLcontext *ctx,
519 GLenum target, GLenum pname, GLint *params )
520 {
521 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
522 struct gl_texture_object *obj;
523
524 switch (target) {
525 case GL_TEXTURE_1D:
526 obj = texUnit->CurrentD[1];
527 break;
528 case GL_TEXTURE_2D:
529 obj = texUnit->CurrentD[2];
530 break;
531 case GL_TEXTURE_3D_EXT:
532 obj = texUnit->CurrentD[3];
533 break;
534 default:
535 gl_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
536 return;
537 }
538
539 switch (pname) {
540 case GL_TEXTURE_MAG_FILTER:
541 *params = (GLint) obj->MagFilter;
542 break;
543 case GL_TEXTURE_MIN_FILTER:
544 *params = (GLint) obj->MinFilter;
545 break;
546 case GL_TEXTURE_WRAP_S:
547 *params = (GLint) obj->WrapS;
548 break;
549 case GL_TEXTURE_WRAP_T:
550 *params = (GLint) obj->WrapT;
551 break;
552 case GL_TEXTURE_WRAP_R_EXT:
553 *params = (GLint) obj->WrapR;
554 break;
555 case GL_TEXTURE_BORDER_COLOR:
556 {
557 GLfloat color[4];
558 color[0] = obj->BorderColor[0]/255.0;
559 color[1] = obj->BorderColor[1]/255.0;
560 color[2] = obj->BorderColor[2]/255.0;
561 color[3] = obj->BorderColor[3]/255.0;
562 params[0] = FLOAT_TO_INT( color[0] );
563 params[1] = FLOAT_TO_INT( color[1] );
564 params[2] = FLOAT_TO_INT( color[2] );
565 params[3] = FLOAT_TO_INT( color[3] );
566 }
567 break;
568 case GL_TEXTURE_RESIDENT:
569 *params = (GLint) GL_TRUE;
570 break;
571 case GL_TEXTURE_PRIORITY:
572 *params = (GLint) obj->Priority;
573 break;
574 case GL_TEXTURE_MIN_LOD:
575 *params = (GLint) obj->MinLod;
576 break;
577 case GL_TEXTURE_MAX_LOD:
578 *params = (GLint) obj->MaxLod;
579 break;
580 case GL_TEXTURE_BASE_LEVEL:
581 *params = obj->BaseLevel;
582 break;
583 case GL_TEXTURE_MAX_LEVEL:
584 *params = obj->MaxLevel;
585 break;
586 default:
587 gl_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
588 }
589 }
590
591
592
593
594 /**********************************************************************/
595 /* Texture Coord Generation */
596 /**********************************************************************/
597
598
599 void gl_TexGenfv( GLcontext *ctx,
600 GLenum coord, GLenum pname, const GLfloat *params )
601 {
602 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
603 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
604 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexGenfv");
605
606 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
607 fprintf(stderr, "texGEN %s %s %x...\n",
608 gl_lookup_enum_by_nr(coord),
609 gl_lookup_enum_by_nr(pname),
610 *(int *)params);
611
612 switch( coord ) {
613 case GL_S:
614 if (pname==GL_TEXTURE_GEN_MODE) {
615 GLenum mode = (GLenum) (GLint) *params;
616 switch (mode) {
617 case GL_OBJECT_LINEAR:
618 texUnit->GenModeS = mode;
619 texUnit->GenBitS = TEXGEN_OBJ_LINEAR;
620 break;
621 case GL_EYE_LINEAR:
622 texUnit->GenModeS = mode;
623 texUnit->GenBitS = TEXGEN_EYE_LINEAR;
624 break;
625 case GL_REFLECTION_MAP_NV:
626 texUnit->GenModeS = mode;
627 texUnit->GenBitS = TEXGEN_REFLECTION_MAP_NV;
628 break;
629 case GL_NORMAL_MAP_NV:
630 texUnit->GenModeS = mode;
631 texUnit->GenBitS = TEXGEN_NORMAL_MAP_NV;
632 break;
633 case GL_SPHERE_MAP:
634 texUnit->GenModeS = mode;
635 texUnit->GenBitS = TEXGEN_SPHERE_MAP;
636 break;
637 default:
638 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
639 return;
640 }
641 }
642 else if (pname==GL_OBJECT_PLANE) {
643 texUnit->ObjectPlaneS[0] = params[0];
644 texUnit->ObjectPlaneS[1] = params[1];
645 texUnit->ObjectPlaneS[2] = params[2];
646 texUnit->ObjectPlaneS[3] = params[3];
647 }
648 else if (pname==GL_EYE_PLANE) {
649 /* Transform plane equation by the inverse modelview matrix */
650 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
651 gl_matrix_analyze( &ctx->ModelView );
652 }
653 gl_transform_vector( texUnit->EyePlaneS, params,
654 ctx->ModelView.inv );
655 }
656 else {
657 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
658 return;
659 }
660 break;
661 case GL_T:
662 if (pname==GL_TEXTURE_GEN_MODE) {
663 GLenum mode = (GLenum) (GLint) *params;
664 switch(mode) {
665 case GL_OBJECT_LINEAR:
666 texUnit->GenModeT = GL_OBJECT_LINEAR;
667 texUnit->GenBitT = TEXGEN_OBJ_LINEAR;
668 break;
669 case GL_EYE_LINEAR:
670 texUnit->GenModeT = GL_EYE_LINEAR;
671 texUnit->GenBitT = TEXGEN_EYE_LINEAR;
672 break;
673 case GL_REFLECTION_MAP_NV:
674 texUnit->GenModeT = GL_REFLECTION_MAP_NV;
675 texUnit->GenBitT = TEXGEN_REFLECTION_MAP_NV;
676 break;
677 case GL_NORMAL_MAP_NV:
678 texUnit->GenModeT = GL_NORMAL_MAP_NV;
679 texUnit->GenBitT = TEXGEN_NORMAL_MAP_NV;
680 break;
681 case GL_SPHERE_MAP:
682 texUnit->GenModeT = GL_SPHERE_MAP;
683 texUnit->GenBitT = TEXGEN_SPHERE_MAP;
684 break;
685 default:
686 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
687 return;
688 }
689 }
690 else if (pname==GL_OBJECT_PLANE) {
691 texUnit->ObjectPlaneT[0] = params[0];
692 texUnit->ObjectPlaneT[1] = params[1];
693 texUnit->ObjectPlaneT[2] = params[2];
694 texUnit->ObjectPlaneT[3] = params[3];
695 }
696 else if (pname==GL_EYE_PLANE) {
697 /* Transform plane equation by the inverse modelview matrix */
698 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
699 gl_matrix_analyze( &ctx->ModelView );
700 }
701 gl_transform_vector( texUnit->EyePlaneT, params,
702 ctx->ModelView.inv );
703 }
704 else {
705 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
706 return;
707 }
708 break;
709 case GL_R:
710 if (pname==GL_TEXTURE_GEN_MODE) {
711 GLenum mode = (GLenum) (GLint) *params;
712 switch (mode) {
713 case GL_OBJECT_LINEAR:
714 texUnit->GenModeR = GL_OBJECT_LINEAR;
715 texUnit->GenBitR = TEXGEN_OBJ_LINEAR;
716 break;
717 case GL_REFLECTION_MAP_NV:
718 texUnit->GenModeR = GL_REFLECTION_MAP_NV;
719 texUnit->GenBitR = TEXGEN_REFLECTION_MAP_NV;
720 break;
721 case GL_NORMAL_MAP_NV:
722 texUnit->GenModeR = GL_NORMAL_MAP_NV;
723 texUnit->GenBitR = TEXGEN_NORMAL_MAP_NV;
724 break;
725 case GL_EYE_LINEAR:
726 texUnit->GenModeR = GL_EYE_LINEAR;
727 texUnit->GenBitR = TEXGEN_EYE_LINEAR;
728 break;
729 default:
730 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
731 return;
732 }
733 }
734 else if (pname==GL_OBJECT_PLANE) {
735 texUnit->ObjectPlaneR[0] = params[0];
736 texUnit->ObjectPlaneR[1] = params[1];
737 texUnit->ObjectPlaneR[2] = params[2];
738 texUnit->ObjectPlaneR[3] = params[3];
739 }
740 else if (pname==GL_EYE_PLANE) {
741 /* Transform plane equation by the inverse modelview matrix */
742 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
743 gl_matrix_analyze( &ctx->ModelView );
744 }
745 gl_transform_vector( texUnit->EyePlaneR, params,
746 ctx->ModelView.inv );
747 }
748 else {
749 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
750 return;
751 }
752 break;
753 case GL_Q:
754 if (pname==GL_TEXTURE_GEN_MODE) {
755 GLenum mode = (GLenum) (GLint) *params;
756 switch (mode) {
757 case GL_OBJECT_LINEAR:
758 texUnit->GenModeQ = GL_OBJECT_LINEAR;
759 texUnit->GenBitQ = TEXGEN_OBJ_LINEAR;
760 break;
761 case GL_EYE_LINEAR:
762 texUnit->GenModeQ = GL_EYE_LINEAR;
763 texUnit->GenBitQ = TEXGEN_EYE_LINEAR;
764 break;
765 default:
766 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
767 return;
768 }
769 }
770 else if (pname==GL_OBJECT_PLANE) {
771 texUnit->ObjectPlaneQ[0] = params[0];
772 texUnit->ObjectPlaneQ[1] = params[1];
773 texUnit->ObjectPlaneQ[2] = params[2];
774 texUnit->ObjectPlaneQ[3] = params[3];
775 }
776 else if (pname==GL_EYE_PLANE) {
777 /* Transform plane equation by the inverse modelview matrix */
778 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
779 gl_matrix_analyze( &ctx->ModelView );
780 }
781 gl_transform_vector( texUnit->EyePlaneQ, params,
782 ctx->ModelView.inv );
783 }
784 else {
785 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
786 return;
787 }
788 break;
789 default:
790 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
791 return;
792 }
793
794 ctx->NewState |= NEW_TEXTURING;
795 }
796
797
798
799 void gl_GetTexGendv( GLcontext *ctx,
800 GLenum coord, GLenum pname, GLdouble *params )
801 {
802 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
803 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
804
805 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGendv");
806
807 switch( coord ) {
808 case GL_S:
809 if (pname==GL_TEXTURE_GEN_MODE) {
810 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
811 }
812 else if (pname==GL_OBJECT_PLANE) {
813 COPY_4V( params, texUnit->ObjectPlaneS );
814 }
815 else if (pname==GL_EYE_PLANE) {
816 COPY_4V( params, texUnit->EyePlaneS );
817 }
818 else {
819 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
820 return;
821 }
822 break;
823 case GL_T:
824 if (pname==GL_TEXTURE_GEN_MODE) {
825 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
826 }
827 else if (pname==GL_OBJECT_PLANE) {
828 COPY_4V( params, texUnit->ObjectPlaneT );
829 }
830 else if (pname==GL_EYE_PLANE) {
831 COPY_4V( params, texUnit->EyePlaneT );
832 }
833 else {
834 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
835 return;
836 }
837 break;
838 case GL_R:
839 if (pname==GL_TEXTURE_GEN_MODE) {
840 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
841 }
842 else if (pname==GL_OBJECT_PLANE) {
843 COPY_4V( params, texUnit->ObjectPlaneR );
844 }
845 else if (pname==GL_EYE_PLANE) {
846 COPY_4V( params, texUnit->EyePlaneR );
847 }
848 else {
849 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
850 return;
851 }
852 break;
853 case GL_Q:
854 if (pname==GL_TEXTURE_GEN_MODE) {
855 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
856 }
857 else if (pname==GL_OBJECT_PLANE) {
858 COPY_4V( params, texUnit->ObjectPlaneQ );
859 }
860 else if (pname==GL_EYE_PLANE) {
861 COPY_4V( params, texUnit->EyePlaneQ );
862 }
863 else {
864 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
865 return;
866 }
867 break;
868 default:
869 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
870 return;
871 }
872 }
873
874
875
876 void gl_GetTexGenfv( GLcontext *ctx,
877 GLenum coord, GLenum pname, GLfloat *params )
878 {
879 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
880 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
881
882 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGenfv");
883
884 switch( coord ) {
885 case GL_S:
886 if (pname==GL_TEXTURE_GEN_MODE) {
887 params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
888 }
889 else if (pname==GL_OBJECT_PLANE) {
890 COPY_4V( params, texUnit->ObjectPlaneS );
891 }
892 else if (pname==GL_EYE_PLANE) {
893 COPY_4V( params, texUnit->EyePlaneS );
894 }
895 else {
896 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
897 return;
898 }
899 break;
900 case GL_T:
901 if (pname==GL_TEXTURE_GEN_MODE) {
902 params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
903 }
904 else if (pname==GL_OBJECT_PLANE) {
905 COPY_4V( params, texUnit->ObjectPlaneT );
906 }
907 else if (pname==GL_EYE_PLANE) {
908 COPY_4V( params, texUnit->EyePlaneT );
909 }
910 else {
911 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
912 return;
913 }
914 break;
915 case GL_R:
916 if (pname==GL_TEXTURE_GEN_MODE) {
917 params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
918 }
919 else if (pname==GL_OBJECT_PLANE) {
920 COPY_4V( params, texUnit->ObjectPlaneR );
921 }
922 else if (pname==GL_EYE_PLANE) {
923 COPY_4V( params, texUnit->EyePlaneR );
924 }
925 else {
926 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
927 return;
928 }
929 break;
930 case GL_Q:
931 if (pname==GL_TEXTURE_GEN_MODE) {
932 params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
933 }
934 else if (pname==GL_OBJECT_PLANE) {
935 COPY_4V( params, texUnit->ObjectPlaneQ );
936 }
937 else if (pname==GL_EYE_PLANE) {
938 COPY_4V( params, texUnit->EyePlaneQ );
939 }
940 else {
941 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
942 return;
943 }
944 break;
945 default:
946 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
947 return;
948 }
949 }
950
951
952
953 void gl_GetTexGeniv( GLcontext *ctx,
954 GLenum coord, GLenum pname, GLint *params )
955 {
956 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
957 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
958
959 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGeniv");
960
961 switch( coord ) {
962 case GL_S:
963 if (pname==GL_TEXTURE_GEN_MODE) {
964 params[0] = texUnit->GenModeS;
965 }
966 else if (pname==GL_OBJECT_PLANE) {
967 COPY_4V( params, texUnit->ObjectPlaneS );
968 }
969 else if (pname==GL_EYE_PLANE) {
970 COPY_4V( params, texUnit->EyePlaneS );
971 }
972 else {
973 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
974 return;
975 }
976 break;
977 case GL_T:
978 if (pname==GL_TEXTURE_GEN_MODE) {
979 params[0] = texUnit->GenModeT;
980 }
981 else if (pname==GL_OBJECT_PLANE) {
982 COPY_4V( params, texUnit->ObjectPlaneT );
983 }
984 else if (pname==GL_EYE_PLANE) {
985 COPY_4V( params, texUnit->EyePlaneT );
986 }
987 else {
988 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
989 return;
990 }
991 break;
992 case GL_R:
993 if (pname==GL_TEXTURE_GEN_MODE) {
994 params[0] = texUnit->GenModeR;
995 }
996 else if (pname==GL_OBJECT_PLANE) {
997 COPY_4V( params, texUnit->ObjectPlaneR );
998 }
999 else if (pname==GL_EYE_PLANE) {
1000 COPY_4V( params, texUnit->EyePlaneR );
1001 }
1002 else {
1003 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1004 return;
1005 }
1006 break;
1007 case GL_Q:
1008 if (pname==GL_TEXTURE_GEN_MODE) {
1009 params[0] = texUnit->GenModeQ;
1010 }
1011 else if (pname==GL_OBJECT_PLANE) {
1012 COPY_4V( params, texUnit->ObjectPlaneQ );
1013 }
1014 else if (pname==GL_EYE_PLANE) {
1015 COPY_4V( params, texUnit->EyePlaneQ );
1016 }
1017 else {
1018 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1019 return;
1020 }
1021 break;
1022 default:
1023 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
1024 return;
1025 }
1026 }
1027
1028
1029 /* GL_ARB_multitexture */
1030 void gl_ActiveTexture( GLcontext *ctx, GLenum target )
1031 {
1032 GLint maxUnits = ctx->Const.MaxTextureUnits;
1033
1034 ASSERT_OUTSIDE_BEGIN_END( ctx, "glActiveTextureARB" );
1035
1036 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1037 fprintf(stderr, "glActiveTexture %s\n",
1038 gl_lookup_enum_by_nr(target));
1039
1040 if (target >= GL_TEXTURE0_ARB && target < GL_TEXTURE0_ARB + maxUnits) {
1041 GLint texUnit = target - GL_TEXTURE0_ARB;
1042 ctx->TexCoordUnit = texUnit;
1043 ctx->Texture.CurrentUnit = texUnit;
1044 ctx->Texture.CurrentTransformUnit = texUnit;
1045 if (ctx->Driver.ActiveTexture) {
1046 (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
1047 }
1048 }
1049 else {
1050 gl_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
1051 }
1052 }
1053
1054
1055 /* GL_ARB_multitexture */
1056 void gl_ClientActiveTexture( GLcontext *ctx, GLenum target )
1057 {
1058 GLint maxUnits = ctx->Const.MaxTextureUnits;
1059
1060 ASSERT_OUTSIDE_BEGIN_END( ctx, "glClientActiveTextureARB" );
1061
1062 if (target >= GL_TEXTURE0_ARB && target < GL_TEXTURE0_ARB + maxUnits) {
1063 GLint texUnit = target - GL_TEXTURE0_ARB;
1064 ctx->Array.ActiveTexture = texUnit;
1065 }
1066 else {
1067 gl_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
1068 }
1069 }
1070
1071
1072
1073 /*
1074 * Put the given texture object into the list of dirty texture objects.
1075 * When a texture object is dirty we have to reexamine it for completeness
1076 * and perhaps choose a different texture sampling function.
1077 */
1078 void gl_put_texobj_on_dirty_list( GLcontext *ctx, struct gl_texture_object *t )
1079 {
1080 ASSERT(ctx);
1081 ASSERT(t);
1082 /* Only insert if not already in the dirty list.
1083 * The Dirty flag is only set iff the texture object is in the dirty list.
1084 */
1085 if (!t->Dirty) {
1086 ASSERT(t->NextDirty == NULL);
1087 t->Dirty = GL_TRUE;
1088 t->NextDirty = ctx->Shared->DirtyTexObjList;
1089 ctx->Shared->DirtyTexObjList = t;
1090 }
1091 #ifdef DEBUG
1092 else {
1093 /* make sure t is in the list */
1094 struct gl_texture_object *obj = ctx->Shared->DirtyTexObjList;
1095 while (obj) {
1096 if (obj == t) {
1097 return;
1098 }
1099 obj = obj->NextDirty;
1100 }
1101 gl_problem(ctx, "Error in gl_put_texobj_on_dirty_list");
1102 }
1103 #endif
1104 }
1105
1106
1107 /*
1108 * Remove a texture object from the dirty texture list.
1109 */
1110 void gl_remove_texobj_from_dirty_list( struct gl_shared_state *shared,
1111 struct gl_texture_object *tObj )
1112 {
1113 struct gl_texture_object *t, *prev = NULL;
1114 ASSERT(shared);
1115 ASSERT(tObj);
1116 for (t = shared->DirtyTexObjList; t; t = t->NextDirty) {
1117 if (t == tObj) {
1118 if (prev) {
1119 prev->NextDirty = t->NextDirty;
1120 }
1121 else {
1122 shared->DirtyTexObjList = t->NextDirty;
1123 }
1124 return;
1125 }
1126 prev = t;
1127 }
1128 }
1129
1130
1131 /*
1132 * This is called by gl_update_state() if the NEW_TEXTURING bit in
1133 * ctx->NewState is unit.
1134 */
1135 void gl_update_dirty_texobjs( GLcontext *ctx )
1136 {
1137 struct gl_texture_object *t, *next;
1138 for (t = ctx->Shared->DirtyTexObjList; t; t = next) {
1139 next = t->NextDirty;
1140 gl_test_texture_object_completeness(ctx, t);
1141 gl_set_texture_sampler(t);
1142 t->NextDirty = NULL;
1143 t->Dirty = GL_FALSE;
1144 }
1145 ctx->Shared->DirtyTexObjList = NULL;
1146 }