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