diff options
Diffstat (limited to 'mesalib/src/mesa/main/texgen.c')
-rw-r--r-- | mesalib/src/mesa/main/texgen.c | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/mesalib/src/mesa/main/texgen.c b/mesalib/src/mesa/main/texgen.c new file mode 100644 index 000000000..e3feb024c --- /dev/null +++ b/mesalib/src/mesa/main/texgen.c @@ -0,0 +1,339 @@ +/* + * Mesa 3-D graphics library + * Version: 7.5 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file texgen.c + * + * glTexGen-related functions + */ + + +#include "main/glheader.h" +#include "main/context.h" +#include "main/enums.h" +#include "main/macros.h" +#include "main/texgen.h" +#include "math/m_matrix.h" + + +/** + * Return texgen state for given coordinate + */ +static struct gl_texgen * +get_texgen(struct gl_texture_unit *texUnit, GLenum coord) +{ + switch (coord) { + case GL_S: + return &texUnit->GenS; + case GL_T: + return &texUnit->GenT; + case GL_R: + return &texUnit->GenR; + case GL_Q: + return &texUnit->GenQ; + default: + return NULL; + } +} + + +void GLAPIENTRY +_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) +{ + struct gl_texture_unit *texUnit; + struct gl_texgen *texgen; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n", + _mesa_lookup_enum_by_nr(coord), + _mesa_lookup_enum_by_nr(pname), + *params, + _mesa_lookup_enum_by_nr((GLenum) (GLint) *params)); + + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + + texgen = get_texgen(texUnit, coord); + if (!texgen) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexGen(coord)"); + return; + } + + switch (pname) { + case GL_TEXTURE_GEN_MODE: + { + GLenum mode = (GLenum) (GLint) params[0]; + GLbitfield bit = 0x0; + if (texgen->Mode == mode) + return; + switch (mode) { + case GL_OBJECT_LINEAR: + bit = TEXGEN_OBJ_LINEAR; + break; + case GL_EYE_LINEAR: + bit = TEXGEN_EYE_LINEAR; + break; + case GL_SPHERE_MAP: + if (coord == GL_S || coord == GL_T) + bit = TEXGEN_SPHERE_MAP; + break; + case GL_REFLECTION_MAP_NV: + if (coord != GL_Q) + bit = TEXGEN_REFLECTION_MAP_NV; + break; + case GL_NORMAL_MAP_NV: + if (coord != GL_Q) + bit = TEXGEN_NORMAL_MAP_NV; + break; + default: + ; /* nop */ + } + if (!bit) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); + return; + } + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texgen->Mode = mode; + texgen->_ModeBit = bit; + } + break; + + case GL_OBJECT_PLANE: + { + if (TEST_EQ_4V(texgen->ObjectPlane, params)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + COPY_4FV(texgen->ObjectPlane, params); + } + break; + + case GL_EYE_PLANE: + { + GLfloat tmp[4]; + /* Transform plane equation by the inverse modelview matrix */ + if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { + _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); + } + _mesa_transform_vector(tmp, params, + ctx->ModelviewMatrixStack.Top->inv); + if (TEST_EQ_4V(texgen->EyePlane, tmp)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + COPY_4FV(texgen->EyePlane, tmp); + } + break; + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); + return; + } + + if (ctx->Driver.TexGen) + ctx->Driver.TexGen( ctx, coord, pname, params ); +} + + +void GLAPIENTRY +_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params ) +{ + GLfloat p[4]; + p[0] = (GLfloat) params[0]; + if (pname == GL_TEXTURE_GEN_MODE) { + p[1] = p[2] = p[3] = 0.0F; + } + else { + p[1] = (GLfloat) params[1]; + p[2] = (GLfloat) params[2]; + p[3] = (GLfloat) params[3]; + } + _mesa_TexGenfv(coord, pname, p); +} + + +void GLAPIENTRY +_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param ) +{ + GLfloat p = (GLfloat) param; + _mesa_TexGenfv( coord, pname, &p ); +} + + +void GLAPIENTRY +_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) +{ + GLfloat p[4]; + p[0] = (GLfloat) params[0]; + if (pname == GL_TEXTURE_GEN_MODE) { + p[1] = p[2] = p[3] = 0.0F; + } + else { + p[1] = (GLfloat) params[1]; + p[2] = (GLfloat) params[2]; + p[3] = (GLfloat) params[3]; + } + _mesa_TexGenfv( coord, pname, p ); +} + + +void GLAPIENTRY +_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) +{ + _mesa_TexGenfv(coord, pname, ¶m); +} + + +void GLAPIENTRY +_mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) +{ + _mesa_TexGeniv( coord, pname, ¶m ); +} + + + +void GLAPIENTRY +_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) +{ + struct gl_texture_unit *texUnit; + struct gl_texgen *texgen; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + + texgen = get_texgen(texUnit, coord); + if (!texgen) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)"); + return; + } + + switch (pname) { + case GL_TEXTURE_GEN_MODE: + params[0] = ENUM_TO_DOUBLE(texgen->Mode); + break; + case GL_OBJECT_PLANE: + COPY_4V(params, texgen->ObjectPlane); + break; + case GL_EYE_PLANE: + COPY_4V(params, texgen->EyePlane); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); + } +} + + + +void GLAPIENTRY +_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) +{ + struct gl_texture_unit *texUnit; + struct gl_texgen *texgen; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + + texgen = get_texgen(texUnit, coord); + if (!texgen) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)"); + return; + } + + switch (pname) { + case GL_TEXTURE_GEN_MODE: + params[0] = ENUM_TO_FLOAT(texgen->Mode); + break; + case GL_OBJECT_PLANE: + COPY_4V(params, texgen->ObjectPlane); + break; + case GL_EYE_PLANE: + COPY_4V(params, texgen->EyePlane); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); + } +} + + + +void GLAPIENTRY +_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ) +{ + struct gl_texture_unit *texUnit; + struct gl_texgen *texgen; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + + texgen = get_texgen(texUnit, coord); + if (!texgen) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)"); + return; + } + + switch (pname) { + case GL_TEXTURE_GEN_MODE: + params[0] = texgen->Mode; + break; + case GL_OBJECT_PLANE: + params[0] = (GLint) texgen->ObjectPlane[0]; + params[1] = (GLint) texgen->ObjectPlane[1]; + params[2] = (GLint) texgen->ObjectPlane[2]; + params[3] = (GLint) texgen->ObjectPlane[3]; + break; + case GL_EYE_PLANE: + params[0] = (GLint) texgen->EyePlane[0]; + params[1] = (GLint) texgen->EyePlane[1]; + params[2] = (GLint) texgen->EyePlane[2]; + params[3] = (GLint) texgen->EyePlane[3]; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); + } +} + + |