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