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(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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(struct gl_context
*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).
200 * The enums were given sequential values for a reason.
206 case GL_SOURCE3_RGB_NV
:
207 term
= pname
- GL_SOURCE0_RGB
;
210 case GL_SOURCE0_ALPHA
:
211 case GL_SOURCE1_ALPHA
:
212 case GL_SOURCE2_ALPHA
:
213 case GL_SOURCE3_ALPHA_NV
:
214 term
= pname
- GL_SOURCE0_ALPHA
;
218 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
222 if ((term
== 3) && !ctx
->Extensions
.NV_texture_env_combine4
) {
223 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
227 assert(term
< MAX_COMBINER_TERMS
);
230 * Error-check param (the source term)
235 case GL_PRIMARY_COLOR
:
247 legal
= (ctx
->Extensions
.ARB_texture_env_crossbar
&&
248 param
- GL_TEXTURE0
< ctx
->Const
.MaxTextureUnits
);
251 legal
= (ctx
->Extensions
.ATI_texture_env_combine3
||
252 ctx
->Extensions
.NV_texture_env_combine4
);
255 legal
= ctx
->Extensions
.ATI_texture_env_combine3
;
262 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", param
);
266 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
269 texUnit
->Combine
.SourceA
[term
] = param
;
271 texUnit
->Combine
.SourceRGB
[term
] = param
;
275 /** Set an RGB or A combiner operand term */
277 set_combiner_operand(struct gl_context
*ctx
,
278 struct gl_texture_unit
*texUnit
,
279 GLenum pname
, GLenum param
)
282 GLboolean alpha
, legal
;
284 if (!ctx
->Extensions
.EXT_texture_env_combine
&&
285 !ctx
->Extensions
.ARB_texture_env_combine
) {
286 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)");
290 /* The enums were given sequential values for a reason.
293 case GL_OPERAND0_RGB
:
294 case GL_OPERAND1_RGB
:
295 case GL_OPERAND2_RGB
:
296 case GL_OPERAND3_RGB_NV
:
297 term
= pname
- GL_OPERAND0_RGB
;
300 case GL_OPERAND0_ALPHA
:
301 case GL_OPERAND1_ALPHA
:
302 case GL_OPERAND2_ALPHA
:
303 case GL_OPERAND3_ALPHA_NV
:
304 term
= pname
- GL_OPERAND0_ALPHA
;
308 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
312 if ((term
== 3) && !ctx
->Extensions
.NV_texture_env_combine4
) {
313 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
317 assert(term
< MAX_COMBINER_TERMS
);
320 * Error-check param (the source operand)
324 case GL_ONE_MINUS_SRC_COLOR
:
325 /* The color input can only be used with GL_OPERAND[01]_RGB in the EXT
326 * version. In the ARB and NV versions they can be used for any RGB
330 && ((term
< 2) || ctx
->Extensions
.ARB_texture_env_combine
331 || ctx
->Extensions
.NV_texture_env_combine4
);
333 case GL_ONE_MINUS_SRC_ALPHA
:
334 /* GL_ONE_MINUS_SRC_ALPHA can only be used with
335 * GL_OPERAND[01]_(RGB|ALPHA) in the EXT version. In the ARB and NV
336 * versions it can be used for any operand.
338 legal
= (term
< 2) || ctx
->Extensions
.ARB_texture_env_combine
339 || ctx
->Extensions
.NV_texture_env_combine4
;
349 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", param
);
353 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
356 texUnit
->Combine
.OperandA
[term
] = param
;
358 texUnit
->Combine
.OperandRGB
[term
] = param
;
363 set_combiner_scale(struct gl_context
*ctx
,
364 struct gl_texture_unit
*texUnit
,
365 GLenum pname
, GLfloat scale
)
369 if (!ctx
->Extensions
.EXT_texture_env_combine
&&
370 !ctx
->Extensions
.ARB_texture_env_combine
) {
371 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)");
378 else if (scale
== 2.0F
) {
381 else if (scale
== 4.0F
) {
385 _mesa_error( ctx
, GL_INVALID_VALUE
,
386 "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
392 if (texUnit
->Combine
.ScaleShiftRGB
== shift
)
394 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
395 texUnit
->Combine
.ScaleShiftRGB
= shift
;
398 if (texUnit
->Combine
.ScaleShiftA
== shift
)
400 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
401 texUnit
->Combine
.ScaleShiftA
= shift
;
404 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
411 _mesa_TexEnvfv( GLenum target
, GLenum pname
, const GLfloat
*param
)
414 GET_CURRENT_CONTEXT(ctx
);
415 struct gl_texture_unit
*texUnit
;
416 ASSERT_OUTSIDE_BEGIN_END(ctx
);
418 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
419 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxTextureImageUnits
;
420 if (ctx
->Texture
.CurrentUnit
>= maxUnit
) {
421 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexEnvfv(current unit)");
425 texUnit
= _mesa_get_current_tex_unit(ctx
);
427 if (target
== GL_TEXTURE_ENV
) {
429 case GL_TEXTURE_ENV_MODE
:
430 set_env_mode(ctx
, texUnit
, (GLenum
) (GLint
) param
[0]);
432 case GL_TEXTURE_ENV_COLOR
:
433 set_env_color(ctx
, texUnit
, param
);
436 case GL_COMBINE_ALPHA
:
437 set_combiner_mode(ctx
, texUnit
, pname
, (GLenum
) (GLint
) param
[0]);
442 case GL_SOURCE3_RGB_NV
:
443 case GL_SOURCE0_ALPHA
:
444 case GL_SOURCE1_ALPHA
:
445 case GL_SOURCE2_ALPHA
:
446 case GL_SOURCE3_ALPHA_NV
:
447 set_combiner_source(ctx
, texUnit
, pname
, (GLenum
) (GLint
) param
[0]);
449 case GL_OPERAND0_RGB
:
450 case GL_OPERAND1_RGB
:
451 case GL_OPERAND2_RGB
:
452 case GL_OPERAND3_RGB_NV
:
453 case GL_OPERAND0_ALPHA
:
454 case GL_OPERAND1_ALPHA
:
455 case GL_OPERAND2_ALPHA
:
456 case GL_OPERAND3_ALPHA_NV
:
457 set_combiner_operand(ctx
, texUnit
, pname
, (GLenum
) (GLint
) param
[0]);
461 set_combiner_scale(ctx
, texUnit
, pname
, param
[0]);
463 case GL_BUMP_TARGET_ATI
:
464 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
465 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname=0x%x)", pname
);
468 if (((GLenum
) (GLint
) param
[0] < GL_TEXTURE0
) ||
469 ((GLenum
) (GLint
) param
[0] > GL_TEXTURE31
)) {
470 /* spec doesn't say this but it seems logical */
471 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(param=0x%x)", (GLenum
) (GLint
) param
[0]);
474 if (!((1 << ((GLenum
) (GLint
) param
[0] - GL_TEXTURE0
)) & ctx
->Const
.SupportedBumpUnits
)) {
475 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexEnv(param=0x%x)", (GLenum
) (GLint
) param
[0]);
479 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
480 texUnit
->BumpTarget
= (GLenum
) (GLint
) param
[0];
484 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)" );
488 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
489 /* GL_EXT_texture_lod_bias */
490 if (!ctx
->Extensions
.EXT_texture_lod_bias
) {
491 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(target=0x%x)", target
);
494 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
495 if (texUnit
->LodBias
== param
[0])
497 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
498 texUnit
->LodBias
= param
[0];
501 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
505 else if (target
== GL_POINT_SPRITE_NV
) {
506 /* GL_ARB_point_sprite / GL_NV_point_sprite */
507 if (!ctx
->Extensions
.NV_point_sprite
508 && !ctx
->Extensions
.ARB_point_sprite
) {
509 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(target=0x%x)", target
);
512 if (pname
== GL_COORD_REPLACE_NV
) {
513 const GLenum value
= (GLenum
) param
[0];
514 if (value
== GL_TRUE
|| value
== GL_FALSE
) {
515 /* It's kind of weird to set point state via glTexEnv,
516 * but that's what the spec calls for.
518 const GLboolean state
= (GLboolean
) value
;
519 if (ctx
->Point
.CoordReplace
[ctx
->Texture
.CurrentUnit
] == state
)
521 FLUSH_VERTICES(ctx
, _NEW_POINT
);
522 ctx
->Point
.CoordReplace
[ctx
->Texture
.CurrentUnit
] = state
;
525 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexEnv(param=0x%x)", value
);
530 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname=0x%x)", pname
);
535 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(target=0x%x)",target
);
539 if (MESA_VERBOSE
&(VERBOSE_API
|VERBOSE_TEXTURE
))
540 _mesa_debug(ctx
, "glTexEnv %s %s %.1f(%s) ...\n",
541 _mesa_lookup_enum_by_nr(target
),
542 _mesa_lookup_enum_by_nr(pname
),
544 _mesa_lookup_enum_by_nr((GLenum
) (GLint
) *param
));
546 /* Tell device driver about the new texture environment */
547 if (ctx
->Driver
.TexEnv
) {
548 (*ctx
->Driver
.TexEnv
)( ctx
, target
, pname
, param
);
554 _mesa_TexEnvf( GLenum target
, GLenum pname
, GLfloat param
)
558 p
[1] = p
[2] = p
[3] = 0.0;
559 _mesa_TexEnvfv( target
, pname
, p
);
565 _mesa_TexEnvi( GLenum target
, GLenum pname
, GLint param
)
568 p
[0] = (GLfloat
) param
;
569 p
[1] = p
[2] = p
[3] = 0.0;
570 _mesa_TexEnvfv( target
, pname
, p
);
575 _mesa_TexEnviv( GLenum target
, GLenum pname
, const GLint
*param
)
578 if (pname
== GL_TEXTURE_ENV_COLOR
) {
579 p
[0] = INT_TO_FLOAT( param
[0] );
580 p
[1] = INT_TO_FLOAT( param
[1] );
581 p
[2] = INT_TO_FLOAT( param
[2] );
582 p
[3] = INT_TO_FLOAT( param
[3] );
585 p
[0] = (GLfloat
) param
[0];
586 p
[1] = p
[2] = p
[3] = 0; /* init to zero, just to be safe */
588 _mesa_TexEnvfv( target
, pname
, p
);
594 * Helper for glGetTexEnvi/f()
595 * \return value of queried pname or -1 if error.
598 get_texenvi(struct gl_context
*ctx
, const struct gl_texture_unit
*texUnit
,
602 case GL_TEXTURE_ENV_MODE
:
603 return texUnit
->EnvMode
;
606 if (ctx
->Extensions
.EXT_texture_env_combine
||
607 ctx
->Extensions
.ARB_texture_env_combine
) {
608 return texUnit
->Combine
.ModeRGB
;
611 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
614 case GL_COMBINE_ALPHA
:
615 if (ctx
->Extensions
.EXT_texture_env_combine
||
616 ctx
->Extensions
.ARB_texture_env_combine
) {
617 return texUnit
->Combine
.ModeA
;
620 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
626 if (ctx
->Extensions
.EXT_texture_env_combine
||
627 ctx
->Extensions
.ARB_texture_env_combine
) {
628 const unsigned rgb_idx
= pname
- GL_SOURCE0_RGB
;
629 return texUnit
->Combine
.SourceRGB
[rgb_idx
];
632 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
635 case GL_SOURCE3_RGB_NV
:
636 if (ctx
->Extensions
.NV_texture_env_combine4
) {
637 return texUnit
->Combine
.SourceRGB
[3];
640 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
643 case GL_SOURCE0_ALPHA
:
644 case GL_SOURCE1_ALPHA
:
645 case GL_SOURCE2_ALPHA
:
646 if (ctx
->Extensions
.EXT_texture_env_combine
||
647 ctx
->Extensions
.ARB_texture_env_combine
) {
648 const unsigned alpha_idx
= pname
- GL_SOURCE0_ALPHA
;
649 return texUnit
->Combine
.SourceA
[alpha_idx
];
652 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
655 case GL_SOURCE3_ALPHA_NV
:
656 if (ctx
->Extensions
.NV_texture_env_combine4
) {
657 return texUnit
->Combine
.SourceA
[3];
660 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
663 case GL_OPERAND0_RGB
:
664 case GL_OPERAND1_RGB
:
665 case GL_OPERAND2_RGB
:
666 if (ctx
->Extensions
.EXT_texture_env_combine
||
667 ctx
->Extensions
.ARB_texture_env_combine
) {
668 const unsigned op_rgb
= pname
- GL_OPERAND0_RGB
;
669 return texUnit
->Combine
.OperandRGB
[op_rgb
];
672 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
675 case GL_OPERAND3_RGB_NV
:
676 if (ctx
->Extensions
.NV_texture_env_combine4
) {
677 return texUnit
->Combine
.OperandRGB
[3];
680 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
683 case GL_OPERAND0_ALPHA
:
684 case GL_OPERAND1_ALPHA
:
685 case GL_OPERAND2_ALPHA
:
686 if (ctx
->Extensions
.EXT_texture_env_combine
||
687 ctx
->Extensions
.ARB_texture_env_combine
) {
688 const unsigned op_alpha
= pname
- GL_OPERAND0_ALPHA
;
689 return texUnit
->Combine
.OperandA
[op_alpha
];
692 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
695 case GL_OPERAND3_ALPHA_NV
:
696 if (ctx
->Extensions
.NV_texture_env_combine4
) {
697 return texUnit
->Combine
.OperandA
[3];
700 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
704 if (ctx
->Extensions
.EXT_texture_env_combine
||
705 ctx
->Extensions
.ARB_texture_env_combine
) {
706 return 1 << texUnit
->Combine
.ScaleShiftRGB
;
709 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
713 if (ctx
->Extensions
.EXT_texture_env_combine
||
714 ctx
->Extensions
.ARB_texture_env_combine
) {
715 return 1 << texUnit
->Combine
.ScaleShiftA
;
718 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
721 case GL_BUMP_TARGET_ATI
:
722 /* spec doesn't say so, but I think this should be queryable */
723 if (ctx
->Extensions
.ATI_envmap_bumpmap
) {
724 return texUnit
->BumpTarget
;
727 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
735 return -1; /* error */
741 _mesa_GetTexEnvfv( GLenum target
, GLenum pname
, GLfloat
*params
)
744 const struct gl_texture_unit
*texUnit
;
745 GET_CURRENT_CONTEXT(ctx
);
746 ASSERT_OUTSIDE_BEGIN_END(ctx
);
748 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
749 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxTextureImageUnits
;
750 if (ctx
->Texture
.CurrentUnit
>= maxUnit
) {
751 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexEnvfv(current unit)");
755 texUnit
= _mesa_get_current_tex_unit(ctx
);
757 if (target
== GL_TEXTURE_ENV
) {
758 if (pname
== GL_TEXTURE_ENV_COLOR
) {
759 COPY_4FV( params
, texUnit
->EnvColor
);
762 GLint val
= get_texenvi(ctx
, texUnit
, pname
);
764 *params
= (GLfloat
) val
;
768 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
769 /* GL_EXT_texture_lod_bias */
770 if (!ctx
->Extensions
.EXT_texture_lod_bias
) {
771 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
774 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
775 *params
= texUnit
->LodBias
;
778 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)" );
782 else if (target
== GL_POINT_SPRITE_NV
) {
783 /* GL_ARB_point_sprite / GL_NV_point_sprite */
784 if (!ctx
->Extensions
.NV_point_sprite
785 && !ctx
->Extensions
.ARB_point_sprite
) {
786 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
789 if (pname
== GL_COORD_REPLACE_NV
) {
790 *params
= (GLfloat
) ctx
->Point
.CoordReplace
[ctx
->Texture
.CurrentUnit
];
793 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)" );
798 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
805 _mesa_GetTexEnviv( GLenum target
, GLenum pname
, GLint
*params
)
808 const struct gl_texture_unit
*texUnit
;
809 GET_CURRENT_CONTEXT(ctx
);
810 ASSERT_OUTSIDE_BEGIN_END(ctx
);
812 maxUnit
= (target
== GL_POINT_SPRITE_NV
&& pname
== GL_COORD_REPLACE_NV
)
813 ? ctx
->Const
.MaxTextureCoordUnits
: ctx
->Const
.MaxTextureImageUnits
;
814 if (ctx
->Texture
.CurrentUnit
>= maxUnit
) {
815 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexEnviv(current unit)");
819 texUnit
= _mesa_get_current_tex_unit(ctx
);
821 if (target
== GL_TEXTURE_ENV
) {
822 if (pname
== GL_TEXTURE_ENV_COLOR
) {
823 params
[0] = FLOAT_TO_INT( texUnit
->EnvColor
[0] );
824 params
[1] = FLOAT_TO_INT( texUnit
->EnvColor
[1] );
825 params
[2] = FLOAT_TO_INT( texUnit
->EnvColor
[2] );
826 params
[3] = FLOAT_TO_INT( texUnit
->EnvColor
[3] );
829 GLint val
= get_texenvi(ctx
, texUnit
, pname
);
835 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
836 /* GL_EXT_texture_lod_bias */
837 if (!ctx
->Extensions
.EXT_texture_lod_bias
) {
838 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );
841 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
842 *params
= (GLint
) texUnit
->LodBias
;
845 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(pname)" );
849 else if (target
== GL_POINT_SPRITE_NV
) {
850 /* GL_ARB_point_sprite / GL_NV_point_sprite */
851 if (!ctx
->Extensions
.NV_point_sprite
852 && !ctx
->Extensions
.ARB_point_sprite
) {
853 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );
856 if (pname
== GL_COORD_REPLACE_NV
) {
857 *params
= (GLint
) ctx
->Point
.CoordReplace
[ctx
->Texture
.CurrentUnit
];
860 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(pname)" );
865 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );
872 * Why does ATI_envmap_bumpmap require new entrypoints? Should just
873 * reuse TexEnv ones...
876 _mesa_TexBumpParameterivATI( GLenum pname
, const GLint
*param
)
879 GET_CURRENT_CONTEXT(ctx
);
880 ASSERT_OUTSIDE_BEGIN_END(ctx
);
882 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
883 /* This isn't an "official" error case, but let's tell the user
884 * that something's wrong.
886 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexBumpParameterivATI");
890 if (pname
== GL_BUMP_ROT_MATRIX_ATI
) {
891 /* hope that conversion is correct here */
892 p
[0] = INT_TO_FLOAT( param
[0] );
893 p
[1] = INT_TO_FLOAT( param
[1] );
894 p
[2] = INT_TO_FLOAT( param
[2] );
895 p
[3] = INT_TO_FLOAT( param
[3] );
898 p
[0] = (GLfloat
) param
[0];
899 p
[1] = p
[2] = p
[3] = 0.0F
; /* init to zero, just to be safe */
901 _mesa_TexBumpParameterfvATI( pname
, p
);
906 _mesa_TexBumpParameterfvATI( GLenum pname
, const GLfloat
*param
)
908 struct gl_texture_unit
*texUnit
;
909 GET_CURRENT_CONTEXT(ctx
);
910 ASSERT_OUTSIDE_BEGIN_END(ctx
);
912 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
913 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glTexBumpParameterfvATI");
917 texUnit
= _mesa_get_current_tex_unit(ctx
);
919 if (pname
== GL_BUMP_ROT_MATRIX_ATI
) {
920 if (TEST_EQ_4V(param
, texUnit
->RotMatrix
))
922 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
923 COPY_4FV(texUnit
->RotMatrix
, param
);
926 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexBumpParameter(pname)" );
929 /* Drivers might want to know about this, instead of dedicated function
930 just shove it into TexEnv where it really belongs anyway */
931 if (ctx
->Driver
.TexEnv
) {
932 (*ctx
->Driver
.TexEnv
)( ctx
, 0, pname
, param
);
938 _mesa_GetTexBumpParameterivATI( GLenum pname
, GLint
*param
)
940 const struct gl_texture_unit
*texUnit
;
942 GET_CURRENT_CONTEXT(ctx
);
943 ASSERT_OUTSIDE_BEGIN_END(ctx
);
945 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
946 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexBumpParameterivATI");
950 texUnit
= _mesa_get_current_tex_unit(ctx
);
952 if (pname
== GL_BUMP_ROT_MATRIX_SIZE_ATI
) {
953 /* spec leaves open to support larger matrices.
954 Don't think anyone would ever want to use it
955 (and apps almost certainly would not understand it and
956 thus fail to submit matrices correctly) so hardcode this. */
959 else if (pname
== GL_BUMP_ROT_MATRIX_ATI
) {
960 /* hope that conversion is correct here */
961 param
[0] = FLOAT_TO_INT(texUnit
->RotMatrix
[0]);
962 param
[1] = FLOAT_TO_INT(texUnit
->RotMatrix
[1]);
963 param
[2] = FLOAT_TO_INT(texUnit
->RotMatrix
[2]);
964 param
[3] = FLOAT_TO_INT(texUnit
->RotMatrix
[3]);
966 else if (pname
== GL_BUMP_NUM_TEX_UNITS_ATI
) {
968 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
969 if (ctx
->Const
.SupportedBumpUnits
& (1 << i
)) {
975 else if (pname
== GL_BUMP_TEX_UNITS_ATI
) {
976 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
977 if (ctx
->Const
.SupportedBumpUnits
& (1 << i
)) {
978 *param
++ = i
+ GL_TEXTURE0
;
983 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexBumpParameter(pname)" );
990 _mesa_GetTexBumpParameterfvATI( GLenum pname
, GLfloat
*param
)
992 const struct gl_texture_unit
*texUnit
;
994 GET_CURRENT_CONTEXT(ctx
);
995 ASSERT_OUTSIDE_BEGIN_END(ctx
);
997 if (!ctx
->Extensions
.ATI_envmap_bumpmap
) {
998 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetTexBumpParameterfvATI");
1002 texUnit
= _mesa_get_current_tex_unit(ctx
);
1004 if (pname
== GL_BUMP_ROT_MATRIX_SIZE_ATI
) {
1005 /* spec leaves open to support larger matrices.
1006 Don't think anyone would ever want to use it
1007 (and apps might not understand it) so hardcode this. */
1010 else if (pname
== GL_BUMP_ROT_MATRIX_ATI
) {
1011 param
[0] = texUnit
->RotMatrix
[0];
1012 param
[1] = texUnit
->RotMatrix
[1];
1013 param
[2] = texUnit
->RotMatrix
[2];
1014 param
[3] = texUnit
->RotMatrix
[3];
1016 else if (pname
== GL_BUMP_NUM_TEX_UNITS_ATI
) {
1018 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
1019 if (ctx
->Const
.SupportedBumpUnits
& (1 << i
)) {
1023 *param
= (GLfloat
) count
;
1025 else if (pname
== GL_BUMP_TEX_UNITS_ATI
) {
1026 for (i
= 0; i
< ctx
->Const
.MaxTextureImageUnits
; i
++) {
1027 if (ctx
->Const
.SupportedBumpUnits
& (1 << i
)) {
1028 *param
++ = (GLfloat
) (i
+ GL_TEXTURE0
);
1033 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexBumpParameter(pname)" );