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