From 3387cacc03e24a4104e96961383e43a62dd92df5 Mon Sep 17 00:00:00 2001 From: havoc Date: Sun, 5 Aug 2018 21:39:11 +0000 Subject: [PATCH] Upload the VBOs for Mod_Mesh models (such as the UI) during Mod_Mesh_Finalize. Refactored the vbooffset handling in models to allow different vertex buffers for each array (this would only happen in the dynamic case when a buffer is recycled - so some code makes that assumption about dynamic buffers when freeing these). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12451 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 36 +++++++------- model_shared.c | 132 ++++++++++++++++++++++++++++++++++++------------- model_shared.h | 43 ++++++++++------ 3 files changed, 142 insertions(+), 69 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index b9cde18c..2ea81a82 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -7200,34 +7200,34 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q r_refdef.stats[r_stat_batch_entitystatic_triangles] += model->surfmesh.num_triangles; } rsurface.modelvertex3f = model->surfmesh.data_vertex3f; - rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f; + rsurface.modelvertex3f_vertexbuffer = model->surfmesh.data_vertex3f_vertexbuffer; + rsurface.modelvertex3f_bufferoffset = model->surfmesh.data_vertex3f_bufferoffset; rsurface.modelsvector3f = model->surfmesh.data_svector3f; - rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f; + rsurface.modelsvector3f_vertexbuffer = model->surfmesh.data_svector3f_vertexbuffer; + rsurface.modelsvector3f_bufferoffset = model->surfmesh.data_svector3f_bufferoffset; rsurface.modeltvector3f = model->surfmesh.data_tvector3f; - rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f; + rsurface.modeltvector3f_vertexbuffer = model->surfmesh.data_tvector3f_vertexbuffer; + rsurface.modeltvector3f_bufferoffset = model->surfmesh.data_tvector3f_bufferoffset; rsurface.modelnormal3f = model->surfmesh.data_normal3f; - rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f; + rsurface.modelnormal3f_vertexbuffer = model->surfmesh.data_normal3f_vertexbuffer; + rsurface.modelnormal3f_bufferoffset = model->surfmesh.data_normal3f_bufferoffset; rsurface.modelgeneratedvertex = false; } rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f; - rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f; + rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.data_lightmapcolor4f_vertexbuffer; + rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.data_lightmapcolor4f_bufferoffset; rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f; - rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f; + rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.data_texcoordtexture2f_vertexbuffer; + rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.data_texcoordtexture2f_bufferoffset; rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f; - rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f; + rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.data_texcoordlightmap2f_vertexbuffer; + rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.data_texcoordlightmap2f_bufferoffset; rsurface.modelskeletalindex4ub = model->surfmesh.data_skeletalindex4ub; - rsurface.modelskeletalindex4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelskeletalindex4ub_bufferoffset = model->surfmesh.vbooffset_skeletalindex4ub; + rsurface.modelskeletalindex4ub_vertexbuffer = model->surfmesh.data_skeletalindex4ub_vertexbuffer; + rsurface.modelskeletalindex4ub_bufferoffset = model->surfmesh.data_skeletalindex4ub_bufferoffset; rsurface.modelskeletalweight4ub = model->surfmesh.data_skeletalweight4ub; - rsurface.modelskeletalweight4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelskeletalweight4ub_bufferoffset = model->surfmesh.vbooffset_skeletalweight4ub; + rsurface.modelskeletalweight4ub_vertexbuffer = model->surfmesh.data_skeletalweight4ub_vertexbuffer; + rsurface.modelskeletalweight4ub_bufferoffset = model->surfmesh.data_skeletalweight4ub_bufferoffset; rsurface.modelelement3i = model->surfmesh.data_element3i; rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer; rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset; diff --git a/model_shared.c b/model_shared.c index 6901e554..48b4315b 100644 --- a/model_shared.c +++ b/model_shared.c @@ -199,15 +199,23 @@ void Mod_UnloadModel (dp_model_t *mod) used = mod->used; if (mod->mempool) { - if (mod->surfmesh.data_element3i_indexbuffer) + if (mod->surfmesh.data_element3i_indexbuffer && !mod->surfmesh.data_element3i_indexbuffer->isdynamic) R_Mesh_DestroyMeshBuffer(mod->surfmesh.data_element3i_indexbuffer); mod->surfmesh.data_element3i_indexbuffer = NULL; - if (mod->surfmesh.data_element3s_indexbuffer) + if (mod->surfmesh.data_element3s_indexbuffer && !mod->surfmesh.data_element3s_indexbuffer->isdynamic) R_Mesh_DestroyMeshBuffer(mod->surfmesh.data_element3s_indexbuffer); mod->surfmesh.data_element3s_indexbuffer = NULL; - if (mod->surfmesh.vbo_vertexbuffer) - R_Mesh_DestroyMeshBuffer(mod->surfmesh.vbo_vertexbuffer); - mod->surfmesh.vbo_vertexbuffer = NULL; + if (mod->surfmesh.data_vertex3f_vertexbuffer && !mod->surfmesh.data_vertex3f_vertexbuffer->isdynamic) + R_Mesh_DestroyMeshBuffer(mod->surfmesh.data_vertex3f_vertexbuffer); + mod->surfmesh.data_vertex3f_vertexbuffer = NULL; + mod->surfmesh.data_svector3f_vertexbuffer = NULL; + mod->surfmesh.data_tvector3f_vertexbuffer = NULL; + mod->surfmesh.data_normal3f_vertexbuffer = NULL; + mod->surfmesh.data_texcoordtexture2f_vertexbuffer = NULL; + mod->surfmesh.data_texcoordlightmap2f_vertexbuffer = NULL; + mod->surfmesh.data_lightmapcolor4f_vertexbuffer = NULL; + mod->surfmesh.data_skeletalindex4ub_vertexbuffer = NULL; + mod->surfmesh.data_skeletalweight4ub_vertexbuffer = NULL; } // free textures/memory attached to the model R_FreeTexturePool(&mod->texturepool); @@ -2910,36 +2918,40 @@ void Mod_BuildVBOs(void) loadmodel->surfmesh.data_element3i_indexbuffer = R_Mesh_CreateMeshBuffer(loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles * sizeof(int[3]), loadmodel->name, true, false, false, false); // only build a vbo if one has not already been created (this is important for brush models which load specially) - // vertex buffer is several arrays and we put them in the same buffer - // - // is this wise? the texcoordtexture2f array is used with dynamic - // vertex/svector/tvector/normal when rendering animated models, on the - // other hand animated models don't use a lot of vertices anyway... - if (!loadmodel->surfmesh.vbo_vertexbuffer) + // we put several vertex data streams in the same buffer + if (!loadmodel->surfmesh.data_vertex3f_vertexbuffer) { int size; unsigned char *mem; size = 0; - loadmodel->surfmesh.vbooffset_vertex3f = size;if (loadmodel->surfmesh.data_vertex3f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[3]); - loadmodel->surfmesh.vbooffset_svector3f = size;if (loadmodel->surfmesh.data_svector3f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[3]); - loadmodel->surfmesh.vbooffset_tvector3f = size;if (loadmodel->surfmesh.data_tvector3f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[3]); - loadmodel->surfmesh.vbooffset_normal3f = size;if (loadmodel->surfmesh.data_normal3f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[3]); - loadmodel->surfmesh.vbooffset_texcoordtexture2f = size;if (loadmodel->surfmesh.data_texcoordtexture2f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[2]); - loadmodel->surfmesh.vbooffset_texcoordlightmap2f = size;if (loadmodel->surfmesh.data_texcoordlightmap2f) size += loadmodel->surfmesh.num_vertices * sizeof(float[2]); - loadmodel->surfmesh.vbooffset_lightmapcolor4f = size;if (loadmodel->surfmesh.data_lightmapcolor4f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[4]); - loadmodel->surfmesh.vbooffset_skeletalindex4ub = size;if (loadmodel->surfmesh.data_skeletalindex4ub ) size += loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]); - loadmodel->surfmesh.vbooffset_skeletalweight4ub = size;if (loadmodel->surfmesh.data_skeletalweight4ub ) size += loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]); + loadmodel->surfmesh.data_vertex3f_bufferoffset = size;if (loadmodel->surfmesh.data_vertex3f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[3]); + loadmodel->surfmesh.data_svector3f_bufferoffset = size;if (loadmodel->surfmesh.data_svector3f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[3]); + loadmodel->surfmesh.data_tvector3f_bufferoffset = size;if (loadmodel->surfmesh.data_tvector3f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[3]); + loadmodel->surfmesh.data_normal3f_bufferoffset = size;if (loadmodel->surfmesh.data_normal3f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[3]); + loadmodel->surfmesh.data_texcoordtexture2f_bufferoffset = size;if (loadmodel->surfmesh.data_texcoordtexture2f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[2]); + loadmodel->surfmesh.data_texcoordlightmap2f_bufferoffset = size;if (loadmodel->surfmesh.data_texcoordlightmap2f) size += loadmodel->surfmesh.num_vertices * sizeof(float[2]); + loadmodel->surfmesh.data_lightmapcolor4f_bufferoffset = size;if (loadmodel->surfmesh.data_lightmapcolor4f ) size += loadmodel->surfmesh.num_vertices * sizeof(float[4]); + loadmodel->surfmesh.data_skeletalindex4ub_bufferoffset = size;if (loadmodel->surfmesh.data_skeletalindex4ub ) size += loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]); + loadmodel->surfmesh.data_skeletalweight4ub_bufferoffset = size;if (loadmodel->surfmesh.data_skeletalweight4ub ) size += loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4]); mem = (unsigned char *)Mem_Alloc(tempmempool, size); - if (loadmodel->surfmesh.data_vertex3f ) memcpy(mem + loadmodel->surfmesh.vbooffset_vertex3f , loadmodel->surfmesh.data_vertex3f , loadmodel->surfmesh.num_vertices * sizeof(float[3])); - if (loadmodel->surfmesh.data_svector3f ) memcpy(mem + loadmodel->surfmesh.vbooffset_svector3f , loadmodel->surfmesh.data_svector3f , loadmodel->surfmesh.num_vertices * sizeof(float[3])); - if (loadmodel->surfmesh.data_tvector3f ) memcpy(mem + loadmodel->surfmesh.vbooffset_tvector3f , loadmodel->surfmesh.data_tvector3f , loadmodel->surfmesh.num_vertices * sizeof(float[3])); - if (loadmodel->surfmesh.data_normal3f ) memcpy(mem + loadmodel->surfmesh.vbooffset_normal3f , loadmodel->surfmesh.data_normal3f , loadmodel->surfmesh.num_vertices * sizeof(float[3])); - if (loadmodel->surfmesh.data_texcoordtexture2f ) memcpy(mem + loadmodel->surfmesh.vbooffset_texcoordtexture2f , loadmodel->surfmesh.data_texcoordtexture2f , loadmodel->surfmesh.num_vertices * sizeof(float[2])); - if (loadmodel->surfmesh.data_texcoordlightmap2f) memcpy(mem + loadmodel->surfmesh.vbooffset_texcoordlightmap2f, loadmodel->surfmesh.data_texcoordlightmap2f, loadmodel->surfmesh.num_vertices * sizeof(float[2])); - if (loadmodel->surfmesh.data_lightmapcolor4f ) memcpy(mem + loadmodel->surfmesh.vbooffset_lightmapcolor4f , loadmodel->surfmesh.data_lightmapcolor4f , loadmodel->surfmesh.num_vertices * sizeof(float[4])); - if (loadmodel->surfmesh.data_skeletalindex4ub ) memcpy(mem + loadmodel->surfmesh.vbooffset_skeletalindex4ub , loadmodel->surfmesh.data_skeletalindex4ub , loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4])); - if (loadmodel->surfmesh.data_skeletalweight4ub ) memcpy(mem + loadmodel->surfmesh.vbooffset_skeletalweight4ub , loadmodel->surfmesh.data_skeletalweight4ub , loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4])); - loadmodel->surfmesh.vbo_vertexbuffer = R_Mesh_CreateMeshBuffer(mem, size, loadmodel->name, false, false, false, false); + if (loadmodel->surfmesh.data_vertex3f ) memcpy(mem + loadmodel->surfmesh.data_vertex3f_bufferoffset , loadmodel->surfmesh.data_vertex3f , loadmodel->surfmesh.num_vertices * sizeof(float[3])); + if (loadmodel->surfmesh.data_svector3f ) memcpy(mem + loadmodel->surfmesh.data_svector3f_bufferoffset , loadmodel->surfmesh.data_svector3f , loadmodel->surfmesh.num_vertices * sizeof(float[3])); + if (loadmodel->surfmesh.data_tvector3f ) memcpy(mem + loadmodel->surfmesh.data_tvector3f_bufferoffset , loadmodel->surfmesh.data_tvector3f , loadmodel->surfmesh.num_vertices * sizeof(float[3])); + if (loadmodel->surfmesh.data_normal3f ) memcpy(mem + loadmodel->surfmesh.data_normal3f_bufferoffset , loadmodel->surfmesh.data_normal3f , loadmodel->surfmesh.num_vertices * sizeof(float[3])); + if (loadmodel->surfmesh.data_texcoordtexture2f ) memcpy(mem + loadmodel->surfmesh.data_texcoordtexture2f_bufferoffset , loadmodel->surfmesh.data_texcoordtexture2f , loadmodel->surfmesh.num_vertices * sizeof(float[2])); + if (loadmodel->surfmesh.data_texcoordlightmap2f) memcpy(mem + loadmodel->surfmesh.data_texcoordlightmap2f_bufferoffset, loadmodel->surfmesh.data_texcoordlightmap2f, loadmodel->surfmesh.num_vertices * sizeof(float[2])); + if (loadmodel->surfmesh.data_lightmapcolor4f ) memcpy(mem + loadmodel->surfmesh.data_lightmapcolor4f_bufferoffset , loadmodel->surfmesh.data_lightmapcolor4f , loadmodel->surfmesh.num_vertices * sizeof(float[4])); + if (loadmodel->surfmesh.data_skeletalindex4ub ) memcpy(mem + loadmodel->surfmesh.data_skeletalindex4ub_bufferoffset , loadmodel->surfmesh.data_skeletalindex4ub , loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4])); + if (loadmodel->surfmesh.data_skeletalweight4ub ) memcpy(mem + loadmodel->surfmesh.data_skeletalweight4ub_bufferoffset , loadmodel->surfmesh.data_skeletalweight4ub , loadmodel->surfmesh.num_vertices * sizeof(unsigned char[4])); + loadmodel->surfmesh.data_vertex3f_vertexbuffer = R_Mesh_CreateMeshBuffer(mem, size, loadmodel->name, false, false, false, false); + loadmodel->surfmesh.data_svector3f_vertexbuffer = loadmodel->surfmesh.data_svector3f ? loadmodel->surfmesh.data_vertex3f_vertexbuffer : NULL; + loadmodel->surfmesh.data_tvector3f_vertexbuffer = loadmodel->surfmesh.data_tvector3f ? loadmodel->surfmesh.data_vertex3f_vertexbuffer : NULL; + loadmodel->surfmesh.data_normal3f_vertexbuffer = loadmodel->surfmesh.data_normal3f ? loadmodel->surfmesh.data_vertex3f_vertexbuffer : NULL; + loadmodel->surfmesh.data_texcoordtexture2f_vertexbuffer = loadmodel->surfmesh.data_texcoordtexture2f ? loadmodel->surfmesh.data_vertex3f_vertexbuffer : NULL; + loadmodel->surfmesh.data_texcoordlightmap2f_vertexbuffer = loadmodel->surfmesh.data_texcoordlightmap2f ? loadmodel->surfmesh.data_vertex3f_vertexbuffer : NULL; + loadmodel->surfmesh.data_lightmapcolor4f_vertexbuffer = loadmodel->surfmesh.data_lightmapcolor4f ? loadmodel->surfmesh.data_vertex3f_vertexbuffer : NULL; + loadmodel->surfmesh.data_skeletalindex4ub_vertexbuffer = loadmodel->surfmesh.data_skeletalindex4ub ? loadmodel->surfmesh.data_vertex3f_vertexbuffer : NULL; + loadmodel->surfmesh.data_skeletalweight4ub_vertexbuffer = loadmodel->surfmesh.data_skeletalweight4ub ? loadmodel->surfmesh.data_vertex3f_vertexbuffer : NULL; Mem_Free(mem); } } @@ -3913,15 +3925,23 @@ static void Mod_GenerateLightmaps_UnweldTriangles(dp_model_t *model) if (model->surfmesh.num_vertices > 65536) model->surfmesh.data_element3s = NULL; - if (model->surfmesh.data_element3i_indexbuffer) + if (model->surfmesh.data_element3i_indexbuffer && !model->surfmesh.data_element3i_indexbuffer->isdynamic) R_Mesh_DestroyMeshBuffer(model->surfmesh.data_element3i_indexbuffer); model->surfmesh.data_element3i_indexbuffer = NULL; - if (model->surfmesh.data_element3s_indexbuffer) + if (model->surfmesh.data_element3s_indexbuffer && !model->surfmesh.data_element3s_indexbuffer->isdynamic) R_Mesh_DestroyMeshBuffer(model->surfmesh.data_element3s_indexbuffer); model->surfmesh.data_element3s_indexbuffer = NULL; - if (model->surfmesh.vbo_vertexbuffer) - R_Mesh_DestroyMeshBuffer(model->surfmesh.vbo_vertexbuffer); - model->surfmesh.vbo_vertexbuffer = 0; + if (model->surfmesh.data_vertex3f_vertexbuffer && !model->surfmesh.data_vertex3f_vertexbuffer->isdynamic) + R_Mesh_DestroyMeshBuffer(model->surfmesh.data_vertex3f_vertexbuffer); + model->surfmesh.data_vertex3f_vertexbuffer = NULL; + model->surfmesh.data_svector3f_vertexbuffer = NULL; + model->surfmesh.data_tvector3f_vertexbuffer = NULL; + model->surfmesh.data_normal3f_vertexbuffer = NULL; + model->surfmesh.data_texcoordtexture2f_vertexbuffer = NULL; + model->surfmesh.data_texcoordlightmap2f_vertexbuffer = NULL; + model->surfmesh.data_lightmapcolor4f_vertexbuffer = NULL; + model->surfmesh.data_skeletalindex4ub_vertexbuffer = NULL; + model->surfmesh.data_skeletalweight4ub_vertexbuffer = NULL; // convert all triangles to unique vertex data outvertexindex = 0; @@ -4638,9 +4658,51 @@ void Mod_Mesh_ComputeBounds(dp_model_t *mod) } } +void Mod_Mesh_Validate(dp_model_t *mod) +{ + int i; + qboolean warned = false; + for (i = 0; i < mod->num_surfaces; i++) + { + msurface_t *surf = mod->data_surfaces + i; + int *e = mod->surfmesh.data_element3i + surf->num_firsttriangle * 3; + int first = surf->num_firstvertex; + int end = surf->num_firstvertex + surf->num_vertices; + int j; + for (j = 0;j < surf->num_triangles * 3;j++) + { + if (e[j] < first || e[j] >= end) + { + if (!warned) + Con_DPrintf("Mod_Mesh_Validate: detected corrupt surface - debug me!\n"); + warned = true; + e[j] = first; + } + } + } +} + +void Mod_Mesh_UploadDynamicBuffers(dp_model_t *mod) +{ + mod->surfmesh.data_element3s_indexbuffer = mod->surfmesh.data_element3s ? R_BufferData_Store(mod->surfmesh.num_triangles * sizeof(short[3]), mod->surfmesh.data_element3s, R_BUFFERDATA_INDEX16, &mod->surfmesh.data_element3s_bufferoffset) : NULL; + mod->surfmesh.data_element3i_indexbuffer = mod->surfmesh.data_element3i ? R_BufferData_Store(mod->surfmesh.num_triangles * sizeof(int[3]), mod->surfmesh.data_element3i, R_BUFFERDATA_INDEX32, &mod->surfmesh.data_element3i_bufferoffset) : NULL; + mod->surfmesh.data_vertex3f_vertexbuffer = mod->surfmesh.data_vertex3f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[3]), mod->surfmesh.data_vertex3f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_vertex3f_bufferoffset) : NULL; + mod->surfmesh.data_svector3f_vertexbuffer = mod->surfmesh.data_svector3f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[3]), mod->surfmesh.data_svector3f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_svector3f_bufferoffset) : NULL; + mod->surfmesh.data_tvector3f_vertexbuffer = mod->surfmesh.data_tvector3f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[3]), mod->surfmesh.data_tvector3f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_tvector3f_bufferoffset) : NULL; + mod->surfmesh.data_normal3f_vertexbuffer = mod->surfmesh.data_normal3f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[3]), mod->surfmesh.data_normal3f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_normal3f_bufferoffset) : NULL; + mod->surfmesh.data_texcoordtexture2f_vertexbuffer = mod->surfmesh.data_texcoordtexture2f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[2]), mod->surfmesh.data_texcoordtexture2f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_texcoordtexture2f_bufferoffset) : NULL; + mod->surfmesh.data_texcoordlightmap2f_vertexbuffer = mod->surfmesh.data_texcoordlightmap2f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[2]), mod->surfmesh.data_texcoordlightmap2f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_texcoordlightmap2f_bufferoffset) : NULL; + mod->surfmesh.data_lightmapcolor4f_vertexbuffer = mod->surfmesh.data_lightmapcolor4f ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(float[4]), mod->surfmesh.data_lightmapcolor4f, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_lightmapcolor4f_bufferoffset) : NULL; + mod->surfmesh.data_skeletalindex4ub_vertexbuffer = mod->surfmesh.data_skeletalindex4ub ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(unsigned char[4]), mod->surfmesh.data_skeletalindex4ub, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_skeletalindex4ub_bufferoffset) : NULL; + mod->surfmesh.data_skeletalweight4ub_vertexbuffer = mod->surfmesh.data_skeletalweight4ub ? R_BufferData_Store(mod->surfmesh.num_vertices * sizeof(unsigned char[4]), mod->surfmesh.data_skeletalweight4ub, R_BUFFERDATA_VERTEX, &mod->surfmesh.data_skeletalweight4ub_bufferoffset) : NULL; +} + void Mod_Mesh_Finalize(dp_model_t *mod) { + if (gl_paranoid.integer) + Mod_Mesh_Validate(mod); Mod_Mesh_ComputeBounds(mod); Mod_Mesh_MakeSortedSurfaces(mod); Mod_BuildTextureVectorsFromNormals(0, mod->surfmesh.num_vertices, mod->surfmesh.num_triangles, mod->surfmesh.data_vertex3f, mod->surfmesh.data_texcoordtexture2f, mod->surfmesh.data_normal3f, mod->surfmesh.data_element3i, mod->surfmesh.data_svector3f, mod->surfmesh.data_tvector3f, true); + Mod_Mesh_UploadDynamicBuffers(mod); } diff --git a/model_shared.h b/model_shared.h index 298a5409..cf64465f 100644 --- a/model_shared.h +++ b/model_shared.h @@ -121,11 +121,7 @@ typedef struct surfmesh_s // triangle data in system memory int num_triangles; // number of triangles in the mesh int *data_element3i; // int[tris*3] triangles of the mesh, 3 indices into vertex arrays for each - r_meshbuffer_t *data_element3i_indexbuffer; - int data_element3i_bufferoffset; - unsigned short *data_element3s; // unsigned short[tris*3] triangles of the mesh in unsigned short format (NULL if num_vertices > 65536) - r_meshbuffer_t *data_element3s_indexbuffer; - int data_element3s_bufferoffset; + // vertex data in system memory int num_vertices; // number of vertices in the mesh float *data_vertex3f; // float[verts*3] vertex locations @@ -138,17 +134,31 @@ typedef struct surfmesh_s unsigned char *data_skeletalindex4ub; unsigned char *data_skeletalweight4ub; int *data_lightmapoffsets; // index into surface's lightmap samples for vertex lighting - // vertex buffer object (stores geometry in video memory) - r_meshbuffer_t *vbo_vertexbuffer; - int vbooffset_vertex3f; - int vbooffset_svector3f; - int vbooffset_tvector3f; - int vbooffset_normal3f; - int vbooffset_texcoordtexture2f; - int vbooffset_texcoordlightmap2f; - int vbooffset_lightmapcolor4f; - int vbooffset_skeletalindex4ub; - int vbooffset_skeletalweight4ub; + // index buffer - only one of these will be non-NULL + r_meshbuffer_t *data_element3i_indexbuffer; + int data_element3i_bufferoffset; + unsigned short *data_element3s; // unsigned short[tris*3] triangles of the mesh in unsigned short format (NULL if num_vertices > 65536) + r_meshbuffer_t *data_element3s_indexbuffer; + int data_element3s_bufferoffset; + // vertex buffers + r_meshbuffer_t *data_vertex3f_vertexbuffer; + int data_vertex3f_bufferoffset; + r_meshbuffer_t *data_svector3f_vertexbuffer; + int data_svector3f_bufferoffset; + r_meshbuffer_t *data_tvector3f_vertexbuffer; + int data_tvector3f_bufferoffset; + r_meshbuffer_t *data_normal3f_vertexbuffer; + int data_normal3f_bufferoffset; + r_meshbuffer_t *data_texcoordtexture2f_vertexbuffer; + int data_texcoordtexture2f_bufferoffset; + r_meshbuffer_t *data_texcoordlightmap2f_vertexbuffer; + int data_texcoordlightmap2f_bufferoffset; + r_meshbuffer_t *data_lightmapcolor4f_vertexbuffer; + int data_lightmapcolor4f_bufferoffset; + r_meshbuffer_t *data_skeletalindex4ub_vertexbuffer; + int data_skeletalindex4ub_bufferoffset; + r_meshbuffer_t *data_skeletalweight4ub_vertexbuffer; + int data_skeletalweight4ub_bufferoffset; // morph blending, these are zero if model is skeletal or static int num_morphframes; struct md3vertex_s *data_morphmd3vertex; @@ -1211,6 +1221,7 @@ texture_t *Mod_Mesh_GetTexture(dp_model_t *mod, const char *name, int defaultdra msurface_t *Mod_Mesh_AddSurface(dp_model_t *mod, texture_t *tex, qboolean batchwithprevioussurface); int Mod_Mesh_IndexForVertex(dp_model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a); void Mod_Mesh_AddTriangle(dp_model_t *mod, msurface_t *surf, int e0, int e1, int e2); +void Mod_Mesh_Validate(dp_model_t *mod); void Mod_Mesh_Finalize(dp_model_t *mod); // Collision optimization using Bounding Interval Hierarchy -- 2.39.2