📄 t_vb_texgen.c
字号:
GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit]; GLvector4f *out = &store->texcoord[unit]; GLfloat (*texcoord)[4] = (GLfloat (*)[4]) out->start; GLuint count = VB->Count; GLuint i; GLfloat (*f)[3] = store->tmp_f; GLfloat *m = store->tmp_m; (build_m_tab[VB->EyePtr->size])( store->tmp_f, store->tmp_m, VB->AttribPtr[_TNL_ATTRIB_NORMAL], VB->EyePtr ); out->size = MAX2(in->size,2); for (i=0;i<count;i++) { texcoord[i][0] = f[i][0] * m[i] + 0.5F; texcoord[i][1] = f[i][1] * m[i] + 0.5F; } out->count = count; out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_2; if (in->size > 2) _mesa_copy_tab[all_bits[in->size] & ~0x3]( out, in );}static void texgen( GLcontext *ctx, struct texgen_stage_data *store, GLuint unit ){ TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit]; GLvector4f *out = &store->texcoord[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->AttribPtr[_TNL_ATTRIB_NORMAL]; const GLfloat *m = store->tmp_m; const GLuint count = VB->Count; GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->data; GLfloat (*f)[3] = store->tmp_f; GLuint copy; if (texUnit->_GenFlags & TEXGEN_NEED_M) { build_m_tab[eye->size]( store->tmp_f, store->tmp_m, normal, eye ); } else if (texUnit->_GenFlags & TEXGEN_NEED_F) { build_f_tab[eye->size]( (GLfloat *)store->tmp_f, 3, normal, eye ); } out->size = MAX2(in->size, store->TexgenSize[unit]); out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled; out->count = count; copy = (all_bits[in->size] & ~texUnit->TexGenEnabled); if (copy) _mesa_copy_tab[copy]( out, in ); if (texUnit->TexGenEnabled & S_BIT) { GLuint i; switch (texUnit->GenModeS) { case GL_OBJECT_LINEAR: _mesa_dotprod_tab[obj->size]( (GLfloat *)out->data, sizeof(out->data[0]), obj, texUnit->ObjectPlaneS ); break; case GL_EYE_LINEAR: _mesa_dotprod_tab[eye->size]( (GLfloat *)out->data, sizeof(out->data[0]), eye, texUnit->EyePlaneS ); break; case GL_SPHERE_MAP: 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++) texcoord[i][0] = f[i][0]; break; case GL_NORMAL_MAP_NV: { const GLfloat *norm = normal->start; for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) { texcoord[i][0] = norm[0]; } break; } default: _mesa_problem(ctx, "Bad S texgen"); } } if (texUnit->TexGenEnabled & T_BIT) { GLuint i; switch (texUnit->GenModeT) { case GL_OBJECT_LINEAR: _mesa_dotprod_tab[obj->size]( &(out->data[0][1]), sizeof(out->data[0]), obj, texUnit->ObjectPlaneT ); break; case GL_EYE_LINEAR: _mesa_dotprod_tab[eye->size]( &(out->data[0][1]), sizeof(out->data[0]), eye, texUnit->EyePlaneT ); break; case GL_SPHERE_MAP: 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][1] = f[i][1]; break; case GL_NORMAL_MAP_NV: { const GLfloat *norm = normal->start; for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) { texcoord[i][1] = norm[1]; } break; } default: _mesa_problem(ctx, "Bad T texgen"); } } if (texUnit->TexGenEnabled & R_BIT) { GLuint i; switch (texUnit->GenModeR) { case GL_OBJECT_LINEAR: _mesa_dotprod_tab[obj->size]( &(out->data[0][2]), sizeof(out->data[0]), obj, texUnit->ObjectPlaneR ); break; case GL_EYE_LINEAR: _mesa_dotprod_tab[eye->size]( &(out->data[0][2]), sizeof(out->data[0]), eye, texUnit->EyePlaneR ); break; case GL_REFLECTION_MAP_NV: for (i=0;i<count;i++) texcoord[i][2] = f[i][2]; break; case GL_NORMAL_MAP_NV: { const GLfloat *norm = normal->start; for (i=0;i<count;i++,STRIDE_F(norm, normal->stride)) { texcoord[i][2] = norm[2]; } break; } default: _mesa_problem(ctx, "Bad R texgen"); } } if (texUnit->TexGenEnabled & Q_BIT) { switch (texUnit->GenModeQ) { case GL_OBJECT_LINEAR: _mesa_dotprod_tab[obj->size]( &(out->data[0][3]), sizeof(out->data[0]), obj, texUnit->ObjectPlaneQ ); break; case GL_EYE_LINEAR: _mesa_dotprod_tab[eye->size]( &(out->data[0][3]), sizeof(out->data[0]), eye, texUnit->EyePlaneQ ); break; default: _mesa_problem(ctx, "Bad Q texgen"); } }}static GLboolean run_texgen_stage( GLcontext *ctx, struct tnl_pipeline_stage *stage ){ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); GLuint i; if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Current) return GL_TRUE; for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; if (texUnit->TexGenEnabled) { store->TexgenFunc[i]( ctx, store, i ); VB->TexCoordPtr[i] = VB->AttribPtr[VERT_ATTRIB_TEX0 + i] = &store->texcoord[i]; } } return GL_TRUE;}static void validate_texgen_stage( GLcontext *ctx, struct tnl_pipeline_stage *stage ){ struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); GLuint i; if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Current) return; 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 & Q_BIT) sz = 4; else if (texUnit->TexGenEnabled & R_BIT) sz = 3; else if (texUnit->TexGenEnabled & T_BIT) sz = 2; else sz = 1; store->TexgenSize[i] = sz; 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; } else if (texUnit->_GenFlags == TEXGEN_NORMAL_MAP_NV) { store->TexgenFunc[i] = texgen_normal_map_nv; } } else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) && texUnit->_GenFlags == TEXGEN_SPHERE_MAP) { store->TexgenFunc[i] = texgen_sphere_map; } } }}/* Called the first time stage->run() is invoked. */static GLboolean alloc_texgen_data( GLcontext *ctx, struct tnl_pipeline_stage *stage ){ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; struct texgen_stage_data *store; GLuint i; stage->privatePtr = CALLOC(sizeof(*store)); store = TEXGEN_STAGE_DATA(stage); if (!store) return GL_FALSE; 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); store->tmp_m = (GLfloat *) MALLOC(VB->Size * sizeof(GLfloat)); return GL_TRUE;}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_COORD_UNITS ; i++) if (store->texcoord[i].data) _mesa_vector4f_free( &store->texcoord[i] ); if (store->tmp_f) FREE( store->tmp_f ); if (store->tmp_m) FREE( store->tmp_m ); FREE( store ); stage->privatePtr = NULL; }}const struct tnl_pipeline_stage _tnl_texgen_stage ={ "texgen", /* name */ NULL, /* private data */ alloc_texgen_data, /* destructor */ free_texgen_data, /* destructor */ validate_texgen_stage, /* check */ run_texgen_stage /* run -- initially set to alloc data */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -