2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
29 * glTexEnv-related functions
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 "main/texstate.h"
41 #define TE_ERROR(errCode, msg, value) \
42 _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
45 /** Set texture env mode */
47 set_env_mode(GLcontext
*ctx
,
48 struct gl_texture_unit
*texUnit
,
53 if (texUnit
->EnvMode
== mode
)
64 mode
= GL_REPLACE
; /* GL_REPLACE_EXT != GL_REPLACE */
68 legal
= ctx
->Extensions
.EXT_texture_env_add
;
71 legal
= (ctx
->Extensions
.EXT_texture_env_combine
||
72 ctx
->Extensions
.ARB_texture_env_combine
);
75 legal
= ctx
->Extensions
.NV_texture_env_combine4
;
82 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
83 texUnit
->EnvMode
= mode
;
86 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", mode
);
92 set_env_color(GLcontext
*ctx
,
93 struct gl_texture_unit
*texUnit
,
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
))
103 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
104 COPY_4FV(texUnit
->EnvColor
, tmp
);
108 /** Set an RGB or A combiner mode/function */
110 set_combiner_mode(GLcontext
*ctx
,
111 struct gl_texture_unit
*texUnit
,
112 GLenum pname
, GLenum mode
)
116 if (!ctx
->Extensions
.EXT_texture_env_combine
&&
117 !ctx
->Extensions
.ARB_texture_env_combine
) {
118 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)");
131 legal
= ctx
->Extensions
.ARB_texture_env_combine
;
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
);
140 legal
= (ctx
->Extensions
.ARB_texture_env_dot3
&&
141 pname
== GL_COMBINE_RGB
);
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
;
148 case GL_BUMP_ENVMAP_ATI
:
149 legal
= (ctx
->Extensions
.ATI_envmap_bumpmap
&&
150 pname
== GL_COMBINE_RGB
);
157 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", mode
);
163 if (texUnit
->Combine
.ModeRGB
== mode
)
165 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
166 texUnit
->Combine
.ModeRGB
= mode
;
169 case GL_COMBINE_ALPHA
:
170 if (texUnit
->Combine
.ModeA
== mode
)
172 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
173 texUnit
->Combine
.ModeA
= mode
;
176 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
182 /** Set an RGB or A combiner source term */
184 set_combiner_source(GLcontext
*ctx
,
185 struct gl_texture_unit
*texUnit
,
186 GLenum pname
, GLenum param
)
189 GLboolean alpha
, legal
;
191 if (!ctx
->Extensions
.EXT_texture_env_combine
&&
192 !ctx
->Extensions
.ARB_texture_env_combine
) {
193 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)");
198 * Translate pname to (term, alpha).
213 case GL_SOURCE3_RGB_NV
:
214 if (ctx
->Extensions
.NV_texture_env_combine4
) {
219 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
223 case GL_SOURCE0_ALPHA
:
227 case GL_SOURCE1_ALPHA
:
231 case GL_SOURCE2_ALPHA
:
235 case GL_SOURCE3_ALPHA_NV
:
236 if (ctx
->Extensions
.NV_texture_env_combine4
) {
241 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
246 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
250 assert(term
< MAX_COMBINER_TERMS
);
253 * Error-check param (the source term)
258 case GL_PRIMARY_COLOR
:
270 legal
= (ctx
->Extensions
.ARB_texture_env_crossbar
&&
271 param
- GL_TEXTURE0
< ctx
->Const
.MaxTextureUnits
);
274 legal
= (ctx
->Extensions
.ATI_texture_env_combine3
||
275 ctx
->Extensions
.NV_texture_env_combine4
);
278 legal
= ctx
->Extensions
.ATI_texture_env_combine3
;
285 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", param
);
289 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
292 texUnit
->Combine
.SourceA
[term
] = param
;
294 texUnit
->Combine
.SourceRGB
[term
] = param
;
298 /** Set an RGB or A combiner operand term */
300 set_combiner_operand(GLcontext
*ctx
,
301 struct gl_texture_unit
*texUnit
,
302 GLenum pname
, GLenum param
)
305 GLboolean alpha
, legal
;
307 if (!ctx
->Extensions
.EXT_texture_env_combine
&&
308 !ctx
->Extensions
.ARB_texture_env_combine
) {
309 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)");
314 case GL_OPERAND0_RGB
:
318 case GL_OPERAND1_RGB
:
322 case GL_OPERAND2_RGB
:
323 if (ctx
->Extensions
.ARB_texture_env_combine
) {
328 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
332 case GL_OPERAND3_RGB_NV
:
333 if (ctx
->Extensions
.NV_texture_env_combine4
) {
338 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
342 case GL_OPERAND0_ALPHA
:
346 case GL_OPERAND1_ALPHA
:
350 case GL_OPERAND2_ALPHA
:
351 if (ctx
->Extensions
.ARB_texture_env_combine
) {
356 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
360 case GL_OPERAND3_ALPHA_NV
:
361 if (ctx
->Extensions
.NV_texture_env_combine4
) {
366 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
371 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
375 assert(term
< MAX_COMBINER_TERMS
);
378 * Error-check param (the source operand)
382 case GL_ONE_MINUS_SRC_COLOR
:
386 case GL_ONE_MINUS_SRC_ALPHA
:
394 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", param
);
398 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
401 texUnit
->Combine
.OperandA
[term
] = param
;
403 texUnit
->Combine
.OperandRGB
[term
] = param
;
408 set_combiner_scale(GLcontext
*ctx
,
409 struct gl_texture_unit
*texUnit
,
410 GLenum pname
, GLfloat scale
)
414 if (!ctx
->Extensions
.EXT_texture_env_combine
&&
415 !ctx
->Extensions
.ARB_texture_env_combine
) {
416 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)");
423 else if (scale
== 2.0F
) {
426 else if (scale
== 4.0F
) {
430 _mesa_error( ctx
, GL_INVALID_VALUE
,
431 "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
437 if (texUnit
->Combine
.ScaleShiftRGB
== shift
)
439 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
440 texUnit
->Combine
.ScaleShiftRGB
= shift
;
443 if (texUnit
->Combine
.ScaleShiftA
== shift
)
445 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
446 texUnit
->Combine
.ScaleShiftA
= shift
;
449 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
456 _mesa_TexEnvfv( GLenum target
, GLenum pname
, const GLfloat
*param
)
459 GET_CURRENT_CONTEXT(ctx
);
460 struct gl_texture_unit
*texUnit
;
461 ASSERT_OUTSIDE_BEGIN_END(ctx
);
463 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
464 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxTextureImageUnits
;
465 if (ctx
->Texture
.CurrentUnit
>= maxUnit
) {
466 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexEnvfv(current unit)");
470 texUnit
= _mesa_get_current_tex_unit(ctx
);
472 if (target
== GL_TEXTURE_ENV
) {
474 case GL_TEXTURE_ENV_MODE
:
475 set_env_mode(ctx
, texUnit
, (GLenum
) (GLint
) param
[0]);
477 case GL_TEXTURE_ENV_COLOR
:
478 set_env_color(ctx
, texUnit
, param
);
481 case GL_COMBINE_ALPHA
:
482 set_combiner_mode(ctx
, texUnit
, pname
, (GLenum
) (GLint
) param
[0]);
487 case GL_SOURCE3_RGB_NV
:
488 case GL_SOURCE0_ALPHA
:
489 case GL_SOURCE1_ALPHA
:
490 case GL_SOURCE2_ALPHA
:
491 case GL_SOURCE3_ALPHA_NV
:
492 set_combiner_source(ctx
, texUnit
, pname
, (GLenum
) (GLint
) param
[0]);
494 case GL_OPERAND0_RGB
:
495 case GL_OPERAND1_RGB
:
496 case GL_OPERAND2_RGB
:
497 case GL_OPERAND3_RGB_NV
:
498 case GL_OPERAND0_ALPHA
:
499 case GL_OPERAND1_ALPHA
:
500 case GL_OPERAND2_ALPHA
:
501 case GL_OPERAND3_ALPHA_NV
:
502 set_combiner_operand(ctx
, texUnit
, pname
, (GLenum
) (GLint
) param
[0]);
506 set_combiner_scale(ctx
, texUnit
, pname
, param
[0]);
508 case GL_BUMP_TARGET_ATI
:
509 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
510 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname=0x%x)", pname
);
513 if (((GLenum
) (GLint
) param
[0] < GL_TEXTURE0
) ||
514 ((GLenum
) (GLint
) param
[0] > GL_TEXTURE31
)) {
515 /* spec doesn't say this but it seems logical */
516 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(param=0x%x)", (GLenum
) (GLint
) param
[0]);
519 if (!((1 << ((GLenum
) (GLint
) param
[0] - GL_TEXTURE0
)) & ctx
->Const
.SupportedBumpUnits
)) {
520 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexEnv(param=0x%x)", (GLenum
) (GLint
) param
[0]);
524 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
525 texUnit
->BumpTarget
= (GLenum
) (GLint
) param
[0];
529 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)" );
533 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
534 /* GL_EXT_texture_lod_bias */
535 if (!ctx
->Extensions
.EXT_texture_lod_bias
) {
536 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(target=0x%x)", target
);
539 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
540 if (texUnit
->LodBias
== param
[0])
542 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
543 texUnit
->LodBias
= param
[0];
546 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
550 else if (target
== GL_POINT_SPRITE_NV
) {
551 /* GL_ARB_point_sprite / GL_NV_point_sprite */
552 if (!ctx
->Extensions
.NV_point_sprite
553 && !ctx
->Extensions
.ARB_point_sprite
) {
554 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(target=0x%x)", target
);
557 if (pname
== GL_COORD_REPLACE_NV
) {
558 const GLenum value
= (GLenum
) param
[0];
559 if (value
== GL_TRUE
|| value
== GL_FALSE
) {
560 /* It's kind of weird to set point state via glTexEnv,
561 * but that's what the spec calls for.
563 const GLboolean state
= (GLboolean
) value
;
564 if (ctx
->Point
.CoordReplace
[ctx
->Texture
.CurrentUnit
] == state
)
566 FLUSH_VERTICES(ctx
, _NEW_POINT
);
567 ctx
->Point
.CoordReplace
[ctx
->Texture
.CurrentUnit
] = state
;
570 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexEnv(param=0x%x)", value
);
575 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname=0x%x)", pname
);
580 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(target=0x%x)",target
);
584 if (MESA_VERBOSE
&(VERBOSE_API
|VERBOSE_TEXTURE
))
585 _mesa_debug(ctx
, "glTexEnv %s %s %.1f(%s) ...\n",
586 _mesa_lookup_enum_by_nr(target
),
587 _mesa_lookup_enum_by_nr(pname
),
589 _mesa_lookup_enum_by_nr((GLenum
) (GLint
) *param
));
591 /* Tell device driver about the new texture environment */
592 if (ctx
->Driver
.TexEnv
) {
593 (*ctx
->Driver
.TexEnv
)( ctx
, target
, pname
, param
);
599 _mesa_TexEnvf( GLenum target
, GLenum pname
, GLfloat param
)
603 p
[1] = p
[2] = p
[3] = 0.0;
604 _mesa_TexEnvfv( target
, pname
, p
);
610 _mesa_TexEnvi( GLenum target
, GLenum pname
, GLint param
)
613 p
[0] = (GLfloat
) param
;
614 p
[1] = p
[2] = p
[3] = 0.0;
615 _mesa_TexEnvfv( target
, pname
, p
);
620 _mesa_TexEnviv( GLenum target
, GLenum pname
, const GLint
*param
)
623 if (pname
== GL_TEXTURE_ENV_COLOR
) {
624 p
[0] = INT_TO_FLOAT( param
[0] );
625 p
[1] = INT_TO_FLOAT( param
[1] );
626 p
[2] = INT_TO_FLOAT( param
[2] );
627 p
[3] = INT_TO_FLOAT( param
[3] );
630 p
[0] = (GLfloat
) param
[0];
631 p
[1] = p
[2] = p
[3] = 0; /* init to zero, just to be safe */
633 _mesa_TexEnvfv( target
, pname
, p
);
639 * Helper for glGetTexEnvi/f()
640 * \return value of queried pname or -1 if error.
643 get_texenvi(GLcontext
*ctx
, const struct gl_texture_unit
*texUnit
,
647 case GL_TEXTURE_ENV_MODE
:
648 return texUnit
->EnvMode
;
651 if (ctx
->Extensions
.EXT_texture_env_combine
||
652 ctx
->Extensions
.ARB_texture_env_combine
) {
653 return texUnit
->Combine
.ModeRGB
;
656 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
659 case GL_COMBINE_ALPHA
:
660 if (ctx
->Extensions
.EXT_texture_env_combine
||
661 ctx
->Extensions
.ARB_texture_env_combine
) {
662 return texUnit
->Combine
.ModeA
;
665 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
671 if (ctx
->Extensions
.EXT_texture_env_combine
||
672 ctx
->Extensions
.ARB_texture_env_combine
) {
673 const unsigned rgb_idx
= pname
- GL_SOURCE0_RGB
;
674 return texUnit
->Combine
.SourceRGB
[rgb_idx
];
677 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
680 case GL_SOURCE3_RGB_NV
:
681 if (ctx
->Extensions
.NV_texture_env_combine4
) {
682 return texUnit
->Combine
.SourceRGB
[3];
685 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
688 case GL_SOURCE0_ALPHA
:
689 case GL_SOURCE1_ALPHA
:
690 case GL_SOURCE2_ALPHA
:
691 if (ctx
->Extensions
.EXT_texture_env_combine
||
692 ctx
->Extensions
.ARB_texture_env_combine
) {
693 const unsigned alpha_idx
= pname
- GL_SOURCE0_ALPHA
;
694 return texUnit
->Combine
.SourceA
[alpha_idx
];
697 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
700 case GL_SOURCE3_ALPHA_NV
:
701 if (ctx
->Extensions
.NV_texture_env_combine4
) {
702 return texUnit
->Combine
.SourceA
[3];
705 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
708 case GL_OPERAND0_RGB
:
709 case GL_OPERAND1_RGB
:
710 case GL_OPERAND2_RGB
:
711 if (ctx
->Extensions
.EXT_texture_env_combine
||
712 ctx
->Extensions
.ARB_texture_env_combine
) {
713 const unsigned op_rgb
= pname
- GL_OPERAND0_RGB
;
714 return texUnit
->Combine
.OperandRGB
[op_rgb
];
717 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
720 case GL_OPERAND3_RGB_NV
:
721 if (ctx
->Extensions
.NV_texture_env_combine4
) {
722 return texUnit
->Combine
.OperandRGB
[3];
725 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
728 case GL_OPERAND0_ALPHA
:
729 case GL_OPERAND1_ALPHA
:
730 case GL_OPERAND2_ALPHA
:
731 if (ctx
->Extensions
.EXT_texture_env_combine
||
732 ctx
->Extensions
.ARB_texture_env_combine
) {
733 const unsigned op_alpha
= pname
- GL_OPERAND0_ALPHA
;
734 return texUnit
->Combine
.OperandA
[op_alpha
];
737 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
740 case GL_OPERAND3_ALPHA_NV
:
741 if (ctx
->Extensions
.NV_texture_env_combine4
) {
742 return texUnit
->Combine
.OperandA
[3];
745 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
749 if (ctx
->Extensions
.EXT_texture_env_combine
||
750 ctx
->Extensions
.ARB_texture_env_combine
) {
751 return 1 << texUnit
->Combine
.ScaleShiftRGB
;
754 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
758 if (ctx
->Extensions
.EXT_texture_env_combine
||
759 ctx
->Extensions
.ARB_texture_env_combine
) {
760 return 1 << texUnit
->Combine
.ScaleShiftA
;
763 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
766 case GL_BUMP_TARGET_ATI
:
767 /* spec doesn't say so, but I think this should be queryable */
768 if (ctx
->Extensions
.ATI_envmap_bumpmap
) {
769 return texUnit
->BumpTarget
;
772 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
780 return -1; /* error */
786 _mesa_GetTexEnvfv( GLenum target
, GLenum pname
, GLfloat
*params
)
789 const struct gl_texture_unit
*texUnit
;
790 GET_CURRENT_CONTEXT(ctx
);
791 ASSERT_OUTSIDE_BEGIN_END(ctx
);
793 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
794 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxTextureImageUnits
;
795 if (ctx
->Texture
.CurrentUnit
>= maxUnit
) {
796 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexEnvfv(current unit)");
800 texUnit
= _mesa_get_current_tex_unit(ctx
);
802 if (target
== GL_TEXTURE_ENV
) {
803 if (pname
== GL_TEXTURE_ENV_COLOR
) {
804 COPY_4FV( params
, texUnit
->EnvColor
);
807 GLint val
= get_texenvi(ctx
, texUnit
, pname
);
809 *params
= (GLfloat
) val
;
813 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
814 /* GL_EXT_texture_lod_bias */
815 if (!ctx
->Extensions
.EXT_texture_lod_bias
) {
816 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
819 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
820 *params
= texUnit
->LodBias
;
823 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)" );
827 else if (target
== GL_POINT_SPRITE_NV
) {
828 /* GL_ARB_point_sprite / GL_NV_point_sprite */
829 if (!ctx
->Extensions
.NV_point_sprite
830 && !ctx
->Extensions
.ARB_point_sprite
) {
831 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
834 if (pname
== GL_COORD_REPLACE_NV
) {
835 *params
= (GLfloat
) ctx
->Point
.CoordReplace
[ctx
->Texture
.CurrentUnit
];
838 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)" );
843 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
850 _mesa_GetTexEnviv( GLenum target
, GLenum pname
, GLint
*params
)
853 const struct gl_texture_unit
*texUnit
;
854 GET_CURRENT_CONTEXT(ctx
);
855 ASSERT_OUTSIDE_BEGIN_END(ctx
);
857 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
858 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxTextureImageUnits
;
859 if (ctx
->Texture
.CurrentUnit
>= maxUnit
) {
860 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexEnviv(current unit)");
864 texUnit
= _mesa_get_current_tex_unit(ctx
);
866 if (target
== GL_TEXTURE_ENV
) {
867 if (pname
== GL_TEXTURE_ENV_COLOR
) {
868 params
[0] = FLOAT_TO_INT( texUnit
->EnvColor
[0] );
869 params
[1] = FLOAT_TO_INT( texUnit
->EnvColor
[1] );
870 params
[2] = FLOAT_TO_INT( texUnit
->EnvColor
[2] );
871 params
[3] = FLOAT_TO_INT( texUnit
->EnvColor
[3] );
874 GLint val
= get_texenvi(ctx
, texUnit
, pname
);
880 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
881 /* GL_EXT_texture_lod_bias */
882 if (!ctx
->Extensions
.EXT_texture_lod_bias
) {
883 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );
886 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
887 *params
= (GLint
) texUnit
->LodBias
;
890 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(pname)" );
894 else if (target
== GL_POINT_SPRITE_NV
) {
895 /* GL_ARB_point_sprite / GL_NV_point_sprite */
896 if (!ctx
->Extensions
.NV_point_sprite
897 && !ctx
->Extensions
.ARB_point_sprite
) {
898 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );
901 if (pname
== GL_COORD_REPLACE_NV
) {
902 *params
= (GLint
) ctx
->Point
.CoordReplace
[ctx
->Texture
.CurrentUnit
];
905 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(pname)" );
910 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );
917 * Why does ATI_envmap_bumpmap require new entrypoints? Should just
918 * reuse TexEnv ones...
921 _mesa_TexBumpParameterivATI( GLenum pname
, const GLint
*param
)
924 GET_CURRENT_CONTEXT(ctx
);
925 ASSERT_OUTSIDE_BEGIN_END(ctx
);
927 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
928 /* This isn't an "official" error case, but let's tell the user
929 * that something's wrong.
931 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexBumpParameterivATI");
935 if (pname
== GL_BUMP_ROT_MATRIX_ATI
) {
936 /* hope that conversion is correct here */
937 p
[0] = INT_TO_FLOAT( param
[0] );
938 p
[1] = INT_TO_FLOAT( param
[1] );
939 p
[2] = INT_TO_FLOAT( param
[2] );
940 p
[3] = INT_TO_FLOAT( param
[3] );
943 p
[0] = (GLfloat
) param
[0];
944 p
[1] = p
[2] = p
[3] = 0.0F
; /* init to zero, just to be safe */
946 _mesa_TexBumpParameterfvATI( pname
, p
);
951 _mesa_TexBumpParameterfvATI( GLenum pname
, const GLfloat
*param
)
953 struct gl_texture_unit
*texUnit
;
954 GET_CURRENT_CONTEXT(ctx
);
955 ASSERT_OUTSIDE_BEGIN_END(ctx
);
957 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
958 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexBumpParameterfvATI");
962 texUnit
= _mesa_get_current_tex_unit(ctx
);
964 if (pname
== GL_BUMP_ROT_MATRIX_ATI
) {
965 if (TEST_EQ_4V(param
, texUnit
->RotMatrix
))
967 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
968 COPY_4FV(texUnit
->RotMatrix
, param
);
971 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexBumpParameter(pname)" );
974 /* Drivers might want to know about this, instead of dedicated function
975 just shove it into TexEnv where it really belongs anyway */
976 if (ctx
->Driver
.TexEnv
) {
977 (*ctx
->Driver
.TexEnv
)( ctx
, 0, pname
, param
);
983 _mesa_GetTexBumpParameterivATI( GLenum pname
, GLint
*param
)
985 const struct gl_texture_unit
*texUnit
;
987 GET_CURRENT_CONTEXT(ctx
);
988 ASSERT_OUTSIDE_BEGIN_END(ctx
);
990 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
991 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexBumpParameterivATI");
995 texUnit
= _mesa_get_current_tex_unit(ctx
);
997 if (pname
== GL_BUMP_ROT_MATRIX_SIZE_ATI
) {
998 /* spec leaves open to support larger matrices.
999 Don't think anyone would ever want to use it
1000 (and apps almost certainly would not understand it and
1001 thus fail to submit matrices correctly) so hardcode this. */
1004 else if (pname
== GL_BUMP_ROT_MATRIX_ATI
) {
1005 /* hope that conversion is correct here */
1006 param
[0] = FLOAT_TO_INT(texUnit
->RotMatrix
[0]);
1007 param
[1] = FLOAT_TO_INT(texUnit
->RotMatrix
[1]);
1008 param
[2] = FLOAT_TO_INT(texUnit
->RotMatrix
[2]);
1009 param
[3] = FLOAT_TO_INT(texUnit
->RotMatrix
[3]);
1011 else if (pname
== GL_BUMP_NUM_TEX_UNITS_ATI
) {
1013 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
1014 if (ctx
->Const
.SupportedBumpUnits
& (1 << i
)) {
1020 else if (pname
== GL_BUMP_TEX_UNITS_ATI
) {
1021 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
1022 if (ctx
->Const
.SupportedBumpUnits
& (1 << i
)) {
1023 *param
++ = i
+ GL_TEXTURE0
;
1028 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexBumpParameter(pname)" );
1035 _mesa_GetTexBumpParameterfvATI( GLenum pname
, GLfloat
*param
)
1037 const struct gl_texture_unit
*texUnit
;
1039 GET_CURRENT_CONTEXT(ctx
);
1040 ASSERT_OUTSIDE_BEGIN_END(ctx
);
1042 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
1043 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexBumpParameterfvATI");
1047 texUnit
= _mesa_get_current_tex_unit(ctx
);
1049 if (pname
== GL_BUMP_ROT_MATRIX_SIZE_ATI
) {
1050 /* spec leaves open to support larger matrices.
1051 Don't think anyone would ever want to use it
1052 (and apps might not understand it) so hardcode this. */
1055 else if (pname
== GL_BUMP_ROT_MATRIX_ATI
) {
1056 param
[0] = texUnit
->RotMatrix
[0];
1057 param
[1] = texUnit
->RotMatrix
[1];
1058 param
[2] = texUnit
->RotMatrix
[2];
1059 param
[3] = texUnit
->RotMatrix
[3];
1061 else if (pname
== GL_BUMP_NUM_TEX_UNITS_ATI
) {
1063 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
1064 if (ctx
->Const
.SupportedBumpUnits
& (1 << i
)) {
1068 *param
= (GLfloat
) count
;
1070 else if (pname
== GL_BUMP_TEX_UNITS_ATI
) {
1071 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
1072 if (ctx
->Const
.SupportedBumpUnits
& (1 << i
)) {
1073 *param
++ = (GLfloat
) (i
+ GL_TEXTURE0
);
1078 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexBumpParameter(pname)" );