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

📄 vbo_save_api.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Called only when buffers are wrapped as the result of filling the * vertex_store struct.   */static void _save_wrap_filled_vertex( GLcontext *ctx ){   struct vbo_save_context *save = &vbo_context(ctx)->save;   GLfloat *data = save->copied.buffer;   GLuint i;   /* Emit a glEnd to close off the last vertex list.    */   _save_wrap_buffers( ctx );       /* Copy stored stored vertices to start of new list.    */   assert(save->max_vert - save->vert_count > save->copied.nr);   for (i = 0 ; i < save->copied.nr ; i++) {      _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat));      data += save->vertex_size;      save->vbptr += save->vertex_size;      save->vert_count++;   }}static void _save_copy_to_current( GLcontext *ctx ){   struct vbo_save_context *save = &vbo_context(ctx)->save;    GLuint i;   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {      if (save->attrsz[i]) {	 save->currentsz[i][0] = save->attrsz[i];	 COPY_CLEAN_4V(save->current[i], 		       save->attrsz[i], 		       save->attrptr[i]);      }   }}static void _save_copy_from_current( GLcontext *ctx ){   struct vbo_save_context *save = &vbo_context(ctx)->save;    GLint i;   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {      switch (save->attrsz[i]) {      case 4: save->attrptr[i][3] = save->current[i][3];      case 3: save->attrptr[i][2] = save->current[i][2];      case 2: save->attrptr[i][1] = save->current[i][1];      case 1: save->attrptr[i][0] = save->current[i][0];      case 0: break;      }   }}/* Flush existing data, set new attrib size, replay copied vertices. */ static void _save_upgrade_vertex( GLcontext *ctx, 				 GLuint attr,				 GLuint newsz ){   struct vbo_save_context *save = &vbo_context(ctx)->save;   GLuint oldsz;   GLuint i;   GLfloat *tmp;   /* Store the current run of vertices, and emit a GL_END.  Emit a    * BEGIN in the new buffer.    */   if (save->vert_count)       _save_wrap_buffers( ctx );   else      assert( 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 = save->attrsz[attr];   save->attrsz[attr] = newsz;   save->vertex_size += newsz - oldsz;   save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / 		      save->vertex_size);   save->vert_count = 0;   /* Recalculate all the attrptr[] values:    */   for (i = 0, tmp = save->vertex ; i < VBO_ATTRIB_MAX ; i++) {      if (save->attrsz[i]) {	 save->attrptr[i] = tmp;	 tmp += save->attrsz[i];      }      else 	 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 (save->copied.nr)   {      GLfloat *data = save->copied.buffer;      GLfloat *dest = save->buffer;      GLuint j;      /* Need to note this and fix up at runtime (or loopback):       */      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {	 assert(oldsz == 0);	 save->dangling_attr_ref = GL_TRUE;      }      for (i = 0 ; i < save->copied.nr ; i++) {	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {	    if (save->attrsz[j]) {	       if (j == attr) {		  if (oldsz) {		     COPY_CLEAN_4V( dest, oldsz, data );		     data += oldsz;		     dest += newsz;		  }		  else {		     COPY_SZ_4V( dest, newsz, save->current[attr] );		     dest += newsz;		  }	       }	       else {		  GLint sz = save->attrsz[j];		  COPY_SZ_4V( dest, sz, data );		  data += sz;		  dest += sz;	       }	    }	 }      }      save->vbptr = dest;      save->vert_count += save->copied.nr;   }}static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ){   struct vbo_save_context *save = &vbo_context(ctx)->save;    if (sz > save->attrsz[attr]) {      /* New size is larger.  Need to flush existing vertices and get       * an enlarged vertex format.       */      _save_upgrade_vertex( ctx, attr, sz );   }   else if (sz < save->active_sz[attr]) {      static GLfloat id[4] = { 0, 0, 0, 1 };      GLuint i;      /* New size is equal or smaller - just need to fill in some       * zeros.       */      for (i = sz ; i <= save->attrsz[attr] ; i++)	 save->attrptr[attr][i-1] = id[i-1];   }   save->active_sz[attr] = sz;}static void _save_reset_vertex( GLcontext *ctx ){   struct vbo_save_context *save = &vbo_context(ctx)->save;   GLuint i;   for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {      save->attrsz[i] = 0;      save->active_sz[i] = 0;   }         save->vertex_size = 0;}#define ERROR()   _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );/* 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 ATTR( A, N, V0, V1, V2, V3 )				\do {								\   struct vbo_save_context *save = &vbo_context(ctx)->save;	\								\   if (save->active_sz[A] != N)				\      save_fixup_vertex(ctx, A, N);				\								\   {								\      GLfloat *dest = save->attrptr[A];			\      if (N>0) dest[0] = V0;					\      if (N>1) dest[1] = V1;					\      if (N>2) dest[2] = V2;					\      if (N>3) dest[3] = V3;					\   }								\								\   if ((A) == 0) {						\      GLuint i;							\								\      for (i = 0; i < save->vertex_size; i++)			\	 save->vbptr[i] = save->vertex[i];			\								\      save->vbptr += save->vertex_size;				\								\      if (++save->vert_count >= save->max_vert)			\	 _save_wrap_filled_vertex( ctx );			\   }								\} while (0)#define TAG(x) _save_##x#include "vbo_attrib_tmp.h"/* Cope with EvalCoord/CallList called within a begin/end object: *     -- Flush current buffer *     -- Fallback to opcodes for the rest of the begin/end object. */#define DO_FALLBACK(ctx) 							\do {									\   struct vbo_save_context *save = &vbo_context(ctx)->save;					\									\   if (save->vert_count || save->prim_count) 						\      _save_compile_vertex_list( ctx );					\									\   _save_copy_to_current( ctx );					\   _save_reset_vertex( ctx );						\   _save_reset_counters( ctx );  \   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );	\   ctx->Driver.SaveNeedFlush = 0;					\} while (0)static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ){   GET_CURRENT_CONTEXT(ctx);   DO_FALLBACK(ctx);   ctx->Save->EvalCoord1f( u );}static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ){   GET_CURRENT_CONTEXT(ctx);   DO_FALLBACK(ctx);   ctx->Save->EvalCoord1fv( v );}static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ){   GET_CURRENT_CONTEXT(ctx);   DO_FALLBACK(ctx);   ctx->Save->EvalCoord2f( u, v );}static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ){   GET_CURRENT_CONTEXT(ctx);   DO_FALLBACK(ctx);   ctx->Save->EvalCoord2fv( v );}static void GLAPIENTRY _save_EvalPoint1( GLint i ){   GET_CURRENT_CONTEXT(ctx);   DO_FALLBACK(ctx);   ctx->Save->EvalPoint1( i );}static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ){   GET_CURRENT_CONTEXT(ctx);   DO_FALLBACK(ctx);   ctx->Save->EvalPoint2( i, j );}static void GLAPIENTRY _save_CallList( GLuint l ){   GET_CURRENT_CONTEXT(ctx);   DO_FALLBACK(ctx);   ctx->Save->CallList( l );}static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ){   GET_CURRENT_CONTEXT(ctx);   DO_FALLBACK(ctx);   ctx->Save->CallLists( n, type, v );}/* This begin is hooked into ...  Updating of * ctx->Driver.CurrentSavePrimitive is already taken care of. */GLboolean vbo_save_NotifyBegin( GLcontext *ctx, GLenum mode ){   struct vbo_save_context *save = &vbo_context(ctx)->save;    GLuint i = save->prim_count++;   assert(i < save->prim_max);   save->prim[i].mode = mode & ~VBO_SAVE_PRIM_WEAK;   save->prim[i].begin = 1;   save->prim[i].end = 0;   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;   save->prim[i].pad = 0;   save->prim[i].start = save->vert_count;   save->prim[i].count = 0;      _mesa_install_save_vtxfmt( ctx, &save->vtxfmt );         ctx->Driver.SaveNeedFlush = 1;   return GL_TRUE;}static void GLAPIENTRY _save_End( void ){   GET_CURRENT_CONTEXT( ctx );    struct vbo_save_context *save = &vbo_context(ctx)->save;    GLint i = save->prim_count - 1;   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;   save->prim[i].end = 1;   save->prim[i].count = (save->vert_count - 			  save->prim[i].start);   if (i == (GLint) save->prim_max - 1) {      _save_compile_vertex_list( ctx );      assert(save->copied.nr == 0);   }   /* Swap out this vertex format while outside begin/end.  Any color,    * etc. received between here and the next begin will be compiled    * as opcodes.    */      _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );}/* These are all errors as this vtxfmt is only installed inside * begin/end pairs. */static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type,			       const GLvoid *indices){   GET_CURRENT_CONTEXT(ctx);   (void) mode; (void) count; (void) type; (void) indices;   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );}static void GLAPIENTRY _save_DrawRangeElements(GLenum mode,				    GLuint start, GLuint end,				    GLsizei count, GLenum type,				    const GLvoid *indices){   GET_CURRENT_CONTEXT(ctx);   (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices;   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );}static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count){   GET_CURRENT_CONTEXT(ctx);   (void) mode; (void) start; (void) count;   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );}

⌨️ 快捷键说明

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