fixed a bunch of g++ warnings/errors. Compiling with g++ can help find lots of poten...
[mesa.git] / src / mesa / main / texstate.c
1 /* $Id: texstate.c,v 1.36 2001/03/07 05:06:12 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 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 "colormac.h"
33 #include "context.h"
34 #include "enums.h"
35 #include "extensions.h"
36 #include "macros.h"
37 #include "texobj.h"
38 #include "teximage.h"
39 #include "texstate.h"
40 #include "mtypes.h"
41 #include "math/m_xform.h"
42 #include "math/m_matrix.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 ASSERT_OUTSIDE_BEGIN_END(ctx);
71
72 if (target==GL_TEXTURE_ENV) {
73 switch (pname) {
74 case GL_TEXTURE_ENV_MODE: {
75 GLenum mode = (GLenum) (GLint) *param;
76
77 switch (mode) {
78 case GL_ADD:
79 if (!ctx->Extensions.EXT_texture_env_add) {
80 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(param)");
81 return;
82 }
83 break;
84 case GL_COMBINE_EXT:
85 if (!ctx->Extensions.EXT_texture_env_combine) {
86 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(param)");
87 return;
88 }
89 break;
90 case GL_MODULATE:
91 case GL_BLEND:
92 case GL_DECAL:
93 case GL_REPLACE:
94 break;
95 default:
96 _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param)" );
97 return;
98 }
99
100 if (texUnit->EnvMode == mode)
101 return;
102 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
103 texUnit->EnvMode = mode;
104 break;
105 }
106 case GL_TEXTURE_ENV_COLOR: {
107 GLfloat tmp[4];
108 tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
109 tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
110 tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
111 tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
112 if (TEST_EQ_4V(tmp, texUnit->EnvColor))
113 return;
114 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
115 COPY_4FV(texUnit->EnvColor, tmp);
116 break;
117 }
118 case GL_COMBINE_RGB_EXT:
119 if (ctx->Extensions.EXT_texture_env_combine) {
120 GLenum mode = (GLenum) (GLint) *param;
121 switch (mode) {
122 case GL_REPLACE:
123 case GL_MODULATE:
124 case GL_ADD:
125 case GL_ADD_SIGNED_EXT:
126 case GL_INTERPOLATE_EXT:
127 break;
128 case GL_DOT3_RGB_EXT:
129 case GL_DOT3_RGBA_EXT:
130 if (!ctx->Extensions.EXT_texture_env_dot3) {
131 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(param)");
132 return;
133 }
134 break;
135 default:
136 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
137 return;
138 }
139 if (texUnit->CombineModeRGB == mode)
140 return;
141 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
142 texUnit->CombineModeRGB = mode;
143 }
144 else {
145 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
146 return;
147 }
148 case GL_COMBINE_ALPHA_EXT:
149 if (ctx->Extensions.EXT_texture_env_combine) {
150 GLenum mode = (GLenum) (GLint) *param;
151 switch (mode) {
152 case GL_REPLACE:
153 case GL_MODULATE:
154 case GL_ADD:
155 case GL_ADD_SIGNED_EXT:
156 case GL_INTERPOLATE_EXT:
157 if (texUnit->CombineModeA == mode)
158 return;
159 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
160 texUnit->CombineModeA = mode;
161 break;
162 default:
163 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
164 return;
165 }
166 }
167 else {
168 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
169 return;
170 }
171 break;
172 case GL_SOURCE0_RGB_EXT:
173 case GL_SOURCE1_RGB_EXT:
174 case GL_SOURCE2_RGB_EXT:
175 if (ctx->Extensions.EXT_texture_env_combine) {
176 GLenum source = (GLenum) (GLint) *param;
177 GLuint s = pname - GL_SOURCE0_RGB_EXT;
178 switch (source) {
179 case GL_TEXTURE:
180 case GL_CONSTANT_EXT:
181 case GL_PRIMARY_COLOR_EXT:
182 case GL_PREVIOUS_EXT:
183 if (texUnit->CombineSourceRGB[s] == source)
184 return;
185 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
186 texUnit->CombineSourceRGB[s] = source;
187 break;
188 default:
189 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
190 return;
191 }
192 }
193 else {
194 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
195 return;
196 }
197 break;
198 case GL_SOURCE0_ALPHA_EXT:
199 case GL_SOURCE1_ALPHA_EXT:
200 case GL_SOURCE2_ALPHA_EXT:
201 if (ctx->Extensions.EXT_texture_env_combine) {
202 GLenum source = (GLenum) (GLint) *param;
203 GLuint s = pname - GL_SOURCE0_ALPHA_EXT;
204 switch (source) {
205 case GL_TEXTURE:
206 case GL_CONSTANT_EXT:
207 case GL_PRIMARY_COLOR_EXT:
208 case GL_PREVIOUS_EXT:
209 if (texUnit->CombineSourceA[s] == source) return;
210 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
211 texUnit->CombineSourceA[s] = source;
212 break;
213 default:
214 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
215 return;
216 }
217 }
218 else {
219 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
220 return;
221 }
222 break;
223 case GL_OPERAND0_RGB_EXT:
224 case GL_OPERAND1_RGB_EXT:
225 if (ctx->Extensions.EXT_texture_env_combine) {
226 GLenum operand = (GLenum) (GLint) *param;
227 GLuint s = pname - GL_OPERAND0_RGB_EXT;
228 switch (operand) {
229 case GL_SRC_COLOR:
230 case GL_ONE_MINUS_SRC_COLOR:
231 case GL_SRC_ALPHA:
232 case GL_ONE_MINUS_SRC_ALPHA:
233 if (texUnit->CombineOperandRGB[s] == operand)
234 return;
235 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
236 texUnit->CombineOperandRGB[s] = operand;
237 break;
238 default:
239 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
240 return;
241 }
242 }
243 else {
244 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
245 return;
246 }
247 break;
248 case GL_OPERAND0_ALPHA_EXT:
249 case GL_OPERAND1_ALPHA_EXT:
250 if (ctx->Extensions.EXT_texture_env_combine) {
251 GLenum operand = (GLenum) (GLint) *param;
252 switch (operand) {
253 case GL_SRC_ALPHA:
254 case GL_ONE_MINUS_SRC_ALPHA:
255 if (texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA_EXT] ==
256 operand)
257 return;
258 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
259 texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA_EXT] = operand;
260 break;
261 default:
262 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
263 return;
264 }
265 }
266 else {
267 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
268 return;
269 }
270 break;
271 case GL_OPERAND2_RGB_EXT:
272 if (ctx->Extensions.EXT_texture_env_combine) {
273 GLenum operand = (GLenum) (GLint) *param;
274 switch (operand) {
275 case GL_SRC_ALPHA:
276 if (texUnit->CombineOperandRGB[2] == operand)
277 return;
278 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
279 texUnit->CombineOperandRGB[2] = operand;
280 default:
281 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
282 return;
283 }
284 }
285 else {
286 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
287 return;
288 }
289 break;
290 case GL_OPERAND2_ALPHA_EXT:
291 if (ctx->Extensions.EXT_texture_env_combine) {
292 GLenum operand = (GLenum) (GLint) *param;
293 switch (operand) {
294 case GL_SRC_ALPHA:
295 if (texUnit->CombineOperandA[2] == operand)
296 return;
297 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
298 texUnit->CombineOperandA[2] = operand;
299 break;
300 default:
301 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
302 return;
303 }
304 }
305 else {
306 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
307 return;
308 }
309 break;
310 case GL_RGB_SCALE_EXT:
311 if (ctx->Extensions.EXT_texture_env_combine) {
312 GLuint newshift;
313 if (*param == 1.0) {
314 newshift = 0;
315 }
316 else if (*param == 2.0) {
317 newshift = 1;
318 }
319 else if (*param == 4.0) {
320 newshift = 2;
321 }
322 else {
323 _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param)" );
324 return;
325 }
326 if (texUnit->CombineScaleShiftRGB == newshift)
327 return;
328 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
329 texUnit->CombineScaleShiftRGB = newshift;
330 }
331 else {
332 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
333 return;
334 }
335 break;
336 case GL_ALPHA_SCALE:
337 if (ctx->Extensions.EXT_texture_env_combine) {
338 GLuint newshift;
339 if (*param == 1.0) {
340 newshift = 0;
341 }
342 else if (*param == 2.0) {
343 newshift = 1;
344 }
345 else if (*param == 4.0) {
346 newshift = 2;
347 }
348 else {
349 _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param)" );
350 return;
351 }
352 if (texUnit->CombineScaleShiftA == newshift)
353 return;
354 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
355 texUnit->CombineScaleShiftA = newshift;
356 }
357 else {
358 _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(pname)");
359 return;
360 }
361 break;
362 default:
363 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
364 return;
365 }
366 }
367 else if (target==GL_TEXTURE_FILTER_CONTROL_EXT) {
368 if (!ctx->Extensions.EXT_texture_lod_bias) {
369 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" );
370 return;
371 }
372 switch (pname) {
373 case GL_TEXTURE_LOD_BIAS_EXT:
374 if (texUnit->LodBias == param[0])
375 return;
376 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
377 texUnit->LodBias = param[0];
378 break;
379 default:
380 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
381 return;
382 }
383 }
384 else {
385 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target)" );
386 return;
387 }
388
389 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
390 fprintf(stderr, "glTexEnv %s %s %.1f(%s) ...\n",
391 _mesa_lookup_enum_by_nr(target),
392 _mesa_lookup_enum_by_nr(pname),
393 *param,
394 _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));
395
396 /* Tell device driver about the new texture environment */
397 if (ctx->Driver.TexEnv) {
398 (*ctx->Driver.TexEnv)( ctx, target, pname, param );
399 }
400 }
401
402
403 void
404 _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
405 {
406 _mesa_TexEnvfv( target, pname, &param );
407 }
408
409
410
411 void
412 _mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
413 {
414 GLfloat p[4];
415 p[0] = (GLfloat) param;
416 p[1] = p[2] = p[3] = 0.0;
417 _mesa_TexEnvfv( target, pname, p );
418 }
419
420
421 void
422 _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
423 {
424 GLfloat p[4];
425 p[0] = INT_TO_FLOAT( param[0] );
426 p[1] = INT_TO_FLOAT( param[1] );
427 p[2] = INT_TO_FLOAT( param[2] );
428 p[3] = INT_TO_FLOAT( param[3] );
429 _mesa_TexEnvfv( target, pname, p );
430 }
431
432
433 void
434 _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
435 {
436 GET_CURRENT_CONTEXT(ctx);
437 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
438 ASSERT_OUTSIDE_BEGIN_END(ctx);
439
440 if (target!=GL_TEXTURE_ENV) {
441 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
442 return;
443 }
444
445 switch (pname) {
446 case GL_TEXTURE_ENV_MODE:
447 *params = ENUM_TO_FLOAT(texUnit->EnvMode);
448 break;
449 case GL_TEXTURE_ENV_COLOR:
450 COPY_4FV( params, texUnit->EnvColor );
451 break;
452 case GL_RGB_SCALE_EXT:
453 if (ctx->Extensions.EXT_texture_env_combine) {
454 if (texUnit->CombineScaleShiftRGB == 0)
455 *params = 1.0;
456 else if (texUnit->CombineScaleShiftRGB == 1)
457 *params = 2.0;
458 else
459 *params = 4.0;
460 }
461 else {
462 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
463 return;
464 }
465 break;
466 case GL_ALPHA_SCALE:
467 if (ctx->Extensions.EXT_texture_env_combine) {
468 if (texUnit->CombineScaleShiftA == 0)
469 *params = 1.0;
470 else if (texUnit->CombineScaleShiftA == 1)
471 *params = 2.0;
472 else
473 *params = 4.0;
474 }
475 else {
476 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
477 return;
478 }
479 break;
480 default:
481 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
482 }
483 }
484
485
486 void
487 _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
488 {
489 GET_CURRENT_CONTEXT(ctx);
490 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
491 ASSERT_OUTSIDE_BEGIN_END(ctx);
492
493 if (target != GL_TEXTURE_ENV) {
494 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
495 return;
496 }
497
498 switch (pname) {
499 case GL_TEXTURE_ENV_MODE:
500 *params = (GLint) texUnit->EnvMode;
501 break;
502 case GL_TEXTURE_ENV_COLOR:
503 params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
504 params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
505 params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
506 params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
507 break;
508 case GL_COMBINE_RGB_EXT:
509 if (ctx->Extensions.EXT_texture_env_combine) {
510 *params = (GLint) texUnit->CombineModeRGB;
511 }
512 else {
513 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
514 }
515 break;
516 case GL_COMBINE_ALPHA_EXT:
517 if (ctx->Extensions.EXT_texture_env_combine) {
518 *params = (GLint) texUnit->CombineModeA;
519 }
520 else {
521 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
522 }
523 break;
524 case GL_SOURCE0_RGB_EXT:
525 if (ctx->Extensions.EXT_texture_env_combine) {
526 *params = (GLint) texUnit->CombineSourceRGB[0];
527 }
528 else {
529 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
530 }
531 break;
532 case GL_SOURCE1_RGB_EXT:
533 if (ctx->Extensions.EXT_texture_env_combine) {
534 *params = (GLint) texUnit->CombineSourceRGB[1];
535 }
536 else {
537 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
538 }
539 break;
540 case GL_SOURCE2_RGB_EXT:
541 if (ctx->Extensions.EXT_texture_env_combine) {
542 *params = (GLint) texUnit->CombineSourceRGB[2];
543 }
544 else {
545 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
546 }
547 break;
548 case GL_SOURCE0_ALPHA_EXT:
549 if (ctx->Extensions.EXT_texture_env_combine) {
550 *params = (GLint) texUnit->CombineSourceA[0];
551 }
552 else {
553 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
554 }
555 break;
556 case GL_SOURCE1_ALPHA_EXT:
557 if (ctx->Extensions.EXT_texture_env_combine) {
558 *params = (GLint) texUnit->CombineSourceA[1];
559 }
560 else {
561 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
562 }
563 break;
564 case GL_SOURCE2_ALPHA_EXT:
565 if (ctx->Extensions.EXT_texture_env_combine) {
566 *params = (GLint) texUnit->CombineSourceA[2];
567 }
568 else {
569 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
570 }
571 break;
572 case GL_OPERAND0_RGB_EXT:
573 if (ctx->Extensions.EXT_texture_env_combine) {
574 *params = (GLint) texUnit->CombineOperandRGB[0];
575 }
576 else {
577 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
578 }
579 break;
580 case GL_OPERAND1_RGB_EXT:
581 if (ctx->Extensions.EXT_texture_env_combine) {
582 *params = (GLint) texUnit->CombineOperandRGB[1];
583 }
584 else {
585 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
586 }
587 break;
588 case GL_OPERAND2_RGB_EXT:
589 if (ctx->Extensions.EXT_texture_env_combine) {
590 *params = (GLint) texUnit->CombineOperandRGB[2];
591 }
592 else {
593 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
594 }
595 break;
596 case GL_OPERAND0_ALPHA_EXT:
597 if (ctx->Extensions.EXT_texture_env_combine) {
598 *params = (GLint) texUnit->CombineOperandA[0];
599 }
600 else {
601 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
602 }
603 break;
604 case GL_OPERAND1_ALPHA_EXT:
605 if (ctx->Extensions.EXT_texture_env_combine) {
606 *params = (GLint) texUnit->CombineOperandA[1];
607 }
608 else {
609 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
610 }
611 break;
612 case GL_OPERAND2_ALPHA_EXT:
613 if (ctx->Extensions.EXT_texture_env_combine) {
614 *params = (GLint) texUnit->CombineOperandA[2];
615 }
616 else {
617 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
618 }
619 break;
620 default:
621 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
622 }
623 }
624
625
626
627
628 /**********************************************************************/
629 /* Texture Parameters */
630 /**********************************************************************/
631
632
633 void
634 _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
635 {
636 _mesa_TexParameterfv(target, pname, &param);
637 }
638
639
640 void
641 _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
642 {
643 GET_CURRENT_CONTEXT(ctx);
644 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
645 GLenum eparam = (GLenum) (GLint) params[0];
646 struct gl_texture_object *texObj;
647 ASSERT_OUTSIDE_BEGIN_END(ctx);
648
649 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
650 fprintf(stderr, "texPARAM %s %s %d...\n",
651 _mesa_lookup_enum_by_nr(target),
652 _mesa_lookup_enum_by_nr(pname),
653 eparam);
654
655
656 switch (target) {
657 case GL_TEXTURE_1D:
658 texObj = texUnit->Current1D;
659 break;
660 case GL_TEXTURE_2D:
661 texObj = texUnit->Current2D;
662 break;
663 case GL_TEXTURE_3D_EXT:
664 texObj = texUnit->Current3D;
665 break;
666 case GL_TEXTURE_CUBE_MAP_ARB:
667 if (ctx->Extensions.ARB_texture_cube_map) {
668 texObj = texUnit->CurrentCubeMap;
669 break;
670 }
671 /* fallthrough */
672 default:
673 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
674 return;
675 }
676
677 switch (pname) {
678 case GL_TEXTURE_MIN_FILTER:
679 /* A small optimization */
680 if (texObj->MinFilter == eparam)
681 return;
682
683 if (eparam==GL_NEAREST || eparam==GL_LINEAR
684 || eparam==GL_NEAREST_MIPMAP_NEAREST
685 || eparam==GL_LINEAR_MIPMAP_NEAREST
686 || eparam==GL_NEAREST_MIPMAP_LINEAR
687 || eparam==GL_LINEAR_MIPMAP_LINEAR) {
688 texObj->MinFilter = eparam;
689 }
690 else {
691 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
692 return;
693 }
694 break;
695 case GL_TEXTURE_MAG_FILTER:
696 /* A small optimization */
697 if (texObj->MagFilter == eparam)
698 return;
699
700 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
701 texObj->MagFilter = eparam;
702 }
703 else {
704 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
705 return;
706 }
707 break;
708 case GL_TEXTURE_WRAP_S:
709 if (texObj->WrapS == eparam)
710 return;
711
712 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
713 texObj->WrapS = eparam;
714 }
715 else {
716 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
717 return;
718 }
719 break;
720 case GL_TEXTURE_WRAP_T:
721 if (texObj->WrapT == eparam)
722 return;
723
724 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
725 texObj->WrapT = eparam;
726 }
727 else {
728 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
729 return;
730 }
731 break;
732 case GL_TEXTURE_WRAP_R_EXT:
733 if (texObj->WrapR == eparam)
734 return;
735
736 if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
737 texObj->WrapR = eparam;
738 }
739 else {
740 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
741 }
742 break;
743 case GL_TEXTURE_BORDER_COLOR:
744 UNCLAMPED_FLOAT_TO_CHAN(texObj->BorderColor[0], params[0]);
745 UNCLAMPED_FLOAT_TO_CHAN(texObj->BorderColor[1], params[1]);
746 UNCLAMPED_FLOAT_TO_CHAN(texObj->BorderColor[2], params[2]);
747 UNCLAMPED_FLOAT_TO_CHAN(texObj->BorderColor[3], params[3]);
748 break;
749 case GL_TEXTURE_MIN_LOD:
750 texObj->MinLod = params[0];
751 break;
752 case GL_TEXTURE_MAX_LOD:
753 texObj->MaxLod = params[0];
754 break;
755 case GL_TEXTURE_BASE_LEVEL:
756 if (params[0] < 0.0) {
757 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
758 return;
759 }
760 texObj->BaseLevel = (GLint) params[0];
761 break;
762 case GL_TEXTURE_MAX_LEVEL:
763 if (params[0] < 0.0) {
764 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
765 return;
766 }
767 texObj->MaxLevel = (GLint) params[0];
768 break;
769 case GL_TEXTURE_PRIORITY:
770 /* (keithh@netcomuk.co.uk) */
771 texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
772 break;
773 case GL_TEXTURE_COMPARE_SGIX:
774 if (ctx->Extensions.SGIX_shadow) {
775 texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
776 }
777 else {
778 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
779 return;
780 }
781 break;
782 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
783 if (ctx->Extensions.SGIX_shadow) {
784 GLenum op = (GLenum) params[0];
785 if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
786 op == GL_TEXTURE_GEQUAL_R_SGIX) {
787 texObj->CompareOperator = op;
788 }
789 else {
790 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
791 }
792 }
793 else {
794 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
795 return;
796 }
797 break;
798 case GL_SHADOW_AMBIENT_SGIX:
799 if (ctx->Extensions.SGIX_shadow_ambient) {
800 UNCLAMPED_FLOAT_TO_CHAN(texObj->ShadowAmbient, params[0]);
801 }
802 else {
803 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
804 return;
805 }
806 break;
807 default:
808 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(pname)" );
809 return;
810 }
811
812 ctx->NewState |= _NEW_TEXTURE;
813 texObj->Complete = GL_FALSE;
814
815 if (ctx->Driver.TexParameter) {
816 (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
817 }
818 }
819
820
821 void
822 _mesa_TexParameteri( GLenum target, GLenum pname, const GLint param )
823 {
824 GLfloat fparam[4];
825 fparam[0] = (GLfloat) param;
826 fparam[1] = fparam[2] = fparam[3] = 0.0;
827 _mesa_TexParameterfv(target, pname, fparam);
828 }
829
830 void
831 _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
832 {
833 GLfloat fparam[4];
834 fparam[0] = (GLfloat) params[0];
835 fparam[1] = fparam[2] = fparam[3] = 0.0;
836 _mesa_TexParameterfv(target, pname, fparam);
837 }
838
839
840 void
841 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
842 GLenum pname, GLfloat *params )
843 {
844 GLint iparam;
845 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
846 *params = (GLfloat) iparam;
847 }
848
849
850 static GLuint
851 tex_image_dimensions(GLcontext *ctx, GLenum target)
852 {
853 switch (target) {
854 case GL_TEXTURE_1D:
855 case GL_PROXY_TEXTURE_1D:
856 return 1;
857 case GL_TEXTURE_2D:
858 case GL_PROXY_TEXTURE_2D:
859 return 2;
860 case GL_TEXTURE_3D:
861 case GL_PROXY_TEXTURE_3D:
862 return 3;
863 case GL_TEXTURE_CUBE_MAP_ARB:
864 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
865 return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
866 default:
867 _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
868 return 0;
869 }
870 }
871
872
873 void
874 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
875 GLenum pname, GLint *params )
876 {
877 GET_CURRENT_CONTEXT(ctx);
878 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
879 const struct gl_texture_image *img = NULL;
880 GLuint dimensions;
881 GLboolean isProxy;
882 ASSERT_OUTSIDE_BEGIN_END(ctx);
883
884 if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
885 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
886 return;
887 }
888
889 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
890 if (dimensions == 0) {
891 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
892 return;
893 }
894
895 img = _mesa_select_tex_image(ctx, texUnit, target, level);
896 if (!img) {
897 if (pname == GL_TEXTURE_COMPONENTS)
898 *params = 1;
899 else
900 *params = 0;
901 return;
902 }
903
904 isProxy = (target == GL_PROXY_TEXTURE_1D) ||
905 (target == GL_PROXY_TEXTURE_2D) ||
906 (target == GL_PROXY_TEXTURE_3D) ||
907 (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB);
908
909 switch (pname) {
910 case GL_TEXTURE_WIDTH:
911 *params = img->Width;
912 return;
913 case GL_TEXTURE_HEIGHT:
914 *params = img->Height;
915 return;
916 case GL_TEXTURE_DEPTH:
917 *params = img->Depth;
918 return;
919 case GL_TEXTURE_COMPONENTS:
920 *params = img->IntFormat;
921 return;
922 case GL_TEXTURE_BORDER:
923 *params = img->Border;
924 return;
925 case GL_TEXTURE_RED_SIZE:
926 *params = img->RedBits;
927 return;
928 case GL_TEXTURE_GREEN_SIZE:
929 *params = img->GreenBits;
930 return;
931 case GL_TEXTURE_BLUE_SIZE:
932 *params = img->BlueBits;
933 return;
934 case GL_TEXTURE_ALPHA_SIZE:
935 *params = img->AlphaBits;
936 return;
937 case GL_TEXTURE_INTENSITY_SIZE:
938 *params = img->IntensityBits;
939 return;
940 case GL_TEXTURE_LUMINANCE_SIZE:
941 *params = img->LuminanceBits;
942 return;
943 case GL_TEXTURE_INDEX_SIZE_EXT:
944 *params = img->IndexBits;
945 return;
946 case GL_DEPTH_BITS:
947 /* XXX this isn't in the GL_SGIX_depth_texture spec
948 * but seems appropriate.
949 */
950 if (ctx->Extensions.SGIX_depth_texture)
951 *params = img->DepthBits;
952 else
953 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
954 return;
955
956 /* GL_ARB_texture_compression */
957 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB:
958 if (ctx->Extensions.ARB_texture_compression) {
959 if (img->IsCompressed && !isProxy)
960 *params = img->CompressedSize;
961 else
962 _mesa_error(ctx, GL_INVALID_OPERATION,
963 "glGetTexLevelParameter[if]v(pname)");
964 }
965 else {
966 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
967 }
968 return;
969 case GL_TEXTURE_COMPRESSED_ARB:
970 if (ctx->Extensions.ARB_texture_compression) {
971 *params = (GLint) img->IsCompressed;
972 }
973 else {
974 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
975 }
976 return;
977
978 default:
979 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
980 }
981 }
982
983
984
985 void
986 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
987 {
988 GET_CURRENT_CONTEXT(ctx);
989 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
990 struct gl_texture_object *obj;
991 ASSERT_OUTSIDE_BEGIN_END(ctx);
992
993 obj = _mesa_select_tex_object(ctx, texUnit, target);
994 if (!obj) {
995 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
996 return;
997 }
998
999 switch (pname) {
1000 case GL_TEXTURE_MAG_FILTER:
1001 *params = ENUM_TO_FLOAT(obj->MagFilter);
1002 break;
1003 case GL_TEXTURE_MIN_FILTER:
1004 *params = ENUM_TO_FLOAT(obj->MinFilter);
1005 break;
1006 case GL_TEXTURE_WRAP_S:
1007 *params = ENUM_TO_FLOAT(obj->WrapS);
1008 break;
1009 case GL_TEXTURE_WRAP_T:
1010 *params = ENUM_TO_FLOAT(obj->WrapT);
1011 break;
1012 case GL_TEXTURE_WRAP_R_EXT:
1013 *params = ENUM_TO_FLOAT(obj->WrapR);
1014 break;
1015 case GL_TEXTURE_BORDER_COLOR:
1016 params[0] = obj->BorderColor[0] / CHAN_MAXF;
1017 params[1] = obj->BorderColor[1] / CHAN_MAXF;
1018 params[2] = obj->BorderColor[2] / CHAN_MAXF;
1019 params[3] = obj->BorderColor[3] / CHAN_MAXF;
1020 break;
1021 case GL_TEXTURE_RESIDENT:
1022 {
1023 GLboolean resident;
1024 if (ctx->Driver.IsTextureResident)
1025 resident = ctx->Driver.IsTextureResident(ctx, obj);
1026 else
1027 resident = GL_TRUE;
1028 *params = ENUM_TO_FLOAT(resident);
1029 }
1030 break;
1031 case GL_TEXTURE_PRIORITY:
1032 *params = obj->Priority;
1033 break;
1034 case GL_TEXTURE_MIN_LOD:
1035 *params = obj->MinLod;
1036 break;
1037 case GL_TEXTURE_MAX_LOD:
1038 *params = obj->MaxLod;
1039 break;
1040 case GL_TEXTURE_BASE_LEVEL:
1041 *params = (GLfloat) obj->BaseLevel;
1042 break;
1043 case GL_TEXTURE_MAX_LEVEL:
1044 *params = (GLfloat) obj->MaxLevel;
1045 break;
1046 case GL_TEXTURE_COMPARE_SGIX:
1047 if (ctx->Extensions.SGIX_shadow) {
1048 *params = (GLfloat) obj->CompareFlag;
1049 }
1050 else {
1051 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
1052 return;
1053 }
1054 break;
1055 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1056 if (ctx->Extensions.SGIX_shadow) {
1057 *params = (GLfloat) obj->CompareOperator;
1058 }
1059 else {
1060 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
1061 return;
1062 }
1063 break;
1064 case GL_SHADOW_AMBIENT_SGIX:
1065 if (ctx->Extensions.SGIX_shadow_ambient) {
1066 *params = CHAN_TO_FLOAT(obj->ShadowAmbient);
1067 }
1068 else {
1069 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)");
1070 return;
1071 }
1072 break;
1073 default:
1074 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
1075 }
1076 }
1077
1078
1079 void
1080 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1081 {
1082 GET_CURRENT_CONTEXT(ctx);
1083 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1084 struct gl_texture_object *obj;
1085 ASSERT_OUTSIDE_BEGIN_END(ctx);
1086
1087 obj = _mesa_select_tex_object(ctx, texUnit, target);
1088 if (!obj) {
1089 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
1090 return;
1091 }
1092
1093 switch (pname) {
1094 case GL_TEXTURE_MAG_FILTER:
1095 *params = (GLint) obj->MagFilter;
1096 break;
1097 case GL_TEXTURE_MIN_FILTER:
1098 *params = (GLint) obj->MinFilter;
1099 break;
1100 case GL_TEXTURE_WRAP_S:
1101 *params = (GLint) obj->WrapS;
1102 break;
1103 case GL_TEXTURE_WRAP_T:
1104 *params = (GLint) obj->WrapT;
1105 break;
1106 case GL_TEXTURE_WRAP_R_EXT:
1107 *params = (GLint) obj->WrapR;
1108 break;
1109 case GL_TEXTURE_BORDER_COLOR:
1110 {
1111 GLfloat color[4];
1112 color[0] = obj->BorderColor[0] / CHAN_MAXF;
1113 color[1] = obj->BorderColor[1] / CHAN_MAXF;
1114 color[2] = obj->BorderColor[2] / CHAN_MAXF;
1115 color[3] = obj->BorderColor[3] / CHAN_MAXF;
1116 params[0] = FLOAT_TO_INT( color[0] );
1117 params[1] = FLOAT_TO_INT( color[1] );
1118 params[2] = FLOAT_TO_INT( color[2] );
1119 params[3] = FLOAT_TO_INT( color[3] );
1120 }
1121 break;
1122 case GL_TEXTURE_RESIDENT:
1123 {
1124 GLboolean resident;
1125 if (ctx->Driver.IsTextureResident)
1126 resident = ctx->Driver.IsTextureResident(ctx, obj);
1127 else
1128 resident = GL_TRUE;
1129 *params = (GLint) resident;
1130 }
1131 break;
1132 case GL_TEXTURE_PRIORITY:
1133 *params = (GLint) obj->Priority;
1134 break;
1135 case GL_TEXTURE_MIN_LOD:
1136 *params = (GLint) obj->MinLod;
1137 break;
1138 case GL_TEXTURE_MAX_LOD:
1139 *params = (GLint) obj->MaxLod;
1140 break;
1141 case GL_TEXTURE_BASE_LEVEL:
1142 *params = obj->BaseLevel;
1143 break;
1144 case GL_TEXTURE_MAX_LEVEL:
1145 *params = obj->MaxLevel;
1146 break;
1147 case GL_TEXTURE_COMPARE_SGIX:
1148 if (ctx->Extensions.SGIX_shadow) {
1149 *params = (GLint) obj->CompareFlag;
1150 }
1151 else {
1152 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
1153 return;
1154 }
1155 break;
1156 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1157 if (ctx->Extensions.SGIX_shadow) {
1158 *params = (GLint) obj->CompareOperator;
1159 }
1160 else {
1161 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
1162 return;
1163 }
1164 break;
1165 case GL_SHADOW_AMBIENT_SGIX:
1166 if (ctx->Extensions.SGIX_shadow_ambient) {
1167 /* XXX range? */
1168 *params = (GLint) CHAN_TO_FLOAT(obj->ShadowAmbient);
1169 }
1170 else {
1171 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)");
1172 return;
1173 }
1174 break;
1175 default:
1176 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
1177 }
1178 }
1179
1180
1181
1182
1183 /**********************************************************************/
1184 /* Texture Coord Generation */
1185 /**********************************************************************/
1186
1187
1188 void
1189 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
1190 {
1191 GET_CURRENT_CONTEXT(ctx);
1192 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1193 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1194 ASSERT_OUTSIDE_BEGIN_END(ctx);
1195
1196 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
1197 fprintf(stderr, "texGEN %s %s %x...\n",
1198 _mesa_lookup_enum_by_nr(coord),
1199 _mesa_lookup_enum_by_nr(pname),
1200 *(int *)params);
1201
1202 switch (coord) {
1203 case GL_S:
1204 if (pname==GL_TEXTURE_GEN_MODE) {
1205 GLenum mode = (GLenum) (GLint) *params;
1206 GLuint bits;
1207 switch (mode) {
1208 case GL_OBJECT_LINEAR:
1209 bits = TEXGEN_OBJ_LINEAR;
1210 break;
1211 case GL_EYE_LINEAR:
1212 bits = TEXGEN_EYE_LINEAR;
1213 break;
1214 case GL_REFLECTION_MAP_NV:
1215 bits = TEXGEN_REFLECTION_MAP_NV;
1216 break;
1217 case GL_NORMAL_MAP_NV:
1218 bits = TEXGEN_NORMAL_MAP_NV;
1219 break;
1220 case GL_SPHERE_MAP:
1221 bits = TEXGEN_SPHERE_MAP;
1222 break;
1223 default:
1224 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1225 return;
1226 }
1227 if (texUnit->GenModeS == mode)
1228 return;
1229 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1230 texUnit->GenModeS = mode;
1231 texUnit->_GenBitS = bits;
1232 }
1233 else if (pname==GL_OBJECT_PLANE) {
1234 if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
1235 return;
1236 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1237 texUnit->ObjectPlaneS[0] = params[0];
1238 texUnit->ObjectPlaneS[1] = params[1];
1239 texUnit->ObjectPlaneS[2] = params[2];
1240 texUnit->ObjectPlaneS[3] = params[3];
1241 }
1242 else if (pname==GL_EYE_PLANE) {
1243 GLfloat tmp[4];
1244
1245 /* Transform plane equation by the inverse modelview matrix */
1246 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
1247 _math_matrix_analyse( &ctx->ModelView );
1248 }
1249 _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
1250 if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
1251 return;
1252 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1253 COPY_4FV(texUnit->EyePlaneS, tmp);
1254 }
1255 else {
1256 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1257 return;
1258 }
1259 break;
1260 case GL_T:
1261 if (pname==GL_TEXTURE_GEN_MODE) {
1262 GLenum mode = (GLenum) (GLint) *params;
1263 GLuint bitt;
1264 switch (mode) {
1265 case GL_OBJECT_LINEAR:
1266 bitt = TEXGEN_OBJ_LINEAR;
1267 break;
1268 case GL_EYE_LINEAR:
1269 bitt = TEXGEN_EYE_LINEAR;
1270 break;
1271 case GL_REFLECTION_MAP_NV:
1272 bitt = TEXGEN_REFLECTION_MAP_NV;
1273 break;
1274 case GL_NORMAL_MAP_NV:
1275 bitt = TEXGEN_NORMAL_MAP_NV;
1276 break;
1277 case GL_SPHERE_MAP:
1278 bitt = TEXGEN_SPHERE_MAP;
1279 break;
1280 default:
1281 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1282 return;
1283 }
1284 if (texUnit->GenModeT == mode)
1285 return;
1286 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1287 texUnit->GenModeT = mode;
1288 texUnit->_GenBitT = bitt;
1289 }
1290 else if (pname==GL_OBJECT_PLANE) {
1291 if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
1292 return;
1293 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1294 texUnit->ObjectPlaneT[0] = params[0];
1295 texUnit->ObjectPlaneT[1] = params[1];
1296 texUnit->ObjectPlaneT[2] = params[2];
1297 texUnit->ObjectPlaneT[3] = params[3];
1298 }
1299 else if (pname==GL_EYE_PLANE) {
1300 GLfloat tmp[4];
1301 /* Transform plane equation by the inverse modelview matrix */
1302 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
1303 _math_matrix_analyse( &ctx->ModelView );
1304 }
1305 _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
1306 if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
1307 return;
1308 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1309 COPY_4FV(texUnit->EyePlaneT, tmp);
1310 }
1311 else {
1312 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1313 return;
1314 }
1315 break;
1316 case GL_R:
1317 if (pname==GL_TEXTURE_GEN_MODE) {
1318 GLenum mode = (GLenum) (GLint) *params;
1319 GLuint bitr;
1320 switch (mode) {
1321 case GL_OBJECT_LINEAR:
1322 bitr = TEXGEN_OBJ_LINEAR;
1323 break;
1324 case GL_REFLECTION_MAP_NV:
1325 bitr = TEXGEN_REFLECTION_MAP_NV;
1326 break;
1327 case GL_NORMAL_MAP_NV:
1328 bitr = TEXGEN_NORMAL_MAP_NV;
1329 break;
1330 case GL_EYE_LINEAR:
1331 bitr = TEXGEN_EYE_LINEAR;
1332 break;
1333 default:
1334 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1335 return;
1336 }
1337 if (texUnit->GenModeR == mode)
1338 return;
1339 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1340 texUnit->GenModeR = mode;
1341 texUnit->_GenBitR = bitr;
1342 }
1343 else if (pname==GL_OBJECT_PLANE) {
1344 if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
1345 return;
1346 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1347 texUnit->ObjectPlaneR[0] = params[0];
1348 texUnit->ObjectPlaneR[1] = params[1];
1349 texUnit->ObjectPlaneR[2] = params[2];
1350 texUnit->ObjectPlaneR[3] = params[3];
1351 }
1352 else if (pname==GL_EYE_PLANE) {
1353 GLfloat tmp[4];
1354 /* Transform plane equation by the inverse modelview matrix */
1355 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
1356 _math_matrix_analyse( &ctx->ModelView );
1357 }
1358 _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
1359 if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
1360 return;
1361 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1362 COPY_4FV(texUnit->EyePlaneR, tmp);
1363 }
1364 else {
1365 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1366 return;
1367 }
1368 break;
1369 case GL_Q:
1370 if (pname==GL_TEXTURE_GEN_MODE) {
1371 GLenum mode = (GLenum) (GLint) *params;
1372 GLuint bitq;
1373 switch (mode) {
1374 case GL_OBJECT_LINEAR:
1375 bitq = TEXGEN_OBJ_LINEAR;
1376 break;
1377 case GL_EYE_LINEAR:
1378 bitq = TEXGEN_EYE_LINEAR;
1379 break;
1380 default:
1381 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1382 return;
1383 }
1384 if (texUnit->GenModeQ == mode)
1385 return;
1386 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1387 texUnit->GenModeQ = mode;
1388 texUnit->_GenBitQ = bitq;
1389 }
1390 else if (pname==GL_OBJECT_PLANE) {
1391 if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
1392 return;
1393 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1394 texUnit->ObjectPlaneQ[0] = params[0];
1395 texUnit->ObjectPlaneQ[1] = params[1];
1396 texUnit->ObjectPlaneQ[2] = params[2];
1397 texUnit->ObjectPlaneQ[3] = params[3];
1398 }
1399 else if (pname==GL_EYE_PLANE) {
1400 GLfloat tmp[4];
1401 /* Transform plane equation by the inverse modelview matrix */
1402 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
1403 _math_matrix_analyse( &ctx->ModelView );
1404 }
1405 _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
1406 if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
1407 return;
1408 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1409 COPY_4FV(texUnit->EyePlaneQ, tmp);
1410 }
1411 else {
1412 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1413 return;
1414 }
1415 break;
1416 default:
1417 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
1418 return;
1419 }
1420
1421 if (ctx->Driver.TexGen)
1422 ctx->Driver.TexGen( ctx, coord, pname, params );
1423 }
1424
1425
1426 void
1427 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
1428 {
1429 GLfloat p[4];
1430 p[0] = params[0];
1431 p[1] = params[1];
1432 p[2] = params[2];
1433 p[3] = params[3];
1434 _mesa_TexGenfv(coord, pname, p);
1435 }
1436
1437
1438 void
1439 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
1440 {
1441 GLfloat p = (GLfloat) param;
1442 _mesa_TexGenfv( coord, pname, &p );
1443 }
1444
1445
1446 void
1447 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
1448 {
1449 GLfloat p[4];
1450 p[0] = params[0];
1451 p[1] = params[1];
1452 p[2] = params[2];
1453 p[3] = params[3];
1454 _mesa_TexGenfv( coord, pname, p );
1455 }
1456
1457
1458 void
1459 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
1460 {
1461 _mesa_TexGenfv(coord, pname, &param);
1462 }
1463
1464
1465 void
1466 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
1467 {
1468 _mesa_TexGeniv( coord, pname, &param );
1469 }
1470
1471
1472
1473 void
1474 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
1475 {
1476 GET_CURRENT_CONTEXT(ctx);
1477 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1478 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1479 ASSERT_OUTSIDE_BEGIN_END(ctx);
1480
1481 switch (coord) {
1482 case GL_S:
1483 if (pname==GL_TEXTURE_GEN_MODE) {
1484 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
1485 }
1486 else if (pname==GL_OBJECT_PLANE) {
1487 COPY_4V( params, texUnit->ObjectPlaneS );
1488 }
1489 else if (pname==GL_EYE_PLANE) {
1490 COPY_4V( params, texUnit->EyePlaneS );
1491 }
1492 else {
1493 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
1494 return;
1495 }
1496 break;
1497 case GL_T:
1498 if (pname==GL_TEXTURE_GEN_MODE) {
1499 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
1500 }
1501 else if (pname==GL_OBJECT_PLANE) {
1502 COPY_4V( params, texUnit->ObjectPlaneT );
1503 }
1504 else if (pname==GL_EYE_PLANE) {
1505 COPY_4V( params, texUnit->EyePlaneT );
1506 }
1507 else {
1508 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
1509 return;
1510 }
1511 break;
1512 case GL_R:
1513 if (pname==GL_TEXTURE_GEN_MODE) {
1514 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
1515 }
1516 else if (pname==GL_OBJECT_PLANE) {
1517 COPY_4V( params, texUnit->ObjectPlaneR );
1518 }
1519 else if (pname==GL_EYE_PLANE) {
1520 COPY_4V( params, texUnit->EyePlaneR );
1521 }
1522 else {
1523 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
1524 return;
1525 }
1526 break;
1527 case GL_Q:
1528 if (pname==GL_TEXTURE_GEN_MODE) {
1529 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
1530 }
1531 else if (pname==GL_OBJECT_PLANE) {
1532 COPY_4V( params, texUnit->ObjectPlaneQ );
1533 }
1534 else if (pname==GL_EYE_PLANE) {
1535 COPY_4V( params, texUnit->EyePlaneQ );
1536 }
1537 else {
1538 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
1539 return;
1540 }
1541 break;
1542 default:
1543 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
1544 return;
1545 }
1546 }
1547
1548
1549
1550 void
1551 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
1552 {
1553 GET_CURRENT_CONTEXT(ctx);
1554 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1555 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1556 ASSERT_OUTSIDE_BEGIN_END(ctx);
1557
1558 switch (coord) {
1559 case GL_S:
1560 if (pname==GL_TEXTURE_GEN_MODE) {
1561 params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
1562 }
1563 else if (pname==GL_OBJECT_PLANE) {
1564 COPY_4V( params, texUnit->ObjectPlaneS );
1565 }
1566 else if (pname==GL_EYE_PLANE) {
1567 COPY_4V( params, texUnit->EyePlaneS );
1568 }
1569 else {
1570 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1571 return;
1572 }
1573 break;
1574 case GL_T:
1575 if (pname==GL_TEXTURE_GEN_MODE) {
1576 params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
1577 }
1578 else if (pname==GL_OBJECT_PLANE) {
1579 COPY_4V( params, texUnit->ObjectPlaneT );
1580 }
1581 else if (pname==GL_EYE_PLANE) {
1582 COPY_4V( params, texUnit->EyePlaneT );
1583 }
1584 else {
1585 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1586 return;
1587 }
1588 break;
1589 case GL_R:
1590 if (pname==GL_TEXTURE_GEN_MODE) {
1591 params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
1592 }
1593 else if (pname==GL_OBJECT_PLANE) {
1594 COPY_4V( params, texUnit->ObjectPlaneR );
1595 }
1596 else if (pname==GL_EYE_PLANE) {
1597 COPY_4V( params, texUnit->EyePlaneR );
1598 }
1599 else {
1600 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1601 return;
1602 }
1603 break;
1604 case GL_Q:
1605 if (pname==GL_TEXTURE_GEN_MODE) {
1606 params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
1607 }
1608 else if (pname==GL_OBJECT_PLANE) {
1609 COPY_4V( params, texUnit->ObjectPlaneQ );
1610 }
1611 else if (pname==GL_EYE_PLANE) {
1612 COPY_4V( params, texUnit->EyePlaneQ );
1613 }
1614 else {
1615 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1616 return;
1617 }
1618 break;
1619 default:
1620 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
1621 return;
1622 }
1623 }
1624
1625
1626
1627 void
1628 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
1629 {
1630 GET_CURRENT_CONTEXT(ctx);
1631 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1632 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1633 ASSERT_OUTSIDE_BEGIN_END(ctx);
1634
1635 switch (coord) {
1636 case GL_S:
1637 if (pname==GL_TEXTURE_GEN_MODE) {
1638 params[0] = texUnit->GenModeS;
1639 }
1640 else if (pname==GL_OBJECT_PLANE) {
1641 params[0] = (GLint) texUnit->ObjectPlaneS[0];
1642 params[1] = (GLint) texUnit->ObjectPlaneS[1];
1643 params[2] = (GLint) texUnit->ObjectPlaneS[2];
1644 params[3] = (GLint) texUnit->ObjectPlaneS[3];
1645 }
1646 else if (pname==GL_EYE_PLANE) {
1647 params[0] = (GLint) texUnit->EyePlaneS[0];
1648 params[1] = (GLint) texUnit->EyePlaneS[1];
1649 params[2] = (GLint) texUnit->EyePlaneS[2];
1650 params[3] = (GLint) texUnit->EyePlaneS[3];
1651 }
1652 else {
1653 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1654 return;
1655 }
1656 break;
1657 case GL_T:
1658 if (pname==GL_TEXTURE_GEN_MODE) {
1659 params[0] = texUnit->GenModeT;
1660 }
1661 else if (pname==GL_OBJECT_PLANE) {
1662 params[0] = (GLint) texUnit->ObjectPlaneT[0];
1663 params[1] = (GLint) texUnit->ObjectPlaneT[1];
1664 params[2] = (GLint) texUnit->ObjectPlaneT[2];
1665 params[3] = (GLint) texUnit->ObjectPlaneT[3];
1666 }
1667 else if (pname==GL_EYE_PLANE) {
1668 params[0] = (GLint) texUnit->EyePlaneT[0];
1669 params[1] = (GLint) texUnit->EyePlaneT[1];
1670 params[2] = (GLint) texUnit->EyePlaneT[2];
1671 params[3] = (GLint) texUnit->EyePlaneT[3];
1672 }
1673 else {
1674 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1675 return;
1676 }
1677 break;
1678 case GL_R:
1679 if (pname==GL_TEXTURE_GEN_MODE) {
1680 params[0] = texUnit->GenModeR;
1681 }
1682 else if (pname==GL_OBJECT_PLANE) {
1683 params[0] = (GLint) texUnit->ObjectPlaneR[0];
1684 params[1] = (GLint) texUnit->ObjectPlaneR[1];
1685 params[2] = (GLint) texUnit->ObjectPlaneR[2];
1686 params[3] = (GLint) texUnit->ObjectPlaneR[3];
1687 }
1688 else if (pname==GL_EYE_PLANE) {
1689 params[0] = (GLint) texUnit->EyePlaneR[0];
1690 params[1] = (GLint) texUnit->EyePlaneR[1];
1691 params[2] = (GLint) texUnit->EyePlaneR[2];
1692 params[3] = (GLint) texUnit->EyePlaneR[3];
1693 }
1694 else {
1695 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1696 return;
1697 }
1698 break;
1699 case GL_Q:
1700 if (pname==GL_TEXTURE_GEN_MODE) {
1701 params[0] = texUnit->GenModeQ;
1702 }
1703 else if (pname==GL_OBJECT_PLANE) {
1704 params[0] = (GLint) texUnit->ObjectPlaneQ[0];
1705 params[1] = (GLint) texUnit->ObjectPlaneQ[1];
1706 params[2] = (GLint) texUnit->ObjectPlaneQ[2];
1707 params[3] = (GLint) texUnit->ObjectPlaneQ[3];
1708 }
1709 else if (pname==GL_EYE_PLANE) {
1710 params[0] = (GLint) texUnit->EyePlaneQ[0];
1711 params[1] = (GLint) texUnit->EyePlaneQ[1];
1712 params[2] = (GLint) texUnit->EyePlaneQ[2];
1713 params[3] = (GLint) texUnit->EyePlaneQ[3];
1714 }
1715 else {
1716 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1717 return;
1718 }
1719 break;
1720 default:
1721 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
1722 return;
1723 }
1724 }
1725
1726
1727 /* GL_ARB_multitexture */
1728 void
1729 _mesa_ActiveTextureARB( GLenum target )
1730 {
1731 GET_CURRENT_CONTEXT(ctx);
1732 GLuint texUnit = target - GL_TEXTURE0_ARB;
1733 ASSERT_OUTSIDE_BEGIN_END(ctx);
1734
1735 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1736 fprintf(stderr, "glActiveTexture %s\n",
1737 _mesa_lookup_enum_by_nr(target));
1738
1739 if (texUnit > ctx->Const.MaxTextureUnits) {
1740 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
1741 return;
1742 }
1743
1744 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1745 ctx->Texture.CurrentUnit = texUnit;
1746 ctx->Texture.CurrentTransformUnit = texUnit;
1747 if (ctx->Driver.ActiveTexture) {
1748 (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
1749 }
1750 }
1751
1752
1753 /* GL_ARB_multitexture */
1754 void
1755 _mesa_ClientActiveTextureARB( GLenum target )
1756 {
1757 GET_CURRENT_CONTEXT(ctx);
1758 GLuint texUnit = target - GL_TEXTURE0_ARB;
1759 ASSERT_OUTSIDE_BEGIN_END(ctx);
1760
1761 if (texUnit > ctx->Const.MaxTextureUnits) {
1762 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
1763 return;
1764 }
1765
1766 FLUSH_VERTICES(ctx, _NEW_ARRAY);
1767 ctx->Array.ActiveTexture = texUnit;
1768 }