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