mesa: refactor: move glTexEnv-related functions into new texenv.c file
[mesa.git] / src / mesa / main / texenv.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file texenv.c
27 *
28 * glTexEnv-related functions
29 */
30
31
32 #include "main/glheader.h"
33 #include "main/context.h"
34 #include "main/enums.h"
35 #include "main/macros.h"
36 #include "main/texenv.h"
37 #include "math/m_xform.h"
38
39
40 #define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
41
42
43 void GLAPIENTRY
44 _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
45 {
46 GLuint maxUnit;
47 GET_CURRENT_CONTEXT(ctx);
48 struct gl_texture_unit *texUnit;
49 ASSERT_OUTSIDE_BEGIN_END(ctx);
50
51 maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
52 ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
53 if (ctx->Texture.CurrentUnit >= maxUnit) {
54 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
55 return;
56 }
57
58 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
59
60 #define TE_ERROR(errCode, msg, value) \
61 _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
62
63 if (target == GL_TEXTURE_ENV) {
64 switch (pname) {
65 case GL_TEXTURE_ENV_MODE:
66 {
67 GLenum mode = (GLenum) (GLint) *param;
68 if (mode == GL_REPLACE_EXT)
69 mode = GL_REPLACE;
70 if (texUnit->EnvMode == mode)
71 return;
72 if (mode == GL_MODULATE ||
73 mode == GL_BLEND ||
74 mode == GL_DECAL ||
75 mode == GL_REPLACE ||
76 (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
77 (mode == GL_COMBINE &&
78 (ctx->Extensions.EXT_texture_env_combine ||
79 ctx->Extensions.ARB_texture_env_combine))) {
80 /* legal */
81 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
82 texUnit->EnvMode = mode;
83 }
84 else {
85 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
86 return;
87 }
88 }
89 break;
90 case GL_TEXTURE_ENV_COLOR:
91 {
92 GLfloat tmp[4];
93 tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
94 tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
95 tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
96 tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
97 if (TEST_EQ_4V(tmp, texUnit->EnvColor))
98 return;
99 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
100 COPY_4FV(texUnit->EnvColor, tmp);
101 }
102 break;
103 case GL_COMBINE_RGB:
104 if (ctx->Extensions.EXT_texture_env_combine ||
105 ctx->Extensions.ARB_texture_env_combine) {
106 const GLenum mode = (GLenum) (GLint) *param;
107 if (texUnit->Combine.ModeRGB == mode)
108 return;
109 switch (mode) {
110 case GL_REPLACE:
111 case GL_MODULATE:
112 case GL_ADD:
113 case GL_ADD_SIGNED:
114 case GL_INTERPOLATE:
115 /* OK */
116 break;
117 case GL_SUBTRACT:
118 if (!ctx->Extensions.ARB_texture_env_combine) {
119 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
120 return;
121 }
122 break;
123 case GL_DOT3_RGB_EXT:
124 case GL_DOT3_RGBA_EXT:
125 if (!ctx->Extensions.EXT_texture_env_dot3) {
126 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
127 return;
128 }
129 break;
130 case GL_DOT3_RGB:
131 case GL_DOT3_RGBA:
132 if (!ctx->Extensions.ARB_texture_env_dot3) {
133 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
134 return;
135 }
136 break;
137 case GL_MODULATE_ADD_ATI:
138 case GL_MODULATE_SIGNED_ADD_ATI:
139 case GL_MODULATE_SUBTRACT_ATI:
140 if (!ctx->Extensions.ATI_texture_env_combine3) {
141 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
142 return;
143 }
144 break;
145 default:
146 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
147 return;
148 }
149 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
150 texUnit->Combine.ModeRGB = mode;
151 }
152 else {
153 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
154 return;
155 }
156 break;
157 case GL_COMBINE_ALPHA:
158 if (ctx->Extensions.EXT_texture_env_combine ||
159 ctx->Extensions.ARB_texture_env_combine) {
160 const GLenum mode = (GLenum) (GLint) *param;
161 if (texUnit->Combine.ModeA == mode)
162 return;
163 switch (mode) {
164 case GL_REPLACE:
165 case GL_MODULATE:
166 case GL_ADD:
167 case GL_ADD_SIGNED:
168 case GL_INTERPOLATE:
169 /* OK */
170 break;
171 case GL_SUBTRACT:
172 if (!ctx->Extensions.ARB_texture_env_combine) {
173 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
174 return;
175 }
176 break;
177 case GL_MODULATE_ADD_ATI:
178 case GL_MODULATE_SIGNED_ADD_ATI:
179 case GL_MODULATE_SUBTRACT_ATI:
180 if (!ctx->Extensions.ATI_texture_env_combine3) {
181 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
182 return;
183 }
184 break;
185 default:
186 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
187 return;
188 }
189 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
190 texUnit->Combine.ModeA = mode;
191 }
192 else {
193 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
194 return;
195 }
196 break;
197 case GL_SOURCE0_RGB:
198 case GL_SOURCE1_RGB:
199 case GL_SOURCE2_RGB:
200 if (ctx->Extensions.EXT_texture_env_combine ||
201 ctx->Extensions.ARB_texture_env_combine) {
202 const GLenum source = (GLenum) (GLint) *param;
203 const GLuint s = pname - GL_SOURCE0_RGB;
204 if (texUnit->Combine.SourceRGB[s] == source)
205 return;
206 if (source == GL_TEXTURE ||
207 source == GL_CONSTANT ||
208 source == GL_PRIMARY_COLOR ||
209 source == GL_PREVIOUS ||
210 (ctx->Extensions.ARB_texture_env_crossbar &&
211 source >= GL_TEXTURE0 &&
212 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
213 (ctx->Extensions.ATI_texture_env_combine3 &&
214 (source == GL_ZERO || source == GL_ONE))) {
215 /* legal */
216 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
217 texUnit->Combine.SourceRGB[s] = source;
218 }
219 else {
220 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
221 return;
222 }
223 }
224 else {
225 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
226 return;
227 }
228 break;
229 case GL_SOURCE0_ALPHA:
230 case GL_SOURCE1_ALPHA:
231 case GL_SOURCE2_ALPHA:
232 if (ctx->Extensions.EXT_texture_env_combine ||
233 ctx->Extensions.ARB_texture_env_combine) {
234 const GLenum source = (GLenum) (GLint) *param;
235 const GLuint s = pname - GL_SOURCE0_ALPHA;
236 if (texUnit->Combine.SourceA[s] == source)
237 return;
238 if (source == GL_TEXTURE ||
239 source == GL_CONSTANT ||
240 source == GL_PRIMARY_COLOR ||
241 source == GL_PREVIOUS ||
242 (ctx->Extensions.ARB_texture_env_crossbar &&
243 source >= GL_TEXTURE0 &&
244 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
245 (ctx->Extensions.ATI_texture_env_combine3 &&
246 (source == GL_ZERO || source == GL_ONE))) {
247 /* legal */
248 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
249 texUnit->Combine.SourceA[s] = source;
250 }
251 else {
252 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
253 return;
254 }
255 }
256 else {
257 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
258 return;
259 }
260 break;
261 case GL_OPERAND0_RGB:
262 case GL_OPERAND1_RGB:
263 if (ctx->Extensions.EXT_texture_env_combine ||
264 ctx->Extensions.ARB_texture_env_combine) {
265 const GLenum operand = (GLenum) (GLint) *param;
266 const GLuint s = pname - GL_OPERAND0_RGB;
267 if (texUnit->Combine.OperandRGB[s] == operand)
268 return;
269 switch (operand) {
270 case GL_SRC_COLOR:
271 case GL_ONE_MINUS_SRC_COLOR:
272 case GL_SRC_ALPHA:
273 case GL_ONE_MINUS_SRC_ALPHA:
274 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
275 texUnit->Combine.OperandRGB[s] = operand;
276 break;
277 default:
278 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
279 return;
280 }
281 }
282 else {
283 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
284 return;
285 }
286 break;
287 case GL_OPERAND0_ALPHA:
288 case GL_OPERAND1_ALPHA:
289 if (ctx->Extensions.EXT_texture_env_combine ||
290 ctx->Extensions.ARB_texture_env_combine) {
291 const GLenum operand = (GLenum) (GLint) *param;
292 if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand)
293 return;
294 switch (operand) {
295 case GL_SRC_ALPHA:
296 case GL_ONE_MINUS_SRC_ALPHA:
297 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
298 texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
299 break;
300 default:
301 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
302 return;
303 }
304 }
305 else {
306 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
307 return;
308 }
309 break;
310 case GL_OPERAND2_RGB:
311 if (ctx->Extensions.ARB_texture_env_combine) {
312 const GLenum operand = (GLenum) (GLint) *param;
313 if (texUnit->Combine.OperandRGB[2] == operand)
314 return;
315 switch (operand) {
316 case GL_SRC_COLOR: /* ARB combine only */
317 case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
318 case GL_SRC_ALPHA:
319 case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
320 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
321 texUnit->Combine.OperandRGB[2] = operand;
322 break;
323 default:
324 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
325 return;
326 }
327 }
328 else if (ctx->Extensions.EXT_texture_env_combine) {
329 const GLenum operand = (GLenum) (GLint) *param;
330 if (texUnit->Combine.OperandRGB[2] == operand)
331 return;
332 /* operand must be GL_SRC_ALPHA which is the initial value - thus
333 don't need to actually compare the operand to the possible value */
334 else {
335 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
336 return;
337 }
338 }
339 else {
340 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
341 return;
342 }
343 break;
344 case GL_OPERAND2_ALPHA:
345 if (ctx->Extensions.ARB_texture_env_combine) {
346 const GLenum operand = (GLenum) (GLint) *param;
347 if (texUnit->Combine.OperandA[2] == operand)
348 return;
349 switch (operand) {
350 case GL_SRC_ALPHA:
351 case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
352 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
353 texUnit->Combine.OperandA[2] = operand;
354 break;
355 default:
356 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
357 return;
358 }
359 }
360 else if (ctx->Extensions.EXT_texture_env_combine) {
361 const GLenum operand = (GLenum) (GLint) *param;
362 if (texUnit->Combine.OperandA[2] == operand)
363 return;
364 /* operand must be GL_SRC_ALPHA which is the initial value - thus
365 don't need to actually compare the operand to the possible value */
366 else {
367 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
368 return;
369 }
370 }
371 else {
372 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
373 return;
374 }
375 break;
376 case GL_RGB_SCALE:
377 if (ctx->Extensions.EXT_texture_env_combine ||
378 ctx->Extensions.ARB_texture_env_combine) {
379 GLuint newshift;
380 if (*param == 1.0) {
381 newshift = 0;
382 }
383 else if (*param == 2.0) {
384 newshift = 1;
385 }
386 else if (*param == 4.0) {
387 newshift = 2;
388 }
389 else {
390 _mesa_error( ctx, GL_INVALID_VALUE,
391 "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
392 return;
393 }
394 if (texUnit->Combine.ScaleShiftRGB == newshift)
395 return;
396 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
397 texUnit->Combine.ScaleShiftRGB = newshift;
398 }
399 else {
400 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
401 return;
402 }
403 break;
404 case GL_ALPHA_SCALE:
405 if (ctx->Extensions.EXT_texture_env_combine ||
406 ctx->Extensions.ARB_texture_env_combine) {
407 GLuint newshift;
408 if (*param == 1.0) {
409 newshift = 0;
410 }
411 else if (*param == 2.0) {
412 newshift = 1;
413 }
414 else if (*param == 4.0) {
415 newshift = 2;
416 }
417 else {
418 _mesa_error( ctx, GL_INVALID_VALUE,
419 "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
420 return;
421 }
422 if (texUnit->Combine.ScaleShiftA == newshift)
423 return;
424 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
425 texUnit->Combine.ScaleShiftA = newshift;
426 }
427 else {
428 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
429 return;
430 }
431 break;
432 default:
433 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
434 return;
435 }
436 }
437 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
438 /* GL_EXT_texture_lod_bias */
439 if (!ctx->Extensions.EXT_texture_lod_bias) {
440 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
441 return;
442 }
443 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
444 if (texUnit->LodBias == param[0])
445 return;
446 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
447 texUnit->LodBias = param[0];
448 }
449 else {
450 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
451 return;
452 }
453 }
454 else if (target == GL_POINT_SPRITE_NV) {
455 /* GL_ARB_point_sprite / GL_NV_point_sprite */
456 if (!ctx->Extensions.NV_point_sprite
457 && !ctx->Extensions.ARB_point_sprite) {
458 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
459 return;
460 }
461 if (pname == GL_COORD_REPLACE_NV) {
462 const GLenum value = (GLenum) param[0];
463 if (value == GL_TRUE || value == GL_FALSE) {
464 /* It's kind of weird to set point state via glTexEnv,
465 * but that's what the spec calls for.
466 */
467 const GLboolean state = (GLboolean) value;
468 if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
469 return;
470 FLUSH_VERTICES(ctx, _NEW_POINT);
471 ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
472 }
473 else {
474 _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
475 return;
476 }
477 }
478 else {
479 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
480 return;
481 }
482 }
483 else {
484 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
485 return;
486 }
487
488 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
489 _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
490 _mesa_lookup_enum_by_nr(target),
491 _mesa_lookup_enum_by_nr(pname),
492 *param,
493 _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));
494
495 /* Tell device driver about the new texture environment */
496 if (ctx->Driver.TexEnv) {
497 (*ctx->Driver.TexEnv)( ctx, target, pname, param );
498 }
499 }
500
501
502 void GLAPIENTRY
503 _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
504 {
505 _mesa_TexEnvfv( target, pname, &param );
506 }
507
508
509
510 void GLAPIENTRY
511 _mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
512 {
513 GLfloat p[4];
514 p[0] = (GLfloat) param;
515 p[1] = p[2] = p[3] = 0.0;
516 _mesa_TexEnvfv( target, pname, p );
517 }
518
519
520 void GLAPIENTRY
521 _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
522 {
523 GLfloat p[4];
524 if (pname == GL_TEXTURE_ENV_COLOR) {
525 p[0] = INT_TO_FLOAT( param[0] );
526 p[1] = INT_TO_FLOAT( param[1] );
527 p[2] = INT_TO_FLOAT( param[2] );
528 p[3] = INT_TO_FLOAT( param[3] );
529 }
530 else {
531 p[0] = (GLfloat) param[0];
532 p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */
533 }
534 _mesa_TexEnvfv( target, pname, p );
535 }
536
537
538 void GLAPIENTRY
539 _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
540 {
541 GLuint maxUnit;
542 const struct gl_texture_unit *texUnit;
543 GET_CURRENT_CONTEXT(ctx);
544 ASSERT_OUTSIDE_BEGIN_END(ctx);
545
546 maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
547 ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
548 if (ctx->Texture.CurrentUnit >= maxUnit) {
549 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)");
550 return;
551 }
552
553 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
554
555 if (target == GL_TEXTURE_ENV) {
556 switch (pname) {
557 case GL_TEXTURE_ENV_MODE:
558 *params = ENUM_TO_FLOAT(texUnit->EnvMode);
559 break;
560 case GL_TEXTURE_ENV_COLOR:
561 COPY_4FV( params, texUnit->EnvColor );
562 break;
563 case GL_COMBINE_RGB:
564 if (ctx->Extensions.EXT_texture_env_combine ||
565 ctx->Extensions.ARB_texture_env_combine) {
566 *params = (GLfloat) texUnit->Combine.ModeRGB;
567 }
568 else {
569 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
570 }
571 break;
572 case GL_COMBINE_ALPHA:
573 if (ctx->Extensions.EXT_texture_env_combine ||
574 ctx->Extensions.ARB_texture_env_combine) {
575 *params = (GLfloat) texUnit->Combine.ModeA;
576 }
577 else {
578 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
579 }
580 break;
581 case GL_SOURCE0_RGB:
582 case GL_SOURCE1_RGB:
583 case GL_SOURCE2_RGB:
584 if (ctx->Extensions.EXT_texture_env_combine ||
585 ctx->Extensions.ARB_texture_env_combine) {
586 const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
587 *params = (GLfloat) texUnit->Combine.SourceRGB[rgb_idx];
588 }
589 else {
590 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
591 }
592 break;
593 case GL_SOURCE0_ALPHA:
594 case GL_SOURCE1_ALPHA:
595 case GL_SOURCE2_ALPHA:
596 if (ctx->Extensions.EXT_texture_env_combine ||
597 ctx->Extensions.ARB_texture_env_combine) {
598 const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
599 *params = (GLfloat) texUnit->Combine.SourceA[alpha_idx];
600 }
601 else {
602 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
603 }
604 break;
605 case GL_OPERAND0_RGB:
606 case GL_OPERAND1_RGB:
607 case GL_OPERAND2_RGB:
608 if (ctx->Extensions.EXT_texture_env_combine ||
609 ctx->Extensions.ARB_texture_env_combine) {
610 const unsigned op_rgb = pname - GL_OPERAND0_RGB;
611 *params = (GLfloat) texUnit->Combine.OperandRGB[op_rgb];
612 }
613 else {
614 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
615 }
616 break;
617 case GL_OPERAND0_ALPHA:
618 case GL_OPERAND1_ALPHA:
619 case GL_OPERAND2_ALPHA:
620 if (ctx->Extensions.EXT_texture_env_combine ||
621 ctx->Extensions.ARB_texture_env_combine) {
622 const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
623 *params = (GLfloat) texUnit->Combine.OperandA[op_alpha];
624 }
625 else {
626 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
627 }
628 break;
629 case GL_RGB_SCALE:
630 if (ctx->Extensions.EXT_texture_env_combine ||
631 ctx->Extensions.ARB_texture_env_combine) {
632 if (texUnit->Combine.ScaleShiftRGB == 0)
633 *params = 1.0;
634 else if (texUnit->Combine.ScaleShiftRGB == 1)
635 *params = 2.0;
636 else
637 *params = 4.0;
638 }
639 else {
640 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
641 return;
642 }
643 break;
644 case GL_ALPHA_SCALE:
645 if (ctx->Extensions.EXT_texture_env_combine ||
646 ctx->Extensions.ARB_texture_env_combine) {
647 if (texUnit->Combine.ScaleShiftA == 0)
648 *params = 1.0;
649 else if (texUnit->Combine.ScaleShiftA == 1)
650 *params = 2.0;
651 else
652 *params = 4.0;
653 }
654 else {
655 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
656 return;
657 }
658 break;
659 default:
660 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname=0x%x)", pname);
661 }
662 }
663 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
664 /* GL_EXT_texture_lod_bias */
665 if (!ctx->Extensions.EXT_texture_lod_bias) {
666 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
667 return;
668 }
669 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
670 *params = texUnit->LodBias;
671 }
672 else {
673 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
674 return;
675 }
676 }
677 else if (target == GL_POINT_SPRITE_NV) {
678 /* GL_ARB_point_sprite / GL_NV_point_sprite */
679 if (!ctx->Extensions.NV_point_sprite
680 && !ctx->Extensions.ARB_point_sprite) {
681 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
682 return;
683 }
684 if (pname == GL_COORD_REPLACE_NV) {
685 *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
686 }
687 else {
688 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
689 return;
690 }
691 }
692 else {
693 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
694 return;
695 }
696 }
697
698
699 void GLAPIENTRY
700 _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
701 {
702 GLuint maxUnit;
703 const struct gl_texture_unit *texUnit;
704 GET_CURRENT_CONTEXT(ctx);
705 ASSERT_OUTSIDE_BEGIN_END(ctx);
706
707 maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
708 ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
709 if (ctx->Texture.CurrentUnit >= maxUnit) {
710 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(current unit)");
711 return;
712 }
713
714 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
715
716 if (target == GL_TEXTURE_ENV) {
717 switch (pname) {
718 case GL_TEXTURE_ENV_MODE:
719 *params = (GLint) texUnit->EnvMode;
720 break;
721 case GL_TEXTURE_ENV_COLOR:
722 params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
723 params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
724 params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
725 params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
726 break;
727 case GL_COMBINE_RGB:
728 if (ctx->Extensions.EXT_texture_env_combine ||
729 ctx->Extensions.ARB_texture_env_combine) {
730 *params = (GLint) texUnit->Combine.ModeRGB;
731 }
732 else {
733 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
734 }
735 break;
736 case GL_COMBINE_ALPHA:
737 if (ctx->Extensions.EXT_texture_env_combine ||
738 ctx->Extensions.ARB_texture_env_combine) {
739 *params = (GLint) texUnit->Combine.ModeA;
740 }
741 else {
742 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
743 }
744 break;
745 case GL_SOURCE0_RGB:
746 case GL_SOURCE1_RGB:
747 case GL_SOURCE2_RGB:
748 if (ctx->Extensions.EXT_texture_env_combine ||
749 ctx->Extensions.ARB_texture_env_combine) {
750 const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
751 *params = (GLint) texUnit->Combine.SourceRGB[rgb_idx];
752 }
753 else {
754 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
755 }
756 break;
757 case GL_SOURCE0_ALPHA:
758 case GL_SOURCE1_ALPHA:
759 case GL_SOURCE2_ALPHA:
760 if (ctx->Extensions.EXT_texture_env_combine ||
761 ctx->Extensions.ARB_texture_env_combine) {
762 const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
763 *params = (GLint) texUnit->Combine.SourceA[alpha_idx];
764 }
765 else {
766 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
767 }
768 break;
769 case GL_OPERAND0_RGB:
770 case GL_OPERAND1_RGB:
771 case GL_OPERAND2_RGB:
772 if (ctx->Extensions.EXT_texture_env_combine ||
773 ctx->Extensions.ARB_texture_env_combine) {
774 const unsigned op_rgb = pname - GL_OPERAND0_RGB;
775 *params = (GLint) texUnit->Combine.OperandRGB[op_rgb];
776 }
777 else {
778 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
779 }
780 break;
781 case GL_OPERAND0_ALPHA:
782 case GL_OPERAND1_ALPHA:
783 case GL_OPERAND2_ALPHA:
784 if (ctx->Extensions.EXT_texture_env_combine ||
785 ctx->Extensions.ARB_texture_env_combine) {
786 const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
787 *params = (GLint) texUnit->Combine.OperandA[op_alpha];
788 }
789 else {
790 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
791 }
792 break;
793 case GL_RGB_SCALE:
794 if (ctx->Extensions.EXT_texture_env_combine ||
795 ctx->Extensions.ARB_texture_env_combine) {
796 if (texUnit->Combine.ScaleShiftRGB == 0)
797 *params = 1;
798 else if (texUnit->Combine.ScaleShiftRGB == 1)
799 *params = 2;
800 else
801 *params = 4;
802 }
803 else {
804 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
805 return;
806 }
807 break;
808 case GL_ALPHA_SCALE:
809 if (ctx->Extensions.EXT_texture_env_combine ||
810 ctx->Extensions.ARB_texture_env_combine) {
811 if (texUnit->Combine.ScaleShiftA == 0)
812 *params = 1;
813 else if (texUnit->Combine.ScaleShiftA == 1)
814 *params = 2;
815 else
816 *params = 4;
817 }
818 else {
819 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
820 return;
821 }
822 break;
823 default:
824 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname=0x%x)",
825 pname);
826 }
827 }
828 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
829 /* GL_EXT_texture_lod_bias */
830 if (!ctx->Extensions.EXT_texture_lod_bias) {
831 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
832 return;
833 }
834 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
835 *params = (GLint) texUnit->LodBias;
836 }
837 else {
838 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
839 return;
840 }
841 }
842 else if (target == GL_POINT_SPRITE_NV) {
843 /* GL_ARB_point_sprite / GL_NV_point_sprite */
844 if (!ctx->Extensions.NV_point_sprite
845 && !ctx->Extensions.ARB_point_sprite) {
846 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
847 return;
848 }
849 if (pname == GL_COORD_REPLACE_NV) {
850 *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
851 }
852 else {
853 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
854 return;
855 }
856 }
857 else {
858 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
859 return;
860 }
861 }
862
863