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

📄 t_vtx_api.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
{   
   GLuint i;

   for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) 
      if (tnl->vtx.attrsz[i]) {
	 GLint j = tnl->vtx.attrsz[i] - 1;
	 tnl->vtx.attrsz[i] = 0;

	 if (i < _TNL_MAX_ATTR_CODEGEN) {
            while (j >= 0) {
	       tnl->vtx.tabfv[i][j] = choose[i][j];
               j--;
            }
         }
      }

   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 );
}


/* Build a list of primitives on the fly.  Keep
 * ctx->Driver.CurrentExecPrimitive uptodate as well.
 */
static void GLAPIENTRY _tnl_Begin( GLenum mode )
{
   GET_CURRENT_CONTEXT( ctx ); 

   if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
      TNLcontext *tnl = TNL_CONTEXT(ctx); 
      int 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)");
            return;
         }

	 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 
      _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
      
}

static void GLAPIENTRY _tnl_End( void )
{
   GET_CURRENT_CONTEXT( ctx ); 

   if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
      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 = GL_POLYGON+1;

      /* 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 
      _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)
      return;

   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 );

   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 + -