-/* $Id: t_vb_texgen.c,v 1.12 2002/01/22 14:35:17 brianp Exp $ */
-
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 6.0
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2004 Brian Paul 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"),
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Brian Paul <brian@valinux.com>
- * Keith Whitwell <keithw@valinux.com>
+ * Brian Paul
+ * Keith Whitwell <keith@tungstengraphics.com>
*/
+/*
+ * Regarding GL_NV_texgen_reflection:
+ *
+ * Portions of this software may use or implement intellectual
+ * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
+ * any and all warranties with respect to such intellectual property,
+ * including any use thereof or modifications thereto.
+ */
#include "glheader.h"
#include "colormac.h"
#include "context.h"
#include "macros.h"
-#include "mmath.h"
-#include "mem.h"
+#include "imports.h"
#include "mtypes.h"
#include "math/m_xform.h"
/* Per-texunit derived state.
*/
- GLuint TexgenSize[MAX_TEXTURE_UNITS];
- GLuint TexgenHoles[MAX_TEXTURE_UNITS];
- texgen_func TexgenFunc[MAX_TEXTURE_UNITS];
+ GLuint TexgenSize[MAX_TEXTURE_COORD_UNITS];
+ GLuint TexgenHoles[MAX_TEXTURE_COORD_UNITS];
+ texgen_func TexgenFunc[MAX_TEXTURE_COORD_UNITS];
/* Temporary values used in texgen.
*/
/* Buffered outputs of the stage.
*/
- GLvector4f texcoord[MAX_TEXTURE_UNITS];
+ GLvector4f texcoord[MAX_TEXTURE_COORD_UNITS];
};
fz = f[i][2] = u[2] - norm[2] * two_nu;
m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F);
if (m[i] != 0.0F) {
- m[i] = 0.5F / (GLfloat) GL_SQRT(m[i]);
+ m[i] = 0.5F * _mesa_inv_sqrtf(m[i]);
}
}
}
fz = f[i][2] = u[2] - norm[2] * two_nu;
m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F);
if (m[i] != 0.0F) {
- m[i] = 0.5F / (GLfloat) GL_SQRT(m[i]);
+ m[i] = 0.5F * _mesa_inv_sqrtf(m[i]);
}
}
}
GLfloat (*f)[3] = store->tmp_f;
GLfloat *m = store->tmp_m;
-/* fprintf(stderr, "%s normstride %d eyestride %d\n", */
-/* __FUNCTION__, VB->NormalPtr->stride, */
-/* VB->EyePtr->stride); */
-
(build_m_tab[VB->EyePtr->size])( store->tmp_f,
store->tmp_m,
VB->NormalPtr,
struct vertex_buffer *VB = &tnl->vb;
GLvector4f *in = VB->TexCoordPtr[unit];
GLvector4f *out = &store->texcoord[unit];
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
const GLvector4f *obj = VB->ObjPtr;
const GLvector4f *eye = VB->EyePtr;
const GLvector4f *normal = VB->NormalPtr;
+ const GLfloat *m = store->tmp_m;
+ const GLuint count = VB->Count;
GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->data;
- GLfloat *indata;
- GLuint count = VB->Count;
GLfloat (*f)[3] = store->tmp_f;
- GLfloat *m = store->tmp_m;
- GLuint holes = 0;
-
+ GLuint holes = 0;
if (texUnit->_GenFlags & TEXGEN_NEED_M) {
- build_m_tab[in->size]( store->tmp_f, store->tmp_m, normal, eye );
+ build_m_tab[eye->size]( store->tmp_f, store->tmp_m, normal, eye );
} else if (texUnit->_GenFlags & TEXGEN_NEED_F) {
- build_f_tab[in->size]( (GLfloat *)store->tmp_f, 3, normal, eye );
+ build_f_tab[eye->size]( (GLfloat *)store->tmp_f, 3, normal, eye );
}
if (!in) {
}
if (holes) {
+ if (holes & VEC_DIRTY_3) _mesa_vector4f_clean_elem(out, count, 3);
if (holes & VEC_DIRTY_2) _mesa_vector4f_clean_elem(out, count, 2);
if (holes & VEC_DIRTY_1) _mesa_vector4f_clean_elem(out, count, 1);
if (holes & VEC_DIRTY_0) _mesa_vector4f_clean_elem(out, count, 0);
texUnit->EyePlaneS );
break;
case GL_SPHERE_MAP:
- for (indata=in->start,i=0 ; i<count ;i++, STRIDE_F(indata,in->stride))
- texcoord[i][0] = indata[0] * m[i] + 0.5F;
+ for (i = 0; i < count; i++)
+ texcoord[i][0] = f[i][0] * m[i] + 0.5F;
break;
case GL_REFLECTION_MAP_NV:
for (i=0;i<count;i++)
texUnit->EyePlaneT );
break;
case GL_SPHERE_MAP:
- for (indata=in->start,i=0; i<count ;i++,STRIDE_F(indata,in->stride))
- texcoord[i][1] = indata[1] * m[i] + 0.5F;
+ for (i = 0; i < count; i++)
+ texcoord[i][1] = f[i][1] * m[i] + 0.5F;
break;
case GL_REFLECTION_MAP_NV:
for (i=0;i<count;i++)
- texcoord[i][0] = f[i][0];
+ texcoord[i][1] = f[i][1];
break;
case GL_NORMAL_MAP_NV: {
const GLfloat *norm = normal->start;
static GLboolean run_texgen_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct texgen_stage_data *store = TEXGEN_STAGE_DATA( stage );
GLuint i;
- for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
+ for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i)) {
- if (stage->changed_inputs & (VERT_BIT_EYE | VERT_BIT_NORMAL | VERT_BIT_TEX(i)))
+ if (stage->changed_inputs & (_TNL_BIT_POS | _TNL_BIT_NORMAL | _TNL_BIT_TEX(i)))
store->TexgenFunc[i]( ctx, store, i );
- VB->TexCoordPtr[i] = &store->texcoord[i];
+ VB->AttribPtr[VERT_ATTRIB_TEX0+i] =
+ VB->TexCoordPtr[i] = &store->texcoord[i];
}
return GL_TRUE;
static GLboolean run_validate_texgen_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
GLuint i;
- for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
+ for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) {
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
if (texUnit->TexGenEnabled) {
GLuint sz;
- if (texUnit->TexGenEnabled & R_BIT)
+ if (texUnit->TexGenEnabled & Q_BIT)
sz = 4;
- else if (texUnit->TexGenEnabled & Q_BIT)
+ else if (texUnit->TexGenEnabled & R_BIT)
sz = 3;
else if (texUnit->TexGenEnabled & T_BIT)
sz = 2;
store->TexgenSize[i] = sz;
store->TexgenHoles[i] = (all_bits[sz] & ~texUnit->TexGenEnabled);
- store->TexgenFunc[i] = texgen;
+ store->TexgenFunc[i] = texgen; /* general solution */
+ /* look for special texgen cases */
if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT)) {
if (texUnit->_GenFlags == TEXGEN_REFLECTION_MAP_NV) {
store->TexgenFunc[i] = texgen_reflection_map_nv;
}
-static void check_texgen( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static void check_texgen( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
GLuint i;
stage->active = 0;
GLuint inputs = 0;
GLuint outputs = 0;
- if (ctx->Texture._GenFlags & TEXGEN_OBJ_LINEAR)
- inputs |= VERT_BIT_POS;
-
- if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)
- inputs |= VERT_BIT_EYE;
+ if (ctx->Texture._GenFlags & (TEXGEN_OBJ_LINEAR | TEXGEN_NEED_EYE_COORD))
+ inputs |= _TNL_BIT_POS;
if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
- inputs |= VERT_BIT_NORMAL;
+ inputs |= _TNL_BIT_NORMAL;
- for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
+ for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i))
{
- outputs |= VERT_BIT_TEX(i);
+ outputs |= _TNL_BIT_TEX(i);
/* Need the original input in case it contains a Q coord:
* (sigh)
*/
- inputs |= VERT_BIT_TEX(i);
+ inputs |= _TNL_BIT_TEX(i);
/* Something for Feedback? */
}
/* Called the first time stage->run() is invoked.
*/
static GLboolean alloc_texgen_data( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct texgen_stage_data *store;
if (!store)
return GL_FALSE;
- for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
+ for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
_mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
store->tmp_f = (GLfloat (*)[3]) MALLOC(VB->Size * sizeof(GLfloat) * 3);
}
-static void free_texgen_data( struct gl_pipeline_stage *stage )
+static void free_texgen_data( struct tnl_pipeline_stage *stage )
{
struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
GLuint i;
if (store) {
- for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
+ for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++)
if (store->texcoord[i].data)
_mesa_vector4f_free( &store->texcoord[i] );
-const struct gl_pipeline_stage _tnl_texgen_stage =
+const struct tnl_pipeline_stage _tnl_texgen_stage =
{
"texgen", /* name */
- _NEW_TEXTURE, /* when to call check() */
+ _NEW_TEXTURE|_NEW_PROGRAM, /* when to call check() */
_NEW_TEXTURE, /* when to invalidate stored data */
GL_FALSE, /* active? */
0, /* inputs */