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

📄 vbo_rebase.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
字号:
/* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 1999-2006  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> *//* Helper for drivers which find themselves rendering a range of * indices starting somewhere above zero.  Typically the application * is issuing multiple DrawArrays() or DrawElements() to draw * successive primitives layed out linearly in the vertex arrays. * Unless the vertex arrays are all in a VBO, the OpenGL semantics * imply that we need to re-upload the vertex data on each draw call. * In that case, we want to avoid starting the upload at zero, as it * will mean every draw call uploads an increasing amount of not-used * vertex data.  Worse - in the software tnl module, all those * vertices will be transformed and lit. * * If we just upload the new data, however, the indices will be * incorrect as we tend to upload each set of vertex data to a new * region.   * * This file provides a helper to adjust the arrays, primitives and * indices of a draw call so that it can be re-issued with a min_index * of zero. */#include "main/glheader.h"#include "main/imports.h"#include "main/mtypes.h"#include "vbo.h"#define REBASE(TYPE) 						\static void *rebase_##TYPE( const void *ptr,			\			  GLuint count, 			\			  TYPE min_index )			\{								\   const TYPE *in = (TYPE *)ptr;				\   TYPE *tmp_indices = malloc(count * sizeof(TYPE));	\   GLuint i;							\								\   for (i = 0; i < count; i++)  				\      tmp_indices[i] = in[i] - min_index;			\								\   return (void *)tmp_indices;					\}REBASE(GLuint)REBASE(GLushort)REBASE(GLubyte)GLboolean vbo_all_varyings_in_vbos( const struct gl_client_array *arrays[] ){   GLuint i;      for (i = 0; i < VERT_ATTRIB_MAX; i++)      if (arrays[i]->StrideB &&	  arrays[i]->BufferObj->Name == 0)	 return GL_FALSE;   return GL_TRUE;}/* Adjust primitives, indices and vertex definitions so that min_index * becomes zero. There are lots of reasons for wanting to do this, eg: * * Software tnl: *    - any time min_index != 0, otherwise unused vertices lower than *      min_index will be transformed. * * Hardware tnl: *    - if ib != NULL and min_index != 0, otherwise vertices lower than  *      min_index will be uploaded.  Requires adjusting index values. * *    - if ib == NULL and min_index != 0, just for convenience so this doesn't *      have to be handled within the driver. * * Hardware tnl with VBO support: *    - as above, but only when vertices are not (all?) in VBO's. *    - can't save time by trying to upload half a vbo - typically it is *      all or nothing. */void vbo_rebase_prims( GLcontext *ctx,		       const struct gl_client_array *arrays[],		       const struct _mesa_prim *prim,		       GLuint nr_prims,		       const struct _mesa_index_buffer *ib,		       GLuint min_index,		       GLuint max_index,		       vbo_draw_func draw ){   struct gl_client_array tmp_arrays[VERT_ATTRIB_MAX];   const struct gl_client_array *tmp_array_pointers[VERT_ATTRIB_MAX];   struct _mesa_index_buffer tmp_ib;   struct _mesa_prim *tmp_prims = NULL;   void *tmp_indices = NULL;   GLuint i;   assert(min_index != 0);   if (0)      _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);   if (ib) {      /* Unfortunately need to adjust each index individually.       */      GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer;      void *ptr;      if (map_ib) 	 ctx->Driver.MapBuffer(ctx, 			       GL_ELEMENT_ARRAY_BUFFER,			       GL_READ_ONLY_ARB,			       ib->obj);      ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);      /* Some users might prefer it if we translated elements to       * GLuints here.  Others wouldn't...       */      switch (ib->type) {      case GL_UNSIGNED_INT: 	 tmp_indices = rebase_GLuint( ptr, ib->count, min_index );	 break;      case GL_UNSIGNED_SHORT: 	 tmp_indices = rebase_GLushort( ptr, ib->count, min_index );	 break;      case GL_UNSIGNED_BYTE: 	 tmp_indices = rebase_GLubyte( ptr, ib->count, min_index );	 break;      }            if (map_ib) 	 ctx->Driver.UnmapBuffer(ctx, 				 GL_ELEMENT_ARRAY_BUFFER,				 ib->obj);      tmp_ib.obj = ctx->Array.NullBufferObj;      tmp_ib.ptr = tmp_indices;      tmp_ib.count = ib->count;      tmp_ib.type = ib->type;      ib = &tmp_ib;   }   else {      /* Otherwise the primitives need adjustment.       */      tmp_prims = (struct _mesa_prim *)_mesa_malloc(sizeof(*prim) * nr_prims);      for (i = 0; i < nr_prims; i++) {	 /* If this fails, it could indicate an application error:	  */	 assert(prim[i].start >= min_index);	 tmp_prims[i] = prim[i];	 tmp_prims[i].start -= min_index;      }      prim = tmp_prims;   }   /* Just need to adjust the pointer values on each incoming array.    * This works for VBO and non-vbo rendering and shouldn't pesimize    * VBO-based upload schemes.  However this may still not be a fast    * path for hardware tnl for VBO based rendering as most machines    * will be happier if you just specify a starting vertex value in    * each primitive.    *    * For drivers with hardware tnl, you only want to do this if you    * are forced to, eg non-VBO indexed rendering with start != 0.    */   for (i = 0; i < VERT_ATTRIB_MAX; i++) {      tmp_arrays[i] = *arrays[i];      tmp_arrays[i].Ptr += min_index * tmp_arrays[i].StrideB;      tmp_array_pointers[i] = &tmp_arrays[i];   }      /* Re-issue the draw call.    */   draw( ctx, 	 tmp_array_pointers, 	 prim, 	 nr_prims, 	 ib, 	 0, 	 max_index - min_index );      if (tmp_indices)      _mesa_free(tmp_indices);      if (tmp_prims)      _mesa_free(tmp_prims);}

⌨️ 快捷键说明

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