- Port 3.4 texture utils, texture format work to 3.5 (including new
[mesa.git] / src / mesa / main / texstate.c
1 /* $Id: texstate.c,v 1.37 2001/03/18 08:53:50 gareth 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_MAX_ANISOTROPY_EXT:
774 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
775 if (params[0] < 1.0) {
776 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
777 return;
778 }
779 texObj->MaxAnisotropy = params[0];
780 }
781 else {
782 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
783 return;
784 }
785 break;
786 case GL_TEXTURE_COMPARE_SGIX:
787 if (ctx->Extensions.SGIX_shadow) {
788 texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
789 }
790 else {
791 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
792 return;
793 }
794 break;
795 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
796 if (ctx->Extensions.SGIX_shadow) {
797 GLenum op = (GLenum) params[0];
798 if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
799 op == GL_TEXTURE_GEQUAL_R_SGIX) {
800 texObj->CompareOperator = op;
801 }
802 else {
803 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
804 }
805 }
806 else {
807 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
808 return;
809 }
810 break;
811 case GL_SHADOW_AMBIENT_SGIX:
812 if (ctx->Extensions.SGIX_shadow_ambient) {
813 UNCLAMPED_FLOAT_TO_CHAN(texObj->ShadowAmbient, params[0]);
814 }
815 else {
816 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
817 return;
818 }
819 break;
820 default:
821 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(pname)" );
822 return;
823 }
824
825 ctx->NewState |= _NEW_TEXTURE;
826 texObj->Complete = GL_FALSE;
827
828 if (ctx->Driver.TexParameter) {
829 (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
830 }
831 }
832
833
834 void
835 _mesa_TexParameteri( GLenum target, GLenum pname, const GLint param )
836 {
837 GLfloat fparam[4];
838 fparam[0] = (GLfloat) param;
839 fparam[1] = fparam[2] = fparam[3] = 0.0;
840 _mesa_TexParameterfv(target, pname, fparam);
841 }
842
843 void
844 _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
845 {
846 GLfloat fparam[4];
847 fparam[0] = (GLfloat) params[0];
848 fparam[1] = fparam[2] = fparam[3] = 0.0;
849 _mesa_TexParameterfv(target, pname, fparam);
850 }
851
852
853 void
854 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
855 GLenum pname, GLfloat *params )
856 {
857 GLint iparam;
858 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
859 *params = (GLfloat) iparam;
860 }
861
862
863 static GLuint
864 tex_image_dimensions(GLcontext *ctx, GLenum target)
865 {
866 switch (target) {
867 case GL_TEXTURE_1D:
868 case GL_PROXY_TEXTURE_1D:
869 return 1;
870 case GL_TEXTURE_2D:
871 case GL_PROXY_TEXTURE_2D:
872 return 2;
873 case GL_TEXTURE_3D:
874 case GL_PROXY_TEXTURE_3D:
875 return 3;
876 case GL_TEXTURE_CUBE_MAP_ARB:
877 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
878 return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
879 default:
880 _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
881 return 0;
882 }
883 }
884
885
886 void
887 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
888 GLenum pname, GLint *params )
889 {
890 GET_CURRENT_CONTEXT(ctx);
891 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
892 const struct gl_texture_image *img = NULL;
893 GLuint dimensions;
894 GLboolean isProxy;
895 ASSERT_OUTSIDE_BEGIN_END(ctx);
896
897 if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
898 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
899 return;
900 }
901
902 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
903 if (dimensions == 0) {
904 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
905 return;
906 }
907
908 img = _mesa_select_tex_image(ctx, texUnit, target, level);
909 if (!img) {
910 if (pname == GL_TEXTURE_COMPONENTS)
911 *params = 1;
912 else
913 *params = 0;
914 return;
915 }
916
917 isProxy = (target == GL_PROXY_TEXTURE_1D) ||
918 (target == GL_PROXY_TEXTURE_2D) ||
919 (target == GL_PROXY_TEXTURE_3D) ||
920 (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB);
921
922 switch (pname) {
923 case GL_TEXTURE_WIDTH:
924 *params = img->Width;
925 return;
926 case GL_TEXTURE_HEIGHT:
927 *params = img->Height;
928 return;
929 case GL_TEXTURE_DEPTH:
930 *params = img->Depth;
931 return;
932 case GL_TEXTURE_COMPONENTS:
933 *params = img->IntFormat;
934 return;
935 case GL_TEXTURE_BORDER:
936 *params = img->Border;
937 return;
938 case GL_TEXTURE_RED_SIZE:
939 *params = img->TexFormat->RedBits;
940 return;
941 case GL_TEXTURE_GREEN_SIZE:
942 *params = img->TexFormat->GreenBits;
943 return;
944 case GL_TEXTURE_BLUE_SIZE:
945 *params = img->TexFormat->BlueBits;
946 return;
947 case GL_TEXTURE_ALPHA_SIZE:
948 *params = img->TexFormat->AlphaBits;
949 return;
950 case GL_TEXTURE_INTENSITY_SIZE:
951 *params = img->TexFormat->IntensityBits;
952 return;
953 case GL_TEXTURE_LUMINANCE_SIZE:
954 *params = img->TexFormat->LuminanceBits;
955 return;
956 case GL_TEXTURE_INDEX_SIZE_EXT:
957 *params = img->TexFormat->IndexBits;
958 return;
959 case GL_DEPTH_BITS:
960 /* XXX this isn't in the GL_SGIX_depth_texture spec
961 * but seems appropriate.
962 */
963 if (ctx->Extensions.SGIX_depth_texture)
964 *params = img->TexFormat->DepthBits;
965 else
966 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
967 return;
968
969 /* GL_ARB_texture_compression */
970 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB:
971 if (ctx->Extensions.ARB_texture_compression) {
972 if (img->IsCompressed && !isProxy)
973 *params = img->CompressedSize;
974 else
975 _mesa_error(ctx, GL_INVALID_OPERATION,
976 "glGetTexLevelParameter[if]v(pname)");
977 }
978 else {
979 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
980 }
981 return;
982 case GL_TEXTURE_COMPRESSED_ARB:
983 if (ctx->Extensions.ARB_texture_compression) {
984 *params = (GLint) img->IsCompressed;
985 }
986 else {
987 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
988 }
989 return;
990
991 default:
992 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
993 }
994 }
995
996
997
998 void
999 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
1000 {
1001 GET_CURRENT_CONTEXT(ctx);
1002 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1003 struct gl_texture_object *obj;
1004 ASSERT_OUTSIDE_BEGIN_END(ctx);
1005
1006 obj = _mesa_select_tex_object(ctx, texUnit, target);
1007 if (!obj) {
1008 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
1009 return;
1010 }
1011
1012 switch (pname) {
1013 case GL_TEXTURE_MAG_FILTER:
1014 *params = ENUM_TO_FLOAT(obj->MagFilter);
1015 break;
1016 case GL_TEXTURE_MIN_FILTER:
1017 *params = ENUM_TO_FLOAT(obj->MinFilter);
1018 break;
1019 case GL_TEXTURE_WRAP_S:
1020 *params = ENUM_TO_FLOAT(obj->WrapS);
1021 break;
1022 case GL_TEXTURE_WRAP_T:
1023 *params = ENUM_TO_FLOAT(obj->WrapT);
1024 break;
1025 case GL_TEXTURE_WRAP_R_EXT:
1026 *params = ENUM_TO_FLOAT(obj->WrapR);
1027 break;
1028 case GL_TEXTURE_BORDER_COLOR:
1029 params[0] = obj->BorderColor[0] / CHAN_MAXF;
1030 params[1] = obj->BorderColor[1] / CHAN_MAXF;
1031 params[2] = obj->BorderColor[2] / CHAN_MAXF;
1032 params[3] = obj->BorderColor[3] / CHAN_MAXF;
1033 break;
1034 case GL_TEXTURE_RESIDENT:
1035 {
1036 GLboolean resident;
1037 if (ctx->Driver.IsTextureResident)
1038 resident = ctx->Driver.IsTextureResident(ctx, obj);
1039 else
1040 resident = GL_TRUE;
1041 *params = ENUM_TO_FLOAT(resident);
1042 }
1043 break;
1044 case GL_TEXTURE_PRIORITY:
1045 *params = obj->Priority;
1046 break;
1047 case GL_TEXTURE_MIN_LOD:
1048 *params = obj->MinLod;
1049 break;
1050 case GL_TEXTURE_MAX_LOD:
1051 *params = obj->MaxLod;
1052 break;
1053 case GL_TEXTURE_BASE_LEVEL:
1054 *params = (GLfloat) obj->BaseLevel;
1055 break;
1056 case GL_TEXTURE_MAX_LEVEL:
1057 *params = (GLfloat) obj->MaxLevel;
1058 break;
1059 case GL_TEXTURE_COMPARE_SGIX:
1060 if (ctx->Extensions.SGIX_shadow) {
1061 *params = (GLfloat) obj->CompareFlag;
1062 }
1063 else {
1064 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
1065 return;
1066 }
1067 break;
1068 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1069 if (ctx->Extensions.SGIX_shadow) {
1070 *params = (GLfloat) obj->CompareOperator;
1071 }
1072 else {
1073 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
1074 return;
1075 }
1076 break;
1077 case GL_SHADOW_AMBIENT_SGIX:
1078 if (ctx->Extensions.SGIX_shadow_ambient) {
1079 *params = CHAN_TO_FLOAT(obj->ShadowAmbient);
1080 }
1081 else {
1082 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)");
1083 return;
1084 }
1085 break;
1086 default:
1087 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
1088 }
1089 }
1090
1091
1092 void
1093 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1094 {
1095 GET_CURRENT_CONTEXT(ctx);
1096 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1097 struct gl_texture_object *obj;
1098 ASSERT_OUTSIDE_BEGIN_END(ctx);
1099
1100 obj = _mesa_select_tex_object(ctx, texUnit, target);
1101 if (!obj) {
1102 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
1103 return;
1104 }
1105
1106 switch (pname) {
1107 case GL_TEXTURE_MAG_FILTER:
1108 *params = (GLint) obj->MagFilter;
1109 break;
1110 case GL_TEXTURE_MIN_FILTER:
1111 *params = (GLint) obj->MinFilter;
1112 break;
1113 case GL_TEXTURE_WRAP_S:
1114 *params = (GLint) obj->WrapS;
1115 break;
1116 case GL_TEXTURE_WRAP_T:
1117 *params = (GLint) obj->WrapT;
1118 break;
1119 case GL_TEXTURE_WRAP_R_EXT:
1120 *params = (GLint) obj->WrapR;
1121 break;
1122 case GL_TEXTURE_BORDER_COLOR:
1123 {
1124 GLfloat color[4];
1125 color[0] = obj->BorderColor[0] / CHAN_MAXF;
1126 color[1] = obj->BorderColor[1] / CHAN_MAXF;
1127 color[2] = obj->BorderColor[2] / CHAN_MAXF;
1128 color[3] = obj->BorderColor[3] / CHAN_MAXF;
1129 params[0] = FLOAT_TO_INT( color[0] );
1130 params[1] = FLOAT_TO_INT( color[1] );
1131 params[2] = FLOAT_TO_INT( color[2] );
1132 params[3] = FLOAT_TO_INT( color[3] );
1133 }
1134 break;
1135 case GL_TEXTURE_RESIDENT:
1136 {
1137 GLboolean resident;
1138 if (ctx->Driver.IsTextureResident)
1139 resident = ctx->Driver.IsTextureResident(ctx, obj);
1140 else
1141 resident = GL_TRUE;
1142 *params = (GLint) resident;
1143 }
1144 break;
1145 case GL_TEXTURE_PRIORITY:
1146 *params = (GLint) obj->Priority;
1147 break;
1148 case GL_TEXTURE_MIN_LOD:
1149 *params = (GLint) obj->MinLod;
1150 break;
1151 case GL_TEXTURE_MAX_LOD:
1152 *params = (GLint) obj->MaxLod;
1153 break;
1154 case GL_TEXTURE_BASE_LEVEL:
1155 *params = obj->BaseLevel;
1156 break;
1157 case GL_TEXTURE_MAX_LEVEL:
1158 *params = obj->MaxLevel;
1159 break;
1160 case GL_TEXTURE_COMPARE_SGIX:
1161 if (ctx->Extensions.SGIX_shadow) {
1162 *params = (GLint) obj->CompareFlag;
1163 }
1164 else {
1165 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
1166 return;
1167 }
1168 break;
1169 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1170 if (ctx->Extensions.SGIX_shadow) {
1171 *params = (GLint) obj->CompareOperator;
1172 }
1173 else {
1174 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
1175 return;
1176 }
1177 break;
1178 case GL_SHADOW_AMBIENT_SGIX:
1179 if (ctx->Extensions.SGIX_shadow_ambient) {
1180 /* XXX range? */
1181 *params = (GLint) CHAN_TO_FLOAT(obj->ShadowAmbient);
1182 }
1183 else {
1184 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)");
1185 return;
1186 }
1187 break;
1188 default:
1189 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
1190 }
1191 }
1192
1193
1194
1195
1196 /**********************************************************************/
1197 /* Texture Coord Generation */
1198 /**********************************************************************/
1199
1200
1201 void
1202 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
1203 {
1204 GET_CURRENT_CONTEXT(ctx);
1205 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1206 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1207 ASSERT_OUTSIDE_BEGIN_END(ctx);
1208
1209 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
1210 fprintf(stderr, "texGEN %s %s %x...\n",
1211 _mesa_lookup_enum_by_nr(coord),
1212 _mesa_lookup_enum_by_nr(pname),
1213 *(int *)params);
1214
1215 switch (coord) {
1216 case GL_S:
1217 if (pname==GL_TEXTURE_GEN_MODE) {
1218 GLenum mode = (GLenum) (GLint) *params;
1219 GLuint bits;
1220 switch (mode) {
1221 case GL_OBJECT_LINEAR:
1222 bits = TEXGEN_OBJ_LINEAR;
1223 break;
1224 case GL_EYE_LINEAR:
1225 bits = TEXGEN_EYE_LINEAR;
1226 break;
1227 case GL_REFLECTION_MAP_NV:
1228 bits = TEXGEN_REFLECTION_MAP_NV;
1229 break;
1230 case GL_NORMAL_MAP_NV:
1231 bits = TEXGEN_NORMAL_MAP_NV;
1232 break;
1233 case GL_SPHERE_MAP:
1234 bits = TEXGEN_SPHERE_MAP;
1235 break;
1236 default:
1237 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1238 return;
1239 }
1240 if (texUnit->GenModeS == mode)
1241 return;
1242 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1243 texUnit->GenModeS = mode;
1244 texUnit->_GenBitS = bits;
1245 }
1246 else if (pname==GL_OBJECT_PLANE) {
1247 if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
1248 return;
1249 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1250 texUnit->ObjectPlaneS[0] = params[0];
1251 texUnit->ObjectPlaneS[1] = params[1];
1252 texUnit->ObjectPlaneS[2] = params[2];
1253 texUnit->ObjectPlaneS[3] = params[3];
1254 }
1255 else if (pname==GL_EYE_PLANE) {
1256 GLfloat tmp[4];
1257
1258 /* Transform plane equation by the inverse modelview matrix */
1259 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
1260 _math_matrix_analyse( &ctx->ModelView );
1261 }
1262 _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
1263 if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
1264 return;
1265 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1266 COPY_4FV(texUnit->EyePlaneS, tmp);
1267 }
1268 else {
1269 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1270 return;
1271 }
1272 break;
1273 case GL_T:
1274 if (pname==GL_TEXTURE_GEN_MODE) {
1275 GLenum mode = (GLenum) (GLint) *params;
1276 GLuint bitt;
1277 switch (mode) {
1278 case GL_OBJECT_LINEAR:
1279 bitt = TEXGEN_OBJ_LINEAR;
1280 break;
1281 case GL_EYE_LINEAR:
1282 bitt = TEXGEN_EYE_LINEAR;
1283 break;
1284 case GL_REFLECTION_MAP_NV:
1285 bitt = TEXGEN_REFLECTION_MAP_NV;
1286 break;
1287 case GL_NORMAL_MAP_NV:
1288 bitt = TEXGEN_NORMAL_MAP_NV;
1289 break;
1290 case GL_SPHERE_MAP:
1291 bitt = TEXGEN_SPHERE_MAP;
1292 break;
1293 default:
1294 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1295 return;
1296 }
1297 if (texUnit->GenModeT == mode)
1298 return;
1299 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1300 texUnit->GenModeT = mode;
1301 texUnit->_GenBitT = bitt;
1302 }
1303 else if (pname==GL_OBJECT_PLANE) {
1304 if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
1305 return;
1306 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1307 texUnit->ObjectPlaneT[0] = params[0];
1308 texUnit->ObjectPlaneT[1] = params[1];
1309 texUnit->ObjectPlaneT[2] = params[2];
1310 texUnit->ObjectPlaneT[3] = params[3];
1311 }
1312 else if (pname==GL_EYE_PLANE) {
1313 GLfloat tmp[4];
1314 /* Transform plane equation by the inverse modelview matrix */
1315 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
1316 _math_matrix_analyse( &ctx->ModelView );
1317 }
1318 _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
1319 if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
1320 return;
1321 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1322 COPY_4FV(texUnit->EyePlaneT, tmp);
1323 }
1324 else {
1325 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1326 return;
1327 }
1328 break;
1329 case GL_R:
1330 if (pname==GL_TEXTURE_GEN_MODE) {
1331 GLenum mode = (GLenum) (GLint) *params;
1332 GLuint bitr;
1333 switch (mode) {
1334 case GL_OBJECT_LINEAR:
1335 bitr = TEXGEN_OBJ_LINEAR;
1336 break;
1337 case GL_REFLECTION_MAP_NV:
1338 bitr = TEXGEN_REFLECTION_MAP_NV;
1339 break;
1340 case GL_NORMAL_MAP_NV:
1341 bitr = TEXGEN_NORMAL_MAP_NV;
1342 break;
1343 case GL_EYE_LINEAR:
1344 bitr = TEXGEN_EYE_LINEAR;
1345 break;
1346 default:
1347 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1348 return;
1349 }
1350 if (texUnit->GenModeR == mode)
1351 return;
1352 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1353 texUnit->GenModeR = mode;
1354 texUnit->_GenBitR = bitr;
1355 }
1356 else if (pname==GL_OBJECT_PLANE) {
1357 if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
1358 return;
1359 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1360 texUnit->ObjectPlaneR[0] = params[0];
1361 texUnit->ObjectPlaneR[1] = params[1];
1362 texUnit->ObjectPlaneR[2] = params[2];
1363 texUnit->ObjectPlaneR[3] = params[3];
1364 }
1365 else if (pname==GL_EYE_PLANE) {
1366 GLfloat tmp[4];
1367 /* Transform plane equation by the inverse modelview matrix */
1368 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
1369 _math_matrix_analyse( &ctx->ModelView );
1370 }
1371 _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
1372 if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
1373 return;
1374 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1375 COPY_4FV(texUnit->EyePlaneR, tmp);
1376 }
1377 else {
1378 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1379 return;
1380 }
1381 break;
1382 case GL_Q:
1383 if (pname==GL_TEXTURE_GEN_MODE) {
1384 GLenum mode = (GLenum) (GLint) *params;
1385 GLuint bitq;
1386 switch (mode) {
1387 case GL_OBJECT_LINEAR:
1388 bitq = TEXGEN_OBJ_LINEAR;
1389 break;
1390 case GL_EYE_LINEAR:
1391 bitq = TEXGEN_EYE_LINEAR;
1392 break;
1393 default:
1394 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1395 return;
1396 }
1397 if (texUnit->GenModeQ == mode)
1398 return;
1399 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1400 texUnit->GenModeQ = mode;
1401 texUnit->_GenBitQ = bitq;
1402 }
1403 else if (pname==GL_OBJECT_PLANE) {
1404 if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
1405 return;
1406 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1407 texUnit->ObjectPlaneQ[0] = params[0];
1408 texUnit->ObjectPlaneQ[1] = params[1];
1409 texUnit->ObjectPlaneQ[2] = params[2];
1410 texUnit->ObjectPlaneQ[3] = params[3];
1411 }
1412 else if (pname==GL_EYE_PLANE) {
1413 GLfloat tmp[4];
1414 /* Transform plane equation by the inverse modelview matrix */
1415 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
1416 _math_matrix_analyse( &ctx->ModelView );
1417 }
1418 _mesa_transform_vector( tmp, params, ctx->ModelView.inv );
1419 if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
1420 return;
1421 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1422 COPY_4FV(texUnit->EyePlaneQ, tmp);
1423 }
1424 else {
1425 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1426 return;
1427 }
1428 break;
1429 default:
1430 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
1431 return;
1432 }
1433
1434 if (ctx->Driver.TexGen)
1435 ctx->Driver.TexGen( ctx, coord, pname, params );
1436 }
1437
1438
1439 void
1440 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
1441 {
1442 GLfloat p[4];
1443 p[0] = params[0];
1444 p[1] = params[1];
1445 p[2] = params[2];
1446 p[3] = params[3];
1447 _mesa_TexGenfv(coord, pname, p);
1448 }
1449
1450
1451 void
1452 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
1453 {
1454 GLfloat p = (GLfloat) param;
1455 _mesa_TexGenfv( coord, pname, &p );
1456 }
1457
1458
1459 void
1460 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
1461 {
1462 GLfloat p[4];
1463 p[0] = params[0];
1464 p[1] = params[1];
1465 p[2] = params[2];
1466 p[3] = params[3];
1467 _mesa_TexGenfv( coord, pname, p );
1468 }
1469
1470
1471 void
1472 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
1473 {
1474 _mesa_TexGenfv(coord, pname, &param);
1475 }
1476
1477
1478 void
1479 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
1480 {
1481 _mesa_TexGeniv( coord, pname, &param );
1482 }
1483
1484
1485
1486 void
1487 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
1488 {
1489 GET_CURRENT_CONTEXT(ctx);
1490 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1491 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1492 ASSERT_OUTSIDE_BEGIN_END(ctx);
1493
1494 switch (coord) {
1495 case GL_S:
1496 if (pname==GL_TEXTURE_GEN_MODE) {
1497 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
1498 }
1499 else if (pname==GL_OBJECT_PLANE) {
1500 COPY_4V( params, texUnit->ObjectPlaneS );
1501 }
1502 else if (pname==GL_EYE_PLANE) {
1503 COPY_4V( params, texUnit->EyePlaneS );
1504 }
1505 else {
1506 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
1507 return;
1508 }
1509 break;
1510 case GL_T:
1511 if (pname==GL_TEXTURE_GEN_MODE) {
1512 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
1513 }
1514 else if (pname==GL_OBJECT_PLANE) {
1515 COPY_4V( params, texUnit->ObjectPlaneT );
1516 }
1517 else if (pname==GL_EYE_PLANE) {
1518 COPY_4V( params, texUnit->EyePlaneT );
1519 }
1520 else {
1521 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
1522 return;
1523 }
1524 break;
1525 case GL_R:
1526 if (pname==GL_TEXTURE_GEN_MODE) {
1527 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
1528 }
1529 else if (pname==GL_OBJECT_PLANE) {
1530 COPY_4V( params, texUnit->ObjectPlaneR );
1531 }
1532 else if (pname==GL_EYE_PLANE) {
1533 COPY_4V( params, texUnit->EyePlaneR );
1534 }
1535 else {
1536 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
1537 return;
1538 }
1539 break;
1540 case GL_Q:
1541 if (pname==GL_TEXTURE_GEN_MODE) {
1542 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
1543 }
1544 else if (pname==GL_OBJECT_PLANE) {
1545 COPY_4V( params, texUnit->ObjectPlaneQ );
1546 }
1547 else if (pname==GL_EYE_PLANE) {
1548 COPY_4V( params, texUnit->EyePlaneQ );
1549 }
1550 else {
1551 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
1552 return;
1553 }
1554 break;
1555 default:
1556 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
1557 return;
1558 }
1559 }
1560
1561
1562
1563 void
1564 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
1565 {
1566 GET_CURRENT_CONTEXT(ctx);
1567 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1568 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1569 ASSERT_OUTSIDE_BEGIN_END(ctx);
1570
1571 switch (coord) {
1572 case GL_S:
1573 if (pname==GL_TEXTURE_GEN_MODE) {
1574 params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
1575 }
1576 else if (pname==GL_OBJECT_PLANE) {
1577 COPY_4V( params, texUnit->ObjectPlaneS );
1578 }
1579 else if (pname==GL_EYE_PLANE) {
1580 COPY_4V( params, texUnit->EyePlaneS );
1581 }
1582 else {
1583 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1584 return;
1585 }
1586 break;
1587 case GL_T:
1588 if (pname==GL_TEXTURE_GEN_MODE) {
1589 params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
1590 }
1591 else if (pname==GL_OBJECT_PLANE) {
1592 COPY_4V( params, texUnit->ObjectPlaneT );
1593 }
1594 else if (pname==GL_EYE_PLANE) {
1595 COPY_4V( params, texUnit->EyePlaneT );
1596 }
1597 else {
1598 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1599 return;
1600 }
1601 break;
1602 case GL_R:
1603 if (pname==GL_TEXTURE_GEN_MODE) {
1604 params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
1605 }
1606 else if (pname==GL_OBJECT_PLANE) {
1607 COPY_4V( params, texUnit->ObjectPlaneR );
1608 }
1609 else if (pname==GL_EYE_PLANE) {
1610 COPY_4V( params, texUnit->EyePlaneR );
1611 }
1612 else {
1613 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1614 return;
1615 }
1616 break;
1617 case GL_Q:
1618 if (pname==GL_TEXTURE_GEN_MODE) {
1619 params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
1620 }
1621 else if (pname==GL_OBJECT_PLANE) {
1622 COPY_4V( params, texUnit->ObjectPlaneQ );
1623 }
1624 else if (pname==GL_EYE_PLANE) {
1625 COPY_4V( params, texUnit->EyePlaneQ );
1626 }
1627 else {
1628 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
1629 return;
1630 }
1631 break;
1632 default:
1633 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
1634 return;
1635 }
1636 }
1637
1638
1639
1640 void
1641 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
1642 {
1643 GET_CURRENT_CONTEXT(ctx);
1644 GLuint tUnit = ctx->Texture.CurrentTransformUnit;
1645 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1646 ASSERT_OUTSIDE_BEGIN_END(ctx);
1647
1648 switch (coord) {
1649 case GL_S:
1650 if (pname==GL_TEXTURE_GEN_MODE) {
1651 params[0] = texUnit->GenModeS;
1652 }
1653 else if (pname==GL_OBJECT_PLANE) {
1654 params[0] = (GLint) texUnit->ObjectPlaneS[0];
1655 params[1] = (GLint) texUnit->ObjectPlaneS[1];
1656 params[2] = (GLint) texUnit->ObjectPlaneS[2];
1657 params[3] = (GLint) texUnit->ObjectPlaneS[3];
1658 }
1659 else if (pname==GL_EYE_PLANE) {
1660 params[0] = (GLint) texUnit->EyePlaneS[0];
1661 params[1] = (GLint) texUnit->EyePlaneS[1];
1662 params[2] = (GLint) texUnit->EyePlaneS[2];
1663 params[3] = (GLint) texUnit->EyePlaneS[3];
1664 }
1665 else {
1666 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1667 return;
1668 }
1669 break;
1670 case GL_T:
1671 if (pname==GL_TEXTURE_GEN_MODE) {
1672 params[0] = texUnit->GenModeT;
1673 }
1674 else if (pname==GL_OBJECT_PLANE) {
1675 params[0] = (GLint) texUnit->ObjectPlaneT[0];
1676 params[1] = (GLint) texUnit->ObjectPlaneT[1];
1677 params[2] = (GLint) texUnit->ObjectPlaneT[2];
1678 params[3] = (GLint) texUnit->ObjectPlaneT[3];
1679 }
1680 else if (pname==GL_EYE_PLANE) {
1681 params[0] = (GLint) texUnit->EyePlaneT[0];
1682 params[1] = (GLint) texUnit->EyePlaneT[1];
1683 params[2] = (GLint) texUnit->EyePlaneT[2];
1684 params[3] = (GLint) texUnit->EyePlaneT[3];
1685 }
1686 else {
1687 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1688 return;
1689 }
1690 break;
1691 case GL_R:
1692 if (pname==GL_TEXTURE_GEN_MODE) {
1693 params[0] = texUnit->GenModeR;
1694 }
1695 else if (pname==GL_OBJECT_PLANE) {
1696 params[0] = (GLint) texUnit->ObjectPlaneR[0];
1697 params[1] = (GLint) texUnit->ObjectPlaneR[1];
1698 params[2] = (GLint) texUnit->ObjectPlaneR[2];
1699 params[3] = (GLint) texUnit->ObjectPlaneR[3];
1700 }
1701 else if (pname==GL_EYE_PLANE) {
1702 params[0] = (GLint) texUnit->EyePlaneR[0];
1703 params[1] = (GLint) texUnit->EyePlaneR[1];
1704 params[2] = (GLint) texUnit->EyePlaneR[2];
1705 params[3] = (GLint) texUnit->EyePlaneR[3];
1706 }
1707 else {
1708 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1709 return;
1710 }
1711 break;
1712 case GL_Q:
1713 if (pname==GL_TEXTURE_GEN_MODE) {
1714 params[0] = texUnit->GenModeQ;
1715 }
1716 else if (pname==GL_OBJECT_PLANE) {
1717 params[0] = (GLint) texUnit->ObjectPlaneQ[0];
1718 params[1] = (GLint) texUnit->ObjectPlaneQ[1];
1719 params[2] = (GLint) texUnit->ObjectPlaneQ[2];
1720 params[3] = (GLint) texUnit->ObjectPlaneQ[3];
1721 }
1722 else if (pname==GL_EYE_PLANE) {
1723 params[0] = (GLint) texUnit->EyePlaneQ[0];
1724 params[1] = (GLint) texUnit->EyePlaneQ[1];
1725 params[2] = (GLint) texUnit->EyePlaneQ[2];
1726 params[3] = (GLint) texUnit->EyePlaneQ[3];
1727 }
1728 else {
1729 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
1730 return;
1731 }
1732 break;
1733 default:
1734 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
1735 return;
1736 }
1737 }
1738
1739
1740 /* GL_ARB_multitexture */
1741 void
1742 _mesa_ActiveTextureARB( GLenum target )
1743 {
1744 GET_CURRENT_CONTEXT(ctx);
1745 GLuint texUnit = target - GL_TEXTURE0_ARB;
1746 ASSERT_OUTSIDE_BEGIN_END(ctx);
1747
1748 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1749 fprintf(stderr, "glActiveTexture %s\n",
1750 _mesa_lookup_enum_by_nr(target));
1751
1752 if (texUnit > ctx->Const.MaxTextureUnits) {
1753 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
1754 return;
1755 }
1756
1757 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1758 ctx->Texture.CurrentUnit = texUnit;
1759 ctx->Texture.CurrentTransformUnit = texUnit;
1760 if (ctx->Driver.ActiveTexture) {
1761 (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
1762 }
1763 }
1764
1765
1766 /* GL_ARB_multitexture */
1767 void
1768 _mesa_ClientActiveTextureARB( GLenum target )
1769 {
1770 GET_CURRENT_CONTEXT(ctx);
1771 GLuint texUnit = target - GL_TEXTURE0_ARB;
1772 ASSERT_OUTSIDE_BEGIN_END(ctx);
1773
1774 if (texUnit > ctx->Const.MaxTextureUnits) {
1775 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
1776 return;
1777 }
1778
1779 FLUSH_VERTICES(ctx, _NEW_ARRAY);
1780 ctx->Array.ActiveTexture = texUnit;
1781 }