texgen.c revision db61b9ce39bccc43140357652ceb78baaf2aea44
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.5 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 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: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 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. 24 */ 25 26/** 27 * \file texgen.c 28 * 29 * glTexGen-related functions 30 */ 31 32 33#include "main/glheader.h" 34#include "main/context.h" 35#include "main/enums.h" 36#include "main/macros.h" 37#include "main/mfeatures.h" 38#include "main/texgen.h" 39#include "main/texstate.h" 40#include "math/m_matrix.h" 41#include "main/dispatch.h" 42 43 44#if FEATURE_texgen 45 46 47/** 48 * Return texgen state for given coordinate 49 */ 50static struct gl_texgen * 51get_texgen(struct gl_texture_unit *texUnit, GLenum coord) 52{ 53 switch (coord) { 54 case GL_S: 55 return &texUnit->GenS; 56 case GL_T: 57 return &texUnit->GenT; 58 case GL_R: 59 return &texUnit->GenR; 60 case GL_Q: 61 return &texUnit->GenQ; 62 default: 63 return NULL; 64 } 65} 66 67 68void GLAPIENTRY 69_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) 70{ 71 struct gl_texture_unit *texUnit; 72 struct gl_texgen *texgen; 73 GET_CURRENT_CONTEXT(ctx); 74 ASSERT_OUTSIDE_BEGIN_END(ctx); 75 76 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) 77 _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n", 78 _mesa_lookup_enum_by_nr(coord), 79 _mesa_lookup_enum_by_nr(pname), 80 *params, 81 _mesa_lookup_enum_by_nr((GLenum) (GLint) *params)); 82 83 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 84 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)"); 85 return; 86 } 87 88 texUnit = _mesa_get_current_tex_unit(ctx); 89 90 texgen = get_texgen(texUnit, coord); 91 if (!texgen) { 92 _mesa_error(ctx, GL_INVALID_ENUM, "glTexGen(coord)"); 93 return; 94 } 95 96 switch (pname) { 97 case GL_TEXTURE_GEN_MODE: 98 { 99 GLenum mode = (GLenum) (GLint) params[0]; 100 GLbitfield bit = 0x0; 101 if (texgen->Mode == mode) 102 return; 103 switch (mode) { 104 case GL_OBJECT_LINEAR: 105 bit = TEXGEN_OBJ_LINEAR; 106 break; 107 case GL_EYE_LINEAR: 108 bit = TEXGEN_EYE_LINEAR; 109 break; 110 case GL_SPHERE_MAP: 111 if (coord == GL_S || coord == GL_T) 112 bit = TEXGEN_SPHERE_MAP; 113 break; 114 case GL_REFLECTION_MAP_NV: 115 if (coord != GL_Q) 116 bit = TEXGEN_REFLECTION_MAP_NV; 117 break; 118 case GL_NORMAL_MAP_NV: 119 if (coord != GL_Q) 120 bit = TEXGEN_NORMAL_MAP_NV; 121 break; 122 default: 123 ; /* nop */ 124 } 125 if (!bit) { 126 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 127 return; 128 } 129 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 130 texgen->Mode = mode; 131 texgen->_ModeBit = bit; 132 } 133 break; 134 135 case GL_OBJECT_PLANE: 136 { 137 if (TEST_EQ_4V(texgen->ObjectPlane, params)) 138 return; 139 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 140 COPY_4FV(texgen->ObjectPlane, params); 141 } 142 break; 143 144 case GL_EYE_PLANE: 145 { 146 GLfloat tmp[4]; 147 /* Transform plane equation by the inverse modelview matrix */ 148 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { 149 _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); 150 } 151 _mesa_transform_vector(tmp, params, 152 ctx->ModelviewMatrixStack.Top->inv); 153 if (TEST_EQ_4V(texgen->EyePlane, tmp)) 154 return; 155 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 156 COPY_4FV(texgen->EyePlane, tmp); 157 } 158 break; 159 160 default: 161 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); 162 return; 163 } 164 165 if (ctx->Driver.TexGen) 166 ctx->Driver.TexGen( ctx, coord, pname, params ); 167} 168 169 170static void GLAPIENTRY 171_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params ) 172{ 173 GLfloat p[4]; 174 p[0] = (GLfloat) params[0]; 175 if (pname == GL_TEXTURE_GEN_MODE) { 176 p[1] = p[2] = p[3] = 0.0F; 177 } 178 else { 179 p[1] = (GLfloat) params[1]; 180 p[2] = (GLfloat) params[2]; 181 p[3] = (GLfloat) params[3]; 182 } 183 _mesa_TexGenfv(coord, pname, p); 184} 185 186 187static void GLAPIENTRY 188_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param ) 189{ 190 GLfloat p[4]; 191 p[0] = (GLfloat) param; 192 p[1] = p[2] = p[3] = 0.0F; 193 _mesa_TexGenfv( coord, pname, p ); 194} 195 196#if FEATURE_ES1 197 198void GLAPIENTRY 199_es_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) 200{ 201 ASSERT(coord == GL_TEXTURE_GEN_STR_OES); 202 _mesa_GetTexGenfv(GL_S, pname, params); 203} 204 205 206void GLAPIENTRY 207_es_TexGenf(GLenum coord, GLenum pname, GLfloat param) 208{ 209 ASSERT(coord == GL_TEXTURE_GEN_STR_OES); 210 /* set S, T, and R at the same time */ 211 _mesa_TexGenf(GL_S, pname, param); 212 _mesa_TexGenf(GL_T, pname, param); 213 _mesa_TexGenf(GL_R, pname, param); 214} 215 216 217void GLAPIENTRY 218_es_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params) 219{ 220 ASSERT(coord == GL_TEXTURE_GEN_STR_OES); 221 /* set S, T, and R at the same time */ 222 _mesa_TexGenfv(GL_S, pname, params); 223 _mesa_TexGenfv(GL_T, pname, params); 224 _mesa_TexGenfv(GL_R, pname, params); 225} 226 227#endif 228 229static void GLAPIENTRY 230_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) 231{ 232 GLfloat p[4]; 233 p[0] = (GLfloat) params[0]; 234 if (pname == GL_TEXTURE_GEN_MODE) { 235 p[1] = p[2] = p[3] = 0.0F; 236 } 237 else { 238 p[1] = (GLfloat) params[1]; 239 p[2] = (GLfloat) params[2]; 240 p[3] = (GLfloat) params[3]; 241 } 242 _mesa_TexGenfv( coord, pname, p ); 243} 244 245 246void GLAPIENTRY 247_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) 248{ 249 GLfloat p[4]; 250 p[0] = param; 251 p[1] = p[2] = p[3] = 0.0F; 252 _mesa_TexGenfv(coord, pname, p); 253} 254 255 256void GLAPIENTRY 257_mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) 258{ 259 GLint p[4]; 260 p[0] = param; 261 p[1] = p[2] = p[3] = 0; 262 _mesa_TexGeniv( coord, pname, p ); 263} 264 265 266 267static void GLAPIENTRY 268_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) 269{ 270 struct gl_texture_unit *texUnit; 271 struct gl_texgen *texgen; 272 GET_CURRENT_CONTEXT(ctx); 273 ASSERT_OUTSIDE_BEGIN_END(ctx); 274 275 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 276 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)"); 277 return; 278 } 279 280 texUnit = _mesa_get_current_tex_unit(ctx); 281 282 texgen = get_texgen(texUnit, coord); 283 if (!texgen) { 284 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)"); 285 return; 286 } 287 288 switch (pname) { 289 case GL_TEXTURE_GEN_MODE: 290 params[0] = ENUM_TO_DOUBLE(texgen->Mode); 291 break; 292 case GL_OBJECT_PLANE: 293 COPY_4V(params, texgen->ObjectPlane); 294 break; 295 case GL_EYE_PLANE: 296 COPY_4V(params, texgen->EyePlane); 297 break; 298 default: 299 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); 300 } 301} 302 303 304 305void GLAPIENTRY 306_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) 307{ 308 struct gl_texture_unit *texUnit; 309 struct gl_texgen *texgen; 310 GET_CURRENT_CONTEXT(ctx); 311 ASSERT_OUTSIDE_BEGIN_END(ctx); 312 313 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 314 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)"); 315 return; 316 } 317 318 texUnit = _mesa_get_current_tex_unit(ctx); 319 320 texgen = get_texgen(texUnit, coord); 321 if (!texgen) { 322 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)"); 323 return; 324 } 325 326 switch (pname) { 327 case GL_TEXTURE_GEN_MODE: 328 params[0] = ENUM_TO_FLOAT(texgen->Mode); 329 break; 330 case GL_OBJECT_PLANE: 331 COPY_4V(params, texgen->ObjectPlane); 332 break; 333 case GL_EYE_PLANE: 334 COPY_4V(params, texgen->EyePlane); 335 break; 336 default: 337 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); 338 } 339} 340 341 342 343static void GLAPIENTRY 344_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ) 345{ 346 struct gl_texture_unit *texUnit; 347 struct gl_texgen *texgen; 348 GET_CURRENT_CONTEXT(ctx); 349 ASSERT_OUTSIDE_BEGIN_END(ctx); 350 351 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 352 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)"); 353 return; 354 } 355 356 texUnit = _mesa_get_current_tex_unit(ctx); 357 358 texgen = get_texgen(texUnit, coord); 359 if (!texgen) { 360 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)"); 361 return; 362 } 363 364 switch (pname) { 365 case GL_TEXTURE_GEN_MODE: 366 params[0] = texgen->Mode; 367 break; 368 case GL_OBJECT_PLANE: 369 params[0] = (GLint) texgen->ObjectPlane[0]; 370 params[1] = (GLint) texgen->ObjectPlane[1]; 371 params[2] = (GLint) texgen->ObjectPlane[2]; 372 params[3] = (GLint) texgen->ObjectPlane[3]; 373 break; 374 case GL_EYE_PLANE: 375 params[0] = (GLint) texgen->EyePlane[0]; 376 params[1] = (GLint) texgen->EyePlane[1]; 377 params[2] = (GLint) texgen->EyePlane[2]; 378 params[3] = (GLint) texgen->EyePlane[3]; 379 break; 380 default: 381 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); 382 } 383} 384 385 386void 387_mesa_init_texgen_dispatch(struct _glapi_table *disp) 388{ 389 SET_GetTexGendv(disp, _mesa_GetTexGendv); 390 SET_GetTexGenfv(disp, _mesa_GetTexGenfv); 391 SET_GetTexGeniv(disp, _mesa_GetTexGeniv); 392 SET_TexGend(disp, _mesa_TexGend); 393 SET_TexGendv(disp, _mesa_TexGendv); 394 SET_TexGenf(disp, _mesa_TexGenf); 395 SET_TexGenfv(disp, _mesa_TexGenfv); 396 SET_TexGeni(disp, _mesa_TexGeni); 397 SET_TexGeniv(disp, _mesa_TexGeniv); 398} 399 400 401#endif /* FEATURE_texgen */ 402