2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
29 * glTexEnv-related functions
33 #include "main/glheader.h"
34 #include "main/context.h"
35 #include "main/blend.h"
36 #include "main/enums.h"
37 #include "main/macros.h"
38 #include "main/mtypes.h"
39 #include "main/state.h"
40 #include "main/texenv.h"
41 #include "main/texstate.h"
44 #define TE_ERROR(errCode, msg, value) \
45 _mesa_error(ctx, errCode, msg, _mesa_enum_to_string(value));
48 /** Set texture env mode */
50 set_env_mode(struct gl_context
*ctx
,
51 struct gl_fixedfunc_texture_unit
*texUnit
,
56 if (texUnit
->EnvMode
== mode
)
69 mode
= GL_REPLACE
; /* GL_REPLACE_EXT != GL_REPLACE */
73 legal
= ctx
->Extensions
.NV_texture_env_combine4
;
80 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
81 texUnit
->EnvMode
= mode
;
84 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", mode
);
90 set_env_color(struct gl_context
*ctx
,
91 struct gl_fixedfunc_texture_unit
*texUnit
,
94 if (TEST_EQ_4V(color
, texUnit
->EnvColorUnclamped
))
96 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
97 COPY_4FV(texUnit
->EnvColorUnclamped
, color
);
98 texUnit
->EnvColor
[0] = CLAMP(color
[0], 0.0F
, 1.0F
);
99 texUnit
->EnvColor
[1] = CLAMP(color
[1], 0.0F
, 1.0F
);
100 texUnit
->EnvColor
[2] = CLAMP(color
[2], 0.0F
, 1.0F
);
101 texUnit
->EnvColor
[3] = CLAMP(color
[3], 0.0F
, 1.0F
);
105 /** Set an RGB or A combiner mode/function */
107 set_combiner_mode(struct gl_context
*ctx
,
108 struct gl_fixedfunc_texture_unit
*texUnit
,
109 GLenum pname
, GLenum mode
)
122 legal
= ctx
->Extensions
.ARB_texture_env_combine
;
124 case GL_DOT3_RGB_EXT
:
125 case GL_DOT3_RGBA_EXT
:
126 legal
= (ctx
->API
== API_OPENGL_COMPAT
&&
127 ctx
->Extensions
.EXT_texture_env_dot3
&&
128 pname
== GL_COMBINE_RGB
);
132 legal
= (ctx
->Extensions
.ARB_texture_env_dot3
&&
133 pname
== GL_COMBINE_RGB
);
135 case GL_MODULATE_ADD_ATI
:
136 case GL_MODULATE_SIGNED_ADD_ATI
:
137 case GL_MODULATE_SUBTRACT_ATI
:
138 legal
= (ctx
->API
== API_OPENGL_COMPAT
&&
139 ctx
->Extensions
.ATI_texture_env_combine3
);
146 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", mode
);
152 if (texUnit
->Combine
.ModeRGB
== mode
)
154 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
155 texUnit
->Combine
.ModeRGB
= mode
;
158 case GL_COMBINE_ALPHA
:
159 if (texUnit
->Combine
.ModeA
== mode
)
161 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
162 texUnit
->Combine
.ModeA
= mode
;
165 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
174 /** Set an RGB or A combiner source term */
176 set_combiner_source(struct gl_context
*ctx
,
177 struct gl_fixedfunc_texture_unit
*texUnit
,
178 GLenum pname
, GLenum param
)
181 GLboolean alpha
, legal
;
184 * Translate pname to (term, alpha).
186 * The enums were given sequential values for a reason.
192 case GL_SOURCE3_RGB_NV
:
193 term
= pname
- GL_SOURCE0_RGB
;
196 case GL_SOURCE0_ALPHA
:
197 case GL_SOURCE1_ALPHA
:
198 case GL_SOURCE2_ALPHA
:
199 case GL_SOURCE3_ALPHA_NV
:
200 term
= pname
- GL_SOURCE0_ALPHA
;
204 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
208 if ((term
== 3) && (ctx
->API
!= API_OPENGL_COMPAT
209 || !ctx
->Extensions
.NV_texture_env_combine4
)) {
210 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
214 assert(term
< MAX_COMBINER_TERMS
);
217 * Error-check param (the source term)
222 case GL_PRIMARY_COLOR
:
234 legal
= (ctx
->Extensions
.ARB_texture_env_crossbar
&&
235 param
- GL_TEXTURE0
< ctx
->Const
.MaxTextureUnits
);
238 legal
= (ctx
->API
== API_OPENGL_COMPAT
&&
239 (ctx
->Extensions
.ATI_texture_env_combine3
||
240 ctx
->Extensions
.NV_texture_env_combine4
));
243 legal
= (ctx
->API
== API_OPENGL_COMPAT
&&
244 ctx
->Extensions
.ATI_texture_env_combine3
);
251 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", param
);
255 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
258 texUnit
->Combine
.SourceA
[term
] = param
;
260 texUnit
->Combine
.SourceRGB
[term
] = param
;
266 /** Set an RGB or A combiner operand term */
268 set_combiner_operand(struct gl_context
*ctx
,
269 struct gl_fixedfunc_texture_unit
*texUnit
,
270 GLenum pname
, GLenum param
)
273 GLboolean alpha
, legal
;
275 /* The enums were given sequential values for a reason.
278 case GL_OPERAND0_RGB
:
279 case GL_OPERAND1_RGB
:
280 case GL_OPERAND2_RGB
:
281 case GL_OPERAND3_RGB_NV
:
282 term
= pname
- GL_OPERAND0_RGB
;
285 case GL_OPERAND0_ALPHA
:
286 case GL_OPERAND1_ALPHA
:
287 case GL_OPERAND2_ALPHA
:
288 case GL_OPERAND3_ALPHA_NV
:
289 term
= pname
- GL_OPERAND0_ALPHA
;
293 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
297 if ((term
== 3) && (ctx
->API
!= API_OPENGL_COMPAT
298 || !ctx
->Extensions
.NV_texture_env_combine4
)) {
299 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
303 assert(term
< MAX_COMBINER_TERMS
);
306 * Error-check param (the source operand)
310 case GL_ONE_MINUS_SRC_COLOR
:
311 /* The color input can only be used with GL_OPERAND[01]_RGB in the EXT
312 * version. In the ARB and NV versions and OpenGL ES 1.x they can be
313 * used for any RGB operand.
316 && ((term
< 2) || ctx
->Extensions
.ARB_texture_env_combine
317 || ctx
->Extensions
.NV_texture_env_combine4
);
319 case GL_ONE_MINUS_SRC_ALPHA
:
320 /* GL_ONE_MINUS_SRC_ALPHA can only be used with
321 * GL_OPERAND[01]_(RGB|ALPHA) in the EXT version. In the ARB and NV
322 * versions and OpenGL ES 1.x it can be used for any operand.
324 legal
= (term
< 2) || ctx
->Extensions
.ARB_texture_env_combine
325 || ctx
->Extensions
.NV_texture_env_combine4
;
335 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", param
);
339 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
342 texUnit
->Combine
.OperandA
[term
] = param
;
344 texUnit
->Combine
.OperandRGB
[term
] = param
;
351 set_combiner_scale(struct gl_context
*ctx
,
352 struct gl_fixedfunc_texture_unit
*texUnit
,
353 GLenum pname
, GLfloat scale
)
360 else if (scale
== 2.0F
) {
363 else if (scale
== 4.0F
) {
367 _mesa_error( ctx
, GL_INVALID_VALUE
,
368 "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
374 if (texUnit
->Combine
.ScaleShiftRGB
== shift
)
376 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
377 texUnit
->Combine
.ScaleShiftRGB
= shift
;
380 if (texUnit
->Combine
.ScaleShiftA
== shift
)
382 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
383 texUnit
->Combine
.ScaleShiftA
= shift
;
386 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
395 _mesa_texenvfv_indexed( struct gl_context
* ctx
, GLuint texunit
, GLenum target
,
396 GLenum pname
, const GLfloat
*param
)
398 const GLint iparam0
= (GLint
) param
[0];
401 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
402 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxCombinedTextureImageUnits
;
403 if (texunit
>= maxUnit
) {
404 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexEnvfv(texunit=%d)", texunit
);
408 if (target
== GL_TEXTURE_ENV
) {
409 struct gl_fixedfunc_texture_unit
*texUnit
=
410 _mesa_get_fixedfunc_tex_unit(ctx
, texunit
);
412 /* The GL spec says that we should report an error if the unit is greater
413 * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only
414 * fixed-function units are usable. This is probably a spec bug.
415 * Ignore glTexEnv(GL_TEXTURE_ENV) calls for non-fixed-func units,
416 * because we don't want to process calls that have no effect.
422 case GL_TEXTURE_ENV_MODE
:
423 set_env_mode(ctx
, texUnit
, (GLenum
) iparam0
);
425 case GL_TEXTURE_ENV_COLOR
:
426 set_env_color(ctx
, texUnit
, param
);
429 case GL_COMBINE_ALPHA
:
430 if (!set_combiner_mode(ctx
, texUnit
, pname
, (GLenum
) iparam0
))
436 case GL_SOURCE3_RGB_NV
:
437 case GL_SOURCE0_ALPHA
:
438 case GL_SOURCE1_ALPHA
:
439 case GL_SOURCE2_ALPHA
:
440 case GL_SOURCE3_ALPHA_NV
:
441 if (!set_combiner_source(ctx
, texUnit
, pname
, (GLenum
) iparam0
))
444 case GL_OPERAND0_RGB
:
445 case GL_OPERAND1_RGB
:
446 case GL_OPERAND2_RGB
:
447 case GL_OPERAND3_RGB_NV
:
448 case GL_OPERAND0_ALPHA
:
449 case GL_OPERAND1_ALPHA
:
450 case GL_OPERAND2_ALPHA
:
451 case GL_OPERAND3_ALPHA_NV
:
452 if (!set_combiner_operand(ctx
, texUnit
, pname
, (GLenum
) iparam0
))
457 if (!set_combiner_scale(ctx
, texUnit
, pname
, param
[0]))
461 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)" );
465 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
466 struct gl_texture_unit
*texUnit
=
467 _mesa_get_tex_unit(ctx
, texunit
);
469 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
470 if (texUnit
->LodBias
== param
[0])
472 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_OBJECT
);
473 texUnit
->LodBias
= param
[0];
476 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
480 else if (target
== GL_POINT_SPRITE_NV
) {
481 /* GL_ARB_point_sprite / GL_NV_point_sprite */
482 if (!ctx
->Extensions
.NV_point_sprite
483 && !ctx
->Extensions
.ARB_point_sprite
) {
484 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(target=0x%x)", target
);
487 if (pname
== GL_COORD_REPLACE_NV
) {
488 /* It's kind of weird to set point state via glTexEnv,
489 * but that's what the spec calls for.
491 if (iparam0
== GL_TRUE
) {
492 if (ctx
->Point
.CoordReplace
& (1u << texunit
))
494 FLUSH_VERTICES(ctx
, _NEW_POINT
);
495 ctx
->Point
.CoordReplace
|= (1u << texunit
);
496 } else if (iparam0
== GL_FALSE
) {
497 if (~(ctx
->Point
.CoordReplace
) & (1u << texunit
))
499 FLUSH_VERTICES(ctx
, _NEW_POINT
);
500 ctx
->Point
.CoordReplace
&= ~(1u << texunit
);
502 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexEnv(param=0x%x)", iparam0
);
507 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname=0x%x)", pname
);
512 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexEnv(target=%s)",
513 _mesa_enum_to_string(target
));
517 if (MESA_VERBOSE
&(VERBOSE_API
|VERBOSE_TEXTURE
))
518 _mesa_debug(ctx
, "glTexEnv %s %s %.1f(%s) ...\n",
519 _mesa_enum_to_string(target
),
520 _mesa_enum_to_string(pname
),
522 _mesa_enum_to_string((GLenum
) iparam0
));
524 /* Tell device driver about the new texture environment */
525 if (ctx
->Driver
.TexEnv
) {
526 ctx
->Driver
.TexEnv(ctx
, target
, pname
, param
);
532 _mesa_TexEnvfv( GLenum target
, GLenum pname
, const GLfloat
*param
)
534 GET_CURRENT_CONTEXT(ctx
);
535 _mesa_texenvfv_indexed(ctx
, ctx
->Texture
.CurrentUnit
, target
, pname
, param
);
540 _mesa_TexEnvf( GLenum target
, GLenum pname
, GLfloat param
)
544 p
[1] = p
[2] = p
[3] = 0.0;
545 _mesa_TexEnvfv( target
, pname
, p
);
550 _mesa_TexEnvi( GLenum target
, GLenum pname
, GLint param
)
553 p
[0] = (GLfloat
) param
;
554 p
[1] = p
[2] = p
[3] = 0.0;
555 _mesa_TexEnvfv( target
, pname
, p
);
560 _mesa_TexEnviv( GLenum target
, GLenum pname
, const GLint
*param
)
563 if (pname
== GL_TEXTURE_ENV_COLOR
) {
564 p
[0] = INT_TO_FLOAT( param
[0] );
565 p
[1] = INT_TO_FLOAT( param
[1] );
566 p
[2] = INT_TO_FLOAT( param
[2] );
567 p
[3] = INT_TO_FLOAT( param
[3] );
570 p
[0] = (GLfloat
) param
[0];
571 p
[1] = p
[2] = p
[3] = 0; /* init to zero, just to be safe */
573 _mesa_TexEnvfv( target
, pname
, p
);
578 _mesa_MultiTexEnvfEXT( GLenum texunit
, GLenum target
,
579 GLenum pname
, GLfloat param
)
581 GET_CURRENT_CONTEXT(ctx
);
584 p
[1] = p
[2] = p
[3] = 0.0;
585 _mesa_texenvfv_indexed(ctx
, texunit
- GL_TEXTURE0
, target
, pname
, p
);
589 _mesa_MultiTexEnvfvEXT( GLenum texunit
, GLenum target
,
590 GLenum pname
, const GLfloat
*param
)
592 GET_CURRENT_CONTEXT(ctx
);
593 _mesa_texenvfv_indexed(ctx
, texunit
- GL_TEXTURE0
, target
, pname
, param
);
598 _mesa_MultiTexEnviEXT( GLenum texunit
, GLenum target
,
599 GLenum pname
, GLint param
)
601 GET_CURRENT_CONTEXT(ctx
);
603 p
[0] = (GLfloat
) param
;
604 p
[1] = p
[2] = p
[3] = 0.0;
605 _mesa_texenvfv_indexed( ctx
, texunit
- GL_TEXTURE0
, target
, pname
, p
);
610 _mesa_MultiTexEnvivEXT( GLenum texunit
, GLenum target
,
611 GLenum pname
, const GLint
*param
)
613 GET_CURRENT_CONTEXT(ctx
);
615 if (pname
== GL_TEXTURE_ENV_COLOR
) {
616 p
[0] = INT_TO_FLOAT( param
[0] );
617 p
[1] = INT_TO_FLOAT( param
[1] );
618 p
[2] = INT_TO_FLOAT( param
[2] );
619 p
[3] = INT_TO_FLOAT( param
[3] );
622 p
[0] = (GLfloat
) param
[0];
623 p
[1] = p
[2] = p
[3] = 0; /* init to zero, just to be safe */
625 _mesa_texenvfv_indexed( ctx
, texunit
- GL_TEXTURE0
, target
, pname
, p
);
632 * Helper for glGetTexEnvi/f()
633 * \return value of queried pname or -1 if error.
636 get_texenvi(struct gl_context
*ctx
,
637 const struct gl_fixedfunc_texture_unit
*texUnit
,
641 case GL_TEXTURE_ENV_MODE
:
642 return texUnit
->EnvMode
;
645 return texUnit
->Combine
.ModeRGB
;
646 case GL_COMBINE_ALPHA
:
647 return texUnit
->Combine
.ModeA
;
650 case GL_SOURCE2_RGB
: {
651 const unsigned rgb_idx
= pname
- GL_SOURCE0_RGB
;
652 return texUnit
->Combine
.SourceRGB
[rgb_idx
];
654 case GL_SOURCE3_RGB_NV
:
655 if (ctx
->API
== API_OPENGL_COMPAT
&& ctx
->Extensions
.NV_texture_env_combine4
) {
656 return texUnit
->Combine
.SourceRGB
[3];
659 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
662 case GL_SOURCE0_ALPHA
:
663 case GL_SOURCE1_ALPHA
:
664 case GL_SOURCE2_ALPHA
: {
665 const unsigned alpha_idx
= pname
- GL_SOURCE0_ALPHA
;
666 return texUnit
->Combine
.SourceA
[alpha_idx
];
668 case GL_SOURCE3_ALPHA_NV
:
669 if (ctx
->API
== API_OPENGL_COMPAT
&& ctx
->Extensions
.NV_texture_env_combine4
) {
670 return texUnit
->Combine
.SourceA
[3];
673 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
676 case GL_OPERAND0_RGB
:
677 case GL_OPERAND1_RGB
:
678 case GL_OPERAND2_RGB
: {
679 const unsigned op_rgb
= pname
- GL_OPERAND0_RGB
;
680 return texUnit
->Combine
.OperandRGB
[op_rgb
];
682 case GL_OPERAND3_RGB_NV
:
683 if (ctx
->API
== API_OPENGL_COMPAT
&& ctx
->Extensions
.NV_texture_env_combine4
) {
684 return texUnit
->Combine
.OperandRGB
[3];
687 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
690 case GL_OPERAND0_ALPHA
:
691 case GL_OPERAND1_ALPHA
:
692 case GL_OPERAND2_ALPHA
: {
693 const unsigned op_alpha
= pname
- GL_OPERAND0_ALPHA
;
694 return texUnit
->Combine
.OperandA
[op_alpha
];
696 case GL_OPERAND3_ALPHA_NV
:
697 if (ctx
->API
== API_OPENGL_COMPAT
&& ctx
->Extensions
.NV_texture_env_combine4
) {
698 return texUnit
->Combine
.OperandA
[3];
701 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
705 return 1 << texUnit
->Combine
.ScaleShiftRGB
;
707 return 1 << texUnit
->Combine
.ScaleShiftA
;
709 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
713 return -1; /* error */
718 _mesa_gettexenvfv_indexed( GLuint texunit
, GLenum target
, GLenum pname
, GLfloat
*params
)
721 GET_CURRENT_CONTEXT(ctx
);
723 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
724 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxCombinedTextureImageUnits
;
725 if (texunit
>= maxUnit
) {
726 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexEnvfv(texunit=%d)", texunit
);
730 if (target
== GL_TEXTURE_ENV
) {
731 struct gl_fixedfunc_texture_unit
*texUnit
=
732 _mesa_get_fixedfunc_tex_unit(ctx
, texunit
);
734 /* The GL spec says that we should report an error if the unit is greater
735 * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only
736 * fixed-function units are usable. This is probably a spec bug.
737 * Ignore calls for non-fixed-func units, because we don't process
738 * glTexEnv for them either.
743 if (pname
== GL_TEXTURE_ENV_COLOR
) {
744 if (_mesa_get_clamp_fragment_color(ctx
, ctx
->DrawBuffer
))
745 COPY_4FV( params
, texUnit
->EnvColor
);
747 COPY_4FV( params
, texUnit
->EnvColorUnclamped
);
750 GLint val
= get_texenvi(ctx
, texUnit
, pname
);
752 *params
= (GLfloat
) val
;
756 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
757 const struct gl_texture_unit
*texUnit
= _mesa_get_tex_unit(ctx
, texunit
);
759 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
760 *params
= texUnit
->LodBias
;
763 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)" );
767 else if (target
== GL_POINT_SPRITE_NV
) {
768 /* GL_ARB_point_sprite / GL_NV_point_sprite */
769 if (!ctx
->Extensions
.NV_point_sprite
770 && !ctx
->Extensions
.ARB_point_sprite
) {
771 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
774 if (pname
== GL_COORD_REPLACE_NV
) {
775 if (ctx
->Point
.CoordReplace
& (1u << texunit
))
781 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)" );
786 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
793 _mesa_gettexenviv_indexed( GLuint texunit
, GLenum target
,
794 GLenum pname
, GLint
*params
)
797 GET_CURRENT_CONTEXT(ctx
);
799 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
800 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxCombinedTextureImageUnits
;
801 if (texunit
>= maxUnit
) {
802 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexEnviv(texunit=%d)",
807 if (target
== GL_TEXTURE_ENV
) {
808 struct gl_fixedfunc_texture_unit
*texUnit
=
809 _mesa_get_fixedfunc_tex_unit(ctx
, texunit
);
811 /* The GL spec says that we should report an error if the unit is greater
812 * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only
813 * fixed-function units are usable. This is probably a spec bug.
814 * Ignore calls for non-fixed-func units, because we don't process
815 * glTexEnv for them either.
820 if (pname
== GL_TEXTURE_ENV_COLOR
) {
821 params
[0] = FLOAT_TO_INT( texUnit
->EnvColor
[0] );
822 params
[1] = FLOAT_TO_INT( texUnit
->EnvColor
[1] );
823 params
[2] = FLOAT_TO_INT( texUnit
->EnvColor
[2] );
824 params
[3] = FLOAT_TO_INT( texUnit
->EnvColor
[3] );
827 GLint val
= get_texenvi(ctx
, texUnit
, pname
);
833 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
834 const struct gl_texture_unit
*texUnit
= _mesa_get_tex_unit(ctx
, texunit
);
836 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
837 *params
= (GLint
) texUnit
->LodBias
;
840 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(pname)" );
844 else if (target
== GL_POINT_SPRITE_NV
) {
845 /* GL_ARB_point_sprite / GL_NV_point_sprite */
846 if (!ctx
->Extensions
.NV_point_sprite
847 && !ctx
->Extensions
.ARB_point_sprite
) {
848 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );
851 if (pname
== GL_COORD_REPLACE_NV
) {
852 if (ctx
->Point
.CoordReplace
& (1u << texunit
))
858 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(pname)" );
863 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );
870 _mesa_GetTexEnvfv( GLenum target
, GLenum pname
, GLfloat
*params
)
872 GET_CURRENT_CONTEXT(ctx
);
873 _mesa_gettexenvfv_indexed(ctx
->Texture
.CurrentUnit
, target
, pname
, params
);
878 _mesa_GetMultiTexEnvfvEXT( GLenum texunit
, GLenum target
,
879 GLenum pname
, GLfloat
*params
)
881 _mesa_gettexenvfv_indexed(texunit
- GL_TEXTURE0
, target
, pname
, params
);
886 _mesa_GetTexEnviv( GLenum target
, GLenum pname
, GLint
*params
)
888 GET_CURRENT_CONTEXT(ctx
);
889 _mesa_gettexenviv_indexed(ctx
->Texture
.CurrentUnit
, target
, pname
, params
);
894 _mesa_GetMultiTexEnvivEXT( GLenum texunit
, GLenum target
,
895 GLenum pname
, GLint
*params
)
897 _mesa_gettexenviv_indexed(texunit
- GL_TEXTURE0
, target
, pname
, params
);