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