texgen.c revision af69d88d
1c1f859d4Smrg/* 2c1f859d4Smrg * Mesa 3-D graphics library 3c1f859d4Smrg * 4c1f859d4Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 54a49301eSmrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6c1f859d4Smrg * 7c1f859d4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8c1f859d4Smrg * copy of this software and associated documentation files (the "Software"), 9c1f859d4Smrg * to deal in the Software without restriction, including without limitation 10c1f859d4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11c1f859d4Smrg * and/or sell copies of the Software, and to permit persons to whom the 12c1f859d4Smrg * Software is furnished to do so, subject to the following conditions: 13c1f859d4Smrg * 14c1f859d4Smrg * The above copyright notice and this permission notice shall be included 15c1f859d4Smrg * in all copies or substantial portions of the Software. 16c1f859d4Smrg * 17c1f859d4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18c1f859d4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19c1f859d4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 24c1f859d4Smrg */ 25c1f859d4Smrg 26c1f859d4Smrg/** 27c1f859d4Smrg * \file texgen.c 28c1f859d4Smrg * 29c1f859d4Smrg * glTexGen-related functions 30c1f859d4Smrg */ 31c1f859d4Smrg 32c1f859d4Smrg 33c1f859d4Smrg#include "main/glheader.h" 34c1f859d4Smrg#include "main/context.h" 35c1f859d4Smrg#include "main/enums.h" 36c1f859d4Smrg#include "main/macros.h" 37c1f859d4Smrg#include "main/texgen.h" 384a49301eSmrg#include "main/texstate.h" 394a49301eSmrg#include "math/m_matrix.h" 40cdc920a0Smrg#include "main/dispatch.h" 41c1f859d4Smrg 42c1f859d4Smrg 434a49301eSmrg/** 444a49301eSmrg * Return texgen state for given coordinate 454a49301eSmrg */ 464a49301eSmrgstatic struct gl_texgen * 47af69d88dSmrgget_texgen(struct gl_context *ctx, struct gl_texture_unit *texUnit, 48af69d88dSmrg GLenum coord) 494a49301eSmrg{ 50af69d88dSmrg if (ctx->API == API_OPENGLES) { 51af69d88dSmrg return (coord == GL_TEXTURE_GEN_STR_OES) 52af69d88dSmrg ? &texUnit->GenS : NULL; 53af69d88dSmrg } 54af69d88dSmrg 554a49301eSmrg switch (coord) { 564a49301eSmrg case GL_S: 574a49301eSmrg return &texUnit->GenS; 584a49301eSmrg case GL_T: 594a49301eSmrg return &texUnit->GenT; 604a49301eSmrg case GL_R: 614a49301eSmrg return &texUnit->GenR; 624a49301eSmrg case GL_Q: 634a49301eSmrg return &texUnit->GenQ; 644a49301eSmrg default: 654a49301eSmrg return NULL; 664a49301eSmrg } 674a49301eSmrg} 684a49301eSmrg 69c1f859d4Smrg 70c1f859d4Smrgvoid GLAPIENTRY 71c1f859d4Smrg_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) 72c1f859d4Smrg{ 73c1f859d4Smrg struct gl_texture_unit *texUnit; 744a49301eSmrg struct gl_texgen *texgen; 754a49301eSmrg GET_CURRENT_CONTEXT(ctx); 76c1f859d4Smrg 77c1f859d4Smrg if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) 78c1f859d4Smrg _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n", 79c1f859d4Smrg _mesa_lookup_enum_by_nr(coord), 80c1f859d4Smrg _mesa_lookup_enum_by_nr(pname), 81c1f859d4Smrg *params, 82c1f859d4Smrg _mesa_lookup_enum_by_nr((GLenum) (GLint) *params)); 83c1f859d4Smrg 84c1f859d4Smrg if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 85c1f859d4Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)"); 86c1f859d4Smrg return; 87c1f859d4Smrg } 88c1f859d4Smrg 894a49301eSmrg texUnit = _mesa_get_current_tex_unit(ctx); 90c1f859d4Smrg 91af69d88dSmrg texgen = get_texgen(ctx, texUnit, coord); 924a49301eSmrg if (!texgen) { 934a49301eSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glTexGen(coord)"); 944a49301eSmrg return; 954a49301eSmrg } 964a49301eSmrg 974a49301eSmrg switch (pname) { 984a49301eSmrg case GL_TEXTURE_GEN_MODE: 994a49301eSmrg { 1004a49301eSmrg GLenum mode = (GLenum) (GLint) params[0]; 1014a49301eSmrg GLbitfield bit = 0x0; 1024a49301eSmrg if (texgen->Mode == mode) 1034a49301eSmrg return; 1044a49301eSmrg switch (mode) { 1054a49301eSmrg case GL_OBJECT_LINEAR: 1064a49301eSmrg bit = TEXGEN_OBJ_LINEAR; 1074a49301eSmrg break; 1084a49301eSmrg case GL_EYE_LINEAR: 1094a49301eSmrg bit = TEXGEN_EYE_LINEAR; 1104a49301eSmrg break; 1114a49301eSmrg case GL_SPHERE_MAP: 1124a49301eSmrg if (coord == GL_S || coord == GL_T) 1134a49301eSmrg bit = TEXGEN_SPHERE_MAP; 1144a49301eSmrg break; 1154a49301eSmrg case GL_REFLECTION_MAP_NV: 1164a49301eSmrg if (coord != GL_Q) 1174a49301eSmrg bit = TEXGEN_REFLECTION_MAP_NV; 1184a49301eSmrg break; 1194a49301eSmrg case GL_NORMAL_MAP_NV: 1204a49301eSmrg if (coord != GL_Q) 1214a49301eSmrg bit = TEXGEN_NORMAL_MAP_NV; 1224a49301eSmrg break; 1234a49301eSmrg default: 1244a49301eSmrg ; /* nop */ 1254a49301eSmrg } 1264a49301eSmrg if (!bit) { 1274a49301eSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 1284a49301eSmrg return; 1294a49301eSmrg } 130af69d88dSmrg if (ctx->API != API_OPENGL_COMPAT 131af69d88dSmrg && (bit & (TEXGEN_REFLECTION_MAP_NV | TEXGEN_NORMAL_MAP_NV)) == 0) { 132af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 133af69d88dSmrg return; 134af69d88dSmrg } 135af69d88dSmrg 1364a49301eSmrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1374a49301eSmrg texgen->Mode = mode; 1384a49301eSmrg texgen->_ModeBit = bit; 1394a49301eSmrg } 1404a49301eSmrg break; 1414a49301eSmrg 1424a49301eSmrg case GL_OBJECT_PLANE: 1434a49301eSmrg { 144af69d88dSmrg if (ctx->API != API_OPENGL_COMPAT) { 145af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 146af69d88dSmrg return; 147af69d88dSmrg } 1484a49301eSmrg if (TEST_EQ_4V(texgen->ObjectPlane, params)) 1494a49301eSmrg return; 1504a49301eSmrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1514a49301eSmrg COPY_4FV(texgen->ObjectPlane, params); 1524a49301eSmrg } 1534a49301eSmrg break; 1544a49301eSmrg 1554a49301eSmrg case GL_EYE_PLANE: 1564a49301eSmrg { 1574a49301eSmrg GLfloat tmp[4]; 158af69d88dSmrg 159af69d88dSmrg if (ctx->API != API_OPENGL_COMPAT) { 160af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 161af69d88dSmrg return; 162af69d88dSmrg } 163af69d88dSmrg 1644a49301eSmrg /* Transform plane equation by the inverse modelview matrix */ 1654a49301eSmrg if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { 1664a49301eSmrg _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); 1674a49301eSmrg } 1684a49301eSmrg _mesa_transform_vector(tmp, params, 1694a49301eSmrg ctx->ModelviewMatrixStack.Top->inv); 1704a49301eSmrg if (TEST_EQ_4V(texgen->EyePlane, tmp)) 1714a49301eSmrg return; 1724a49301eSmrg FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1734a49301eSmrg COPY_4FV(texgen->EyePlane, tmp); 1744a49301eSmrg } 1754a49301eSmrg break; 1764a49301eSmrg 1774a49301eSmrg default: 1784a49301eSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); 1794a49301eSmrg return; 180c1f859d4Smrg } 181c1f859d4Smrg 182c1f859d4Smrg if (ctx->Driver.TexGen) 183c1f859d4Smrg ctx->Driver.TexGen( ctx, coord, pname, params ); 184c1f859d4Smrg} 185c1f859d4Smrg 186c1f859d4Smrg 187af69d88dSmrgvoid GLAPIENTRY 188c1f859d4Smrg_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params ) 189c1f859d4Smrg{ 190c1f859d4Smrg GLfloat p[4]; 191c1f859d4Smrg p[0] = (GLfloat) params[0]; 192c1f859d4Smrg if (pname == GL_TEXTURE_GEN_MODE) { 193c1f859d4Smrg p[1] = p[2] = p[3] = 0.0F; 194c1f859d4Smrg } 195c1f859d4Smrg else { 196c1f859d4Smrg p[1] = (GLfloat) params[1]; 197c1f859d4Smrg p[2] = (GLfloat) params[2]; 198c1f859d4Smrg p[3] = (GLfloat) params[3]; 199c1f859d4Smrg } 200c1f859d4Smrg _mesa_TexGenfv(coord, pname, p); 201c1f859d4Smrg} 202c1f859d4Smrg 203c1f859d4Smrg 204af69d88dSmrgvoid GLAPIENTRY 205c1f859d4Smrg_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param ) 206c1f859d4Smrg{ 2074a49301eSmrg GLfloat p[4]; 2084a49301eSmrg p[0] = (GLfloat) param; 2094a49301eSmrg p[1] = p[2] = p[3] = 0.0F; 2104a49301eSmrg _mesa_TexGenfv( coord, pname, p ); 211c1f859d4Smrg} 212c1f859d4Smrg 2133464ebd5Sriastradh 2143464ebd5Sriastradhvoid GLAPIENTRY 2153464ebd5Sriastradh_es_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) 2163464ebd5Sriastradh{ 2173464ebd5Sriastradh _mesa_GetTexGenfv(GL_S, pname, params); 2183464ebd5Sriastradh} 2193464ebd5Sriastradh 2203464ebd5Sriastradh 2213464ebd5Sriastradhvoid GLAPIENTRY 2223464ebd5Sriastradh_es_TexGenf(GLenum coord, GLenum pname, GLfloat param) 2233464ebd5Sriastradh{ 224af69d88dSmrg if (coord != GL_TEXTURE_GEN_STR_OES) { 225af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 226af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx](pname)" ); 227af69d88dSmrg return; 228af69d88dSmrg } 2293464ebd5Sriastradh /* set S, T, and R at the same time */ 2303464ebd5Sriastradh _mesa_TexGenf(GL_S, pname, param); 2313464ebd5Sriastradh _mesa_TexGenf(GL_T, pname, param); 2323464ebd5Sriastradh _mesa_TexGenf(GL_R, pname, param); 2333464ebd5Sriastradh} 2343464ebd5Sriastradh 2353464ebd5Sriastradh 2363464ebd5Sriastradhvoid GLAPIENTRY 2373464ebd5Sriastradh_es_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params) 2383464ebd5Sriastradh{ 239af69d88dSmrg if (coord != GL_TEXTURE_GEN_STR_OES) { 240af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 241af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx]v(pname)" ); 242af69d88dSmrg return; 243af69d88dSmrg } 2443464ebd5Sriastradh /* set S, T, and R at the same time */ 2453464ebd5Sriastradh _mesa_TexGenfv(GL_S, pname, params); 2463464ebd5Sriastradh _mesa_TexGenfv(GL_T, pname, params); 2473464ebd5Sriastradh _mesa_TexGenfv(GL_R, pname, params); 2483464ebd5Sriastradh} 2493464ebd5Sriastradh 250c1f859d4Smrg 251af69d88dSmrgvoid GLAPIENTRY 252c1f859d4Smrg_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) 253c1f859d4Smrg{ 254c1f859d4Smrg GLfloat p[4]; 255c1f859d4Smrg p[0] = (GLfloat) params[0]; 256c1f859d4Smrg if (pname == GL_TEXTURE_GEN_MODE) { 257c1f859d4Smrg p[1] = p[2] = p[3] = 0.0F; 258c1f859d4Smrg } 259c1f859d4Smrg else { 260c1f859d4Smrg p[1] = (GLfloat) params[1]; 261c1f859d4Smrg p[2] = (GLfloat) params[2]; 262c1f859d4Smrg p[3] = (GLfloat) params[3]; 263c1f859d4Smrg } 264c1f859d4Smrg _mesa_TexGenfv( coord, pname, p ); 265c1f859d4Smrg} 266c1f859d4Smrg 267c1f859d4Smrg 268cdc920a0Smrgvoid GLAPIENTRY 269c1f859d4Smrg_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) 270c1f859d4Smrg{ 2714a49301eSmrg GLfloat p[4]; 2724a49301eSmrg p[0] = param; 2734a49301eSmrg p[1] = p[2] = p[3] = 0.0F; 2744a49301eSmrg _mesa_TexGenfv(coord, pname, p); 275c1f859d4Smrg} 276c1f859d4Smrg 277c1f859d4Smrg 278c1f859d4Smrgvoid GLAPIENTRY 279c1f859d4Smrg_mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) 280c1f859d4Smrg{ 2814a49301eSmrg GLint p[4]; 2824a49301eSmrg p[0] = param; 2834a49301eSmrg p[1] = p[2] = p[3] = 0; 2844a49301eSmrg _mesa_TexGeniv( coord, pname, p ); 285c1f859d4Smrg} 286c1f859d4Smrg 287c1f859d4Smrg 288c1f859d4Smrg 289af69d88dSmrgvoid GLAPIENTRY 290c1f859d4Smrg_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) 291c1f859d4Smrg{ 2924a49301eSmrg struct gl_texture_unit *texUnit; 2934a49301eSmrg struct gl_texgen *texgen; 294c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 295c1f859d4Smrg 296c1f859d4Smrg if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 297c1f859d4Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)"); 298c1f859d4Smrg return; 299c1f859d4Smrg } 300c1f859d4Smrg 3014a49301eSmrg texUnit = _mesa_get_current_tex_unit(ctx); 302c1f859d4Smrg 303af69d88dSmrg texgen = get_texgen(ctx, texUnit, coord); 3044a49301eSmrg if (!texgen) { 3054a49301eSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)"); 3064a49301eSmrg return; 3074a49301eSmrg } 3084a49301eSmrg 3094a49301eSmrg switch (pname) { 3104a49301eSmrg case GL_TEXTURE_GEN_MODE: 3114a49301eSmrg params[0] = ENUM_TO_DOUBLE(texgen->Mode); 3124a49301eSmrg break; 3134a49301eSmrg case GL_OBJECT_PLANE: 3144a49301eSmrg COPY_4V(params, texgen->ObjectPlane); 3154a49301eSmrg break; 3164a49301eSmrg case GL_EYE_PLANE: 3174a49301eSmrg COPY_4V(params, texgen->EyePlane); 3184a49301eSmrg break; 3194a49301eSmrg default: 3204a49301eSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); 321c1f859d4Smrg } 322c1f859d4Smrg} 323c1f859d4Smrg 324c1f859d4Smrg 325c1f859d4Smrg 326cdc920a0Smrgvoid GLAPIENTRY 327c1f859d4Smrg_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) 328c1f859d4Smrg{ 3294a49301eSmrg struct gl_texture_unit *texUnit; 3304a49301eSmrg struct gl_texgen *texgen; 331c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 332c1f859d4Smrg 333c1f859d4Smrg if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 334c1f859d4Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)"); 335c1f859d4Smrg return; 336c1f859d4Smrg } 337c1f859d4Smrg 3384a49301eSmrg texUnit = _mesa_get_current_tex_unit(ctx); 339c1f859d4Smrg 340af69d88dSmrg texgen = get_texgen(ctx, texUnit, coord); 3414a49301eSmrg if (!texgen) { 3424a49301eSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)"); 3434a49301eSmrg return; 3444a49301eSmrg } 3454a49301eSmrg 3464a49301eSmrg switch (pname) { 3474a49301eSmrg case GL_TEXTURE_GEN_MODE: 3484a49301eSmrg params[0] = ENUM_TO_FLOAT(texgen->Mode); 3494a49301eSmrg break; 3504a49301eSmrg case GL_OBJECT_PLANE: 351af69d88dSmrg if (ctx->API != API_OPENGL_COMPAT) { 352af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(param)" ); 353af69d88dSmrg return; 354af69d88dSmrg } 3554a49301eSmrg COPY_4V(params, texgen->ObjectPlane); 3564a49301eSmrg break; 3574a49301eSmrg case GL_EYE_PLANE: 358af69d88dSmrg if (ctx->API != API_OPENGL_COMPAT) { 359af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(param)" ); 360af69d88dSmrg return; 361af69d88dSmrg } 3624a49301eSmrg COPY_4V(params, texgen->EyePlane); 3634a49301eSmrg break; 3644a49301eSmrg default: 3654a49301eSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); 366c1f859d4Smrg } 367c1f859d4Smrg} 368c1f859d4Smrg 369c1f859d4Smrg 370c1f859d4Smrg 371af69d88dSmrgvoid GLAPIENTRY 372c1f859d4Smrg_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ) 373c1f859d4Smrg{ 3744a49301eSmrg struct gl_texture_unit *texUnit; 3754a49301eSmrg struct gl_texgen *texgen; 376c1f859d4Smrg GET_CURRENT_CONTEXT(ctx); 377c1f859d4Smrg 378c1f859d4Smrg if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 379c1f859d4Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)"); 380c1f859d4Smrg return; 381c1f859d4Smrg } 382c1f859d4Smrg 3834a49301eSmrg texUnit = _mesa_get_current_tex_unit(ctx); 384c1f859d4Smrg 385af69d88dSmrg texgen = get_texgen(ctx, texUnit, coord); 3864a49301eSmrg if (!texgen) { 3874a49301eSmrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)"); 3884a49301eSmrg return; 389c1f859d4Smrg } 3904a49301eSmrg 3914a49301eSmrg switch (pname) { 3924a49301eSmrg case GL_TEXTURE_GEN_MODE: 3934a49301eSmrg params[0] = texgen->Mode; 3944a49301eSmrg break; 3954a49301eSmrg case GL_OBJECT_PLANE: 396af69d88dSmrg if (ctx->API != API_OPENGL_COMPAT) { 397af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(param)" ); 398af69d88dSmrg return; 399af69d88dSmrg } 4004a49301eSmrg params[0] = (GLint) texgen->ObjectPlane[0]; 4014a49301eSmrg params[1] = (GLint) texgen->ObjectPlane[1]; 4024a49301eSmrg params[2] = (GLint) texgen->ObjectPlane[2]; 4034a49301eSmrg params[3] = (GLint) texgen->ObjectPlane[3]; 4044a49301eSmrg break; 4054a49301eSmrg case GL_EYE_PLANE: 406af69d88dSmrg if (ctx->API != API_OPENGL_COMPAT) { 407af69d88dSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(param)" ); 408af69d88dSmrg return; 409af69d88dSmrg } 4104a49301eSmrg params[0] = (GLint) texgen->EyePlane[0]; 4114a49301eSmrg params[1] = (GLint) texgen->EyePlane[1]; 4124a49301eSmrg params[2] = (GLint) texgen->EyePlane[2]; 4134a49301eSmrg params[3] = (GLint) texgen->EyePlane[3]; 4144a49301eSmrg break; 4154a49301eSmrg default: 4164a49301eSmrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); 4174a49301eSmrg } 4184a49301eSmrg} 419