texenv.c revision 848b8605
1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 24848b8605Smrg */ 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file texenv.c 28848b8605Smrg * 29848b8605Smrg * glTexEnv-related functions 30848b8605Smrg */ 31848b8605Smrg 32848b8605Smrg 33848b8605Smrg#include "main/glheader.h" 34848b8605Smrg#include "main/context.h" 35848b8605Smrg#include "main/blend.h" 36848b8605Smrg#include "main/enums.h" 37848b8605Smrg#include "main/macros.h" 38848b8605Smrg#include "main/mtypes.h" 39848b8605Smrg#include "main/state.h" 40848b8605Smrg#include "main/texenv.h" 41848b8605Smrg#include "main/texstate.h" 42848b8605Smrg 43848b8605Smrg 44848b8605Smrg#define TE_ERROR(errCode, msg, value) \ 45848b8605Smrg _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value)); 46848b8605Smrg 47848b8605Smrg 48848b8605Smrg/** Set texture env mode */ 49848b8605Smrgstatic void 50848b8605Smrgset_env_mode(struct gl_context *ctx, 51848b8605Smrg struct gl_texture_unit *texUnit, 52848b8605Smrg GLenum mode) 53848b8605Smrg{ 54848b8605Smrg GLboolean legal; 55848b8605Smrg 56848b8605Smrg if (texUnit->EnvMode == mode) 57848b8605Smrg return; 58848b8605Smrg 59848b8605Smrg switch (mode) { 60848b8605Smrg case GL_MODULATE: 61848b8605Smrg case GL_BLEND: 62848b8605Smrg case GL_DECAL: 63848b8605Smrg case GL_REPLACE: 64848b8605Smrg case GL_ADD: 65848b8605Smrg case GL_COMBINE: 66848b8605Smrg legal = GL_TRUE; 67848b8605Smrg break; 68848b8605Smrg case GL_REPLACE_EXT: 69848b8605Smrg mode = GL_REPLACE; /* GL_REPLACE_EXT != GL_REPLACE */ 70848b8605Smrg legal = GL_TRUE; 71848b8605Smrg break; 72848b8605Smrg case GL_COMBINE4_NV: 73848b8605Smrg legal = ctx->Extensions.NV_texture_env_combine4; 74848b8605Smrg break; 75848b8605Smrg default: 76848b8605Smrg legal = GL_FALSE; 77848b8605Smrg } 78848b8605Smrg 79848b8605Smrg if (legal) { 80848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 81848b8605Smrg texUnit->EnvMode = mode; 82848b8605Smrg } 83848b8605Smrg else { 84848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 85848b8605Smrg } 86848b8605Smrg} 87848b8605Smrg 88848b8605Smrg 89848b8605Smrgstatic void 90848b8605Smrgset_env_color(struct gl_context *ctx, 91848b8605Smrg struct gl_texture_unit *texUnit, 92848b8605Smrg const GLfloat *color) 93848b8605Smrg{ 94848b8605Smrg if (TEST_EQ_4V(color, texUnit->EnvColorUnclamped)) 95848b8605Smrg return; 96848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 97848b8605Smrg COPY_4FV(texUnit->EnvColorUnclamped, color); 98848b8605Smrg texUnit->EnvColor[0] = CLAMP(color[0], 0.0F, 1.0F); 99848b8605Smrg texUnit->EnvColor[1] = CLAMP(color[1], 0.0F, 1.0F); 100848b8605Smrg texUnit->EnvColor[2] = CLAMP(color[2], 0.0F, 1.0F); 101848b8605Smrg texUnit->EnvColor[3] = CLAMP(color[3], 0.0F, 1.0F); 102848b8605Smrg} 103848b8605Smrg 104848b8605Smrg 105848b8605Smrg/** Set an RGB or A combiner mode/function */ 106848b8605Smrgstatic void 107848b8605Smrgset_combiner_mode(struct gl_context *ctx, 108848b8605Smrg struct gl_texture_unit *texUnit, 109848b8605Smrg GLenum pname, GLenum mode) 110848b8605Smrg{ 111848b8605Smrg GLboolean legal; 112848b8605Smrg 113848b8605Smrg switch (mode) { 114848b8605Smrg case GL_REPLACE: 115848b8605Smrg case GL_MODULATE: 116848b8605Smrg case GL_ADD: 117848b8605Smrg case GL_ADD_SIGNED: 118848b8605Smrg case GL_INTERPOLATE: 119848b8605Smrg legal = GL_TRUE; 120848b8605Smrg break; 121848b8605Smrg case GL_SUBTRACT: 122848b8605Smrg legal = ctx->Extensions.ARB_texture_env_combine; 123848b8605Smrg break; 124848b8605Smrg case GL_DOT3_RGB_EXT: 125848b8605Smrg case GL_DOT3_RGBA_EXT: 126848b8605Smrg legal = (ctx->API == API_OPENGL_COMPAT && 127848b8605Smrg ctx->Extensions.EXT_texture_env_dot3 && 128848b8605Smrg pname == GL_COMBINE_RGB); 129848b8605Smrg break; 130848b8605Smrg case GL_DOT3_RGB: 131848b8605Smrg case GL_DOT3_RGBA: 132848b8605Smrg legal = (ctx->Extensions.ARB_texture_env_dot3 && 133848b8605Smrg pname == GL_COMBINE_RGB); 134848b8605Smrg break; 135848b8605Smrg case GL_MODULATE_ADD_ATI: 136848b8605Smrg case GL_MODULATE_SIGNED_ADD_ATI: 137848b8605Smrg case GL_MODULATE_SUBTRACT_ATI: 138848b8605Smrg legal = (ctx->API == API_OPENGL_COMPAT && 139848b8605Smrg ctx->Extensions.ATI_texture_env_combine3); 140848b8605Smrg break; 141848b8605Smrg default: 142848b8605Smrg legal = GL_FALSE; 143848b8605Smrg } 144848b8605Smrg 145848b8605Smrg if (!legal) { 146848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 147848b8605Smrg return; 148848b8605Smrg } 149848b8605Smrg 150848b8605Smrg switch (pname) { 151848b8605Smrg case GL_COMBINE_RGB: 152848b8605Smrg if (texUnit->Combine.ModeRGB == mode) 153848b8605Smrg return; 154848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 155848b8605Smrg texUnit->Combine.ModeRGB = mode; 156848b8605Smrg break; 157848b8605Smrg 158848b8605Smrg case GL_COMBINE_ALPHA: 159848b8605Smrg if (texUnit->Combine.ModeA == mode) 160848b8605Smrg return; 161848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 162848b8605Smrg texUnit->Combine.ModeA = mode; 163848b8605Smrg break; 164848b8605Smrg default: 165848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 166848b8605Smrg } 167848b8605Smrg} 168848b8605Smrg 169848b8605Smrg 170848b8605Smrg 171848b8605Smrg/** Set an RGB or A combiner source term */ 172848b8605Smrgstatic void 173848b8605Smrgset_combiner_source(struct gl_context *ctx, 174848b8605Smrg struct gl_texture_unit *texUnit, 175848b8605Smrg GLenum pname, GLenum param) 176848b8605Smrg{ 177848b8605Smrg GLuint term; 178848b8605Smrg GLboolean alpha, legal; 179848b8605Smrg 180848b8605Smrg /* 181848b8605Smrg * Translate pname to (term, alpha). 182848b8605Smrg * 183848b8605Smrg * The enums were given sequential values for a reason. 184848b8605Smrg */ 185848b8605Smrg switch (pname) { 186848b8605Smrg case GL_SOURCE0_RGB: 187848b8605Smrg case GL_SOURCE1_RGB: 188848b8605Smrg case GL_SOURCE2_RGB: 189848b8605Smrg case GL_SOURCE3_RGB_NV: 190848b8605Smrg term = pname - GL_SOURCE0_RGB; 191848b8605Smrg alpha = GL_FALSE; 192848b8605Smrg break; 193848b8605Smrg case GL_SOURCE0_ALPHA: 194848b8605Smrg case GL_SOURCE1_ALPHA: 195848b8605Smrg case GL_SOURCE2_ALPHA: 196848b8605Smrg case GL_SOURCE3_ALPHA_NV: 197848b8605Smrg term = pname - GL_SOURCE0_ALPHA; 198848b8605Smrg alpha = GL_TRUE; 199848b8605Smrg break; 200848b8605Smrg default: 201848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 202848b8605Smrg return; 203848b8605Smrg } 204848b8605Smrg 205848b8605Smrg if ((term == 3) && (ctx->API != API_OPENGL_COMPAT 206848b8605Smrg || !ctx->Extensions.NV_texture_env_combine4)) { 207848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 208848b8605Smrg return; 209848b8605Smrg } 210848b8605Smrg 211848b8605Smrg assert(term < MAX_COMBINER_TERMS); 212848b8605Smrg 213848b8605Smrg /* 214848b8605Smrg * Error-check param (the source term) 215848b8605Smrg */ 216848b8605Smrg switch (param) { 217848b8605Smrg case GL_TEXTURE: 218848b8605Smrg case GL_CONSTANT: 219848b8605Smrg case GL_PRIMARY_COLOR: 220848b8605Smrg case GL_PREVIOUS: 221848b8605Smrg legal = GL_TRUE; 222848b8605Smrg break; 223848b8605Smrg case GL_TEXTURE0: 224848b8605Smrg case GL_TEXTURE1: 225848b8605Smrg case GL_TEXTURE2: 226848b8605Smrg case GL_TEXTURE3: 227848b8605Smrg case GL_TEXTURE4: 228848b8605Smrg case GL_TEXTURE5: 229848b8605Smrg case GL_TEXTURE6: 230848b8605Smrg case GL_TEXTURE7: 231848b8605Smrg legal = (ctx->Extensions.ARB_texture_env_crossbar && 232848b8605Smrg param - GL_TEXTURE0 < ctx->Const.MaxTextureUnits); 233848b8605Smrg break; 234848b8605Smrg case GL_ZERO: 235848b8605Smrg legal = (ctx->API == API_OPENGL_COMPAT && 236848b8605Smrg (ctx->Extensions.ATI_texture_env_combine3 || 237848b8605Smrg ctx->Extensions.NV_texture_env_combine4)); 238848b8605Smrg break; 239848b8605Smrg case GL_ONE: 240848b8605Smrg legal = (ctx->API == API_OPENGL_COMPAT && 241848b8605Smrg ctx->Extensions.ATI_texture_env_combine3); 242848b8605Smrg break; 243848b8605Smrg default: 244848b8605Smrg legal = GL_FALSE; 245848b8605Smrg } 246848b8605Smrg 247848b8605Smrg if (!legal) { 248848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", param); 249848b8605Smrg return; 250848b8605Smrg } 251848b8605Smrg 252848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 253848b8605Smrg 254848b8605Smrg if (alpha) 255848b8605Smrg texUnit->Combine.SourceA[term] = param; 256848b8605Smrg else 257848b8605Smrg texUnit->Combine.SourceRGB[term] = param; 258848b8605Smrg} 259848b8605Smrg 260848b8605Smrg 261848b8605Smrg/** Set an RGB or A combiner operand term */ 262848b8605Smrgstatic void 263848b8605Smrgset_combiner_operand(struct gl_context *ctx, 264848b8605Smrg struct gl_texture_unit *texUnit, 265848b8605Smrg GLenum pname, GLenum param) 266848b8605Smrg{ 267848b8605Smrg GLuint term; 268848b8605Smrg GLboolean alpha, legal; 269848b8605Smrg 270848b8605Smrg /* The enums were given sequential values for a reason. 271848b8605Smrg */ 272848b8605Smrg switch (pname) { 273848b8605Smrg case GL_OPERAND0_RGB: 274848b8605Smrg case GL_OPERAND1_RGB: 275848b8605Smrg case GL_OPERAND2_RGB: 276848b8605Smrg case GL_OPERAND3_RGB_NV: 277848b8605Smrg term = pname - GL_OPERAND0_RGB; 278848b8605Smrg alpha = GL_FALSE; 279848b8605Smrg break; 280848b8605Smrg case GL_OPERAND0_ALPHA: 281848b8605Smrg case GL_OPERAND1_ALPHA: 282848b8605Smrg case GL_OPERAND2_ALPHA: 283848b8605Smrg case GL_OPERAND3_ALPHA_NV: 284848b8605Smrg term = pname - GL_OPERAND0_ALPHA; 285848b8605Smrg alpha = GL_TRUE; 286848b8605Smrg break; 287848b8605Smrg default: 288848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 289848b8605Smrg return; 290848b8605Smrg } 291848b8605Smrg 292848b8605Smrg if ((term == 3) && (ctx->API != API_OPENGL_COMPAT 293848b8605Smrg || !ctx->Extensions.NV_texture_env_combine4)) { 294848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 295848b8605Smrg return; 296848b8605Smrg } 297848b8605Smrg 298848b8605Smrg assert(term < MAX_COMBINER_TERMS); 299848b8605Smrg 300848b8605Smrg /* 301848b8605Smrg * Error-check param (the source operand) 302848b8605Smrg */ 303848b8605Smrg switch (param) { 304848b8605Smrg case GL_SRC_COLOR: 305848b8605Smrg case GL_ONE_MINUS_SRC_COLOR: 306848b8605Smrg /* The color input can only be used with GL_OPERAND[01]_RGB in the EXT 307848b8605Smrg * version. In the ARB and NV versions and OpenGL ES 1.x they can be 308848b8605Smrg * used for any RGB operand. 309848b8605Smrg */ 310848b8605Smrg legal = !alpha 311848b8605Smrg && ((term < 2) || ctx->Extensions.ARB_texture_env_combine 312848b8605Smrg || ctx->Extensions.NV_texture_env_combine4); 313848b8605Smrg break; 314848b8605Smrg case GL_ONE_MINUS_SRC_ALPHA: 315848b8605Smrg /* GL_ONE_MINUS_SRC_ALPHA can only be used with 316848b8605Smrg * GL_OPERAND[01]_(RGB|ALPHA) in the EXT version. In the ARB and NV 317848b8605Smrg * versions and OpenGL ES 1.x it can be used for any operand. 318848b8605Smrg */ 319848b8605Smrg legal = (term < 2) || ctx->Extensions.ARB_texture_env_combine 320848b8605Smrg || ctx->Extensions.NV_texture_env_combine4; 321848b8605Smrg break; 322848b8605Smrg case GL_SRC_ALPHA: 323848b8605Smrg legal = GL_TRUE; 324848b8605Smrg break; 325848b8605Smrg default: 326848b8605Smrg legal = GL_FALSE; 327848b8605Smrg } 328848b8605Smrg 329848b8605Smrg if (!legal) { 330848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", param); 331848b8605Smrg return; 332848b8605Smrg } 333848b8605Smrg 334848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 335848b8605Smrg 336848b8605Smrg if (alpha) 337848b8605Smrg texUnit->Combine.OperandA[term] = param; 338848b8605Smrg else 339848b8605Smrg texUnit->Combine.OperandRGB[term] = param; 340848b8605Smrg} 341848b8605Smrg 342848b8605Smrg 343848b8605Smrgstatic void 344848b8605Smrgset_combiner_scale(struct gl_context *ctx, 345848b8605Smrg struct gl_texture_unit *texUnit, 346848b8605Smrg GLenum pname, GLfloat scale) 347848b8605Smrg{ 348848b8605Smrg GLuint shift; 349848b8605Smrg 350848b8605Smrg if (scale == 1.0F) { 351848b8605Smrg shift = 0; 352848b8605Smrg } 353848b8605Smrg else if (scale == 2.0F) { 354848b8605Smrg shift = 1; 355848b8605Smrg } 356848b8605Smrg else if (scale == 4.0F) { 357848b8605Smrg shift = 2; 358848b8605Smrg } 359848b8605Smrg else { 360848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, 361848b8605Smrg "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" ); 362848b8605Smrg return; 363848b8605Smrg } 364848b8605Smrg 365848b8605Smrg switch (pname) { 366848b8605Smrg case GL_RGB_SCALE: 367848b8605Smrg if (texUnit->Combine.ScaleShiftRGB == shift) 368848b8605Smrg return; 369848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 370848b8605Smrg texUnit->Combine.ScaleShiftRGB = shift; 371848b8605Smrg break; 372848b8605Smrg case GL_ALPHA_SCALE: 373848b8605Smrg if (texUnit->Combine.ScaleShiftA == shift) 374848b8605Smrg return; 375848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 376848b8605Smrg texUnit->Combine.ScaleShiftA = shift; 377848b8605Smrg break; 378848b8605Smrg default: 379848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 380848b8605Smrg } 381848b8605Smrg} 382848b8605Smrg 383848b8605Smrg 384848b8605Smrg 385848b8605Smrgvoid GLAPIENTRY 386848b8605Smrg_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 387848b8605Smrg{ 388848b8605Smrg const GLint iparam0 = (GLint) param[0]; 389848b8605Smrg struct gl_texture_unit *texUnit; 390848b8605Smrg GLuint maxUnit; 391848b8605Smrg GET_CURRENT_CONTEXT(ctx); 392848b8605Smrg 393848b8605Smrg maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) 394848b8605Smrg ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits; 395848b8605Smrg if (ctx->Texture.CurrentUnit >= maxUnit) { 396848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)"); 397848b8605Smrg return; 398848b8605Smrg } 399848b8605Smrg 400848b8605Smrg texUnit = _mesa_get_current_tex_unit(ctx); 401848b8605Smrg 402848b8605Smrg if (target == GL_TEXTURE_ENV) { 403848b8605Smrg switch (pname) { 404848b8605Smrg case GL_TEXTURE_ENV_MODE: 405848b8605Smrg set_env_mode(ctx, texUnit, (GLenum) iparam0); 406848b8605Smrg break; 407848b8605Smrg case GL_TEXTURE_ENV_COLOR: 408848b8605Smrg set_env_color(ctx, texUnit, param); 409848b8605Smrg break; 410848b8605Smrg case GL_COMBINE_RGB: 411848b8605Smrg case GL_COMBINE_ALPHA: 412848b8605Smrg set_combiner_mode(ctx, texUnit, pname, (GLenum) iparam0); 413848b8605Smrg break; 414848b8605Smrg case GL_SOURCE0_RGB: 415848b8605Smrg case GL_SOURCE1_RGB: 416848b8605Smrg case GL_SOURCE2_RGB: 417848b8605Smrg case GL_SOURCE3_RGB_NV: 418848b8605Smrg case GL_SOURCE0_ALPHA: 419848b8605Smrg case GL_SOURCE1_ALPHA: 420848b8605Smrg case GL_SOURCE2_ALPHA: 421848b8605Smrg case GL_SOURCE3_ALPHA_NV: 422848b8605Smrg set_combiner_source(ctx, texUnit, pname, (GLenum) iparam0); 423848b8605Smrg break; 424848b8605Smrg case GL_OPERAND0_RGB: 425848b8605Smrg case GL_OPERAND1_RGB: 426848b8605Smrg case GL_OPERAND2_RGB: 427848b8605Smrg case GL_OPERAND3_RGB_NV: 428848b8605Smrg case GL_OPERAND0_ALPHA: 429848b8605Smrg case GL_OPERAND1_ALPHA: 430848b8605Smrg case GL_OPERAND2_ALPHA: 431848b8605Smrg case GL_OPERAND3_ALPHA_NV: 432848b8605Smrg set_combiner_operand(ctx, texUnit, pname, (GLenum) iparam0); 433848b8605Smrg break; 434848b8605Smrg case GL_RGB_SCALE: 435848b8605Smrg case GL_ALPHA_SCALE: 436848b8605Smrg set_combiner_scale(ctx, texUnit, pname, param[0]); 437848b8605Smrg break; 438848b8605Smrg default: 439848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" ); 440848b8605Smrg return; 441848b8605Smrg } 442848b8605Smrg } 443848b8605Smrg else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 444848b8605Smrg if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 445848b8605Smrg if (texUnit->LodBias == param[0]) 446848b8605Smrg return; 447848b8605Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 448848b8605Smrg texUnit->LodBias = param[0]; 449848b8605Smrg } 450848b8605Smrg else { 451848b8605Smrg TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 452848b8605Smrg return; 453848b8605Smrg } 454848b8605Smrg } 455848b8605Smrg else if (target == GL_POINT_SPRITE_NV) { 456848b8605Smrg /* GL_ARB_point_sprite / GL_NV_point_sprite */ 457848b8605Smrg if (!ctx->Extensions.NV_point_sprite 458848b8605Smrg && !ctx->Extensions.ARB_point_sprite) { 459848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target ); 460848b8605Smrg return; 461848b8605Smrg } 462848b8605Smrg if (pname == GL_COORD_REPLACE_NV) { 463848b8605Smrg if (iparam0 == GL_TRUE || iparam0 == GL_FALSE) { 464848b8605Smrg /* It's kind of weird to set point state via glTexEnv, 465848b8605Smrg * but that's what the spec calls for. 466848b8605Smrg */ 467848b8605Smrg const GLboolean state = (GLboolean) iparam0; 468848b8605Smrg if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state) 469848b8605Smrg return; 470848b8605Smrg FLUSH_VERTICES(ctx, _NEW_POINT); 471848b8605Smrg ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state; 472848b8605Smrg } 473848b8605Smrg else { 474848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", iparam0); 475848b8605Smrg return; 476848b8605Smrg } 477848b8605Smrg } 478848b8605Smrg else { 479848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname ); 480848b8605Smrg return; 481848b8605Smrg } 482848b8605Smrg } 483848b8605Smrg else { 484848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(target=%s)", 485848b8605Smrg _mesa_lookup_enum_by_nr(target)); 486848b8605Smrg return; 487848b8605Smrg } 488848b8605Smrg 489848b8605Smrg if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) 490848b8605Smrg _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n", 491848b8605Smrg _mesa_lookup_enum_by_nr(target), 492848b8605Smrg _mesa_lookup_enum_by_nr(pname), 493848b8605Smrg *param, 494848b8605Smrg _mesa_lookup_enum_by_nr((GLenum) iparam0)); 495848b8605Smrg 496848b8605Smrg /* Tell device driver about the new texture environment */ 497848b8605Smrg if (ctx->Driver.TexEnv) { 498848b8605Smrg (*ctx->Driver.TexEnv)( ctx, target, pname, param ); 499848b8605Smrg } 500848b8605Smrg} 501848b8605Smrg 502848b8605Smrg 503848b8605Smrgvoid GLAPIENTRY 504848b8605Smrg_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ) 505848b8605Smrg{ 506848b8605Smrg GLfloat p[4]; 507848b8605Smrg p[0] = param; 508848b8605Smrg p[1] = p[2] = p[3] = 0.0; 509848b8605Smrg _mesa_TexEnvfv( target, pname, p ); 510848b8605Smrg} 511848b8605Smrg 512848b8605Smrg 513848b8605Smrg 514848b8605Smrgvoid GLAPIENTRY 515848b8605Smrg_mesa_TexEnvi( GLenum target, GLenum pname, GLint param ) 516848b8605Smrg{ 517848b8605Smrg GLfloat p[4]; 518848b8605Smrg p[0] = (GLfloat) param; 519848b8605Smrg p[1] = p[2] = p[3] = 0.0; 520848b8605Smrg _mesa_TexEnvfv( target, pname, p ); 521848b8605Smrg} 522848b8605Smrg 523848b8605Smrg 524848b8605Smrgvoid GLAPIENTRY 525848b8605Smrg_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ) 526848b8605Smrg{ 527848b8605Smrg GLfloat p[4]; 528848b8605Smrg if (pname == GL_TEXTURE_ENV_COLOR) { 529848b8605Smrg p[0] = INT_TO_FLOAT( param[0] ); 530848b8605Smrg p[1] = INT_TO_FLOAT( param[1] ); 531848b8605Smrg p[2] = INT_TO_FLOAT( param[2] ); 532848b8605Smrg p[3] = INT_TO_FLOAT( param[3] ); 533848b8605Smrg } 534848b8605Smrg else { 535848b8605Smrg p[0] = (GLfloat) param[0]; 536848b8605Smrg p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */ 537848b8605Smrg } 538848b8605Smrg _mesa_TexEnvfv( target, pname, p ); 539848b8605Smrg} 540848b8605Smrg 541848b8605Smrg 542848b8605Smrg 543848b8605Smrg/** 544848b8605Smrg * Helper for glGetTexEnvi/f() 545848b8605Smrg * \return value of queried pname or -1 if error. 546848b8605Smrg */ 547848b8605Smrgstatic GLint 548848b8605Smrgget_texenvi(struct gl_context *ctx, const struct gl_texture_unit *texUnit, 549848b8605Smrg GLenum pname) 550848b8605Smrg{ 551848b8605Smrg switch (pname) { 552848b8605Smrg case GL_TEXTURE_ENV_MODE: 553848b8605Smrg return texUnit->EnvMode; 554848b8605Smrg break; 555848b8605Smrg case GL_COMBINE_RGB: 556848b8605Smrg return texUnit->Combine.ModeRGB; 557848b8605Smrg case GL_COMBINE_ALPHA: 558848b8605Smrg return texUnit->Combine.ModeA; 559848b8605Smrg case GL_SOURCE0_RGB: 560848b8605Smrg case GL_SOURCE1_RGB: 561848b8605Smrg case GL_SOURCE2_RGB: { 562848b8605Smrg const unsigned rgb_idx = pname - GL_SOURCE0_RGB; 563848b8605Smrg return texUnit->Combine.SourceRGB[rgb_idx]; 564848b8605Smrg } 565848b8605Smrg case GL_SOURCE3_RGB_NV: 566848b8605Smrg if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { 567848b8605Smrg return texUnit->Combine.SourceRGB[3]; 568848b8605Smrg } 569848b8605Smrg else { 570848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 571848b8605Smrg } 572848b8605Smrg break; 573848b8605Smrg case GL_SOURCE0_ALPHA: 574848b8605Smrg case GL_SOURCE1_ALPHA: 575848b8605Smrg case GL_SOURCE2_ALPHA: { 576848b8605Smrg const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA; 577848b8605Smrg return texUnit->Combine.SourceA[alpha_idx]; 578848b8605Smrg } 579848b8605Smrg case GL_SOURCE3_ALPHA_NV: 580848b8605Smrg if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { 581848b8605Smrg return texUnit->Combine.SourceA[3]; 582848b8605Smrg } 583848b8605Smrg else { 584848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 585848b8605Smrg } 586848b8605Smrg break; 587848b8605Smrg case GL_OPERAND0_RGB: 588848b8605Smrg case GL_OPERAND1_RGB: 589848b8605Smrg case GL_OPERAND2_RGB: { 590848b8605Smrg const unsigned op_rgb = pname - GL_OPERAND0_RGB; 591848b8605Smrg return texUnit->Combine.OperandRGB[op_rgb]; 592848b8605Smrg } 593848b8605Smrg case GL_OPERAND3_RGB_NV: 594848b8605Smrg if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { 595848b8605Smrg return texUnit->Combine.OperandRGB[3]; 596848b8605Smrg } 597848b8605Smrg else { 598848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 599848b8605Smrg } 600848b8605Smrg break; 601848b8605Smrg case GL_OPERAND0_ALPHA: 602848b8605Smrg case GL_OPERAND1_ALPHA: 603848b8605Smrg case GL_OPERAND2_ALPHA: { 604848b8605Smrg const unsigned op_alpha = pname - GL_OPERAND0_ALPHA; 605848b8605Smrg return texUnit->Combine.OperandA[op_alpha]; 606848b8605Smrg } 607848b8605Smrg case GL_OPERAND3_ALPHA_NV: 608848b8605Smrg if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { 609848b8605Smrg return texUnit->Combine.OperandA[3]; 610848b8605Smrg } 611848b8605Smrg else { 612848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 613848b8605Smrg } 614848b8605Smrg break; 615848b8605Smrg case GL_RGB_SCALE: 616848b8605Smrg return 1 << texUnit->Combine.ScaleShiftRGB; 617848b8605Smrg case GL_ALPHA_SCALE: 618848b8605Smrg return 1 << texUnit->Combine.ScaleShiftA; 619848b8605Smrg default: 620848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 621848b8605Smrg break; 622848b8605Smrg } 623848b8605Smrg 624848b8605Smrg return -1; /* error */ 625848b8605Smrg} 626848b8605Smrg 627848b8605Smrg 628848b8605Smrg 629848b8605Smrgvoid GLAPIENTRY 630848b8605Smrg_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) 631848b8605Smrg{ 632848b8605Smrg GLuint maxUnit; 633848b8605Smrg const struct gl_texture_unit *texUnit; 634848b8605Smrg GET_CURRENT_CONTEXT(ctx); 635848b8605Smrg 636848b8605Smrg maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) 637848b8605Smrg ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits; 638848b8605Smrg if (ctx->Texture.CurrentUnit >= maxUnit) { 639848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)"); 640848b8605Smrg return; 641848b8605Smrg } 642848b8605Smrg 643848b8605Smrg texUnit = _mesa_get_current_tex_unit(ctx); 644848b8605Smrg 645848b8605Smrg if (target == GL_TEXTURE_ENV) { 646848b8605Smrg if (pname == GL_TEXTURE_ENV_COLOR) { 647848b8605Smrg if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) 648848b8605Smrg _mesa_update_state(ctx); 649848b8605Smrg if (_mesa_get_clamp_fragment_color(ctx)) 650848b8605Smrg COPY_4FV( params, texUnit->EnvColor ); 651848b8605Smrg else 652848b8605Smrg COPY_4FV( params, texUnit->EnvColorUnclamped ); 653848b8605Smrg } 654848b8605Smrg else { 655848b8605Smrg GLint val = get_texenvi(ctx, texUnit, pname); 656848b8605Smrg if (val >= 0) { 657848b8605Smrg *params = (GLfloat) val; 658848b8605Smrg } 659848b8605Smrg } 660848b8605Smrg } 661848b8605Smrg else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 662848b8605Smrg if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 663848b8605Smrg *params = texUnit->LodBias; 664848b8605Smrg } 665848b8605Smrg else { 666848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); 667848b8605Smrg return; 668848b8605Smrg } 669848b8605Smrg } 670848b8605Smrg else if (target == GL_POINT_SPRITE_NV) { 671848b8605Smrg /* GL_ARB_point_sprite / GL_NV_point_sprite */ 672848b8605Smrg if (!ctx->Extensions.NV_point_sprite 673848b8605Smrg && !ctx->Extensions.ARB_point_sprite) { 674848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); 675848b8605Smrg return; 676848b8605Smrg } 677848b8605Smrg if (pname == GL_COORD_REPLACE_NV) { 678848b8605Smrg *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit]; 679848b8605Smrg } 680848b8605Smrg else { 681848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); 682848b8605Smrg return; 683848b8605Smrg } 684848b8605Smrg } 685848b8605Smrg else { 686848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); 687848b8605Smrg return; 688848b8605Smrg } 689848b8605Smrg} 690848b8605Smrg 691848b8605Smrg 692848b8605Smrgvoid GLAPIENTRY 693848b8605Smrg_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) 694848b8605Smrg{ 695848b8605Smrg GLuint maxUnit; 696848b8605Smrg const struct gl_texture_unit *texUnit; 697848b8605Smrg GET_CURRENT_CONTEXT(ctx); 698848b8605Smrg 699848b8605Smrg maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) 700848b8605Smrg ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits; 701848b8605Smrg if (ctx->Texture.CurrentUnit >= maxUnit) { 702848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(current unit)"); 703848b8605Smrg return; 704848b8605Smrg } 705848b8605Smrg 706848b8605Smrg texUnit = _mesa_get_current_tex_unit(ctx); 707848b8605Smrg 708848b8605Smrg if (target == GL_TEXTURE_ENV) { 709848b8605Smrg if (pname == GL_TEXTURE_ENV_COLOR) { 710848b8605Smrg params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] ); 711848b8605Smrg params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] ); 712848b8605Smrg params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] ); 713848b8605Smrg params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] ); 714848b8605Smrg } 715848b8605Smrg else { 716848b8605Smrg GLint val = get_texenvi(ctx, texUnit, pname); 717848b8605Smrg if (val >= 0) { 718848b8605Smrg *params = val; 719848b8605Smrg } 720848b8605Smrg } 721848b8605Smrg } 722848b8605Smrg else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 723848b8605Smrg if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 724848b8605Smrg *params = (GLint) texUnit->LodBias; 725848b8605Smrg } 726848b8605Smrg else { 727848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" ); 728848b8605Smrg return; 729848b8605Smrg } 730848b8605Smrg } 731848b8605Smrg else if (target == GL_POINT_SPRITE_NV) { 732848b8605Smrg /* GL_ARB_point_sprite / GL_NV_point_sprite */ 733848b8605Smrg if (!ctx->Extensions.NV_point_sprite 734848b8605Smrg && !ctx->Extensions.ARB_point_sprite) { 735848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); 736848b8605Smrg return; 737848b8605Smrg } 738848b8605Smrg if (pname == GL_COORD_REPLACE_NV) { 739848b8605Smrg *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit]; 740848b8605Smrg } 741848b8605Smrg else { 742848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" ); 743848b8605Smrg return; 744848b8605Smrg } 745848b8605Smrg } 746848b8605Smrg else { 747848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); 748848b8605Smrg return; 749848b8605Smrg } 750848b8605Smrg} 751848b8605Smrg 752