2a6abedf823ee6a2b13d0edfec4c28e3c7049e16
[mesa.git] / src / mesa / main / texstate.c
1 /* $Id: texstate.c,v 1.87 2002/11/05 20:58:37 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 5.0
6 *
7 * Copyright (C) 1999-2002 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 #include "glheader.h"
29 #include "colormac.h"
30 #include "context.h"
31 #include "enums.h"
32 #include "extensions.h"
33 #include "macros.h"
34 #include "texobj.h"
35 #include "teximage.h"
36 #include "texstate.h"
37 #include "mtypes.h"
38 #include "math/m_xform.h"
39 #include "math/m_matrix.h"
40
41
42
43 #ifdef SPECIALCAST
44 /* Needed for an Amiga compiler */
45 #define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
46 #define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
47 #else
48 /* all other compilers */
49 #define ENUM_TO_FLOAT(X) ((GLfloat)(X))
50 #define ENUM_TO_DOUBLE(X) ((GLdouble)(X))
51 #endif
52
53
54
55 void
56 _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
57 {
58 GLuint i;
59
60 ASSERT(src);
61 ASSERT(dst);
62
63 dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
64 dst->Texture._GenFlags = src->Texture._GenFlags;
65 dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
66 dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
67 dst->Texture.SharedPalette = src->Texture.SharedPalette;
68
69 /* per-unit state */
70 for (i = 0; i < src->Const.MaxTextureUnits; i++) {
71 dst->Texture.Unit[i].Enabled = src->Texture.Unit[i].Enabled;
72 dst->Texture.Unit[i].EnvMode = src->Texture.Unit[i].EnvMode;
73 COPY_4V(dst->Texture.Unit[i].EnvColor, src->Texture.Unit[i].EnvColor);
74 dst->Texture.Unit[i].TexGenEnabled = src->Texture.Unit[i].TexGenEnabled;
75 dst->Texture.Unit[i].GenModeS = src->Texture.Unit[i].GenModeS;
76 dst->Texture.Unit[i].GenModeT = src->Texture.Unit[i].GenModeT;
77 dst->Texture.Unit[i].GenModeR = src->Texture.Unit[i].GenModeR;
78 dst->Texture.Unit[i].GenModeQ = src->Texture.Unit[i].GenModeQ;
79 dst->Texture.Unit[i]._GenBitS = src->Texture.Unit[i]._GenBitS;
80 dst->Texture.Unit[i]._GenBitT = src->Texture.Unit[i]._GenBitT;
81 dst->Texture.Unit[i]._GenBitR = src->Texture.Unit[i]._GenBitR;
82 dst->Texture.Unit[i]._GenBitQ = src->Texture.Unit[i]._GenBitQ;
83 dst->Texture.Unit[i]._GenFlags = src->Texture.Unit[i]._GenFlags;
84 COPY_4V(dst->Texture.Unit[i].ObjectPlaneS, src->Texture.Unit[i].ObjectPlaneS);
85 COPY_4V(dst->Texture.Unit[i].ObjectPlaneT, src->Texture.Unit[i].ObjectPlaneT);
86 COPY_4V(dst->Texture.Unit[i].ObjectPlaneR, src->Texture.Unit[i].ObjectPlaneR);
87 COPY_4V(dst->Texture.Unit[i].ObjectPlaneQ, src->Texture.Unit[i].ObjectPlaneQ);
88 COPY_4V(dst->Texture.Unit[i].EyePlaneS, src->Texture.Unit[i].EyePlaneS);
89 COPY_4V(dst->Texture.Unit[i].EyePlaneT, src->Texture.Unit[i].EyePlaneT);
90 COPY_4V(dst->Texture.Unit[i].EyePlaneR, src->Texture.Unit[i].EyePlaneR);
91 COPY_4V(dst->Texture.Unit[i].EyePlaneQ, src->Texture.Unit[i].EyePlaneQ);
92 dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias;
93
94 /* GL_EXT_texture_env_combine */
95 dst->Texture.Unit[i].CombineModeRGB = src->Texture.Unit[i].CombineModeRGB;
96 dst->Texture.Unit[i].CombineModeA = src->Texture.Unit[i].CombineModeA;
97 COPY_3V(dst->Texture.Unit[i].CombineSourceRGB, src->Texture.Unit[i].CombineSourceRGB);
98 COPY_3V(dst->Texture.Unit[i].CombineSourceA, src->Texture.Unit[i].CombineSourceA);
99 COPY_3V(dst->Texture.Unit[i].CombineOperandRGB, src->Texture.Unit[i].CombineOperandRGB);
100 COPY_3V(dst->Texture.Unit[i].CombineOperandA, src->Texture.Unit[i].CombineOperandA);
101 dst->Texture.Unit[i].CombineScaleShiftRGB = src->Texture.Unit[i].CombineScaleShiftRGB;
102 dst->Texture.Unit[i].CombineScaleShiftA = src->Texture.Unit[i].CombineScaleShiftA;
103
104 /* texture object state */
105 _mesa_copy_texture_object(dst->Texture.Unit[i].Current1D,
106 src->Texture.Unit[i].Current1D);
107 _mesa_copy_texture_object(dst->Texture.Unit[i].Current2D,
108 src->Texture.Unit[i].Current2D);
109 _mesa_copy_texture_object(dst->Texture.Unit[i].Current3D,
110 src->Texture.Unit[i].Current3D);
111 _mesa_copy_texture_object(dst->Texture.Unit[i].CurrentCubeMap,
112 src->Texture.Unit[i].CurrentCubeMap);
113 _mesa_copy_texture_object(dst->Texture.Unit[i].CurrentRect,
114 src->Texture.Unit[i].CurrentRect);
115 }
116 }
117
118
119 /**********************************************************************/
120 /* Texture Environment */
121 /**********************************************************************/
122
123
124 void
125 _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
126 {
127 GET_CURRENT_CONTEXT(ctx);
128 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
129 ASSERT_OUTSIDE_BEGIN_END(ctx);
130
131 #define TE_ERROR(errCode, msg, value) \
132 _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
133
134 if (target == GL_TEXTURE_ENV) {
135 switch (pname) {
136 case GL_TEXTURE_ENV_MODE:
137 {
138 const GLenum mode = (GLenum) (GLint) *param;
139 if (mode == GL_MODULATE ||
140 mode == GL_BLEND ||
141 mode == GL_DECAL ||
142 mode == GL_REPLACE ||
143 (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
144 (mode == GL_COMBINE_EXT &&
145 (ctx->Extensions.EXT_texture_env_combine ||
146 ctx->Extensions.ARB_texture_env_combine))) {
147 /* legal */
148 if (texUnit->EnvMode == mode)
149 return;
150 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
151 texUnit->EnvMode = mode;
152 }
153 else {
154 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
155 return;
156 }
157 }
158 break;
159 case GL_TEXTURE_ENV_COLOR:
160 {
161 GLfloat tmp[4];
162 tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
163 tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
164 tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
165 tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
166 if (TEST_EQ_4V(tmp, texUnit->EnvColor))
167 return;
168 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
169 COPY_4FV(texUnit->EnvColor, tmp);
170 }
171 break;
172 case GL_COMBINE_RGB_EXT:
173 if (ctx->Extensions.EXT_texture_env_combine ||
174 ctx->Extensions.ARB_texture_env_combine) {
175 const GLenum mode = (GLenum) (GLint) *param;
176 switch (mode) {
177 case GL_REPLACE:
178 case GL_MODULATE:
179 case GL_ADD:
180 case GL_ADD_SIGNED_EXT:
181 case GL_INTERPOLATE_EXT:
182 /* OK */
183 break;
184 case GL_SUBTRACT_ARB:
185 if (!ctx->Extensions.ARB_texture_env_combine) {
186 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
187 return;
188 }
189 break;
190 case GL_DOT3_RGB_EXT:
191 case GL_DOT3_RGBA_EXT:
192 if (!ctx->Extensions.EXT_texture_env_dot3) {
193 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
194 return;
195 }
196 break;
197 case GL_DOT3_RGB_ARB:
198 case GL_DOT3_RGBA_ARB:
199 if (!ctx->Extensions.ARB_texture_env_dot3) {
200 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
201 return;
202 }
203 break;
204 default:
205 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
206 return;
207 }
208 if (texUnit->CombineModeRGB == mode)
209 return;
210 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
211 texUnit->CombineModeRGB = mode;
212 }
213 else {
214 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
215 return;
216 }
217 break;
218 case GL_COMBINE_ALPHA_EXT:
219 if (ctx->Extensions.EXT_texture_env_combine ||
220 ctx->Extensions.ARB_texture_env_combine) {
221 const GLenum mode = (GLenum) (GLint) *param;
222 if (mode == GL_REPLACE ||
223 mode == GL_MODULATE ||
224 mode == GL_ADD ||
225 mode == GL_ADD_SIGNED_EXT ||
226 mode == GL_INTERPOLATE_EXT ||
227 (mode == GL_SUBTRACT_ARB &&
228 ctx->Extensions.ARB_texture_env_combine)) {
229 /* legal */
230 if (texUnit->CombineModeA == mode)
231 return;
232 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
233 texUnit->CombineModeA = mode;
234 }
235 else {
236 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
237 return;
238 }
239 }
240 else {
241 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
242 return;
243 }
244 break;
245 case GL_SOURCE0_RGB_EXT:
246 case GL_SOURCE1_RGB_EXT:
247 case GL_SOURCE2_RGB_EXT:
248 if (ctx->Extensions.EXT_texture_env_combine ||
249 ctx->Extensions.ARB_texture_env_combine) {
250 const GLenum source = (GLenum) (GLint) *param;
251 const GLuint s = pname - GL_SOURCE0_RGB_EXT;
252 if (source == GL_TEXTURE ||
253 source == GL_CONSTANT_EXT ||
254 source == GL_PRIMARY_COLOR_EXT ||
255 source == GL_PREVIOUS_EXT ||
256 (ctx->Extensions.ARB_texture_env_crossbar &&
257 source >= GL_TEXTURE0_ARB &&
258 source < GL_TEXTURE0_ARB + ctx->Const.MaxTextureUnits)) {
259 /* legal */
260 if (texUnit->CombineSourceRGB[s] == source)
261 return;
262 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
263 texUnit->CombineSourceRGB[s] = source;
264 }
265 else {
266 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
267 return;
268 }
269 }
270 else {
271 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
272 return;
273 }
274 break;
275 case GL_SOURCE0_ALPHA_EXT:
276 case GL_SOURCE1_ALPHA_EXT:
277 case GL_SOURCE2_ALPHA_EXT:
278 if (ctx->Extensions.EXT_texture_env_combine ||
279 ctx->Extensions.ARB_texture_env_combine) {
280 const GLenum source = (GLenum) (GLint) *param;
281 const GLuint s = pname - GL_SOURCE0_ALPHA_EXT;
282 if (source == GL_TEXTURE ||
283 source == GL_CONSTANT_EXT ||
284 source == GL_PRIMARY_COLOR_EXT ||
285 source == GL_PREVIOUS_EXT ||
286 (ctx->Extensions.ARB_texture_env_crossbar &&
287 source >= GL_TEXTURE0_ARB &&
288 source < GL_TEXTURE0_ARB + ctx->Const.MaxTextureUnits)) {
289 /* legal */
290 if (texUnit->CombineSourceA[s] == source)
291 return;
292 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
293 texUnit->CombineSourceA[s] = source;
294 }
295 else {
296 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
297 return;
298 }
299 }
300 else {
301 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
302 return;
303 }
304 break;
305 case GL_OPERAND0_RGB_EXT:
306 case GL_OPERAND1_RGB_EXT:
307 if (ctx->Extensions.EXT_texture_env_combine ||
308 ctx->Extensions.ARB_texture_env_combine) {
309 const GLenum operand = (GLenum) (GLint) *param;
310 const GLuint s = pname - GL_OPERAND0_RGB_EXT;
311 switch (operand) {
312 case GL_SRC_COLOR:
313 case GL_ONE_MINUS_SRC_COLOR:
314 case GL_SRC_ALPHA:
315 case GL_ONE_MINUS_SRC_ALPHA:
316 if (texUnit->CombineOperandRGB[s] == operand)
317 return;
318 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
319 texUnit->CombineOperandRGB[s] = operand;
320 break;
321 default:
322 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
323 return;
324 }
325 }
326 else {
327 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
328 return;
329 }
330 break;
331 case GL_OPERAND0_ALPHA_EXT:
332 case GL_OPERAND1_ALPHA_EXT:
333 if (ctx->Extensions.EXT_texture_env_combine ||
334 ctx->Extensions.ARB_texture_env_combine) {
335 const GLenum operand = (GLenum) (GLint) *param;
336 switch (operand) {
337 case GL_SRC_ALPHA:
338 case GL_ONE_MINUS_SRC_ALPHA:
339 if (texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA_EXT] ==
340 operand)
341 return;
342 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
343 texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA_EXT] = operand;
344 break;
345 default:
346 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
347 return;
348 }
349 }
350 else {
351 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
352 return;
353 }
354 break;
355 case GL_OPERAND2_RGB_EXT:
356 if (ctx->Extensions.EXT_texture_env_combine ||
357 ctx->Extensions.ARB_texture_env_combine) {
358 const GLenum operand = (GLenum) (GLint) *param;
359 switch (operand) {
360 case GL_SRC_COLOR: /* ARB combine only */
361 case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
362 case GL_SRC_ALPHA:
363 case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
364 if (texUnit->CombineOperandRGB[2] == operand)
365 return;
366 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
367 texUnit->CombineOperandRGB[2] = operand;
368 default:
369 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
370 return;
371 }
372 }
373 else {
374 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
375 return;
376 }
377 break;
378 case GL_OPERAND2_ALPHA_EXT:
379 if (ctx->Extensions.EXT_texture_env_combine ||
380 ctx->Extensions.ARB_texture_env_combine) {
381 const GLenum operand = (GLenum) (GLint) *param;
382 switch (operand) {
383 case GL_SRC_ALPHA:
384 case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
385 if (texUnit->CombineOperandA[2] == operand)
386 return;
387 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
388 texUnit->CombineOperandA[2] = operand;
389 break;
390 default:
391 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
392 return;
393 }
394 }
395 else {
396 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
397 return;
398 }
399 break;
400 case GL_RGB_SCALE_EXT:
401 if (ctx->Extensions.EXT_texture_env_combine ||
402 ctx->Extensions.ARB_texture_env_combine) {
403 GLuint newshift;
404 if (*param == 1.0) {
405 newshift = 0;
406 }
407 else if (*param == 2.0) {
408 newshift = 1;
409 }
410 else if (*param == 4.0) {
411 newshift = 2;
412 }
413 else {
414 _mesa_error( ctx, GL_INVALID_VALUE,
415 "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
416 return;
417 }
418 if (texUnit->CombineScaleShiftRGB == newshift)
419 return;
420 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
421 texUnit->CombineScaleShiftRGB = newshift;
422 }
423 else {
424 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
425 return;
426 }
427 break;
428 case GL_ALPHA_SCALE:
429 if (ctx->Extensions.EXT_texture_env_combine ||
430 ctx->Extensions.ARB_texture_env_combine) {
431 GLuint newshift;
432 if (*param == 1.0) {
433 newshift = 0;
434 }
435 else if (*param == 2.0) {
436 newshift = 1;
437 }
438 else if (*param == 4.0) {
439 newshift = 2;
440 }
441 else {
442 _mesa_error( ctx, GL_INVALID_VALUE,
443 "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
444 return;
445 }
446 if (texUnit->CombineScaleShiftA == newshift)
447 return;
448 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
449 texUnit->CombineScaleShiftA = newshift;
450 }
451 else {
452 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
453 return;
454 }
455 break;
456 default:
457 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
458 return;
459 }
460 }
461 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
462 /* GL_EXT_texture_lod_bias */
463 if (!ctx->Extensions.EXT_texture_lod_bias) {
464 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
465 return;
466 }
467 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
468 if (texUnit->LodBias == param[0])
469 return;
470 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
471 texUnit->LodBias = CLAMP(param[0], -ctx->Const.MaxTextureLodBias,
472 ctx->Const.MaxTextureLodBias);
473 }
474 else {
475 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
476 return;
477 }
478 }
479 else if (target == GL_POINT_SPRITE_NV) {
480 /* GL_NV_point_sprite */
481 if (!ctx->Extensions.NV_point_sprite) {
482 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
483 return;
484 }
485 if (pname == GL_COORD_REPLACE_NV) {
486 const GLenum value = (GLenum) param[0];
487 if (value == GL_TRUE || value == GL_FALSE) {
488 /* It's kind of weird to set point state via glTexEnv,
489 * but that's what the spec calls for.
490 */
491 const GLboolean state = (GLboolean) value;
492 if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
493 return;
494 FLUSH_VERTICES(ctx, _NEW_POINT);
495 ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
496 }
497 else {
498 _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
499 return;
500 }
501 }
502 else {
503 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
504 return;
505 }
506 }
507 else {
508 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
509 return;
510 }
511
512 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
513 _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
514 _mesa_lookup_enum_by_nr(target),
515 _mesa_lookup_enum_by_nr(pname),
516 *param,
517 _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));
518
519 /* Tell device driver about the new texture environment */
520 if (ctx->Driver.TexEnv) {
521 (*ctx->Driver.TexEnv)( ctx, target, pname, param );
522 }
523 }
524
525
526 void
527 _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
528 {
529 _mesa_TexEnvfv( target, pname, &param );
530 }
531
532
533
534 void
535 _mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
536 {
537 GLfloat p[4];
538 p[0] = (GLfloat) param;
539 p[1] = p[2] = p[3] = 0.0;
540 _mesa_TexEnvfv( target, pname, p );
541 }
542
543
544 void
545 _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
546 {
547 GLfloat p[4];
548 if (pname == GL_TEXTURE_ENV_COLOR) {
549 p[0] = INT_TO_FLOAT( param[0] );
550 p[1] = INT_TO_FLOAT( param[1] );
551 p[2] = INT_TO_FLOAT( param[2] );
552 p[3] = INT_TO_FLOAT( param[3] );
553 }
554 else {
555 p[0] = (GLfloat) param[0];
556 p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */
557 }
558 _mesa_TexEnvfv( target, pname, p );
559 }
560
561
562 void
563 _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
564 {
565 GET_CURRENT_CONTEXT(ctx);
566 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
567 ASSERT_OUTSIDE_BEGIN_END(ctx);
568
569 if (target == GL_TEXTURE_ENV) {
570 switch (pname) {
571 case GL_TEXTURE_ENV_MODE:
572 *params = ENUM_TO_FLOAT(texUnit->EnvMode);
573 break;
574 case GL_TEXTURE_ENV_COLOR:
575 COPY_4FV( params, texUnit->EnvColor );
576 break;
577 case GL_COMBINE_RGB_EXT:
578 if (ctx->Extensions.EXT_texture_env_combine ||
579 ctx->Extensions.ARB_texture_env_combine) {
580 *params = (GLfloat) texUnit->CombineModeRGB;
581 }
582 else {
583 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
584 }
585 break;
586 case GL_COMBINE_ALPHA_EXT:
587 if (ctx->Extensions.EXT_texture_env_combine ||
588 ctx->Extensions.ARB_texture_env_combine) {
589 *params = (GLfloat) texUnit->CombineModeA;
590 }
591 else {
592 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
593 }
594 break;
595 case GL_SOURCE0_RGB_EXT:
596 if (ctx->Extensions.EXT_texture_env_combine ||
597 ctx->Extensions.ARB_texture_env_combine) {
598 *params = (GLfloat) texUnit->CombineSourceRGB[0];
599 }
600 else {
601 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
602 }
603 break;
604 case GL_SOURCE1_RGB_EXT:
605 if (ctx->Extensions.EXT_texture_env_combine ||
606 ctx->Extensions.ARB_texture_env_combine) {
607 *params = (GLfloat) texUnit->CombineSourceRGB[1];
608 }
609 else {
610 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
611 }
612 break;
613 case GL_SOURCE2_RGB_EXT:
614 if (ctx->Extensions.EXT_texture_env_combine ||
615 ctx->Extensions.ARB_texture_env_combine) {
616 *params = (GLfloat) texUnit->CombineSourceRGB[2];
617 }
618 else {
619 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
620 }
621 break;
622 case GL_SOURCE0_ALPHA_EXT:
623 if (ctx->Extensions.EXT_texture_env_combine ||
624 ctx->Extensions.ARB_texture_env_combine) {
625 *params = (GLfloat) texUnit->CombineSourceA[0];
626 }
627 else {
628 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
629 }
630 break;
631 case GL_SOURCE1_ALPHA_EXT:
632 if (ctx->Extensions.EXT_texture_env_combine ||
633 ctx->Extensions.ARB_texture_env_combine) {
634 *params = (GLfloat) texUnit->CombineSourceA[1];
635 }
636 else {
637 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
638 }
639 break;
640 case GL_SOURCE2_ALPHA_EXT:
641 if (ctx->Extensions.EXT_texture_env_combine ||
642 ctx->Extensions.ARB_texture_env_combine) {
643 *params = (GLfloat) texUnit->CombineSourceA[2];
644 }
645 else {
646 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
647 }
648 break;
649 case GL_OPERAND0_RGB_EXT:
650 if (ctx->Extensions.EXT_texture_env_combine ||
651 ctx->Extensions.ARB_texture_env_combine) {
652 *params = (GLfloat) texUnit->CombineOperandRGB[0];
653 }
654 else {
655 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
656 }
657 break;
658 case GL_OPERAND1_RGB_EXT:
659 if (ctx->Extensions.EXT_texture_env_combine ||
660 ctx->Extensions.ARB_texture_env_combine) {
661 *params = (GLfloat) texUnit->CombineOperandRGB[1];
662 }
663 else {
664 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
665 }
666 break;
667 case GL_OPERAND2_RGB_EXT:
668 if (ctx->Extensions.EXT_texture_env_combine ||
669 ctx->Extensions.ARB_texture_env_combine) {
670 *params = (GLfloat) texUnit->CombineOperandRGB[2];
671 }
672 else {
673 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
674 }
675 break;
676 case GL_OPERAND0_ALPHA_EXT:
677 if (ctx->Extensions.EXT_texture_env_combine ||
678 ctx->Extensions.ARB_texture_env_combine) {
679 *params = (GLfloat) texUnit->CombineOperandA[0];
680 }
681 else {
682 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
683 }
684 break;
685 case GL_OPERAND1_ALPHA_EXT:
686 if (ctx->Extensions.EXT_texture_env_combine ||
687 ctx->Extensions.ARB_texture_env_combine) {
688 *params = (GLfloat) texUnit->CombineOperandA[1];
689 }
690 else {
691 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
692 }
693 break;
694 case GL_OPERAND2_ALPHA_EXT:
695 if (ctx->Extensions.EXT_texture_env_combine ||
696 ctx->Extensions.ARB_texture_env_combine) {
697 *params = (GLfloat) texUnit->CombineOperandA[2];
698 }
699 else {
700 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
701 }
702 break;
703 case GL_RGB_SCALE_EXT:
704 if (ctx->Extensions.EXT_texture_env_combine ||
705 ctx->Extensions.ARB_texture_env_combine) {
706 if (texUnit->CombineScaleShiftRGB == 0)
707 *params = 1.0;
708 else if (texUnit->CombineScaleShiftRGB == 1)
709 *params = 2.0;
710 else
711 *params = 4.0;
712 }
713 else {
714 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
715 return;
716 }
717 break;
718 case GL_ALPHA_SCALE:
719 if (ctx->Extensions.EXT_texture_env_combine ||
720 ctx->Extensions.ARB_texture_env_combine) {
721 if (texUnit->CombineScaleShiftA == 0)
722 *params = 1.0;
723 else if (texUnit->CombineScaleShiftA == 1)
724 *params = 2.0;
725 else
726 *params = 4.0;
727 }
728 else {
729 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
730 return;
731 }
732 break;
733 default:
734 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
735 }
736 }
737 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
738 /* GL_EXT_texture_lod_bias */
739 if (!ctx->Extensions.EXT_texture_lod_bias) {
740 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
741 return;
742 }
743 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
744 *params = texUnit->LodBias;
745 }
746 else {
747 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
748 return;
749 }
750 }
751 else if (target == GL_POINT_SPRITE_NV) {
752 /* GL_NV_point_sprite */
753 if (!ctx->Extensions.NV_point_sprite) {
754 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
755 return;
756 }
757 if (pname == GL_COORD_REPLACE_NV) {
758 *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
759 }
760 else {
761 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
762 return;
763 }
764 }
765 else {
766 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
767 return;
768 }
769 }
770
771
772 void
773 _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
774 {
775 GET_CURRENT_CONTEXT(ctx);
776 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
777 ASSERT_OUTSIDE_BEGIN_END(ctx);
778
779 if (target == GL_TEXTURE_ENV) {
780 switch (pname) {
781 case GL_TEXTURE_ENV_MODE:
782 *params = (GLint) texUnit->EnvMode;
783 break;
784 case GL_TEXTURE_ENV_COLOR:
785 params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
786 params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
787 params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
788 params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
789 break;
790 case GL_COMBINE_RGB_EXT:
791 if (ctx->Extensions.EXT_texture_env_combine ||
792 ctx->Extensions.ARB_texture_env_combine) {
793 *params = (GLint) texUnit->CombineModeRGB;
794 }
795 else {
796 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
797 }
798 break;
799 case GL_COMBINE_ALPHA_EXT:
800 if (ctx->Extensions.EXT_texture_env_combine ||
801 ctx->Extensions.ARB_texture_env_combine) {
802 *params = (GLint) texUnit->CombineModeA;
803 }
804 else {
805 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
806 }
807 break;
808 case GL_SOURCE0_RGB_EXT:
809 if (ctx->Extensions.EXT_texture_env_combine ||
810 ctx->Extensions.ARB_texture_env_combine) {
811 *params = (GLint) texUnit->CombineSourceRGB[0];
812 }
813 else {
814 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
815 }
816 break;
817 case GL_SOURCE1_RGB_EXT:
818 if (ctx->Extensions.EXT_texture_env_combine ||
819 ctx->Extensions.ARB_texture_env_combine) {
820 *params = (GLint) texUnit->CombineSourceRGB[1];
821 }
822 else {
823 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
824 }
825 break;
826 case GL_SOURCE2_RGB_EXT:
827 if (ctx->Extensions.EXT_texture_env_combine ||
828 ctx->Extensions.ARB_texture_env_combine) {
829 *params = (GLint) texUnit->CombineSourceRGB[2];
830 }
831 else {
832 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
833 }
834 break;
835 case GL_SOURCE0_ALPHA_EXT:
836 if (ctx->Extensions.EXT_texture_env_combine ||
837 ctx->Extensions.ARB_texture_env_combine) {
838 *params = (GLint) texUnit->CombineSourceA[0];
839 }
840 else {
841 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
842 }
843 break;
844 case GL_SOURCE1_ALPHA_EXT:
845 if (ctx->Extensions.EXT_texture_env_combine ||
846 ctx->Extensions.ARB_texture_env_combine) {
847 *params = (GLint) texUnit->CombineSourceA[1];
848 }
849 else {
850 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
851 }
852 break;
853 case GL_SOURCE2_ALPHA_EXT:
854 if (ctx->Extensions.EXT_texture_env_combine ||
855 ctx->Extensions.ARB_texture_env_combine) {
856 *params = (GLint) texUnit->CombineSourceA[2];
857 }
858 else {
859 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
860 }
861 break;
862 case GL_OPERAND0_RGB_EXT:
863 if (ctx->Extensions.EXT_texture_env_combine ||
864 ctx->Extensions.ARB_texture_env_combine) {
865 *params = (GLint) texUnit->CombineOperandRGB[0];
866 }
867 else {
868 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
869 }
870 break;
871 case GL_OPERAND1_RGB_EXT:
872 if (ctx->Extensions.EXT_texture_env_combine ||
873 ctx->Extensions.ARB_texture_env_combine) {
874 *params = (GLint) texUnit->CombineOperandRGB[1];
875 }
876 else {
877 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
878 }
879 break;
880 case GL_OPERAND2_RGB_EXT:
881 if (ctx->Extensions.EXT_texture_env_combine ||
882 ctx->Extensions.ARB_texture_env_combine) {
883 *params = (GLint) texUnit->CombineOperandRGB[2];
884 }
885 else {
886 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
887 }
888 break;
889 case GL_OPERAND0_ALPHA_EXT:
890 if (ctx->Extensions.EXT_texture_env_combine ||
891 ctx->Extensions.ARB_texture_env_combine) {
892 *params = (GLint) texUnit->CombineOperandA[0];
893 }
894 else {
895 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
896 }
897 break;
898 case GL_OPERAND1_ALPHA_EXT:
899 if (ctx->Extensions.EXT_texture_env_combine ||
900 ctx->Extensions.ARB_texture_env_combine) {
901 *params = (GLint) texUnit->CombineOperandA[1];
902 }
903 else {
904 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
905 }
906 break;
907 case GL_OPERAND2_ALPHA_EXT:
908 if (ctx->Extensions.EXT_texture_env_combine ||
909 ctx->Extensions.ARB_texture_env_combine) {
910 *params = (GLint) texUnit->CombineOperandA[2];
911 }
912 else {
913 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
914 }
915 break;
916 case GL_RGB_SCALE_EXT:
917 if (ctx->Extensions.EXT_texture_env_combine ||
918 ctx->Extensions.ARB_texture_env_combine) {
919 if (texUnit->CombineScaleShiftRGB == 0)
920 *params = 1;
921 else if (texUnit->CombineScaleShiftRGB == 1)
922 *params = 2;
923 else
924 *params = 4;
925 }
926 else {
927 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
928 return;
929 }
930 break;
931 case GL_ALPHA_SCALE:
932 if (ctx->Extensions.EXT_texture_env_combine ||
933 ctx->Extensions.ARB_texture_env_combine) {
934 if (texUnit->CombineScaleShiftA == 0)
935 *params = 1;
936 else if (texUnit->CombineScaleShiftA == 1)
937 *params = 2;
938 else
939 *params = 4;
940 }
941 else {
942 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
943 return;
944 }
945 break;
946 default:
947 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
948 }
949 }
950 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
951 /* GL_EXT_texture_lod_bias */
952 if (!ctx->Extensions.EXT_texture_lod_bias) {
953 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
954 return;
955 }
956 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
957 *params = (GLint) texUnit->LodBias;
958 }
959 else {
960 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
961 return;
962 }
963 }
964 else if (target == GL_POINT_SPRITE_NV) {
965 /* GL_NV_point_sprite */
966 if (!ctx->Extensions.NV_point_sprite) {
967 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
968 return;
969 }
970 if (pname == GL_COORD_REPLACE_NV) {
971 *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
972 }
973 else {
974 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
975 return;
976 }
977 }
978 else {
979 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
980 return;
981 }
982 }
983
984
985
986
987 /**********************************************************************/
988 /* Texture Parameters */
989 /**********************************************************************/
990
991
992 void
993 _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
994 {
995 _mesa_TexParameterfv(target, pname, &param);
996 }
997
998
999 void
1000 _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
1001 {
1002 GET_CURRENT_CONTEXT(ctx);
1003 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1004 GLenum eparam = (GLenum) (GLint) params[0];
1005 struct gl_texture_object *texObj;
1006 ASSERT_OUTSIDE_BEGIN_END(ctx);
1007
1008 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
1009 _mesa_debug(ctx, "texPARAM %s %s %d...\n",
1010 _mesa_lookup_enum_by_nr(target),
1011 _mesa_lookup_enum_by_nr(pname),
1012 eparam);
1013
1014
1015 switch (target) {
1016 case GL_TEXTURE_1D:
1017 texObj = texUnit->Current1D;
1018 break;
1019 case GL_TEXTURE_2D:
1020 texObj = texUnit->Current2D;
1021 break;
1022 case GL_TEXTURE_3D_EXT:
1023 texObj = texUnit->Current3D;
1024 break;
1025 case GL_TEXTURE_CUBE_MAP_ARB:
1026 if (!ctx->Extensions.ARB_texture_cube_map) {
1027 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
1028 return;
1029 }
1030 texObj = texUnit->CurrentCubeMap;
1031 break;
1032 case GL_TEXTURE_RECTANGLE_NV:
1033 if (!ctx->Extensions.NV_texture_rectangle) {
1034 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
1035 return;
1036 }
1037 texObj = texUnit->CurrentRect;
1038 break;
1039 default:
1040 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
1041 return;
1042 }
1043
1044 switch (pname) {
1045 case GL_TEXTURE_MIN_FILTER:
1046 /* A small optimization */
1047 if (texObj->MinFilter == eparam)
1048 return;
1049 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
1050 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1051 texObj->MinFilter = eparam;
1052 }
1053 else if ((eparam==GL_NEAREST_MIPMAP_NEAREST ||
1054 eparam==GL_LINEAR_MIPMAP_NEAREST ||
1055 eparam==GL_NEAREST_MIPMAP_LINEAR ||
1056 eparam==GL_LINEAR_MIPMAP_LINEAR) &&
1057 texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
1058 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1059 texObj->MinFilter = eparam;
1060 }
1061 else {
1062 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1063 return;
1064 }
1065 break;
1066 case GL_TEXTURE_MAG_FILTER:
1067 /* A small optimization */
1068 if (texObj->MagFilter == eparam)
1069 return;
1070
1071 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
1072 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1073 texObj->MagFilter = eparam;
1074 }
1075 else {
1076 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1077 return;
1078 }
1079 break;
1080 case GL_TEXTURE_WRAP_S:
1081 if (texObj->WrapS == eparam)
1082 return;
1083 if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
1084 (eparam == GL_CLAMP_TO_BORDER_ARB &&
1085 ctx->Extensions.ARB_texture_border_clamp)) {
1086 /* any texture target */
1087 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1088 texObj->WrapS = eparam;
1089 }
1090 else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
1091 (eparam == GL_REPEAT ||
1092 (eparam == GL_MIRRORED_REPEAT_ARB &&
1093 ctx->Extensions.ARB_texture_mirrored_repeat) ||
1094 (eparam == GL_MIRROR_CLAMP_ATI &&
1095 ctx->Extensions.ATI_texture_mirror_once) ||
1096 (eparam == GL_MIRROR_CLAMP_TO_EDGE_ATI &&
1097 ctx->Extensions.ATI_texture_mirror_once))) {
1098 /* non-rectangle texture */
1099 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1100 texObj->WrapS = eparam;
1101 }
1102 else {
1103 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1104 return;
1105 }
1106 break;
1107 case GL_TEXTURE_WRAP_T:
1108 if (texObj->WrapT == eparam)
1109 return;
1110 if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
1111 (eparam == GL_CLAMP_TO_BORDER_ARB &&
1112 ctx->Extensions.ARB_texture_border_clamp)) {
1113 /* any texture target */
1114 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1115 texObj->WrapT = eparam;
1116 }
1117 else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
1118 (eparam == GL_REPEAT ||
1119 (eparam == GL_MIRRORED_REPEAT_ARB &&
1120 ctx->Extensions.ARB_texture_mirrored_repeat) ||
1121 (eparam == GL_MIRROR_CLAMP_ATI &&
1122 ctx->Extensions.ATI_texture_mirror_once) ||
1123 (eparam == GL_MIRROR_CLAMP_TO_EDGE_ATI &&
1124 ctx->Extensions.ATI_texture_mirror_once))) {
1125 /* non-rectangle texture */
1126 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1127 texObj->WrapT = eparam;
1128 }
1129 else {
1130 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1131 return;
1132 }
1133 break;
1134 case GL_TEXTURE_WRAP_R_EXT:
1135 if (texObj->WrapR == eparam)
1136 return;
1137 if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
1138 (eparam == GL_CLAMP_TO_BORDER_ARB &&
1139 ctx->Extensions.ARB_texture_border_clamp)) {
1140 /* any texture target */
1141 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1142 texObj->WrapR = eparam;
1143 }
1144 else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
1145 (eparam == GL_REPEAT ||
1146 (eparam == GL_MIRRORED_REPEAT_ARB &&
1147 ctx->Extensions.ARB_texture_mirrored_repeat) ||
1148 (eparam == GL_MIRROR_CLAMP_ATI &&
1149 ctx->Extensions.ATI_texture_mirror_once) ||
1150 (eparam == GL_MIRROR_CLAMP_TO_EDGE_ATI &&
1151 ctx->Extensions.ATI_texture_mirror_once))) {
1152 /* non-rectangle texture */
1153 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1154 texObj->WrapR = eparam;
1155 }
1156 else {
1157 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1158 }
1159 break;
1160 case GL_TEXTURE_BORDER_COLOR:
1161 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1162 texObj->BorderColor[RCOMP] = params[0];
1163 texObj->BorderColor[GCOMP] = params[1];
1164 texObj->BorderColor[BCOMP] = params[2];
1165 texObj->BorderColor[ACOMP] = params[3];
1166 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
1167 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
1168 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
1169 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
1170 break;
1171 case GL_TEXTURE_MIN_LOD:
1172 if (texObj->MinLod == params[0])
1173 return;
1174 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1175 texObj->MinLod = params[0];
1176 break;
1177 case GL_TEXTURE_MAX_LOD:
1178 if (texObj->MaxLod == params[0])
1179 return;
1180 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1181 texObj->MaxLod = params[0];
1182 break;
1183 case GL_TEXTURE_BASE_LEVEL:
1184 if (params[0] < 0.0) {
1185 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1186 return;
1187 }
1188 if (target == GL_TEXTURE_RECTANGLE_NV && params[0] != 0.0) {
1189 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1190 return;
1191 }
1192 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1193 texObj->BaseLevel = (GLint) params[0];
1194 break;
1195 case GL_TEXTURE_MAX_LEVEL:
1196 if (params[0] < 0.0) {
1197 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1198 return;
1199 }
1200 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1201 texObj->MaxLevel = (GLint) params[0];
1202 break;
1203 case GL_TEXTURE_PRIORITY:
1204 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1205 texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
1206 break;
1207 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1208 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1209 if (params[0] < 1.0) {
1210 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
1211 return;
1212 }
1213 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1214 texObj->MaxAnisotropy = params[0];
1215 }
1216 else {
1217 _mesa_error(ctx, GL_INVALID_ENUM,
1218 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
1219 return;
1220 }
1221 break;
1222 case GL_TEXTURE_COMPARE_SGIX:
1223 if (ctx->Extensions.SGIX_shadow) {
1224 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1225 texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
1226 }
1227 else {
1228 _mesa_error(ctx, GL_INVALID_ENUM,
1229 "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
1230 return;
1231 }
1232 break;
1233 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1234 if (ctx->Extensions.SGIX_shadow) {
1235 GLenum op = (GLenum) params[0];
1236 if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
1237 op == GL_TEXTURE_GEQUAL_R_SGIX) {
1238 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1239 texObj->CompareOperator = op;
1240 }
1241 else {
1242 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
1243 }
1244 }
1245 else {
1246 _mesa_error(ctx, GL_INVALID_ENUM,
1247 "glTexParameter(pname=GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
1248 return;
1249 }
1250 break;
1251 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1252 if (ctx->Extensions.SGIX_shadow_ambient) {
1253 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1254 texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F);
1255 }
1256 else {
1257 _mesa_error(ctx, GL_INVALID_ENUM,
1258 "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
1259 return;
1260 }
1261 break;
1262 case GL_GENERATE_MIPMAP_SGIS:
1263 if (ctx->Extensions.SGIS_generate_mipmap) {
1264 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
1265 }
1266 else {
1267 _mesa_error(ctx, GL_INVALID_ENUM,
1268 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
1269 return;
1270 }
1271 break;
1272 case GL_TEXTURE_COMPARE_MODE_ARB:
1273 if (ctx->Extensions.ARB_shadow) {
1274 const GLenum mode = (GLenum) params[0];
1275 if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
1276 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1277 texObj->CompareMode = mode;
1278 }
1279 else {
1280 _mesa_error(ctx, GL_INVALID_ENUM,
1281 "glTexParameter(bad GL_TEXTURE_COMPARE_MODE_ARB)");
1282 return;
1283 }
1284 }
1285 else {
1286 _mesa_error(ctx, GL_INVALID_ENUM,
1287 "glTexParameter(pname=GL_TEXTURE_COMPARE_MODE_ARB)");
1288 return;
1289 }
1290 break;
1291 case GL_TEXTURE_COMPARE_FUNC_ARB:
1292 if (ctx->Extensions.ARB_shadow) {
1293 const GLenum func = (GLenum) params[0];
1294 if (func == GL_LEQUAL || func == GL_GEQUAL) {
1295 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1296 texObj->CompareFunc = func;
1297 }
1298 else if (ctx->Extensions.EXT_shadow_funcs &&
1299 (func == GL_EQUAL ||
1300 func == GL_NOTEQUAL ||
1301 func == GL_LESS ||
1302 func == GL_GREATER ||
1303 func == GL_ALWAYS ||
1304 func == GL_NEVER)) {
1305 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1306 texObj->CompareFunc = func;
1307 }
1308 else {
1309 _mesa_error(ctx, GL_INVALID_ENUM,
1310 "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)");
1311 return;
1312 }
1313 }
1314 else {
1315 _mesa_error(ctx, GL_INVALID_ENUM,
1316 "glTexParameter(pname=GL_TEXTURE_COMPARE_FUNC_ARB)");
1317 return;
1318 }
1319 break;
1320 case GL_DEPTH_TEXTURE_MODE_ARB:
1321 if (ctx->Extensions.ARB_depth_texture) {
1322 const GLenum result = (GLenum) params[0];
1323 if (result == GL_LUMINANCE || result == GL_INTENSITY
1324 || result == GL_ALPHA) {
1325 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1326 texObj->DepthMode = result;
1327 }
1328 else {
1329 _mesa_error(ctx, GL_INVALID_ENUM,
1330 "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
1331 return;
1332 }
1333 }
1334 else {
1335 _mesa_error(ctx, GL_INVALID_ENUM,
1336 "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)");
1337 return;
1338 }
1339 break;
1340
1341 default:
1342 _mesa_error(ctx, GL_INVALID_ENUM,
1343 "glTexParameter(pname=0x%x)", pname);
1344 return;
1345 }
1346
1347 texObj->Complete = GL_FALSE;
1348
1349 if (ctx->Driver.TexParameter) {
1350 (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
1351 }
1352 }
1353
1354
1355 void
1356 _mesa_TexParameteri( GLenum target, GLenum pname, GLint param )
1357 {
1358 GLfloat fparam[4];
1359 fparam[0] = (GLfloat) param;
1360 fparam[1] = fparam[2] = fparam[3] = 0.0;
1361 _mesa_TexParameterfv(target, pname, fparam);
1362 }
1363
1364
1365 void
1366 _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
1367 {
1368 GLfloat fparam[4];
1369 if (pname == GL_TEXTURE_BORDER_COLOR) {
1370 fparam[0] = INT_TO_FLOAT(params[0]);
1371 fparam[1] = INT_TO_FLOAT(params[1]);
1372 fparam[2] = INT_TO_FLOAT(params[2]);
1373 fparam[3] = INT_TO_FLOAT(params[3]);
1374 }
1375 else {
1376 fparam[0] = (GLfloat) params[0];
1377 fparam[1] = fparam[2] = fparam[3] = 0.0F;
1378 }
1379 _mesa_TexParameterfv(target, pname, fparam);
1380 }
1381
1382
1383 void
1384 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
1385 GLenum pname, GLfloat *params )
1386 {
1387 GLint iparam;
1388 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
1389 *params = (GLfloat) iparam;
1390 }
1391
1392
1393 static GLuint
1394 tex_image_dimensions(GLcontext *ctx, GLenum target)
1395 {
1396 switch (target) {
1397 case GL_TEXTURE_1D:
1398 case GL_PROXY_TEXTURE_1D:
1399 return 1;
1400 case GL_TEXTURE_2D:
1401 case GL_PROXY_TEXTURE_2D:
1402 return 2;
1403 case GL_TEXTURE_3D:
1404 case GL_PROXY_TEXTURE_3D:
1405 return 3;
1406 case GL_TEXTURE_CUBE_MAP_ARB:
1407 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
1408 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1409 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1410 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1411 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1412 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1413 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1414 return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
1415 case GL_TEXTURE_RECTANGLE_NV:
1416 case GL_PROXY_TEXTURE_RECTANGLE_NV:
1417 return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
1418 default:
1419 _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
1420 return 0;
1421 }
1422 }
1423
1424
1425 void
1426 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
1427 GLenum pname, GLint *params )
1428 {
1429 GET_CURRENT_CONTEXT(ctx);
1430 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1431 const struct gl_texture_image *img = NULL;
1432 GLuint dimensions;
1433 GLboolean isProxy;
1434 GLint maxLevels;
1435 ASSERT_OUTSIDE_BEGIN_END(ctx);
1436
1437 /* this will catch bad target values */
1438 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
1439 if (dimensions == 0) {
1440 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
1441 return;
1442 }
1443
1444 switch (target) {
1445 case GL_TEXTURE_1D:
1446 case GL_PROXY_TEXTURE_1D:
1447 case GL_TEXTURE_2D:
1448 case GL_PROXY_TEXTURE_2D:
1449 maxLevels = ctx->Const.MaxTextureLevels;
1450 break;
1451 case GL_TEXTURE_3D:
1452 case GL_PROXY_TEXTURE_3D:
1453 maxLevels = ctx->Const.Max3DTextureLevels;
1454 break;
1455 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1456 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1457 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1458 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1459 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1460 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1461 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
1462 maxLevels = ctx->Const.MaxCubeTextureLevels;
1463 break;
1464 case GL_TEXTURE_RECTANGLE_NV:
1465 case GL_PROXY_TEXTURE_RECTANGLE_NV:
1466 maxLevels = 1;
1467 break;
1468 default:
1469 _mesa_problem(ctx, "switch in _mesa_GetTexLevelParameter");
1470 return;
1471 }
1472
1473 if (level < 0 || level >= maxLevels) {
1474 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
1475 return;
1476 }
1477
1478 img = _mesa_select_tex_image(ctx, texUnit, target, level);
1479 if (!img || !img->TexFormat) {
1480 /* undefined texture image */
1481 if (pname == GL_TEXTURE_COMPONENTS)
1482 *params = 1;
1483 else
1484 *params = 0;
1485 return;
1486 }
1487
1488 isProxy = (target == GL_PROXY_TEXTURE_1D) ||
1489 (target == GL_PROXY_TEXTURE_2D) ||
1490 (target == GL_PROXY_TEXTURE_3D) ||
1491 (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) ||
1492 (target == GL_PROXY_TEXTURE_RECTANGLE_NV);
1493
1494 switch (pname) {
1495 case GL_TEXTURE_WIDTH:
1496 *params = img->Width;
1497 return;
1498 case GL_TEXTURE_HEIGHT:
1499 *params = img->Height;
1500 return;
1501 case GL_TEXTURE_DEPTH:
1502 *params = img->Depth;
1503 return;
1504 case GL_TEXTURE_INTERNAL_FORMAT:
1505 *params = img->IntFormat;
1506 return;
1507 case GL_TEXTURE_BORDER:
1508 *params = img->Border;
1509 return;
1510 case GL_TEXTURE_RED_SIZE:
1511 if (img->Format == GL_RGB || img->Format == GL_RGBA)
1512 *params = img->TexFormat->RedBits;
1513 else
1514 *params = 0;
1515 return;
1516 case GL_TEXTURE_GREEN_SIZE:
1517 if (img->Format == GL_RGB || img->Format == GL_RGBA)
1518 *params = img->TexFormat->GreenBits;
1519 else
1520 *params = 0;
1521 return;
1522 case GL_TEXTURE_BLUE_SIZE:
1523 if (img->Format == GL_RGB || img->Format == GL_RGBA)
1524 *params = img->TexFormat->BlueBits;
1525 else
1526 *params = 0;
1527 return;
1528 case GL_TEXTURE_ALPHA_SIZE:
1529 if (img->Format == GL_ALPHA || img->Format == GL_LUMINANCE_ALPHA ||
1530 img->Format == GL_RGBA)
1531 *params = img->TexFormat->AlphaBits;
1532 else
1533 *params = 0;
1534 return;
1535 case GL_TEXTURE_INTENSITY_SIZE:
1536 if (img->Format != GL_INTENSITY)
1537 *params = 0;
1538 else if (img->TexFormat->IntensityBits > 0)
1539 *params = img->TexFormat->IntensityBits;
1540 else /* intensity probably stored as rgb texture */
1541 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
1542 return;
1543 case GL_TEXTURE_LUMINANCE_SIZE:
1544 if (img->Format != GL_LUMINANCE &&
1545 img->Format != GL_LUMINANCE_ALPHA)
1546 *params = 0;
1547 else if (img->TexFormat->LuminanceBits > 0)
1548 *params = img->TexFormat->LuminanceBits;
1549 else /* luminance probably stored as rgb texture */
1550 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
1551 return;
1552 case GL_TEXTURE_INDEX_SIZE_EXT:
1553 if (img->Format == GL_COLOR_INDEX)
1554 *params = img->TexFormat->IndexBits;
1555 else
1556 *params = 0;
1557 return;
1558 case GL_DEPTH_BITS:
1559 /* XXX this isn't in the GL_SGIX_depth_texture spec
1560 * but seems appropriate.
1561 */
1562 if (ctx->Extensions.SGIX_depth_texture)
1563 *params = img->TexFormat->DepthBits;
1564 else
1565 _mesa_error(ctx, GL_INVALID_ENUM,
1566 "glGetTexLevelParameter[if]v(pname)");
1567 return;
1568
1569 /* GL_ARB_texture_compression */
1570 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB:
1571 if (ctx->Extensions.ARB_texture_compression) {
1572 if (img->IsCompressed && !isProxy)
1573 *params = img->CompressedSize;
1574 else
1575 _mesa_error(ctx, GL_INVALID_OPERATION,
1576 "glGetTexLevelParameter[if]v(pname)");
1577 }
1578 else {
1579 _mesa_error(ctx, GL_INVALID_ENUM,
1580 "glGetTexLevelParameter[if]v(pname)");
1581 }
1582 return;
1583 case GL_TEXTURE_COMPRESSED_ARB:
1584 if (ctx->Extensions.ARB_texture_compression) {
1585 *params = (GLint) img->IsCompressed;
1586 }
1587 else {
1588 _mesa_error(ctx, GL_INVALID_ENUM,
1589 "glGetTexLevelParameter[if]v(pname)");
1590 }
1591 return;
1592
1593 default:
1594 _mesa_error(ctx, GL_INVALID_ENUM,
1595 "glGetTexLevelParameter[if]v(pname)");
1596 }
1597 }
1598
1599
1600
1601 void
1602 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
1603 {
1604 GET_CURRENT_CONTEXT(ctx);
1605 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1606 struct gl_texture_object *obj;
1607 ASSERT_OUTSIDE_BEGIN_END(ctx);
1608
1609 obj = _mesa_select_tex_object(ctx, texUnit, target);
1610 if (!obj) {
1611 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
1612 return;
1613 }
1614
1615 switch (pname) {
1616 case GL_TEXTURE_MAG_FILTER:
1617 *params = ENUM_TO_FLOAT(obj->MagFilter);
1618 return;
1619 case GL_TEXTURE_MIN_FILTER:
1620 *params = ENUM_TO_FLOAT(obj->MinFilter);
1621 return;
1622 case GL_TEXTURE_WRAP_S:
1623 *params = ENUM_TO_FLOAT(obj->WrapS);
1624 return;
1625 case GL_TEXTURE_WRAP_T:
1626 *params = ENUM_TO_FLOAT(obj->WrapT);
1627 return;
1628 case GL_TEXTURE_WRAP_R_EXT:
1629 *params = ENUM_TO_FLOAT(obj->WrapR);
1630 return;
1631 case GL_TEXTURE_BORDER_COLOR:
1632 params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
1633 params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
1634 params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
1635 params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
1636 return;
1637 case GL_TEXTURE_RESIDENT:
1638 {
1639 GLboolean resident;
1640 if (ctx->Driver.IsTextureResident)
1641 resident = ctx->Driver.IsTextureResident(ctx, obj);
1642 else
1643 resident = GL_TRUE;
1644 *params = ENUM_TO_FLOAT(resident);
1645 }
1646 return;
1647 case GL_TEXTURE_PRIORITY:
1648 *params = obj->Priority;
1649 return;
1650 case GL_TEXTURE_MIN_LOD:
1651 *params = obj->MinLod;
1652 return;
1653 case GL_TEXTURE_MAX_LOD:
1654 *params = obj->MaxLod;
1655 return;
1656 case GL_TEXTURE_BASE_LEVEL:
1657 *params = (GLfloat) obj->BaseLevel;
1658 return;
1659 case GL_TEXTURE_MAX_LEVEL:
1660 *params = (GLfloat) obj->MaxLevel;
1661 return;
1662 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1663 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1664 *params = obj->MaxAnisotropy;
1665 return;
1666 }
1667 break;
1668 case GL_TEXTURE_COMPARE_SGIX:
1669 if (ctx->Extensions.SGIX_shadow) {
1670 *params = (GLfloat) obj->CompareFlag;
1671 return;
1672 }
1673 break;
1674 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1675 if (ctx->Extensions.SGIX_shadow) {
1676 *params = (GLfloat) obj->CompareOperator;
1677 return;
1678 }
1679 break;
1680 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1681 if (ctx->Extensions.SGIX_shadow_ambient) {
1682 *params = obj->ShadowAmbient;
1683 return;
1684 }
1685 break;
1686 case GL_GENERATE_MIPMAP_SGIS:
1687 if (ctx->Extensions.SGIS_generate_mipmap) {
1688 *params = (GLfloat) obj->GenerateMipmap;
1689 return;
1690 }
1691 break;
1692 case GL_TEXTURE_COMPARE_MODE_ARB:
1693 if (ctx->Extensions.ARB_shadow) {
1694 *params = (GLfloat) obj->CompareMode;
1695 return;
1696 }
1697 break;
1698 case GL_TEXTURE_COMPARE_FUNC_ARB:
1699 if (ctx->Extensions.ARB_shadow) {
1700 *params = (GLfloat) obj->CompareFunc;
1701 return;
1702 }
1703 break;
1704 case GL_DEPTH_TEXTURE_MODE_ARB:
1705 if (ctx->Extensions.ARB_depth_texture) {
1706 *params = (GLfloat) obj->DepthMode;
1707 return;
1708 }
1709 break;
1710 default:
1711 ; /* silence warnings */
1712 }
1713 /* If we get here, pname was an unrecognized enum */
1714 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
1715 }
1716
1717
1718 void
1719 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1720 {
1721 GET_CURRENT_CONTEXT(ctx);
1722 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1723 struct gl_texture_object *obj;
1724 ASSERT_OUTSIDE_BEGIN_END(ctx);
1725
1726 obj = _mesa_select_tex_object(ctx, texUnit, target);
1727 if (!obj) {
1728 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
1729 return;
1730 }
1731
1732 switch (pname) {
1733 case GL_TEXTURE_MAG_FILTER:
1734 *params = (GLint) obj->MagFilter;
1735 return;
1736 case GL_TEXTURE_MIN_FILTER:
1737 *params = (GLint) obj->MinFilter;
1738 return;
1739 case GL_TEXTURE_WRAP_S:
1740 *params = (GLint) obj->WrapS;
1741 return;
1742 case GL_TEXTURE_WRAP_T:
1743 *params = (GLint) obj->WrapT;
1744 return;
1745 case GL_TEXTURE_WRAP_R_EXT:
1746 *params = (GLint) obj->WrapR;
1747 return;
1748 case GL_TEXTURE_BORDER_COLOR:
1749 {
1750 GLfloat b[4];
1751 b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
1752 b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
1753 b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
1754 b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
1755 params[0] = FLOAT_TO_INT(b[0]);
1756 params[1] = FLOAT_TO_INT(b[1]);
1757 params[2] = FLOAT_TO_INT(b[2]);
1758 params[3] = FLOAT_TO_INT(b[3]);
1759 }
1760 return;
1761 case GL_TEXTURE_RESIDENT:
1762 {
1763 GLboolean resident;
1764 if (ctx->Driver.IsTextureResident)
1765 resident = ctx->Driver.IsTextureResident(ctx, obj);
1766 else
1767 resident = GL_TRUE;
1768 *params = (GLint) resident;
1769 }
1770 return;
1771 case GL_TEXTURE_PRIORITY:
1772 *params = (GLint) obj->Priority;
1773 return;
1774 case GL_TEXTURE_MIN_LOD:
1775 *params = (GLint) obj->MinLod;
1776 return;
1777 case GL_TEXTURE_MAX_LOD:
1778 *params = (GLint) obj->MaxLod;
1779 return;
1780 case GL_TEXTURE_BASE_LEVEL:
1781 *params = obj->BaseLevel;
1782 return;
1783 case GL_TEXTURE_MAX_LEVEL:
1784 *params = obj->MaxLevel;
1785 return;
1786 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1787 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1788 *params = (GLint) obj->MaxAnisotropy;
1789 return;
1790 }
1791 break;
1792 case GL_TEXTURE_COMPARE_SGIX:
1793 if (ctx->Extensions.SGIX_shadow) {
1794 *params = (GLint) obj->CompareFlag;
1795 return;
1796 }
1797 break;
1798 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1799 if (ctx->Extensions.SGIX_shadow) {
1800 *params = (GLint) obj->CompareOperator;
1801 return;
1802 }
1803 break;
1804 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1805 if (ctx->Extensions.SGIX_shadow_ambient) {
1806 *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
1807 return;
1808 }
1809 break;
1810 case GL_GENERATE_MIPMAP_SGIS:
1811 if (ctx->Extensions.SGIS_generate_mipmap) {
1812 *params = (GLint) obj->GenerateMipmap;
1813 return;
1814 }
1815 break;
1816 case GL_TEXTURE_COMPARE_MODE_ARB:
1817 if (ctx->Extensions.ARB_shadow) {
1818 *params = (GLint) obj->CompareMode;
1819 return;
1820 }
1821 break;
1822 case GL_TEXTURE_COMPARE_FUNC_ARB:
1823 if (ctx->Extensions.ARB_shadow) {
1824 *params = (GLint) obj->CompareFunc;
1825 return;
1826 }
1827 break;
1828 case GL_DEPTH_TEXTURE_MODE_ARB:
1829 if (ctx->Extensions.ARB_depth_texture) {
1830 *params = (GLint) obj->DepthMode;
1831 return;
1832 }
1833 break;
1834 default:
1835 ; /* silence warnings */
1836 }
1837 /* If we get here, pname was an unrecognized enum */
1838 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
1839 }
1840
1841
1842
1843
1844 /**********************************************************************/
1845 /* Texture Coord Generation */
1846 /**********************************************************************/
1847
1848
1849 void
1850 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
1851 {
1852 GET_CURRENT_CONTEXT(ctx);
1853 GLuint tUnit = ctx->Texture.CurrentUnit;
1854 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
1855 ASSERT_OUTSIDE_BEGIN_END(ctx);
1856
1857 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
1858 _mesa_debug(ctx, "texGEN %s %s %x...\n",
1859 _mesa_lookup_enum_by_nr(coord),
1860 _mesa_lookup_enum_by_nr(pname),
1861 *(int *)params);
1862
1863 switch (coord) {
1864 case GL_S:
1865 if (pname==GL_TEXTURE_GEN_MODE) {
1866 GLenum mode = (GLenum) (GLint) *params;
1867 GLuint bits;
1868 switch (mode) {
1869 case GL_OBJECT_LINEAR:
1870 bits = TEXGEN_OBJ_LINEAR;
1871 break;
1872 case GL_EYE_LINEAR:
1873 bits = TEXGEN_EYE_LINEAR;
1874 break;
1875 case GL_REFLECTION_MAP_NV:
1876 bits = TEXGEN_REFLECTION_MAP_NV;
1877 break;
1878 case GL_NORMAL_MAP_NV:
1879 bits = TEXGEN_NORMAL_MAP_NV;
1880 break;
1881 case GL_SPHERE_MAP:
1882 bits = TEXGEN_SPHERE_MAP;
1883 break;
1884 default:
1885 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1886 return;
1887 }
1888 if (texUnit->GenModeS == mode)
1889 return;
1890 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1891 texUnit->GenModeS = mode;
1892 texUnit->_GenBitS = bits;
1893 }
1894 else if (pname==GL_OBJECT_PLANE) {
1895 if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
1896 return;
1897 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1898 texUnit->ObjectPlaneS[0] = params[0];
1899 texUnit->ObjectPlaneS[1] = params[1];
1900 texUnit->ObjectPlaneS[2] = params[2];
1901 texUnit->ObjectPlaneS[3] = params[3];
1902 }
1903 else if (pname==GL_EYE_PLANE) {
1904 GLfloat tmp[4];
1905
1906 /* Transform plane equation by the inverse modelview matrix */
1907 if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
1908 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
1909 }
1910 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
1911 if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
1912 return;
1913 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1914 COPY_4FV(texUnit->EyePlaneS, tmp);
1915 }
1916 else {
1917 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1918 return;
1919 }
1920 break;
1921 case GL_T:
1922 if (pname==GL_TEXTURE_GEN_MODE) {
1923 GLenum mode = (GLenum) (GLint) *params;
1924 GLuint bitt;
1925 switch (mode) {
1926 case GL_OBJECT_LINEAR:
1927 bitt = TEXGEN_OBJ_LINEAR;
1928 break;
1929 case GL_EYE_LINEAR:
1930 bitt = TEXGEN_EYE_LINEAR;
1931 break;
1932 case GL_REFLECTION_MAP_NV:
1933 bitt = TEXGEN_REFLECTION_MAP_NV;
1934 break;
1935 case GL_NORMAL_MAP_NV:
1936 bitt = TEXGEN_NORMAL_MAP_NV;
1937 break;
1938 case GL_SPHERE_MAP:
1939 bitt = TEXGEN_SPHERE_MAP;
1940 break;
1941 default:
1942 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1943 return;
1944 }
1945 if (texUnit->GenModeT == mode)
1946 return;
1947 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1948 texUnit->GenModeT = mode;
1949 texUnit->_GenBitT = bitt;
1950 }
1951 else if (pname==GL_OBJECT_PLANE) {
1952 if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
1953 return;
1954 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1955 texUnit->ObjectPlaneT[0] = params[0];
1956 texUnit->ObjectPlaneT[1] = params[1];
1957 texUnit->ObjectPlaneT[2] = params[2];
1958 texUnit->ObjectPlaneT[3] = params[3];
1959 }
1960 else if (pname==GL_EYE_PLANE) {
1961 GLfloat tmp[4];
1962 /* Transform plane equation by the inverse modelview matrix */
1963 if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
1964 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
1965 }
1966 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
1967 if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
1968 return;
1969 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1970 COPY_4FV(texUnit->EyePlaneT, tmp);
1971 }
1972 else {
1973 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
1974 return;
1975 }
1976 break;
1977 case GL_R:
1978 if (pname==GL_TEXTURE_GEN_MODE) {
1979 GLenum mode = (GLenum) (GLint) *params;
1980 GLuint bitr;
1981 switch (mode) {
1982 case GL_OBJECT_LINEAR:
1983 bitr = TEXGEN_OBJ_LINEAR;
1984 break;
1985 case GL_REFLECTION_MAP_NV:
1986 bitr = TEXGEN_REFLECTION_MAP_NV;
1987 break;
1988 case GL_NORMAL_MAP_NV:
1989 bitr = TEXGEN_NORMAL_MAP_NV;
1990 break;
1991 case GL_EYE_LINEAR:
1992 bitr = TEXGEN_EYE_LINEAR;
1993 break;
1994 default:
1995 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
1996 return;
1997 }
1998 if (texUnit->GenModeR == mode)
1999 return;
2000 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2001 texUnit->GenModeR = mode;
2002 texUnit->_GenBitR = bitr;
2003 }
2004 else if (pname==GL_OBJECT_PLANE) {
2005 if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
2006 return;
2007 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2008 texUnit->ObjectPlaneR[0] = params[0];
2009 texUnit->ObjectPlaneR[1] = params[1];
2010 texUnit->ObjectPlaneR[2] = params[2];
2011 texUnit->ObjectPlaneR[3] = params[3];
2012 }
2013 else if (pname==GL_EYE_PLANE) {
2014 GLfloat tmp[4];
2015 /* Transform plane equation by the inverse modelview matrix */
2016 if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
2017 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
2018 }
2019 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
2020 if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
2021 return;
2022 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2023 COPY_4FV(texUnit->EyePlaneR, tmp);
2024 }
2025 else {
2026 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
2027 return;
2028 }
2029 break;
2030 case GL_Q:
2031 if (pname==GL_TEXTURE_GEN_MODE) {
2032 GLenum mode = (GLenum) (GLint) *params;
2033 GLuint bitq;
2034 switch (mode) {
2035 case GL_OBJECT_LINEAR:
2036 bitq = TEXGEN_OBJ_LINEAR;
2037 break;
2038 case GL_EYE_LINEAR:
2039 bitq = TEXGEN_EYE_LINEAR;
2040 break;
2041 default:
2042 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
2043 return;
2044 }
2045 if (texUnit->GenModeQ == mode)
2046 return;
2047 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2048 texUnit->GenModeQ = mode;
2049 texUnit->_GenBitQ = bitq;
2050 }
2051 else if (pname==GL_OBJECT_PLANE) {
2052 if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
2053 return;
2054 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2055 texUnit->ObjectPlaneQ[0] = params[0];
2056 texUnit->ObjectPlaneQ[1] = params[1];
2057 texUnit->ObjectPlaneQ[2] = params[2];
2058 texUnit->ObjectPlaneQ[3] = params[3];
2059 }
2060 else if (pname==GL_EYE_PLANE) {
2061 GLfloat tmp[4];
2062 /* Transform plane equation by the inverse modelview matrix */
2063 if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) {
2064 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
2065 }
2066 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
2067 if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
2068 return;
2069 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2070 COPY_4FV(texUnit->EyePlaneQ, tmp);
2071 }
2072 else {
2073 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
2074 return;
2075 }
2076 break;
2077 default:
2078 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
2079 return;
2080 }
2081
2082 if (ctx->Driver.TexGen)
2083 ctx->Driver.TexGen( ctx, coord, pname, params );
2084 }
2085
2086
2087 void
2088 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
2089 {
2090 GLfloat p[4];
2091 p[0] = (GLfloat) params[0];
2092 p[1] = (GLfloat) params[1];
2093 p[2] = (GLfloat) params[2];
2094 p[3] = (GLfloat) params[3];
2095 _mesa_TexGenfv(coord, pname, p);
2096 }
2097
2098
2099 void
2100 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
2101 {
2102 GLfloat p = (GLfloat) param;
2103 _mesa_TexGenfv( coord, pname, &p );
2104 }
2105
2106
2107 void
2108 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
2109 {
2110 GLfloat p[4];
2111 p[0] = (GLfloat) params[0];
2112 p[1] = (GLfloat) params[1];
2113 p[2] = (GLfloat) params[2];
2114 p[3] = (GLfloat) params[3];
2115 _mesa_TexGenfv( coord, pname, p );
2116 }
2117
2118
2119 void
2120 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
2121 {
2122 _mesa_TexGenfv(coord, pname, &param);
2123 }
2124
2125
2126 void
2127 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
2128 {
2129 _mesa_TexGeniv( coord, pname, &param );
2130 }
2131
2132
2133
2134 void
2135 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
2136 {
2137 GET_CURRENT_CONTEXT(ctx);
2138 GLuint tUnit = ctx->Texture.CurrentUnit;
2139 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
2140 ASSERT_OUTSIDE_BEGIN_END(ctx);
2141
2142 switch (coord) {
2143 case GL_S:
2144 if (pname==GL_TEXTURE_GEN_MODE) {
2145 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
2146 }
2147 else if (pname==GL_OBJECT_PLANE) {
2148 COPY_4V( params, texUnit->ObjectPlaneS );
2149 }
2150 else if (pname==GL_EYE_PLANE) {
2151 COPY_4V( params, texUnit->EyePlaneS );
2152 }
2153 else {
2154 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
2155 return;
2156 }
2157 break;
2158 case GL_T:
2159 if (pname==GL_TEXTURE_GEN_MODE) {
2160 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
2161 }
2162 else if (pname==GL_OBJECT_PLANE) {
2163 COPY_4V( params, texUnit->ObjectPlaneT );
2164 }
2165 else if (pname==GL_EYE_PLANE) {
2166 COPY_4V( params, texUnit->EyePlaneT );
2167 }
2168 else {
2169 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
2170 return;
2171 }
2172 break;
2173 case GL_R:
2174 if (pname==GL_TEXTURE_GEN_MODE) {
2175 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
2176 }
2177 else if (pname==GL_OBJECT_PLANE) {
2178 COPY_4V( params, texUnit->ObjectPlaneR );
2179 }
2180 else if (pname==GL_EYE_PLANE) {
2181 COPY_4V( params, texUnit->EyePlaneR );
2182 }
2183 else {
2184 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
2185 return;
2186 }
2187 break;
2188 case GL_Q:
2189 if (pname==GL_TEXTURE_GEN_MODE) {
2190 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
2191 }
2192 else if (pname==GL_OBJECT_PLANE) {
2193 COPY_4V( params, texUnit->ObjectPlaneQ );
2194 }
2195 else if (pname==GL_EYE_PLANE) {
2196 COPY_4V( params, texUnit->EyePlaneQ );
2197 }
2198 else {
2199 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
2200 return;
2201 }
2202 break;
2203 default:
2204 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
2205 return;
2206 }
2207 }
2208
2209
2210
2211 void
2212 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
2213 {
2214 GET_CURRENT_CONTEXT(ctx);
2215 GLuint tUnit = ctx->Texture.CurrentUnit;
2216 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
2217 ASSERT_OUTSIDE_BEGIN_END(ctx);
2218
2219 switch (coord) {
2220 case GL_S:
2221 if (pname==GL_TEXTURE_GEN_MODE) {
2222 params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
2223 }
2224 else if (pname==GL_OBJECT_PLANE) {
2225 COPY_4V( params, texUnit->ObjectPlaneS );
2226 }
2227 else if (pname==GL_EYE_PLANE) {
2228 COPY_4V( params, texUnit->EyePlaneS );
2229 }
2230 else {
2231 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
2232 return;
2233 }
2234 break;
2235 case GL_T:
2236 if (pname==GL_TEXTURE_GEN_MODE) {
2237 params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
2238 }
2239 else if (pname==GL_OBJECT_PLANE) {
2240 COPY_4V( params, texUnit->ObjectPlaneT );
2241 }
2242 else if (pname==GL_EYE_PLANE) {
2243 COPY_4V( params, texUnit->EyePlaneT );
2244 }
2245 else {
2246 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
2247 return;
2248 }
2249 break;
2250 case GL_R:
2251 if (pname==GL_TEXTURE_GEN_MODE) {
2252 params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
2253 }
2254 else if (pname==GL_OBJECT_PLANE) {
2255 COPY_4V( params, texUnit->ObjectPlaneR );
2256 }
2257 else if (pname==GL_EYE_PLANE) {
2258 COPY_4V( params, texUnit->EyePlaneR );
2259 }
2260 else {
2261 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
2262 return;
2263 }
2264 break;
2265 case GL_Q:
2266 if (pname==GL_TEXTURE_GEN_MODE) {
2267 params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
2268 }
2269 else if (pname==GL_OBJECT_PLANE) {
2270 COPY_4V( params, texUnit->ObjectPlaneQ );
2271 }
2272 else if (pname==GL_EYE_PLANE) {
2273 COPY_4V( params, texUnit->EyePlaneQ );
2274 }
2275 else {
2276 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
2277 return;
2278 }
2279 break;
2280 default:
2281 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
2282 return;
2283 }
2284 }
2285
2286
2287
2288 void
2289 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
2290 {
2291 GET_CURRENT_CONTEXT(ctx);
2292 GLuint tUnit = ctx->Texture.CurrentUnit;
2293 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
2294 ASSERT_OUTSIDE_BEGIN_END(ctx);
2295
2296 switch (coord) {
2297 case GL_S:
2298 if (pname==GL_TEXTURE_GEN_MODE) {
2299 params[0] = texUnit->GenModeS;
2300 }
2301 else if (pname==GL_OBJECT_PLANE) {
2302 params[0] = (GLint) texUnit->ObjectPlaneS[0];
2303 params[1] = (GLint) texUnit->ObjectPlaneS[1];
2304 params[2] = (GLint) texUnit->ObjectPlaneS[2];
2305 params[3] = (GLint) texUnit->ObjectPlaneS[3];
2306 }
2307 else if (pname==GL_EYE_PLANE) {
2308 params[0] = (GLint) texUnit->EyePlaneS[0];
2309 params[1] = (GLint) texUnit->EyePlaneS[1];
2310 params[2] = (GLint) texUnit->EyePlaneS[2];
2311 params[3] = (GLint) texUnit->EyePlaneS[3];
2312 }
2313 else {
2314 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
2315 return;
2316 }
2317 break;
2318 case GL_T:
2319 if (pname==GL_TEXTURE_GEN_MODE) {
2320 params[0] = texUnit->GenModeT;
2321 }
2322 else if (pname==GL_OBJECT_PLANE) {
2323 params[0] = (GLint) texUnit->ObjectPlaneT[0];
2324 params[1] = (GLint) texUnit->ObjectPlaneT[1];
2325 params[2] = (GLint) texUnit->ObjectPlaneT[2];
2326 params[3] = (GLint) texUnit->ObjectPlaneT[3];
2327 }
2328 else if (pname==GL_EYE_PLANE) {
2329 params[0] = (GLint) texUnit->EyePlaneT[0];
2330 params[1] = (GLint) texUnit->EyePlaneT[1];
2331 params[2] = (GLint) texUnit->EyePlaneT[2];
2332 params[3] = (GLint) texUnit->EyePlaneT[3];
2333 }
2334 else {
2335 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
2336 return;
2337 }
2338 break;
2339 case GL_R:
2340 if (pname==GL_TEXTURE_GEN_MODE) {
2341 params[0] = texUnit->GenModeR;
2342 }
2343 else if (pname==GL_OBJECT_PLANE) {
2344 params[0] = (GLint) texUnit->ObjectPlaneR[0];
2345 params[1] = (GLint) texUnit->ObjectPlaneR[1];
2346 params[2] = (GLint) texUnit->ObjectPlaneR[2];
2347 params[3] = (GLint) texUnit->ObjectPlaneR[3];
2348 }
2349 else if (pname==GL_EYE_PLANE) {
2350 params[0] = (GLint) texUnit->EyePlaneR[0];
2351 params[1] = (GLint) texUnit->EyePlaneR[1];
2352 params[2] = (GLint) texUnit->EyePlaneR[2];
2353 params[3] = (GLint) texUnit->EyePlaneR[3];
2354 }
2355 else {
2356 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
2357 return;
2358 }
2359 break;
2360 case GL_Q:
2361 if (pname==GL_TEXTURE_GEN_MODE) {
2362 params[0] = texUnit->GenModeQ;
2363 }
2364 else if (pname==GL_OBJECT_PLANE) {
2365 params[0] = (GLint) texUnit->ObjectPlaneQ[0];
2366 params[1] = (GLint) texUnit->ObjectPlaneQ[1];
2367 params[2] = (GLint) texUnit->ObjectPlaneQ[2];
2368 params[3] = (GLint) texUnit->ObjectPlaneQ[3];
2369 }
2370 else if (pname==GL_EYE_PLANE) {
2371 params[0] = (GLint) texUnit->EyePlaneQ[0];
2372 params[1] = (GLint) texUnit->EyePlaneQ[1];
2373 params[2] = (GLint) texUnit->EyePlaneQ[2];
2374 params[3] = (GLint) texUnit->EyePlaneQ[3];
2375 }
2376 else {
2377 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
2378 return;
2379 }
2380 break;
2381 default:
2382 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
2383 return;
2384 }
2385 }
2386
2387
2388 /* GL_ARB_multitexture */
2389 void
2390 _mesa_ActiveTextureARB( GLenum target )
2391 {
2392 GET_CURRENT_CONTEXT(ctx);
2393 GLuint texUnit = target - GL_TEXTURE0_ARB;
2394 ASSERT_OUTSIDE_BEGIN_END(ctx);
2395
2396 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2397 _mesa_debug(ctx, "glActiveTexture %s\n",
2398 _mesa_lookup_enum_by_nr(target));
2399
2400 if (texUnit > ctx->Const.MaxTextureUnits) {
2401 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTextureARB(target)");
2402 return;
2403 }
2404
2405 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
2406 ctx->Texture.CurrentUnit = texUnit;
2407 if (ctx->Driver.ActiveTexture) {
2408 (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
2409 }
2410 }
2411
2412
2413 /* GL_ARB_multitexture */
2414 void
2415 _mesa_ClientActiveTextureARB( GLenum target )
2416 {
2417 GET_CURRENT_CONTEXT(ctx);
2418 GLuint texUnit = target - GL_TEXTURE0_ARB;
2419 ASSERT_OUTSIDE_BEGIN_END(ctx);
2420
2421 if (texUnit > ctx->Const.MaxTextureUnits) {
2422 _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTextureARB(target)");
2423 return;
2424 }
2425
2426 FLUSH_VERTICES(ctx, _NEW_ARRAY);
2427 ctx->Array.ActiveTexture = texUnit;
2428 }
2429
2430
2431
2432 /**********************************************************************/
2433 /* Pixel Texgen Extensions */
2434 /**********************************************************************/
2435
2436 void
2437 _mesa_PixelTexGenSGIX(GLenum mode)
2438 {
2439 GLenum newRgbSource, newAlphaSource;
2440 GET_CURRENT_CONTEXT(ctx);
2441 ASSERT_OUTSIDE_BEGIN_END(ctx);
2442
2443 switch (mode) {
2444 case GL_NONE:
2445 newRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
2446 newAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
2447 break;
2448 case GL_ALPHA:
2449 newRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
2450 newAlphaSource = GL_CURRENT_RASTER_COLOR;
2451 break;
2452 case GL_RGB:
2453 newRgbSource = GL_CURRENT_RASTER_COLOR;
2454 newAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
2455 break;
2456 case GL_RGBA:
2457 newRgbSource = GL_CURRENT_RASTER_COLOR;
2458 newAlphaSource = GL_CURRENT_RASTER_COLOR;
2459 break;
2460 default:
2461 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenSGIX(mode)");
2462 return;
2463 }
2464
2465 if (newRgbSource == ctx->Pixel.FragmentRgbSource &&
2466 newAlphaSource == ctx->Pixel.FragmentAlphaSource)
2467 return;
2468
2469 FLUSH_VERTICES(ctx, _NEW_PIXEL);
2470 ctx->Pixel.FragmentRgbSource = newRgbSource;
2471 ctx->Pixel.FragmentAlphaSource = newAlphaSource;
2472 }
2473
2474
2475 void
2476 _mesa_PixelTexGenParameterfSGIS(GLenum target, GLfloat value)
2477 {
2478 _mesa_PixelTexGenParameteriSGIS(target, (GLint) value);
2479 }
2480
2481
2482 void
2483 _mesa_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value)
2484 {
2485 _mesa_PixelTexGenParameteriSGIS(target, (GLint) *value);
2486 }
2487
2488
2489 void
2490 _mesa_PixelTexGenParameteriSGIS(GLenum target, GLint value)
2491 {
2492 GET_CURRENT_CONTEXT(ctx);
2493 ASSERT_OUTSIDE_BEGIN_END(ctx);
2494
2495 if (value != GL_CURRENT_RASTER_COLOR && value != GL_PIXEL_GROUP_COLOR_SGIS) {
2496 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenParameterSGIS(value)");
2497 return;
2498 }
2499
2500 switch (target) {
2501 case GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS:
2502 if (ctx->Pixel.FragmentRgbSource == (GLenum) value)
2503 return;
2504 FLUSH_VERTICES(ctx, _NEW_PIXEL);
2505 ctx->Pixel.FragmentRgbSource = (GLenum) value;
2506 break;
2507 case GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS:
2508 if (ctx->Pixel.FragmentAlphaSource == (GLenum) value)
2509 return;
2510 FLUSH_VERTICES(ctx, _NEW_PIXEL);
2511 ctx->Pixel.FragmentAlphaSource = (GLenum) value;
2512 break;
2513 default:
2514 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenParameterSGIS(target)");
2515 return;
2516 }
2517 }
2518
2519
2520 void
2521 _mesa_PixelTexGenParameterivSGIS(GLenum target, const GLint *value)
2522 {
2523 _mesa_PixelTexGenParameteriSGIS(target, *value);
2524 }
2525
2526
2527 void
2528 _mesa_GetPixelTexGenParameterfvSGIS(GLenum target, GLfloat *value)
2529 {
2530 GET_CURRENT_CONTEXT(ctx);
2531 ASSERT_OUTSIDE_BEGIN_END(ctx);
2532
2533 if (target == GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) {
2534 *value = (GLfloat) ctx->Pixel.FragmentRgbSource;
2535 }
2536 else if (target == GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) {
2537 *value = (GLfloat) ctx->Pixel.FragmentAlphaSource;
2538 }
2539 else {
2540 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelTexGenParameterfvSGIS(target)");
2541 }
2542 }
2543
2544
2545 void
2546 _mesa_GetPixelTexGenParameterivSGIS(GLenum target, GLint *value)
2547 {
2548 GET_CURRENT_CONTEXT(ctx);
2549 ASSERT_OUTSIDE_BEGIN_END(ctx);
2550
2551 if (target == GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) {
2552 *value = (GLint) ctx->Pixel.FragmentRgbSource;
2553 }
2554 else if (target == GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) {
2555 *value = (GLint) ctx->Pixel.FragmentAlphaSource;
2556 }
2557 else {
2558 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelTexGenParameterivSGIS(target)");
2559 }
2560 }