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