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