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 + -
显示快捷键?