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