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
34 #define TE_ERROR(errCode, msg, value) \
35 _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
38 /** Set texture env mode */
40 set_env_mode(struct gl_context
*ctx
,
41 struct gl_texture_unit
*texUnit
,
46 if (texUnit
->EnvMode
== mode
)
59 mode
= GL_REPLACE
; /* GL_REPLACE_EXT != GL_REPLACE */
63 legal
= ctx
->Extensions
.NV_texture_env_combine4
;
70 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
71 texUnit
->EnvMode
= mode
;
74 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", mode
);
80 set_env_color(struct gl_context
*ctx
,
81 struct gl_texture_unit
*texUnit
,
84 if (TEST_EQ_4V(color
, texUnit
->EnvColor
))
86 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
87 COPY_4FV(texUnit
->EnvColor
, color
);
91 /** Set an RGB or A combiner mode/function */
93 set_combiner_mode(struct gl_context
*ctx
,
94 struct gl_texture_unit
*texUnit
,
95 GLenum pname
, GLenum mode
)
108 legal
= ctx
->Extensions
.ARB_texture_env_combine
;
110 case GL_DOT3_RGB_EXT
:
111 case GL_DOT3_RGBA_EXT
:
112 legal
= (ctx
->Extensions
.EXT_texture_env_dot3
&&
113 pname
== GL_COMBINE_RGB
);
117 legal
= (ctx
->Extensions
.ARB_texture_env_dot3
&&
118 pname
== GL_COMBINE_RGB
);
120 case GL_MODULATE_ADD_ATI
:
121 case GL_MODULATE_SIGNED_ADD_ATI
:
122 case GL_MODULATE_SUBTRACT_ATI
:
123 legal
= ctx
->Extensions
.ATI_texture_env_combine3
;
130 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", mode
);
136 if (texUnit
->Combine
.ModeRGB
== mode
)
138 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
139 texUnit
->Combine
.ModeRGB
= mode
;
142 case GL_COMBINE_ALPHA
:
143 if (texUnit
->Combine
.ModeA
== mode
)
145 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
146 texUnit
->Combine
.ModeA
= mode
;
149 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
155 /** Set an RGB or A combiner source term */
157 set_combiner_source(struct gl_context
*ctx
,
158 struct gl_texture_unit
*texUnit
,
159 GLenum pname
, GLenum param
)
162 GLboolean alpha
, legal
;
165 * Translate pname to (term, alpha).
167 * The enums were given sequential values for a reason.
173 case GL_SOURCE3_RGB_NV
:
174 term
= pname
- GL_SOURCE0_RGB
;
177 case GL_SOURCE0_ALPHA
:
178 case GL_SOURCE1_ALPHA
:
179 case GL_SOURCE2_ALPHA
:
180 case GL_SOURCE3_ALPHA_NV
:
181 term
= pname
- GL_SOURCE0_ALPHA
;
185 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
189 if ((term
== 3) && !ctx
->Extensions
.NV_texture_env_combine4
) {
190 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
194 assert(term
< MAX_COMBINER_TERMS
);
197 * Error-check param (the source term)
202 case GL_PRIMARY_COLOR
:
207 legal
= (ctx
->Extensions
.ATI_texture_env_combine3
||
208 ctx
->Extensions
.NV_texture_env_combine4
);
211 legal
= ctx
->Extensions
.ATI_texture_env_combine3
;
218 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", param
);
222 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
225 texUnit
->Combine
.SourceA
[term
] = param
;
227 texUnit
->Combine
.SourceRGB
[term
] = param
;
231 /** Set an RGB or A combiner operand term */
233 set_combiner_operand(struct gl_context
*ctx
,
234 struct gl_texture_unit
*texUnit
,
235 GLenum pname
, GLenum param
)
238 GLboolean alpha
, legal
;
240 /* The enums were given sequential values for a reason.
243 case GL_OPERAND0_RGB
:
244 case GL_OPERAND1_RGB
:
245 case GL_OPERAND2_RGB
:
246 case GL_OPERAND3_RGB_NV
:
247 term
= pname
- GL_OPERAND0_RGB
;
250 case GL_OPERAND0_ALPHA
:
251 case GL_OPERAND1_ALPHA
:
252 case GL_OPERAND2_ALPHA
:
253 case GL_OPERAND3_ALPHA_NV
:
254 term
= pname
- GL_OPERAND0_ALPHA
;
258 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
262 if ((term
== 3) && !ctx
->Extensions
.NV_texture_env_combine4
) {
263 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
267 assert(term
< MAX_COMBINER_TERMS
);
270 * Error-check param (the source operand)
274 case GL_ONE_MINUS_SRC_COLOR
:
275 /* The color input can only be used with GL_OPERAND[01]_RGB in the EXT
276 * version. In the ARB and NV versions they can be used for any RGB
280 && ((term
< 2) || ctx
->Extensions
.ARB_texture_env_combine
281 || ctx
->Extensions
.NV_texture_env_combine4
);
283 case GL_ONE_MINUS_SRC_ALPHA
:
284 /* GL_ONE_MINUS_SRC_ALPHA can only be used with
285 * GL_OPERAND[01]_(RGB|ALPHA) in the EXT version. In the ARB and NV
286 * versions it can be used for any operand.
288 legal
= (term
< 2) || ctx
->Extensions
.ARB_texture_env_combine
289 || ctx
->Extensions
.NV_texture_env_combine4
;
299 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(param=%s)", param
);
303 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
306 texUnit
->Combine
.OperandA
[term
] = param
;
308 texUnit
->Combine
.OperandRGB
[term
] = param
;
313 set_combiner_scale(struct gl_context
*ctx
,
314 struct gl_texture_unit
*texUnit
,
315 GLenum pname
, GLfloat scale
)
322 else if (scale
== 2.0F
) {
325 else if (scale
== 4.0F
) {
329 _mesa_error( ctx
, GL_INVALID_VALUE
,
330 "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
336 if (texUnit
->Combine
.ScaleShiftRGB
== shift
)
338 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
339 texUnit
->Combine
.ScaleShiftRGB
= shift
;
342 if (texUnit
->Combine
.ScaleShiftA
== shift
)
344 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
345 texUnit
->Combine
.ScaleShiftA
= shift
;
348 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
355 _mesa_TexEnvfv( GLenum target
, GLenum pname
, const GLfloat
*param
)
357 const GLint iparam0
= (GLint
) param
[0];
358 struct gl_texture_unit
*texUnit
;
359 GET_CURRENT_CONTEXT(ctx
);
360 ASSERT_OUTSIDE_BEGIN_END(ctx
);
362 texUnit
= &ctx
->Texture
.Unit
;
364 if (target
== GL_TEXTURE_ENV
) {
366 case GL_TEXTURE_ENV_MODE
:
367 set_env_mode(ctx
, texUnit
, (GLenum
) iparam0
);
369 case GL_TEXTURE_ENV_COLOR
:
370 set_env_color(ctx
, texUnit
, param
);
373 case GL_COMBINE_ALPHA
:
374 set_combiner_mode(ctx
, texUnit
, pname
, (GLenum
) iparam0
);
379 case GL_SOURCE3_RGB_NV
:
380 case GL_SOURCE0_ALPHA
:
381 case GL_SOURCE1_ALPHA
:
382 case GL_SOURCE2_ALPHA
:
383 case GL_SOURCE3_ALPHA_NV
:
384 set_combiner_source(ctx
, texUnit
, pname
, (GLenum
) iparam0
);
386 case GL_OPERAND0_RGB
:
387 case GL_OPERAND1_RGB
:
388 case GL_OPERAND2_RGB
:
389 case GL_OPERAND3_RGB_NV
:
390 case GL_OPERAND0_ALPHA
:
391 case GL_OPERAND1_ALPHA
:
392 case GL_OPERAND2_ALPHA
:
393 case GL_OPERAND3_ALPHA_NV
:
394 set_combiner_operand(ctx
, texUnit
, pname
, (GLenum
) iparam0
);
398 set_combiner_scale(ctx
, texUnit
, pname
, param
[0]);
401 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(pname)" );
405 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
406 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
407 if (texUnit
->LodBias
== param
[0])
409 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
410 texUnit
->LodBias
= param
[0];
413 TE_ERROR(GL_INVALID_ENUM
, "glTexEnv(pname=%s)", pname
);
418 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexEnv(target=0x%x)",target
);
422 if (MESA_VERBOSE
&(VERBOSE_API
|VERBOSE_TEXTURE
))
423 _mesa_debug(ctx
, "glTexEnv %s %s %.1f(%s) ...\n",
424 _mesa_lookup_enum_by_nr(target
),
425 _mesa_lookup_enum_by_nr(pname
),
427 _mesa_lookup_enum_by_nr((GLenum
) iparam0
));
429 /* Tell device driver about the new texture environment */
430 if (ctx
->Driver
.TexEnv
) {
431 (*ctx
->Driver
.TexEnv
)( ctx
, target
, pname
, param
);
437 _mesa_TexEnvf( GLenum target
, GLenum pname
, GLfloat param
)
441 p
[1] = p
[2] = p
[3] = 0.0;
442 _mesa_TexEnvfv( target
, pname
, p
);
448 _mesa_TexEnvi( GLenum target
, GLenum pname
, GLint param
)
451 p
[0] = (GLfloat
) param
;
452 p
[1] = p
[2] = p
[3] = 0.0;
453 _mesa_TexEnvfv( target
, pname
, p
);
458 _mesa_TexEnviv( GLenum target
, GLenum pname
, const GLint
*param
)
461 if (pname
== GL_TEXTURE_ENV_COLOR
) {
462 p
[0] = INT_TO_FLOAT( param
[0] );
463 p
[1] = INT_TO_FLOAT( param
[1] );
464 p
[2] = INT_TO_FLOAT( param
[2] );
465 p
[3] = INT_TO_FLOAT( param
[3] );
468 p
[0] = (GLfloat
) param
[0];
469 p
[1] = p
[2] = p
[3] = 0; /* init to zero, just to be safe */
471 _mesa_TexEnvfv( target
, pname
, p
);
477 * Helper for glGetTexEnvi/f()
478 * \return value of queried pname or -1 if error.
481 get_texenvi(struct gl_context
*ctx
, const struct gl_texture_unit
*texUnit
,
485 case GL_TEXTURE_ENV_MODE
:
486 return texUnit
->EnvMode
;
489 return texUnit
->Combine
.ModeRGB
;
490 case GL_COMBINE_ALPHA
:
491 return texUnit
->Combine
.ModeA
;
494 case GL_SOURCE2_RGB
: {
495 const unsigned rgb_idx
= pname
- GL_SOURCE0_RGB
;
496 return texUnit
->Combine
.SourceRGB
[rgb_idx
];
498 case GL_SOURCE3_RGB_NV
:
499 if (ctx
->Extensions
.NV_texture_env_combine4
) {
500 return texUnit
->Combine
.SourceRGB
[3];
503 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
506 case GL_SOURCE0_ALPHA
:
507 case GL_SOURCE1_ALPHA
:
508 case GL_SOURCE2_ALPHA
: {
509 const unsigned alpha_idx
= pname
- GL_SOURCE0_ALPHA
;
510 return texUnit
->Combine
.SourceA
[alpha_idx
];
512 case GL_SOURCE3_ALPHA_NV
:
513 if (ctx
->Extensions
.NV_texture_env_combine4
) {
514 return texUnit
->Combine
.SourceA
[3];
517 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
520 case GL_OPERAND0_RGB
:
521 case GL_OPERAND1_RGB
:
522 case GL_OPERAND2_RGB
: {
523 const unsigned op_rgb
= pname
- GL_OPERAND0_RGB
;
524 return texUnit
->Combine
.OperandRGB
[op_rgb
];
526 case GL_OPERAND3_RGB_NV
:
527 if (ctx
->Extensions
.NV_texture_env_combine4
) {
528 return texUnit
->Combine
.OperandRGB
[3];
531 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
534 case GL_OPERAND0_ALPHA
:
535 case GL_OPERAND1_ALPHA
:
536 case GL_OPERAND2_ALPHA
: {
537 const unsigned op_alpha
= pname
- GL_OPERAND0_ALPHA
;
538 return texUnit
->Combine
.OperandA
[op_alpha
];
540 case GL_OPERAND3_ALPHA_NV
:
541 if (ctx
->Extensions
.NV_texture_env_combine4
) {
542 return texUnit
->Combine
.OperandA
[3];
545 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
549 return 1 << texUnit
->Combine
.ScaleShiftRGB
;
551 return 1 << texUnit
->Combine
.ScaleShiftA
;
554 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)");
558 return -1; /* error */
564 _mesa_GetTexEnvfv( GLenum target
, GLenum pname
, GLfloat
*params
)
566 GET_CURRENT_CONTEXT(ctx
);
567 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
;
568 ASSERT_OUTSIDE_BEGIN_END(ctx
);
570 if (target
== GL_TEXTURE_ENV
) {
571 if (pname
== GL_TEXTURE_ENV_COLOR
) {
572 if(ctx
->NewState
& _NEW_BUFFERS
)
573 _mesa_update_state(ctx
);
574 COPY_4FV( params
, texUnit
->EnvColor
);
577 GLint val
= get_texenvi(ctx
, texUnit
, pname
);
579 *params
= (GLfloat
) val
;
583 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
584 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
585 *params
= texUnit
->LodBias
;
588 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(pname)" );
593 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnvfv(target)" );
600 _mesa_GetTexEnviv( GLenum target
, GLenum pname
, GLint
*params
)
602 GET_CURRENT_CONTEXT(ctx
);
603 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
;;
604 ASSERT_OUTSIDE_BEGIN_END(ctx
);
606 if (target
== GL_TEXTURE_ENV
) {
607 if (pname
== GL_TEXTURE_ENV_COLOR
) {
608 params
[0] = FLOAT_TO_INT( texUnit
->EnvColor
[0] );
609 params
[1] = FLOAT_TO_INT( texUnit
->EnvColor
[1] );
610 params
[2] = FLOAT_TO_INT( texUnit
->EnvColor
[2] );
611 params
[3] = FLOAT_TO_INT( texUnit
->EnvColor
[3] );
614 GLint val
= get_texenvi(ctx
, texUnit
, pname
);
620 else if (target
== GL_TEXTURE_FILTER_CONTROL_EXT
) {
621 if (pname
== GL_TEXTURE_LOD_BIAS_EXT
) {
622 *params
= (GLint
) texUnit
->LodBias
;
625 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(pname)" );
630 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetTexEnviv(target)" );