t_vtx_exec.c

来自「mesa-6.5-minigui源码」· C语言 代码 · 共 289 行

C
289
字号
/* * Mesa 3-D graphics library * Version:  5.1 * * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Authors: *    Keith Whitwell <keith@tungstengraphics.com> */#include "glheader.h"#include "api_eval.h"#include "context.h"#include "enums.h"#include "state.h"#include "macros.h"#include "math/m_eval.h"#include "t_vtx_api.h"#include "t_pipeline.h"static void _tnl_print_vtx( GLcontext *ctx ){   TNLcontext *tnl = TNL_CONTEXT(ctx);   GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter;   GLuint i;   _mesa_debug(ctx, "_tnl_print_vtx: %u vertices %d primitives, %d vertsize\n",               count,	       tnl->vtx.prim_count,	       tnl->vtx.vertex_size);   for (i = 0 ; i < tnl->vtx.prim_count ; i++) {      struct tnl_prim *prim = &tnl->vtx.prim[i];      _mesa_debug(NULL, "   prim %d: %s %d..%d %s %s\n",		  i, 		  _mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK),		  prim->start, 		  prim->start + prim->count,		  (prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)",		  (prim->mode & PRIM_END) ? "END" : "(wrap)");   }}GLboolean *_tnl_translate_edgeflag( GLcontext *ctx, const GLfloat *data,				    GLuint count, GLuint stride ){   TNLcontext *tnl = TNL_CONTEXT(ctx);   GLboolean *ef = tnl->vtx.edgeflag_tmp;   GLuint i;   if (!ef)       ef = tnl->vtx.edgeflag_tmp = (GLboolean *) MALLOC( tnl->vb.Size );      for (i = 0 ; i < count ; i++, data += stride)      ef[i] = (data[0] == 1.0);   return ef;}GLboolean *_tnl_import_current_edgeflag( GLcontext *ctx,					 GLuint count ){   TNLcontext *tnl = TNL_CONTEXT(ctx);   GLboolean *ef = tnl->vtx.edgeflag_tmp;   GLboolean tmp = ctx->Current.EdgeFlag;   GLuint i;   if (!ef)       ef = tnl->vtx.edgeflag_tmp = (GLboolean *) MALLOC( tnl->vb.Size );   for (i = 0 ; i < count ; i++)      ef[i] = tmp;   return ef;}static INLINE GLint get_size( const GLfloat *f ){   if (f[3] != 1.0) return 4;   if (f[2] != 0.0) return 3;   return 2;}/* Some nasty stuff still hanging on here.   * * TODO - remove VB->NormalPtr, etc and just use the AttrPtr's. */static void _tnl_vb_bind_vtx( GLcontext *ctx ){   TNLcontext *tnl = TNL_CONTEXT(ctx);   struct vertex_buffer *VB = &tnl->vb;   struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs;   GLfloat *data = tnl->vtx.buffer;   GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter;   GLuint attr, i;#undef DEBUG_VTX#ifdef DEBUG_VTX   fprintf(stderr, "_tnl_vb_bind_vtx(): %d verts %d vertsize\n",		  count, tnl->vtx.vertex_size);#endif   /* Setup constant data in the VB.    */   VB->Count = count;   VB->Primitive = tnl->vtx.prim;   VB->PrimitiveCount = tnl->vtx.prim_count;   VB->Elts = NULL;   VB->NormalLengthPtr = NULL;   for (attr = 0; attr <= _TNL_ATTRIB_INDEX ; attr++) {      if (tnl->vtx.attrsz[attr]) {	 tmp->Attribs[attr].count = count;	 tmp->Attribs[attr].data = (GLfloat (*)[4]) data;	 tmp->Attribs[attr].start = data;	 tmp->Attribs[attr].size = tnl->vtx.attrsz[attr];	 tmp->Attribs[attr].stride = tnl->vtx.vertex_size * sizeof(GLfloat);	 VB->AttribPtr[attr] = &tmp->Attribs[attr];	 data += tnl->vtx.attrsz[attr];      }      else {/* 	 VB->AttribPtr[attr] = &tnl->current.Attribs[attr]; */	 tmp->Attribs[attr].count = 1;	 tmp->Attribs[attr].data = (GLfloat (*)[4]) tnl->vtx.current[attr];	 tmp->Attribs[attr].start = tnl->vtx.current[attr];	 tmp->Attribs[attr].size = get_size( tnl->vtx.current[attr] );	 tmp->Attribs[attr].stride = 0;	 VB->AttribPtr[attr] = &tmp->Attribs[attr];      }   }      /* Copy and translate EdgeFlag to a contiguous array of GLbooleans    */   if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) {      if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) {	 VB->EdgeFlag = _tnl_translate_edgeflag( ctx, data, count,						 tnl->vtx.vertex_size );	 data++;      }      else 	 VB->EdgeFlag = _tnl_import_current_edgeflag( ctx, count );   }   /* Legacy pointers -- remove one day.    */   VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];   VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];   VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];   VB->ColorPtr[1] = NULL;   VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_INDEX];   VB->IndexPtr[1] = NULL;   VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];   VB->SecondaryColorPtr[1] = NULL;   VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {      VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];   }}/* * NOTE: Need to have calculated primitives by this point -- do it on the fly. * NOTE: Old 'parity' issue is gone. */static GLuint _tnl_copy_vertices( GLcontext *ctx ){   TNLcontext *tnl = TNL_CONTEXT( ctx );   GLuint nr = tnl->vtx.prim[tnl->vtx.prim_count-1].count;   GLuint ovf, i;   GLuint sz = tnl->vtx.vertex_size;   GLfloat *dst = tnl->vtx.copied.buffer;   GLfloat *src = (tnl->vtx.buffer + 		   tnl->vtx.prim[tnl->vtx.prim_count-1].start * 		   tnl->vtx.vertex_size);   switch( ctx->Driver.CurrentExecPrimitive )   {   case GL_POINTS:      return 0;   case GL_LINES:      ovf = nr&1;      for (i = 0 ; i < ovf ; i++)	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );      return i;   case GL_TRIANGLES:      ovf = nr%3;      for (i = 0 ; i < ovf ; i++)	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );      return i;   case GL_QUADS:      ovf = nr&3;      for (i = 0 ; i < ovf ; i++)	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );      return i;   case GL_LINE_STRIP:      if (nr == 0) 	 return 0;      else {	 _mesa_memcpy( dst, src+(nr-1)*sz, sz * sizeof(GLfloat) );	 return 1;      }   case GL_LINE_LOOP:   case GL_TRIANGLE_FAN:   case GL_POLYGON:      if (nr == 0) 	 return 0;      else if (nr == 1) {	 _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) );	 return 1;      } else {	 _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) );	 _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat) );	 return 2;      }   case GL_TRIANGLE_STRIP:   case GL_QUAD_STRIP:      switch (nr) {      case 0: ovf = 0; break;      case 1: ovf = 1; break;      default: ovf = 2 + (nr&1); break;      }      for (i = 0 ; i < ovf ; i++)	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );      return i;   case PRIM_OUTSIDE_BEGIN_END:      return 0;   default:      assert(0);      return 0;   }}/** * Execute the buffer and save copied verts. */void _tnl_flush_vtx( GLcontext *ctx ){   TNLcontext *tnl = TNL_CONTEXT(ctx);   GLuint vertex_count = tnl->vtx.initial_counter - tnl->vtx.counter;   if (0)      _tnl_print_vtx( ctx );   if (tnl->vtx.prim_count && vertex_count) {      tnl->vtx.copied.nr = _tnl_copy_vertices( ctx );       if (tnl->vtx.copied.nr != vertex_count) {	 if (ctx->NewState)	    _mesa_update_state( ctx );      	 _tnl_vb_bind_vtx( ctx );	 tnl->Driver.RunPipeline( ctx );      }   }   tnl->vtx.prim_count = 0;   tnl->vtx.counter = tnl->vtx.initial_counter;   tnl->vtx.vbptr = tnl->vtx.buffer;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?