⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t_save_api.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
   /* 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)
#endif


static 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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -