📄 t_vtx_api.c
字号:
} tnl->vtx.vertex_size = 0; tnl->vtx.have_materials = 0;} /* Materials: * * These are treated as per-vertex attributes, at indices above where * the NV_vertex_program leaves off. There are a lot of good things * about treating materials this way. * * However: I don't want to double the number of generated functions * just to cope with this, so I unroll the 'C' varients of CHOOSE and * ATTRF into this function, and dispense with codegen and * second-level dispatch. * * There is no aliasing of material attributes with other entrypoints. */#define OTHER_ATTR( A, N, params ) \do { \ if (tnl->vtx.attrsz[A] != N) { \ _tnl_fixup_vertex( ctx, A, N ); \ } \ \ { \ GLfloat *dest = tnl->vtx.attrptr[A]; \ if (N>0) dest[0] = (params)[0]; \ if (N>1) dest[1] = (params)[1]; \ if (N>2) dest[2] = (params)[2]; \ if (N>3) dest[3] = (params)[3]; \ } \} while (0)#define MAT( ATTR, N, face, params ) \do { \ if (face != GL_BACK) \ OTHER_ATTR( ATTR, N, params ); /* front */ \ if (face != GL_FRONT) \ OTHER_ATTR( ATTR + 1, N, params ); /* back */ \} while (0)/* Colormaterial is dealt with later on. */static void GLAPIENTRY _tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params ){ GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); switch (face) { case GL_FRONT: case GL_BACK: case GL_FRONT_AND_BACK: break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); return; } switch (pname) { case GL_EMISSION: MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); break; case GL_AMBIENT: MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); break; case GL_DIFFUSE: MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); break; case GL_SPECULAR: MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); break; case GL_SHININESS: MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); break; case GL_COLOR_INDEXES: MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); break; case GL_AMBIENT_AND_DIFFUSE: MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); return; } tnl->vtx.have_materials = GL_TRUE;}static void GLAPIENTRY _tnl_EdgeFlag( GLboolean b ){ GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); GLfloat f = (GLfloat)b; OTHER_ATTR( _TNL_ATTRIB_EDGEFLAG, 1, &f );}static void GLAPIENTRY _tnl_EdgeFlagv( const GLboolean *v ){ GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); GLfloat f = (GLfloat)v[0]; OTHER_ATTR( _TNL_ATTRIB_EDGEFLAG, 1, &f );}static void GLAPIENTRY _tnl_Indexf( GLfloat f ){ GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); OTHER_ATTR( _TNL_ATTRIB_INDEX, 1, &f );}static void GLAPIENTRY _tnl_Indexfv( const GLfloat *v ){ GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); OTHER_ATTR( _TNL_ATTRIB_INDEX, 1, v );}/* Eval */static void GLAPIENTRY _tnl_EvalCoord1f( GLfloat u ){ GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); /* TODO: use a CHOOSE() function for this: */ { GLint i; if (tnl->vtx.eval.new_state) _tnl_update_eval( ctx ); for (i = 0 ; i <= _TNL_ATTRIB_INDEX ; i++) { if (tnl->vtx.eval.map1[i].map) if (tnl->vtx.attrsz[i] != tnl->vtx.eval.map1[i].sz) _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map1[i].sz ); } } _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, tnl->vtx.vertex_size * sizeof(GLfloat)); _tnl_do_EvalCoord1f( ctx, u ); _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, tnl->vtx.vertex_size * sizeof(GLfloat));}static void GLAPIENTRY _tnl_EvalCoord2f( GLfloat u, GLfloat v ){ GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); /* TODO: use a CHOOSE() function for this: */ { GLint i; if (tnl->vtx.eval.new_state) _tnl_update_eval( ctx ); for (i = 0 ; i <= _TNL_ATTRIB_INDEX ; i++) { if (tnl->vtx.eval.map2[i].map) if (tnl->vtx.attrsz[i] != tnl->vtx.eval.map2[i].sz) _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map2[i].sz ); } if (ctx->Eval.AutoNormal) if (tnl->vtx.attrsz[_TNL_ATTRIB_NORMAL] != 3) _tnl_fixup_vertex( ctx, _TNL_ATTRIB_NORMAL, 3 ); } _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, tnl->vtx.vertex_size * sizeof(GLfloat)); _tnl_do_EvalCoord2f( ctx, u, v ); _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, tnl->vtx.vertex_size * sizeof(GLfloat));}static void GLAPIENTRY _tnl_EvalCoord1fv( const GLfloat *u ){ _tnl_EvalCoord1f( u[0] );}static void GLAPIENTRY _tnl_EvalCoord2fv( const GLfloat *u ){ _tnl_EvalCoord2f( u[0], u[1] );}static void GLAPIENTRY _tnl_EvalPoint1( GLint i ){ GET_CURRENT_CONTEXT( ctx ); GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / (GLfloat) ctx->Eval.MapGrid1un); GLfloat u = i * du + ctx->Eval.MapGrid1u1; _tnl_EvalCoord1f( u );}static void GLAPIENTRY _tnl_EvalPoint2( GLint i, GLint j ){ GET_CURRENT_CONTEXT( ctx ); GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / (GLfloat) ctx->Eval.MapGrid2un); GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / (GLfloat) ctx->Eval.MapGrid2vn); GLfloat u = i * du + ctx->Eval.MapGrid2u1; GLfloat v = j * dv + ctx->Eval.MapGrid2v1; _tnl_EvalCoord2f( u, v );}/** * Called from glBegin. * ctx->Driver.CurrentExecPrimitive will be set to <mode>. */static void GLAPIENTRY _tnl_Begin( GLenum mode ){ GET_CURRENT_CONTEXT( ctx ); if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { /* we're not inside a glBegin/End pair */ TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint i; if (ctx->NewState) { _mesa_update_state( ctx ); if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBegin (invalid vertex/fragment program)"); tnl->DiscardPrimitive = GL_TRUE; return; } if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "glBegin(incomplete framebuffer)"); tnl->DiscardPrimitive = GL_TRUE; return; } tnl->DiscardPrimitive = GL_FALSE; if (!(tnl->Driver.NotifyBegin && tnl->Driver.NotifyBegin( ctx, mode ))) CALL_Begin(ctx->Exec, (mode)); return; } /* Heuristic: attempt to isolate attributes occuring outside * begin/end pairs. */ if (tnl->vtx.vertex_size && !tnl->vtx.attrsz[0]) _tnl_FlushVertices( ctx, ~0 ); i = tnl->vtx.prim_count++; tnl->vtx.prim[i].mode = mode | PRIM_BEGIN; tnl->vtx.prim[i].start = tnl->vtx.initial_counter - tnl->vtx.counter; tnl->vtx.prim[i].count = 0; ctx->Driver.CurrentExecPrimitive = mode; } else { /* already inside glBegin/End */ _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); } }/** * Called from glEnd. */static void GLAPIENTRY _tnl_End( void ){ GET_CURRENT_CONTEXT( ctx ); if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { /* closing an open glBegin primitive */ TNLcontext *tnl = TNL_CONTEXT(ctx); int idx = tnl->vtx.initial_counter - tnl->vtx.counter; int i = tnl->vtx.prim_count - 1; tnl->vtx.prim[i].mode |= PRIM_END; tnl->vtx.prim[i].count = idx - tnl->vtx.prim[i].start; ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; /* Two choices which effect the way vertex attributes are * carried over (or not) between adjacent primitives. */#if 0 if (tnl->vtx.prim_count == TNL_MAX_PRIM) _tnl_FlushVertices( ctx, ~0 );#else if (tnl->vtx.prim_count == TNL_MAX_PRIM) _tnl_flush_vtx( ctx ); #endif } else { /* glBegin hasn't been called! */ _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); }}static void _tnl_exec_vtxfmt_init( GLcontext *ctx ){ GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt); vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ vfmt->Begin = _tnl_Begin; vfmt->CallList = _mesa_CallList; vfmt->CallLists = _mesa_CallLists; vfmt->EdgeFlag = _tnl_EdgeFlag; vfmt->EdgeFlagv = _tnl_EdgeFlagv; vfmt->End = _tnl_End; vfmt->EvalCoord1f = _tnl_EvalCoord1f; vfmt->EvalCoord1fv = _tnl_EvalCoord1fv; vfmt->EvalCoord2f = _tnl_EvalCoord2f; vfmt->EvalCoord2fv = _tnl_EvalCoord2fv; vfmt->EvalPoint1 = _tnl_EvalPoint1; vfmt->EvalPoint2 = _tnl_EvalPoint2; vfmt->Indexf = _tnl_Indexf; vfmt->Indexfv = _tnl_Indexfv; vfmt->Materialfv = _tnl_Materialfv; vfmt->Rectf = _mesa_noop_Rectf; vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;}void _tnl_FlushVertices( GLcontext *ctx, GLuint flags ){ TNLcontext *tnl = TNL_CONTEXT(ctx); (void) flags; if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { /* still inside a glBegin/End pair. How'd we get here??? */ return; } if (tnl->DiscardPrimitive) { /* discard any primitives */ tnl->vtx.prim_count = 0; tnl->vtx.counter = tnl->vtx.initial_counter; tnl->vtx.vbptr = tnl->vtx.buffer; } if (tnl->vtx.counter != tnl->vtx.initial_counter) { _tnl_flush_vtx( ctx ); } if (tnl->vtx.vertex_size) { _tnl_copy_to_current( ctx ); reset_attrfv( tnl ); } ctx->Driver.NeedFlush = 0;}static void _tnl_current_init( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLint i; /* setup the pointers for the typical 16 vertex attributes */ for (i = 0; i < VERT_ATTRIB_MAX; i++) tnl->vtx.current[i] = ctx->Current.Attrib[i]; /* setup pointers for the 12 material attributes */ for (i = 0; i < MAT_ATTRIB_MAX; i++) tnl->vtx.current[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = ctx->Light.Material.Attrib[i]; tnl->vtx.current[_TNL_ATTRIB_INDEX] = &ctx->Current.Index; tnl->vtx.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->vtx.CurrentFloatEdgeFlag;}static struct _tnl_dynfn *no_codegen( GLcontext *ctx, int key ){ (void) ctx; (void) key; return NULL;}void _tnl_vtx_init( GLcontext *ctx ){ TNLcontext *tnl = TNL_CONTEXT(ctx); struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs; GLuint i; static int firsttime = 1; if (firsttime) { firsttime = 0; INIT_CHOOSERS( 0 ); INIT_CHOOSERS( 1 ); INIT_CHOOSERS( 2 ); INIT_CHOOSERS( 3 ); INIT_CHOOSERS( 4 ); INIT_CHOOSERS( 5 ); INIT_CHOOSERS( 6 ); INIT_CHOOSERS( 7 ); INIT_CHOOSERS( 8 ); INIT_CHOOSERS( 9 ); INIT_CHOOSERS( 10 ); INIT_CHOOSERS( 11 ); INIT_CHOOSERS( 12 ); INIT_CHOOSERS( 13 ); INIT_CHOOSERS( 14 ); INIT_CHOOSERS( 15 ); choose[ERROR_ATTRIB][0] = error_attrib; choose[ERROR_ATTRIB][1] = error_attrib; choose[ERROR_ATTRIB][2] = error_attrib; choose[ERROR_ATTRIB][3] = error_attrib;#ifdef USE_X86_ASM if (tnl->AllowCodegen) { _tnl_x86choosers(choose, do_choose); /* x86 INIT_CHOOSERS */ }#endif _tnl_generic_attr_table_init( generic_attr_func ); } for (i = 0; i < _TNL_ATTRIB_INDEX; i++) _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); for (i = 0; i < 4; i++) { make_empty_list( &tnl->vtx.cache.Vertex[i] ); make_empty_list( &tnl->vtx.cache.Attribute[i] ); tnl->vtx.gen.Vertex[i] = no_codegen; tnl->vtx.gen.Attribute[i] = no_codegen; }#ifdef USE_X86_ASM _tnl_InitX86Codegen( &tnl->vtx.gen );#endif _tnl_current_init( ctx ); _tnl_exec_vtxfmt_init( ctx ); _tnl_generic_exec_vtxfmt_init( ctx );#ifdef USE_X86_ASM if (tnl->AllowCodegen) { _tnl_x86_exec_vtxfmt_init( ctx ); /* x86 DISPATCH_ATTRFV */ }#endif _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt ); _mesa_memcpy( tnl->vtx.tabfv, choose, sizeof(choose) ); for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) tnl->vtx.attrsz[i] = 0; tnl->vtx.vertex_size = 0; tnl->vtx.have_materials = 0;}static void free_funcs( struct _tnl_dynfn *l ){ struct _tnl_dynfn *f, *tmp; foreach_s (f, tmp, l) { remove_from_list( f ); ALIGN_FREE( f->code ); FREE( f ); }}void _tnl_vtx_destroy( GLcontext *ctx ){ TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint i; for (i = 0; i < 4; i++) { free_funcs( &tnl->vtx.cache.Vertex[i] ); free_funcs( &tnl->vtx.cache.Attribute[i] ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -