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