t_save_api.c
来自「mesa-6.5-minigui源码」· C语言 代码 · 共 1,725 行 · 第 1/4 页
C
1,725 行
/* Store the current run of vertices, and emit a GL_END. Emit a * BEGIN in the new buffer. */ if (tnl->save.initial_counter != tnl->save.counter) _save_wrap_buffers( ctx ); else assert( tnl->save.copied.nr == 0 ); /* Do a COPY_TO_CURRENT to ensure back-copying works for the case * when the attribute already exists in the vertex and is having * its size increased. */ _save_copy_to_current( ctx ); /* Fix up sizes: */ oldsz = tnl->save.attrsz[attr]; tnl->save.attrsz[attr] = newsz; tnl->save.vertex_size += newsz - oldsz; tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) / tnl->save.vertex_size); if (tnl->save.counter > ctx->Const.MaxArrayLockSize ) tnl->save.counter = ctx->Const.MaxArrayLockSize; tnl->save.initial_counter = tnl->save.counter; /* Recalculate all the attrptr[] values: */ for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) { if (tnl->save.attrsz[i]) { tnl->save.attrptr[i] = tmp; tmp += tnl->save.attrsz[i]; } else tnl->save.attrptr[i] = NULL; /* will not be dereferenced. */ } /* Copy from current to repopulate the vertex with correct values. */ _save_copy_from_current( ctx ); /* Replay stored vertices to translate them to new format here. * * If there are copied vertices and the new (upgraded) attribute * has not been defined before, this list is somewhat degenerate, * and will need fixup at runtime. */ if (tnl->save.copied.nr) { GLfloat *data = tnl->save.copied.buffer; GLfloat *dest = tnl->save.buffer; GLuint j; /* Need to note this and fix up at runtime (or loopback): */ if (tnl->save.currentsz[attr][0] == 0) { assert(oldsz == 0); tnl->save.dangling_attr_ref = GL_TRUE;/* _mesa_debug(NULL, "_save_upgrade_vertex: dangling reference attr %d\n", *//* attr); */#if 0 /* The current strategy is to punt these degenerate cases * through _tnl_loopback_vertex_list(), a lower-performance * option. To minimize the impact of this, artificially * reduce the size of this vertex_list. */ if (t->save.counter > 10) { t->save.initial_counter = 10; t->save.counter = 10; }#endif } for (i = 0 ; i < tnl->save.copied.nr ; i++) { for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { if (tnl->save.attrsz[j]) { if (j == attr) { if (oldsz) { COPY_CLEAN_4V( dest, oldsz, data ); data += oldsz; dest += newsz; } else { COPY_SZ_4V( dest, newsz, tnl->save.current[attr] ); dest += newsz; } } else { GLint sz = tnl->save.attrsz[j]; COPY_SZ_4V( dest, sz, data ); data += sz; dest += sz; } } } } tnl->save.vbptr = dest; tnl->save.counter -= tnl->save.copied.nr; }}/* Helper function for 'CHOOSE' macro. Do what's necessary when an * entrypoint is called for the first time. */static void do_choose( GLuint attr, GLuint sz, void (*attr_func)( const GLfloat *), void (*choose1)( const GLfloat *), void (*choose2)( const GLfloat *), void (*choose3)( const GLfloat *), void (*choose4)( const GLfloat *), const GLfloat *v ){ GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); static GLfloat id[4] = { 0, 0, 0, 1 }; int i; if (tnl->save.attrsz[attr] < sz) { /* New size is larger. Need to flush existing vertices and get * an enlarged vertex format. */ _save_upgrade_vertex( ctx, attr, sz ); } else { /* New size is equal or smaller - just need to fill in some * zeros. */ for (i = sz ; i <= tnl->save.attrsz[attr] ; i++) tnl->save.attrptr[attr][i-1] = id[i-1]; } /* Reset any active pointers for this attribute */ tnl->save.tabfv[attr][0] = choose1; tnl->save.tabfv[attr][1] = choose2; tnl->save.tabfv[attr][2] = choose3; tnl->save.tabfv[attr][3] = choose4; /* Update the secondary dispatch table with the new function */ tnl->save.tabfv[attr][sz-1] = attr_func; (*attr_func)(v);}/* Only one size for each attribute may be active at once. Eg. if * Color3f is installed/active, then Color4f may not be, even if the * vertex actually contains 4 color coordinates. This is because the * 3f version won't otherwise set color[3] to 1.0 -- this is the job * of the chooser function when switching between Color4f and Color3f. */#define ATTRFV( ATTR, N ) \static void save_choose_##ATTR##_##N( const GLfloat *v ); \ \static void save_attrib_##ATTR##_##N( const GLfloat *v ) \{ \ GET_CURRENT_CONTEXT( ctx ); \ TNLcontext *tnl = TNL_CONTEXT(ctx); \ \ if ((ATTR) == 0) { \ GLuint i; \ \ if (N>0) tnl->save.vbptr[0] = v[0]; \ if (N>1) tnl->save.vbptr[1] = v[1]; \ if (N>2) tnl->save.vbptr[2] = v[2]; \ if (N>3) tnl->save.vbptr[3] = v[3]; \ \ for (i = N; i < tnl->save.vertex_size; i++) \ tnl->save.vbptr[i] = tnl->save.vertex[i]; \ \ tnl->save.vbptr += tnl->save.vertex_size; \ \ if (--tnl->save.counter == 0) \ _save_wrap_filled_vertex( ctx ); \ } \ else { \ GLfloat *dest = tnl->save.attrptr[ATTR]; \ if (N>0) dest[0] = v[0]; \ if (N>1) dest[1] = v[1]; \ if (N>2) dest[2] = v[2]; \ if (N>3) dest[3] = v[3]; \ } \}#define CHOOSE( ATTR, N ) \static void save_choose_##ATTR##_##N( const GLfloat *v ) \{ \ do_choose(ATTR, N, \ save_attrib_##ATTR##_##N, \ save_choose_##ATTR##_1, \ save_choose_##ATTR##_2, \ save_choose_##ATTR##_3, \ save_choose_##ATTR##_4, \ v ); \}#define INIT(ATTR) \static void save_init_##ATTR( TNLcontext *tnl ) \{ \ tnl->save.tabfv[ATTR][0] = save_choose_##ATTR##_1; \ tnl->save.tabfv[ATTR][1] = save_choose_##ATTR##_2; \ tnl->save.tabfv[ATTR][2] = save_choose_##ATTR##_3; \ tnl->save.tabfv[ATTR][3] = save_choose_##ATTR##_4; \} #define ATTRS( ATTRIB ) \ ATTRFV( ATTRIB, 1 ) \ ATTRFV( ATTRIB, 2 ) \ ATTRFV( ATTRIB, 3 ) \ ATTRFV( ATTRIB, 4 ) \ CHOOSE( ATTRIB, 1 ) \ CHOOSE( ATTRIB, 2 ) \ CHOOSE( ATTRIB, 3 ) \ CHOOSE( ATTRIB, 4 ) \ INIT( ATTRIB ) \/* Generate a lot of functions. These are the actual worker * functions, which are equivalent to those generated via codegen * elsewhere. */ATTRS( 0 )ATTRS( 1 )ATTRS( 2 )ATTRS( 3 )ATTRS( 4 )ATTRS( 5 )ATTRS( 6 )ATTRS( 7 )ATTRS( 8 )ATTRS( 9 )ATTRS( 10 )ATTRS( 11 )ATTRS( 12 )ATTRS( 13 )ATTRS( 14 )ATTRS( 15 )static void _save_reset_vertex( GLcontext *ctx ){ TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint i; save_init_0( tnl ); save_init_1( tnl ); save_init_2( tnl ); save_init_3( tnl ); save_init_4( tnl ); save_init_5( tnl ); save_init_6( tnl ); save_init_7( tnl ); save_init_8( tnl ); save_init_9( tnl ); save_init_10( tnl ); save_init_11( tnl ); save_init_12( tnl ); save_init_13( tnl ); save_init_14( tnl ); save_init_15( tnl ); for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) tnl->save.attrsz[i] = 0; tnl->save.vertex_size = 0; tnl->save.have_materials = 0; _save_reset_counters( ctx ); }/* Cope with aliasing of classic Vertex, Normal, etc. and the fan-out * of glMultTexCoord and glProgramParamterNV by routing all these * through a second level dispatch table. */#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \do { \ GET_CURRENT_CONTEXT( ctx ); \ TNLcontext *tnl = TNL_CONTEXT(ctx); \ tnl->save.tabfv[ATTR][COUNT-1]( P ); \} while (0)#define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V )#define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V )#define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V )#define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V )#define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) )#if defined(USE_X86_ASM) && 0 /* will break register calling convention *//* Naughty cheat: */#define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) )#define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) )#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) )#else/* Safe: */#define DISPATCH_ATTR2F( ATTR, S,T ) \do { \ GLfloat v[2]; \ v[0] = S; v[1] = T; \ DISPATCH_ATTR2FV( ATTR, v ); \} while (0)#define DISPATCH_ATTR3F( ATTR, S,T,R ) \do { \ GLfloat v[3]; \ v[0] = S; v[1] = T; v[2] = R; \ DISPATCH_ATTR3FV( ATTR, v ); \} while (0)#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \do { \ GLfloat v[4]; \ v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \ DISPATCH_ATTR4FV( ATTR, v ); \} while (0)#endifstatic void enum_error( void ){ GET_CURRENT_CONTEXT( ctx ); _mesa_compile_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" );}static void GLAPIENTRY _save_Vertex2f( GLfloat x, GLfloat y ){ DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y );}static void GLAPIENTRY _save_Vertex2fv( const GLfloat *v ){ DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v );}static void GLAPIENTRY _save_Vertex3f( GLfloat x, GLfloat y, GLfloat z ){ DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z );}static void GLAPIENTRY _save_Vertex3fv( const GLfloat *v ){ DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v );}static void GLAPIENTRY _save_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ){ DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w );}static void GLAPIENTRY _save_Vertex4fv( const GLfloat *v ){ DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v );}static void GLAPIENTRY _save_TexCoord1f( GLfloat x ){ DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x );}static void GLAPIENTRY _save_TexCoord1fv( const GLfloat *v ){ DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v );}static void GLAPIENTRY _save_TexCoord2f( GLfloat x, GLfloat y ){ DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y );}static void GLAPIENTRY _save_TexCoord2fv( const GLfloat *v ){ DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v );}static void GLAPIENTRY _save_TexCoord3f( GLfloat x, GLfloat y, GLfloat z ){ DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z );}static void GLAPIENTRY _save_TexCoord3fv( const GLfloat *v ){ DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v );}static void GLAPIENTRY _save_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ){ DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w );}static void GLAPIENTRY _save_TexCoord4fv( const GLfloat *v ){ DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v );}static void GLAPIENTRY _save_Normal3f( GLfloat x, GLfloat y, GLfloat z ){ DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z );}static void GLAPIENTRY _save_Normal3fv( const GLfloat *v ){ DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v );}static void GLAPIENTRY _save_FogCoordfEXT( GLfloat x ){ DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x );}static void GLAPIENTRY _save_FogCoordfvEXT( const GLfloat *v ){ DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v );}static void GLAPIENTRY _save_Color3f( GLfloat x, GLfloat y, GLfloat z ){ DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z );}static void GLAPIENTRY _save_Color3fv( const GLfloat *v ){ DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?