more texture cube work, misc code clean-up
[mesa.git] / src / mesa / main / texstate.c
1 /* $Id: texstate.c,v 1.12 2000/05/23 17:14:49 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 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 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "context.h"
33 #include "enums.h"
34 #include "extensions.h"
35 #include "macros.h"
36 #include "matrix.h"
37 #include "texobj.h"
38 #include "teximage.h"
39 #include "texstate.h"
40 #include "texture.h"
41 #include "types.h"
42 #include "xform.h"
43 #endif
44
45
46
47 #ifdef SPECIALCAST
48 /* Needed for an Amiga compiler */
49 #define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
50 #define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
51 #else
52 /* all other compilers */
53 #define ENUM_TO_FLOAT(X) ((GLfloat)(X))
54 #define ENUM_TO_DOUBLE(X) ((GLdouble)(X))
55 #endif
56
57
58
59
60 /**********************************************************************/
61 /* Texture Environment */
62 /**********************************************************************/
63
64
65 void
66 _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
67 {
68 GET_CURRENT_CONTEXT(ctx);
69 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
70
71 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexEnv");
72
73 if (target==GL_TEXTURE_ENV) {
74
75 if (pname==GL_TEXTURE_ENV_MODE) {
76 GLenum mode = (GLenum) (GLint) *param;
77 switch (mode) {
78 case GL_ADD:
79 if (!ctx->Extensions.HaveTextureEnvAdd) {
80 gl_error(ctx, GL_INVALID_ENUM, "glTexEnv(param)");
81 return;
82 }
83 /* FALL-THROUGH */
84 case GL_MODULATE:
85 case GL_BLEND:
86 case GL_DECAL:
87 case GL_REPLACE:
88 /* A small optimization for drivers */
89 if (texUnit->EnvMode == mode)
90 return;
91
92 if (MESA_VERBOSE & (VERBOSE_STATE|VERBOSE_TEXTURE))
93 fprintf(stderr, "glTexEnv: old mode %s, new mode %s\n",
94 gl_lookup_enum_by_nr(texUnit->EnvMode),
95 gl_lookup_enum_by_nr(mode));
96
97 texUnit->EnvMode = mode;
98 ctx->NewState |= NEW_TEXTURE_ENV;
99 break;
100 default:
101 gl_error( ctx, GL_INVALID_VALUE, "glTexEnv(param)" );
102 return;
103 }
104 }
105 else if (pname==GL_TEXTURE_ENV_COLOR) {
106 texUnit->EnvColor[0] = CLAMP( param[0], 0.0F, 1.0F );
107 texUnit->EnvColor[1] = CLAMP( param[1], 0.0F, 1.0F );
108 texUnit->EnvColor[2] = CLAMP( param[2], 0.0F, 1.0F );
109 texUnit->EnvColor[3] = CLAMP( param[3], 0.0F, 1.0F );
110 }
111 else {
112 gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
113 return;
114 }
115
116 }
117 else if (target==GL_TEXTURE_FILTER_CONTROL_EXT) {
118
119 if (!ctx->Extensions.HaveTextureLodBias) {
120 gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
121 return;
122 }
123
124 if (pname==GL_TEXTURE_LOD_BIAS_EXT) {
125 texUnit->LodBias = param[0];
126 }
127 else {
128 gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
129 return;
130 }
131
132 }
133 else {
134 gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(target)" );
135 return;
136 }
137
138 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
139 fprintf(stderr, "glTexEnv %s %s %.1f(%s) ...\n",
140 gl_lookup_enum_by_nr(target),
141 gl_lookup_enum_by_nr(pname),
142 *param,
143 gl_lookup_enum_by_nr((GLenum) (GLint) *param));
144
145 /* Tell device driver about the new texture environment */
146 if (ctx->Driver.TexEnv) {
147 (*ctx->Driver.TexEnv)( ctx, target, pname, param );
148 }
149
150 }
151
152
153 void
154 _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
155 {
156 _mesa_TexEnvfv( target, pname, &param );
157 }
158
159
160
161 void
162 _mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
163 {
164 GLfloat p[4];
165 p[0] = (GLfloat) param;
166 p[1] = p[2] = p[3] = 0.0;
167 _mesa_TexEnvfv( target, pname, p );
168 }
169
170
171 void
172 _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
173 {
174 GLfloat p[4];
175 p[0] = INT_TO_FLOAT( param[0] );
176 p[1] = INT_TO_FLOAT( param[1] );
177 p[2] = INT_TO_FLOAT( param[2] );
178 p[3] = INT_TO_FLOAT( param[3] );
179 _mesa_TexEnvfv( target, pname, p );
180 }
181
182
183 void
184 _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
185 {
186 GET_CURRENT_CONTEXT(ctx);
187 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
188
189 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexEnvfv");
190
191 if (target!=GL_TEXTURE_ENV) {
192 gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
193 return;
194 }
195 switch (pname) {
196 case GL_TEXTURE_ENV_MODE:
197 *params = ENUM_TO_FLOAT(texUnit->EnvMode);
198 break;
199 case GL_TEXTURE_ENV_COLOR:
200 COPY_4FV( params, texUnit->EnvColor );
201 break;
202 default:
203 gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
204 }
205 }
206
207
208 void
209 _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
210 {
211 GET_CURRENT_CONTEXT(ctx);
212 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
213
214 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexEnviv");
215
216 if (target!=GL_TEXTURE_ENV) {
217 gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
218 return;
219 }
220 switch (pname) {
221 case GL_TEXTURE_ENV_MODE:
222 *params = (GLint) texUnit->EnvMode;
223 break;
224 case GL_TEXTURE_ENV_COLOR:
225 params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
226 params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
227 params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
228 params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
229 break;
230 default:
231 gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
232 }
233 }
234
235
236
237
238 /**********************************************************************/
239 /* Texture Parameters */
240 /**********************************************************************/
241
242
243 void
244 _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
245 {
246 _mesa_TexParameterfv(target, pname, &param);
247 }
248
249
250 void
251 _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
252 {
253 GET_CURRENT_CONTEXT(ctx);
254 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
255 GLenum eparam = (GLenum) (GLint) params[0];
256 struct gl_texture_object *texObj;
257
258 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexParameterfv");
259
260 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
261 fprintf(stderr, "texPARAM %s %s %d...\n",
262 gl_lookup_enum_by_nr(target),
263 gl_lookup_enum_by_nr(pname),
264 eparam);
265
266
267 switch (target) {
268 case GL_TEXTURE_1D:
269 texObj = texUnit->CurrentD[1];
270 break;
271 case GL_TEXTURE_2D:
272 texObj = texUnit->CurrentD[2];
273 break;
274 case GL_TEXTURE_3D_EXT:
275 texObj = texUnit->CurrentD[3];
276 break;
277 case GL_TEXTURE_CUBE_MAP_ARB:
278 if (ctx->Extensions.HaveTextureCubeMap) {
279 texObj = texUnit->CurrentCubeMap;
280 break;
281 }
282 /* fallthrough */
283 default:
284 gl_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
285 return;
286 }
287
288 switch (pname) {
289 case GL_TEXTURE_MIN_FILTER:
290 /* A small optimization */
291 if (texObj->MinFilter == eparam)
292 return;
293
294 if (eparam==GL_NEAREST || eparam==GL_LINEAR
295 || eparam==GL_NEAREST_MIPMAP_NEAREST
296 || eparam==GL_LINEAR_MIPMAP_NEAREST
297 || eparam==GL_NEAREST_MIPMAP_LINEAR
298 || eparam==GL_LINEAR_MIPMAP_LINEAR) {
299 texObj->MinFilter = eparam;
300 ctx->NewState |= NEW_TEXTURING;
301 }
302 else {
303 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
304 return;
305 }
306 break;
307 case GL_TEXTURE_MAG_FILTER:
308 /* A small optimization */
309 if (texObj->MagFilter == eparam)
310 return;
311
312 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
313 texObj->MagFilter = eparam;
314 ctx->NewState |= NEW_TEXTURING;
315 }
316 else {
317 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
318 return;
319 }
320 break;
321 case GL_TEXTURE_WRAP_S:
322 if (texObj->WrapS == eparam)
323 return;
324
325 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
326 texObj->WrapS = eparam;
327 ctx->NewState |= NEW_TEXTURING;
328 }
329 else {
330 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
331 return;
332 }
333 break;
334 case GL_TEXTURE_WRAP_T:
335 if (texObj->WrapT == eparam)
336 return;
337
338 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
339 texObj->WrapT = eparam;
340 ctx->NewState |= NEW_TEXTURING;
341 }
342 else {
343 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
344 return;
345 }
346 break;
347 case GL_TEXTURE_WRAP_R_EXT:
348 if (texObj->WrapR == eparam)
349 return;
350
351 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
352 texObj->WrapR = eparam;
353 ctx->NewState |= NEW_TEXTURING;
354 }
355 else {
356 gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
357 }
358 break;
359 case GL_TEXTURE_BORDER_COLOR:
360 texObj->BorderColor[0] = (GLubyte) CLAMP((GLint)(params[0]*255.0), 0, 255);
361 texObj->BorderColor[1] = (GLubyte) CLAMP((GLint)(params[1]*255.0), 0, 255);
362 texObj->BorderColor[2] = (GLubyte) CLAMP((GLint)(params[2]*255.0), 0, 255);
363 texObj->BorderColor[3] = (GLubyte) CLAMP((GLint)(params[3]*255.0), 0, 255);
364 break;
365 case GL_TEXTURE_MIN_LOD:
366 texObj->MinLod = params[0];
367 ctx->NewState |= NEW_TEXTURING;
368 break;
369 case GL_TEXTURE_MAX_LOD:
370 texObj->MaxLod = params[0];
371 ctx->NewState |= NEW_TEXTURING;
372 break;
373 case GL_TEXTURE_BASE_LEVEL:
374 if (params[0] < 0.0) {
375 gl_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
376 return;
377 }
378 texObj->BaseLevel = (GLint) params[0];
379 ctx->NewState |= NEW_TEXTURING;
380 break;
381 case GL_TEXTURE_MAX_LEVEL:
382 if (params[0] < 0.0) {
383 gl_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
384 return;
385 }
386 texObj->MaxLevel = (GLint) params[0];
387 ctx->NewState |= NEW_TEXTURING;
388 break;
389 case GL_TEXTURE_PRIORITY:
390 /* (keithh@netcomuk.co.uk) */
391 texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
392 break;
393 default:
394 gl_error( ctx, GL_INVALID_ENUM, "glTexParameter(pname)" );
395 return;
396 }
397
398 gl_put_texobj_on_dirty_list( ctx, texObj );
399
400 if (ctx->Driver.TexParameter) {
401 (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
402 }
403 }
404
405
406 void
407 _mesa_TexParameteri( GLenum target, GLenum pname, const GLint param )
408 {
409 GLfloat fparam[4];
410 fparam[0] = (GLfloat) param;
411 fparam[1] = fparam[2] = fparam[3] = 0.0;
412 _mesa_TexParameterfv(target, pname, fparam);
413 }
414
415 void
416 _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
417 {
418 GLfloat fparam[4];
419 fparam[0] = (GLfloat) params[0];
420 fparam[1] = fparam[2] = fparam[3] = 0.0;
421 _mesa_TexParameterfv(target, pname, fparam);
422 }
423
424
425 void
426 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
427 GLenum pname, GLfloat *params )
428 {
429 GLint iparam;
430 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
431 *params = (GLfloat) iparam;
432 }
433
434
435 static GLuint
436 tex_image_dimensions(GLcontext *ctx, GLenum target)
437 {
438 switch (target) {
439 case GL_TEXTURE_1D:
440 case GL_PROXY_TEXTURE_1D:
441 return 1;
442 case GL_TEXTURE_2D:
443 case GL_PROXY_TEXTURE_2D:
444 return 2;
445 case GL_TEXTURE_3D:
446 case GL_PROXY_TEXTURE_3D:
447 return 3;
448 case GL_TEXTURE_CUBE_MAP_ARB:
449 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
450 return ctx->Extensions.HaveTextureCubeMap ? 2 : 0;
451 default:
452 gl_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
453 return 0;
454 }
455 }
456
457
458 void
459 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
460 GLenum pname, GLint *params )
461 {
462 GET_CURRENT_CONTEXT(ctx);
463 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
464 const struct gl_texture_image *img = NULL;
465 GLuint dimensions;
466
467 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexLevelParameter");
468
469 if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
470 gl_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
471 return;
472 }
473
474 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
475 if (dimensions == 0) {
476 gl_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
477 return;
478 }
479
480 img = _mesa_select_tex_image(ctx, texUnit, target, level);
481 if (!img) {
482 if (pname == GL_TEXTURE_COMPONENTS)
483 *params = 1;
484 else
485 *params = 0;
486 return;
487 }
488
489 switch (pname) {
490 case GL_TEXTURE_WIDTH:
491 *params = img->Width;
492 return;
493 case GL_TEXTURE_HEIGHT:
494 if (dimensions > 1) {
495 *params = img->Height;
496 }
497 else {
498 gl_error( ctx, GL_INVALID_ENUM,
499 "glGetTexLevelParameter[if]v(pname=GL_TEXTURE_HEIGHT)" );
500 }
501 return;
502 case GL_TEXTURE_DEPTH:
503 if (dimensions > 2) {
504 *params = img->Depth;
505 }
506 else {
507 gl_error( ctx, GL_INVALID_ENUM,
508 "glGetTexLevelParameter[if]v(pname=GL_TEXTURE_DEPTH)" );
509 }
510 return;
511 case GL_TEXTURE_COMPONENTS:
512 *params = img->IntFormat;
513 return;
514 case GL_TEXTURE_BORDER:
515 *params = img->Border;
516 return;
517 case GL_TEXTURE_RED_SIZE:
518 *params = img->RedBits;
519 return;
520 case GL_TEXTURE_GREEN_SIZE:
521 *params = img->GreenBits;
522 return;
523 case GL_TEXTURE_BLUE_SIZE:
524 *params = img->BlueBits;
525 return;
526 case GL_TEXTURE_ALPHA_SIZE:
527 *params = img->AlphaBits;
528 return;
529 case GL_TEXTURE_INTENSITY_SIZE:
530 *params = img->IntensityBits;
531 return;
532 case GL_TEXTURE_LUMINANCE_SIZE:
533 *params = img->LuminanceBits;
534 return;
535 case GL_TEXTURE_INDEX_SIZE_EXT:
536 *params = img->IndexBits;
537 return;
538 default:
539 gl_error( ctx, GL_INVALID_ENUM,
540 "glGetTexLevelParameter[if]v(pname)" );
541 }
542 }
543
544
545
546 void
547 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
548 {
549 GET_CURRENT_CONTEXT(ctx);
550 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
551 struct gl_texture_object *obj;
552
553 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexParameterfv");
554
555 obj = _mesa_select_tex_object(ctx, texUnit, target);
556 if (!obj) {
557 gl_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
558 return;
559 }
560
561 switch (pname) {
562 case GL_TEXTURE_MAG_FILTER:
563 *params = ENUM_TO_FLOAT(obj->MagFilter);
564 break;
565 case GL_TEXTURE_MIN_FILTER:
566 *params = ENUM_TO_FLOAT(obj->MinFilter);
567 break;
568 case GL_TEXTURE_WRAP_S:
569 *params = ENUM_TO_FLOAT(obj->WrapS);
570 break;
571 case GL_TEXTURE_WRAP_T:
572 *params = ENUM_TO_FLOAT(obj->WrapT);
573 break;
574 case GL_TEXTURE_WRAP_R_EXT:
575 *params = ENUM_TO_FLOAT(obj->WrapR);
576 break;
577 case GL_TEXTURE_BORDER_COLOR:
578 params[0] = obj->BorderColor[0] / 255.0F;
579 params[1] = obj->BorderColor[1] / 255.0F;
580 params[2] = obj->BorderColor[2] / 255.0F;
581 params[3] = obj->BorderColor[3] / 255.0F;
582 break;
583 case GL_TEXTURE_RESIDENT:
584 *params = ENUM_TO_FLOAT(GL_TRUE);
585 break;
586 case GL_TEXTURE_PRIORITY:
587 *params = obj->Priority;
588 break;
589 case GL_TEXTURE_MIN_LOD:
590 *params = obj->MinLod;
591 break;
592 case GL_TEXTURE_MAX_LOD:
593 *params = obj->MaxLod;
594 break;
595 case GL_TEXTURE_BASE_LEVEL:
596 *params = (GLfloat) obj->BaseLevel;
597 break;
598 case GL_TEXTURE_MAX_LEVEL:
599 *params = (GLfloat) obj->MaxLevel;
600 break;
601 default:
602 gl_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
603 }
604 }
605
606
607 void
608 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
609 {
610 GET_CURRENT_CONTEXT(ctx);
611 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
612 struct gl_texture_object *obj;
613
614 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexParameteriv");
615
616 obj = _mesa_select_tex_object(ctx, texUnit, target);
617 if (!obj) {
618 gl_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
619 return;
620 }
621
622 switch (pname) {
623 case GL_TEXTURE_MAG_FILTER:
624 *params = (GLint) obj->MagFilter;
625 break;
626 case GL_TEXTURE_MIN_FILTER:
627 *params = (GLint) obj->MinFilter;
628 break;
629 case GL_TEXTURE_WRAP_S:
630 *params = (GLint) obj->WrapS;
631 break;
632 case GL_TEXTURE_WRAP_T:
633 *params = (GLint) obj->WrapT;
634 break;
635 case GL_TEXTURE_WRAP_R_EXT:
636 *params = (GLint) obj->WrapR;
637 break;
638 case GL_TEXTURE_BORDER_COLOR:
639 {
640 GLfloat color[4];
641 color[0] = obj->BorderColor[0] / 255.0F;
642 color[1] = obj->BorderColor[1] / 255.0F;
643 color[2] = obj->BorderColor[2] / 255.0F;
644 color[3] = obj->BorderColor[3] / 255.0F;
645 params[0] = FLOAT_TO_INT( color[0] );
646 params[1] = FLOAT_TO_INT( color[1] );
647 params[2] = FLOAT_TO_INT( color[2] );
648 params[3] = FLOAT_TO_INT( color[3] );
649 }
650 break;
651 case GL_TEXTURE_RESIDENT:
652 *params = (GLint) GL_TRUE;
653 break;
654 case GL_TEXTURE_PRIORITY:
655 *params = (GLint) obj->Priority;
656 break;
657 case GL_TEXTURE_MIN_LOD:
658 *params = (GLint) obj->MinLod;
659 break;
660 case GL_TEXTURE_MAX_LOD:
661 *params = (GLint) obj->MaxLod;
662 break;
663 case GL_TEXTURE_BASE_LEVEL:
664 *params = obj->BaseLevel;
665 break;
666 case GL_TEXTURE_MAX_LEVEL:
667 *params = obj->MaxLevel;
668 break;
669 default:
670 gl_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
671 }
672 }
673
674
675
676
677 /**********************************************************************/
678 /* Texture Coord Generation */
679 /**********************************************************************/
680
681
682 void
683 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
684 {
685 GET_CURRENT_CONTEXT(ctx);
686 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
687 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
688 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexGenfv");
689
690 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
691 fprintf(stderr, "texGEN %s %s %x...\n",
692 gl_lookup_enum_by_nr(coord),
693 gl_lookup_enum_by_nr(pname),
694 *(int *)params);
695
696 switch (coord) {
697 case GL_S:
698 if (pname==GL_TEXTURE_GEN_MODE) {
699 GLenum mode = (GLenum) (GLint) *params;
700 switch (mode) {
701 case GL_OBJECT_LINEAR:
702 texUnit->GenModeS = mode;
703 texUnit->GenBitS = TEXGEN_OBJ_LINEAR;
704 break;
705 case GL_EYE_LINEAR:
706 texUnit->GenModeS = mode;
707 texUnit->GenBitS = TEXGEN_EYE_LINEAR;
708 break;
709 case GL_REFLECTION_MAP_NV:
710 texUnit->GenModeS = mode;
711 texUnit->GenBitS = TEXGEN_REFLECTION_MAP_NV;
712 break;
713 case GL_NORMAL_MAP_NV:
714 texUnit->GenModeS = mode;
715 texUnit->GenBitS = TEXGEN_NORMAL_MAP_NV;
716 break;
717 case GL_SPHERE_MAP:
718 texUnit->GenModeS = mode;
719 texUnit->GenBitS = TEXGEN_SPHERE_MAP;
720 break;
721 default:
722 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
723 return;
724 }
725 }
726 else if (pname==GL_OBJECT_PLANE) {
727 texUnit->ObjectPlaneS[0] = params[0];
728 texUnit->ObjectPlaneS[1] = params[1];
729 texUnit->ObjectPlaneS[2] = params[2];
730 texUnit->ObjectPlaneS[3] = params[3];
731 }
732 else if (pname==GL_EYE_PLANE) {
733 /* Transform plane equation by the inverse modelview matrix */
734 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
735 gl_matrix_analyze( &ctx->ModelView );
736 }
737 gl_transform_vector( texUnit->EyePlaneS, params,
738 ctx->ModelView.inv );
739 }
740 else {
741 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
742 return;
743 }
744 break;
745 case GL_T:
746 if (pname==GL_TEXTURE_GEN_MODE) {
747 GLenum mode = (GLenum) (GLint) *params;
748 switch (mode) {
749 case GL_OBJECT_LINEAR:
750 texUnit->GenModeT = GL_OBJECT_LINEAR;
751 texUnit->GenBitT = TEXGEN_OBJ_LINEAR;
752 break;
753 case GL_EYE_LINEAR:
754 texUnit->GenModeT = GL_EYE_LINEAR;
755 texUnit->GenBitT = TEXGEN_EYE_LINEAR;
756 break;
757 case GL_REFLECTION_MAP_NV:
758 texUnit->GenModeT = GL_REFLECTION_MAP_NV;
759 texUnit->GenBitT = TEXGEN_REFLECTION_MAP_NV;
760 break;
761 case GL_NORMAL_MAP_NV:
762 texUnit->GenModeT = GL_NORMAL_MAP_NV;
763 texUnit->GenBitT = TEXGEN_NORMAL_MAP_NV;
764 break;
765 case GL_SPHERE_MAP:
766 texUnit->GenModeT = GL_SPHERE_MAP;
767 texUnit->GenBitT = TEXGEN_SPHERE_MAP;
768 break;
769 default:
770 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
771 return;
772 }
773 }
774 else if (pname==GL_OBJECT_PLANE) {
775 texUnit->ObjectPlaneT[0] = params[0];
776 texUnit->ObjectPlaneT[1] = params[1];
777 texUnit->ObjectPlaneT[2] = params[2];
778 texUnit->ObjectPlaneT[3] = params[3];
779 }
780 else if (pname==GL_EYE_PLANE) {
781 /* Transform plane equation by the inverse modelview matrix */
782 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
783 gl_matrix_analyze( &ctx->ModelView );
784 }
785 gl_transform_vector( texUnit->EyePlaneT, params,
786 ctx->ModelView.inv );
787 }
788 else {
789 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
790 return;
791 }
792 break;
793 case GL_R:
794 if (pname==GL_TEXTURE_GEN_MODE) {
795 GLenum mode = (GLenum) (GLint) *params;
796 switch (mode) {
797 case GL_OBJECT_LINEAR:
798 texUnit->GenModeR = GL_OBJECT_LINEAR;
799 texUnit->GenBitR = TEXGEN_OBJ_LINEAR;
800 break;
801 case GL_REFLECTION_MAP_NV:
802 texUnit->GenModeR = GL_REFLECTION_MAP_NV;
803 texUnit->GenBitR = TEXGEN_REFLECTION_MAP_NV;
804 break;
805 case GL_NORMAL_MAP_NV:
806 texUnit->GenModeR = GL_NORMAL_MAP_NV;
807 texUnit->GenBitR = TEXGEN_NORMAL_MAP_NV;
808 break;
809 case GL_EYE_LINEAR:
810 texUnit->GenModeR = GL_EYE_LINEAR;
811 texUnit->GenBitR = TEXGEN_EYE_LINEAR;
812 break;
813 default:
814 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
815 return;
816 }
817 }
818 else if (pname==GL_OBJECT_PLANE) {
819 texUnit->ObjectPlaneR[0] = params[0];
820 texUnit->ObjectPlaneR[1] = params[1];
821 texUnit->ObjectPlaneR[2] = params[2];
822 texUnit->ObjectPlaneR[3] = params[3];
823 }
824 else if (pname==GL_EYE_PLANE) {
825 /* Transform plane equation by the inverse modelview matrix */
826 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
827 gl_matrix_analyze( &ctx->ModelView );
828 }
829 gl_transform_vector( texUnit->EyePlaneR, params,
830 ctx->ModelView.inv );
831 }
832 else {
833 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
834 return;
835 }
836 break;
837 case GL_Q:
838 if (pname==GL_TEXTURE_GEN_MODE) {
839 GLenum mode = (GLenum) (GLint) *params;
840 switch (mode) {
841 case GL_OBJECT_LINEAR:
842 texUnit->GenModeQ = GL_OBJECT_LINEAR;
843 texUnit->GenBitQ = TEXGEN_OBJ_LINEAR;
844 break;
845 case GL_EYE_LINEAR:
846 texUnit->GenModeQ = GL_EYE_LINEAR;
847 texUnit->GenBitQ = TEXGEN_EYE_LINEAR;
848 break;
849 default:
850 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
851 return;
852 }
853 }
854 else if (pname==GL_OBJECT_PLANE) {
855 texUnit->ObjectPlaneQ[0] = params[0];
856 texUnit->ObjectPlaneQ[1] = params[1];
857 texUnit->ObjectPlaneQ[2] = params[2];
858 texUnit->ObjectPlaneQ[3] = params[3];
859 }
860 else if (pname==GL_EYE_PLANE) {
861 /* Transform plane equation by the inverse modelview matrix */
862 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
863 gl_matrix_analyze( &ctx->ModelView );
864 }
865 gl_transform_vector( texUnit->EyePlaneQ, params,
866 ctx->ModelView.inv );
867 }
868 else {
869 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
870 return;
871 }
872 break;
873 default:
874 gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
875 return;
876 }
877
878 ctx->NewState |= NEW_TEXTURING;
879 }
880
881
882 void
883 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
884 {
885 GLfloat p[4];
886 p[0] = params[0];
887 p[1] = params[1];
888 p[2] = params[2];
889 p[3] = params[3];
890 _mesa_TexGenfv(coord, pname, p);
891 }
892
893
894 void
895 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
896 {
897 GLfloat p = (GLfloat) param;
898 _mesa_TexGenfv( coord, pname, &p );
899 }
900
901
902 void
903 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
904 {
905 GLfloat p[4];
906 p[0] = params[0];
907 p[1] = params[1];
908 p[2] = params[2];
909 p[3] = params[3];
910 _mesa_TexGenfv( coord, pname, p );
911 }
912
913
914 void
915 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
916 {
917 _mesa_TexGenfv(coord, pname, &param);
918 }
919
920
921 void
922 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
923 {
924 _mesa_TexGeniv( coord, pname, &param );
925 }
926
927
928
929 void
930 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
931 {
932 GET_CURRENT_CONTEXT(ctx);
933 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
934 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
935
936 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGendv");
937
938 switch (coord) {
939 case GL_S:
940 if (pname==GL_TEXTURE_GEN_MODE) {
941 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
942 }
943 else if (pname==GL_OBJECT_PLANE) {
944 COPY_4V( params, texUnit->ObjectPlaneS );
945 }
946 else if (pname==GL_EYE_PLANE) {
947 COPY_4V( params, texUnit->EyePlaneS );
948 }
949 else {
950 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
951 return;
952 }
953 break;
954 case GL_T:
955 if (pname==GL_TEXTURE_GEN_MODE) {
956 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
957 }
958 else if (pname==GL_OBJECT_PLANE) {
959 COPY_4V( params, texUnit->ObjectPlaneT );
960 }
961 else if (pname==GL_EYE_PLANE) {
962 COPY_4V( params, texUnit->EyePlaneT );
963 }
964 else {
965 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
966 return;
967 }
968 break;
969 case GL_R:
970 if (pname==GL_TEXTURE_GEN_MODE) {
971 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
972 }
973 else if (pname==GL_OBJECT_PLANE) {
974 COPY_4V( params, texUnit->ObjectPlaneR );
975 }
976 else if (pname==GL_EYE_PLANE) {
977 COPY_4V( params, texUnit->EyePlaneR );
978 }
979 else {
980 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
981 return;
982 }
983 break;
984 case GL_Q:
985 if (pname==GL_TEXTURE_GEN_MODE) {
986 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
987 }
988 else if (pname==GL_OBJECT_PLANE) {
989 COPY_4V( params, texUnit->ObjectPlaneQ );
990 }
991 else if (pname==GL_EYE_PLANE) {
992 COPY_4V( params, texUnit->EyePlaneQ );
993 }
994 else {
995 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
996 return;
997 }
998 break;
999 default:
1000 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
1001 return;
1002 }
1003 }
1004
1005
1006
1007 void
1008 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
1009 {
1010 GET_CURRENT_CONTEXT(ctx);
1011 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1012 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1013
1014 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGenfv");
1015
1016 switch (coord) {
1017 case GL_S:
1018 if (pname==GL_TEXTURE_GEN_MODE) {
1019 params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
1020 }
1021 else if (pname==GL_OBJECT_PLANE) {
1022 COPY_4V( params, texUnit->ObjectPlaneS );
1023 }
1024 else if (pname==GL_EYE_PLANE) {
1025 COPY_4V( params, texUnit->EyePlaneS );
1026 }
1027 else {
1028 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1029 return;
1030 }
1031 break;
1032 case GL_T:
1033 if (pname==GL_TEXTURE_GEN_MODE) {
1034 params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
1035 }
1036 else if (pname==GL_OBJECT_PLANE) {
1037 COPY_4V( params, texUnit->ObjectPlaneT );
1038 }
1039 else if (pname==GL_EYE_PLANE) {
1040 COPY_4V( params, texUnit->EyePlaneT );
1041 }
1042 else {
1043 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1044 return;
1045 }
1046 break;
1047 case GL_R:
1048 if (pname==GL_TEXTURE_GEN_MODE) {
1049 params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
1050 }
1051 else if (pname==GL_OBJECT_PLANE) {
1052 COPY_4V( params, texUnit->ObjectPlaneR );
1053 }
1054 else if (pname==GL_EYE_PLANE) {
1055 COPY_4V( params, texUnit->EyePlaneR );
1056 }
1057 else {
1058 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1059 return;
1060 }
1061 break;
1062 case GL_Q:
1063 if (pname==GL_TEXTURE_GEN_MODE) {
1064 params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
1065 }
1066 else if (pname==GL_OBJECT_PLANE) {
1067 COPY_4V( params, texUnit->ObjectPlaneQ );
1068 }
1069 else if (pname==GL_EYE_PLANE) {
1070 COPY_4V( params, texUnit->EyePlaneQ );
1071 }
1072 else {
1073 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1074 return;
1075 }
1076 break;
1077 default:
1078 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
1079 return;
1080 }
1081 }
1082
1083
1084
1085 void
1086 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
1087 {
1088 GET_CURRENT_CONTEXT(ctx);
1089 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1090 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1091
1092 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGeniv");
1093
1094 switch (coord) {
1095 case GL_S:
1096 if (pname==GL_TEXTURE_GEN_MODE) {
1097 params[0] = texUnit->GenModeS;
1098 }
1099 else if (pname==GL_OBJECT_PLANE) {
1100 params[0] = (GLint) texUnit->ObjectPlaneS[0];
1101 params[1] = (GLint) texUnit->ObjectPlaneS[1];
1102 params[2] = (GLint) texUnit->ObjectPlaneS[2];
1103 params[3] = (GLint) texUnit->ObjectPlaneS[3];
1104 }
1105 else if (pname==GL_EYE_PLANE) {
1106 params[0] = (GLint) texUnit->EyePlaneS[0];
1107 params[1] = (GLint) texUnit->EyePlaneS[1];
1108 params[2] = (GLint) texUnit->EyePlaneS[2];
1109 params[3] = (GLint) texUnit->EyePlaneS[3];
1110 }
1111 else {
1112 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1113 return;
1114 }
1115 break;
1116 case GL_T:
1117 if (pname==GL_TEXTURE_GEN_MODE) {
1118 params[0] = texUnit->GenModeT;
1119 }
1120 else if (pname==GL_OBJECT_PLANE) {
1121 params[0] = (GLint) texUnit->ObjectPlaneT[0];
1122 params[1] = (GLint) texUnit->ObjectPlaneT[1];
1123 params[2] = (GLint) texUnit->ObjectPlaneT[2];
1124 params[3] = (GLint) texUnit->ObjectPlaneT[3];
1125 }
1126 else if (pname==GL_EYE_PLANE) {
1127 params[0] = (GLint) texUnit->EyePlaneT[0];
1128 params[1] = (GLint) texUnit->EyePlaneT[1];
1129 params[2] = (GLint) texUnit->EyePlaneT[2];
1130 params[3] = (GLint) texUnit->EyePlaneT[3];
1131 }
1132 else {
1133 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1134 return;
1135 }
1136 break;
1137 case GL_R:
1138 if (pname==GL_TEXTURE_GEN_MODE) {
1139 params[0] = texUnit->GenModeR;
1140 }
1141 else if (pname==GL_OBJECT_PLANE) {
1142 params[0] = (GLint) texUnit->ObjectPlaneR[0];
1143 params[1] = (GLint) texUnit->ObjectPlaneR[1];
1144 params[2] = (GLint) texUnit->ObjectPlaneR[2];
1145 params[3] = (GLint) texUnit->ObjectPlaneR[3];
1146 }
1147 else if (pname==GL_EYE_PLANE) {
1148 params[0] = (GLint) texUnit->EyePlaneR[0];
1149 params[1] = (GLint) texUnit->EyePlaneR[1];
1150 params[2] = (GLint) texUnit->EyePlaneR[2];
1151 params[3] = (GLint) texUnit->EyePlaneR[3];
1152 }
1153 else {
1154 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1155 return;
1156 }
1157 break;
1158 case GL_Q:
1159 if (pname==GL_TEXTURE_GEN_MODE) {
1160 params[0] = texUnit->GenModeQ;
1161 }
1162 else if (pname==GL_OBJECT_PLANE) {
1163 params[0] = (GLint) texUnit->ObjectPlaneQ[0];
1164 params[1] = (GLint) texUnit->ObjectPlaneQ[1];
1165 params[2] = (GLint) texUnit->ObjectPlaneQ[2];
1166 params[3] = (GLint) texUnit->ObjectPlaneQ[3];
1167 }
1168 else if (pname==GL_EYE_PLANE) {
1169 params[0] = (GLint) texUnit->EyePlaneQ[0];
1170 params[1] = (GLint) texUnit->EyePlaneQ[1];
1171 params[2] = (GLint) texUnit->EyePlaneQ[2];
1172 params[3] = (GLint) texUnit->EyePlaneQ[3];
1173 }
1174 else {
1175 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1176 return;
1177 }
1178 break;
1179 default:
1180 gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
1181 return;
1182 }
1183 }
1184
1185
1186 /* GL_ARB_multitexture */
1187 void
1188 _mesa_ActiveTextureARB( GLenum target )
1189 {
1190 GET_CURRENT_CONTEXT(ctx);
1191 GLint maxUnits = ctx->Const.MaxTextureUnits;
1192
1193 ASSERT_OUTSIDE_BEGIN_END( ctx, "glActiveTextureARB" );
1194
1195 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1196 fprintf(stderr, "glActiveTexture %s\n",
1197 gl_lookup_enum_by_nr(target));
1198
1199 if (target >= GL_TEXTURE0_ARB && target < GL_TEXTURE0_ARB + maxUnits) {
1200 GLint texUnit = target - GL_TEXTURE0_ARB;
1201 ctx->Texture.CurrentUnit = texUnit;
1202 ctx->Texture.CurrentTransformUnit = texUnit;
1203 if (ctx->Driver.ActiveTexture) {
1204 (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
1205 }
1206 }
1207 else {
1208 gl_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
1209 }
1210 }
1211
1212
1213 /* GL_ARB_multitexture */
1214 void
1215 _mesa_ClientActiveTextureARB( GLenum target )
1216 {
1217 GET_CURRENT_CONTEXT(ctx);
1218 GLint maxUnits = ctx->Const.MaxTextureUnits;
1219
1220 ASSERT_OUTSIDE_BEGIN_END( ctx, "glClientActiveTextureARB" );
1221
1222 if (target >= GL_TEXTURE0_ARB && target < GL_TEXTURE0_ARB + maxUnits) {
1223 GLint texUnit = target - GL_TEXTURE0_ARB;
1224 ctx->Array.ActiveTexture = texUnit;
1225 }
1226 else {
1227 gl_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
1228 }
1229 }
1230
1231
1232
1233 /*
1234 * Put the given texture object into the list of dirty texture objects.
1235 * When a texture object is dirty we have to reexamine it for completeness
1236 * and perhaps choose a different texture sampling function.
1237 */
1238 void gl_put_texobj_on_dirty_list( GLcontext *ctx, struct gl_texture_object *t )
1239 {
1240 ASSERT(ctx);
1241 ASSERT(t);
1242 /* Only insert if not already in the dirty list.
1243 * The Dirty flag is only set iff the texture object is in the dirty list.
1244 */
1245 if (!t->Dirty) {
1246 ASSERT(t->NextDirty == NULL);
1247 t->Dirty = GL_TRUE;
1248 t->NextDirty = ctx->Shared->DirtyTexObjList;
1249 ctx->Shared->DirtyTexObjList = t;
1250 }
1251 #ifdef DEBUG
1252 else {
1253 /* make sure t is in the list */
1254 struct gl_texture_object *obj = ctx->Shared->DirtyTexObjList;
1255 while (obj) {
1256 if (obj == t) {
1257 return;
1258 }
1259 obj = obj->NextDirty;
1260 }
1261 gl_problem(ctx, "Error in gl_put_texobj_on_dirty_list");
1262 }
1263 #endif
1264 }
1265
1266
1267 /*
1268 * Remove a texture object from the dirty texture list.
1269 */
1270 void gl_remove_texobj_from_dirty_list( struct gl_shared_state *shared,
1271 struct gl_texture_object *tObj )
1272 {
1273 struct gl_texture_object *t, *prev = NULL;
1274 ASSERT(shared);
1275 ASSERT(tObj);
1276 for (t = shared->DirtyTexObjList; t; t = t->NextDirty) {
1277 if (t == tObj) {
1278 if (prev) {
1279 prev->NextDirty = t->NextDirty;
1280 }
1281 else {
1282 shared->DirtyTexObjList = t->NextDirty;
1283 }
1284 return;
1285 }
1286 prev = t;
1287 }
1288 }
1289
1290
1291 /*
1292 * This is called by gl_update_state() if the NEW_TEXTURING bit in
1293 * ctx->NewState is set.
1294 */
1295 void gl_update_dirty_texobjs( GLcontext *ctx )
1296 {
1297 struct gl_texture_object *t, *next;
1298 for (t = ctx->Shared->DirtyTexObjList; t; t = next) {
1299 next = t->NextDirty;
1300 _mesa_test_texobj_completeness(ctx, t);
1301 _mesa_set_texture_sampler(t);
1302 t->NextDirty = NULL;
1303 t->Dirty = GL_FALSE;
1304 }
1305 ctx->Shared->DirtyTexObjList = NULL;
1306 }