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