#include "r_shadow.h"
#include "polygon.h"
-cvar_t r_mipskins = {CVAR_SAVE, "r_mipskins", "0", "mipmaps model skins so they render faster in the distance and do not display noise artifacts, can cause discoloration of skins if they contain undesirable border colors"};
-cvar_t r_mipnormalmaps = {CVAR_SAVE, "r_mipnormalmaps", "1", "mipmaps normalmaps (turning it off looks sharper but may have aliasing)"};
-cvar_t mod_generatelightmaps_unitspersample = {CVAR_SAVE, "mod_generatelightmaps_unitspersample", "8", "lightmap resolution"};
-cvar_t mod_generatelightmaps_borderpixels = {CVAR_SAVE, "mod_generatelightmaps_borderpixels", "2", "extra space around polygons to prevent sampling artifacts"};
-cvar_t mod_generatelightmaps_texturesize = {CVAR_SAVE, "mod_generatelightmaps_texturesize", "1024", "size of lightmap textures"};
-cvar_t mod_generatelightmaps_lightmapsamples = {CVAR_SAVE, "mod_generatelightmaps_lightmapsamples", "16", "number of shadow tests done per lightmap pixel"};
-cvar_t mod_generatelightmaps_vertexsamples = {CVAR_SAVE, "mod_generatelightmaps_vertexsamples", "16", "number of shadow tests done per vertex"};
-cvar_t mod_generatelightmaps_gridsamples = {CVAR_SAVE, "mod_generatelightmaps_gridsamples", "64", "number of shadow tests done per lightgrid cell"};
-cvar_t mod_generatelightmaps_lightmapradius = {CVAR_SAVE, "mod_generatelightmaps_lightmapradius", "16", "sampling area around each lightmap pixel"};
-cvar_t mod_generatelightmaps_vertexradius = {CVAR_SAVE, "mod_generatelightmaps_vertexradius", "16", "sampling area around each vertex"};
-cvar_t mod_generatelightmaps_gridradius = {CVAR_SAVE, "mod_generatelightmaps_gridradius", "64", "sampling area around each lightgrid cell center"};
+cvar_t r_mipskins = {CVAR_CLIENT | CVAR_SAVE, "r_mipskins", "0", "mipmaps model skins so they render faster in the distance and do not display noise artifacts, can cause discoloration of skins if they contain undesirable border colors"};
+cvar_t r_mipnormalmaps = {CVAR_CLIENT | CVAR_SAVE, "r_mipnormalmaps", "1", "mipmaps normalmaps (turning it off looks sharper but may have aliasing)"};
+cvar_t mod_generatelightmaps_unitspersample = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_unitspersample", "8", "lightmap resolution"};
+cvar_t mod_generatelightmaps_borderpixels = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_borderpixels", "2", "extra space around polygons to prevent sampling artifacts"};
+cvar_t mod_generatelightmaps_texturesize = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_texturesize", "1024", "size of lightmap textures"};
+cvar_t mod_generatelightmaps_lightmapsamples = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_lightmapsamples", "16", "number of shadow tests done per lightmap pixel"};
+cvar_t mod_generatelightmaps_vertexsamples = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_vertexsamples", "16", "number of shadow tests done per vertex"};
+cvar_t mod_generatelightmaps_gridsamples = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_gridsamples", "64", "number of shadow tests done per lightgrid cell"};
+cvar_t mod_generatelightmaps_lightmapradius = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_lightmapradius", "16", "sampling area around each lightmap pixel"};
+cvar_t mod_generatelightmaps_vertexradius = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_vertexradius", "16", "sampling area around each vertex"};
+cvar_t mod_generatelightmaps_gridradius = {CVAR_CLIENT | CVAR_SAVE, "mod_generatelightmaps_gridradius", "64", "sampling area around each lightgrid cell center"};
dp_model_t *loadmodel;
Mod_Init
===============
*/
-static void Mod_Print(void);
-static void Mod_Precache (void);
-static void Mod_Decompile_f(void);
-static void Mod_GenerateLightmaps_f(void);
+static void Mod_Print_f(cmd_state_t *cmd);
+static void Mod_Precache_f(cmd_state_t *cmd);
+static void Mod_Decompile_f(cmd_state_t *cmd);
+static void Mod_GenerateLightmaps_f(cmd_state_t *cmd);
void Mod_Init (void)
{
mod_mempool = Mem_AllocPool("modelinfo", 0, NULL);
Cvar_RegisterVariable(&mod_generatelightmaps_vertexradius);
Cvar_RegisterVariable(&mod_generatelightmaps_gridradius);
- Cmd_AddCommand ("modellist", Mod_Print, "prints a list of loaded models");
- Cmd_AddCommand ("modelprecache", Mod_Precache, "load a model");
- Cmd_AddCommand ("modeldecompile", Mod_Decompile_f, "exports a model in several formats for editing purposes");
- Cmd_AddCommand ("mod_generatelightmaps", Mod_GenerateLightmaps_f, "rebuilds lighting on current worldmodel");
+ Cmd_AddCommand(&cmd_client, "modellist", Mod_Print_f, "prints a list of loaded models");
+ Cmd_AddCommand(&cmd_client, "modelprecache", Mod_Precache_f, "load a model");
+ Cmd_AddCommand(&cmd_client, "modeldecompile", Mod_Decompile_f, "exports a model in several formats for editing purposes");
+ Cmd_AddCommand(&cmd_client, "mod_generatelightmaps", Mod_GenerateLightmaps_f, "rebuilds lighting on current worldmodel");
}
void Mod_RenderInit(void)
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);
SCR_PushLoadingScreen(true, mod->name, 1);
- // LordHavoc: unload the existing model in this slot (if there is one)
+ // LadyHavoc: unload the existing model in this slot (if there is one)
if (mod->loaded || mod->mempool)
Mod_UnloadModel(mod);
}
else if (crash)
{
- // LordHavoc: Sys_Error was *ANNOYING*
+ // LadyHavoc: Sys_Error was *ANNOYING*
Con_Printf ("Mod_LoadModel: %s not found\n", mod->name);
}
Mod_Print
================
*/
-static void Mod_Print(void)
+static void Mod_Print_f(cmd_state_t *cmd)
{
int i;
int nummodels = (int)Mem_ExpandableArray_IndexRange(&models);
Mod_Precache
================
*/
-static void Mod_Precache(void)
+static void Mod_Precache_f(cmd_state_t *cmd)
{
- if (Cmd_Argc() == 2)
- Mod_ForName(Cmd_Argv(1), false, true, Cmd_Argv(1)[0] == '*' ? cl.model_name[1] : NULL);
+ if (Cmd_Argc(cmd) == 2)
+ Mod_ForName(Cmd_Argv(cmd, 1), false, true, Cmd_Argv(cmd, 1)[0] == '*' ? cl.model_name[1] : NULL);
else
Con_Print("usage: modelprecache <filename>\n");
}
Con_Printf("Mod_ValidateElements(%i, %i, %i, %p, %p) called at %s:%d", numelements, first, last, element3i, element3s, filename, fileline);
Con_Printf(", %i elements are invalid in element3i (example: element3i[%i] == %i)", invalidintcount, invalidintexample, element3i ? element3i[invalidintexample] : 0);
Con_Printf(", %i elements are invalid in element3s (example: element3s[%i] == %i)", invalidshortcount, invalidshortexample, element3s ? element3s[invalidshortexample] : 0);
- Con_Printf(", %i elements mismatch between element3i and element3s (example: element3s[%i] is %i and element3i[i] is %i)", invalidmismatchcount, invalidmismatchexample, element3i ? element3i[invalidmismatchexample] : 0, invalidmismatchexample, element3s ? element3s[invalidmismatchexample] : 0);
+ Con_Printf(", %i elements mismatch between element3i and element3s (example: element3s[%i] is %i and element3i[%i] is %i)", invalidmismatchcount, invalidmismatchexample, element3s ? element3s[invalidmismatchexample] : 0, invalidmismatchexample, element3i ? element3i[invalidmismatchexample] : 0);
Con_Print(". Please debug the engine code - these elements have been modified to not crash, but nothing more.\n");
// edit the elements to make them safer, as the driver will crash otherwise
}
}
-shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int expandable)
+shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtriangles)
{
shadowmesh_t *newmesh;
- unsigned char *data;
- int size;
- size = sizeof(shadowmesh_t);
- size += maxverts * sizeof(float[3]);
- if (light)
- size += maxverts * sizeof(float[11]);
- size += maxtriangles * sizeof(int[3]);
- if (maxverts <= 65536)
- size += maxtriangles * sizeof(unsigned short[3]);
- if (expandable)
- size += SHADOWMESHVERTEXHASH * sizeof(shadowmeshvertexhash_t *) + maxverts * sizeof(shadowmeshvertexhash_t);
- data = (unsigned char *)Mem_Alloc(mempool, size);
- newmesh = (shadowmesh_t *)data;data += sizeof(*newmesh);
- newmesh->map_diffuse = map_diffuse;
- newmesh->map_specular = map_specular;
- newmesh->map_normal = map_normal;
+ newmesh = (shadowmesh_t *)Mem_Alloc(mempool, sizeof(shadowmesh_t));
+ newmesh->mempool = mempool;
newmesh->maxverts = maxverts;
newmesh->maxtriangles = maxtriangles;
newmesh->numverts = 0;
memset(newmesh->sideoffsets, 0, sizeof(newmesh->sideoffsets));
memset(newmesh->sidetotals, 0, sizeof(newmesh->sidetotals));
- newmesh->vertex3f = (float *)data;data += maxverts * sizeof(float[3]);
- if (light)
- {
- newmesh->svector3f = (float *)data;data += maxverts * sizeof(float[3]);
- newmesh->tvector3f = (float *)data;data += maxverts * sizeof(float[3]);
- newmesh->normal3f = (float *)data;data += maxverts * sizeof(float[3]);
- newmesh->texcoord2f = (float *)data;data += maxverts * sizeof(float[2]);
- }
- newmesh->element3i = (int *)data;data += maxtriangles * sizeof(int[3]);
- if (expandable)
- {
- newmesh->vertexhashtable = (shadowmeshvertexhash_t **)data;data += SHADOWMESHVERTEXHASH * sizeof(shadowmeshvertexhash_t *);
- newmesh->vertexhashentries = (shadowmeshvertexhash_t *)data;data += maxverts * sizeof(shadowmeshvertexhash_t);
- }
- if (maxverts <= 65536)
- newmesh->element3s = (unsigned short *)data;data += maxtriangles * sizeof(unsigned short[3]);
+ newmesh->vertex3f = (float *)Mem_Alloc(mempool, maxverts * sizeof(float[3]));
+ newmesh->element3i = (int *)Mem_Alloc(mempool, maxtriangles * sizeof(int[3]));
+ newmesh->vertexhashtable = (shadowmeshvertexhash_t **)Mem_Alloc(mempool, SHADOWMESHVERTEXHASH * sizeof(shadowmeshvertexhash_t *));
+ newmesh->vertexhashentries = (shadowmeshvertexhash_t *)Mem_Alloc(mempool, maxverts * sizeof(shadowmeshvertexhash_t));
return newmesh;
}
-shadowmesh_t *Mod_ShadowMesh_ReAlloc(mempool_t *mempool, shadowmesh_t *oldmesh, int light)
-{
- shadowmesh_t *newmesh;
- newmesh = Mod_ShadowMesh_Alloc(mempool, oldmesh->numverts, oldmesh->numtriangles, oldmesh->map_diffuse, oldmesh->map_specular, oldmesh->map_normal, light, false);
- newmesh->numverts = oldmesh->numverts;
- newmesh->numtriangles = oldmesh->numtriangles;
- memcpy(newmesh->sideoffsets, oldmesh->sideoffsets, sizeof(oldmesh->sideoffsets));
- memcpy(newmesh->sidetotals, oldmesh->sidetotals, sizeof(oldmesh->sidetotals));
-
- memcpy(newmesh->vertex3f, oldmesh->vertex3f, oldmesh->numverts * sizeof(float[3]));
- if (newmesh->svector3f && oldmesh->svector3f)
- {
- memcpy(newmesh->svector3f, oldmesh->svector3f, oldmesh->numverts * sizeof(float[3]));
- memcpy(newmesh->tvector3f, oldmesh->tvector3f, oldmesh->numverts * sizeof(float[3]));
- memcpy(newmesh->normal3f, oldmesh->normal3f, oldmesh->numverts * sizeof(float[3]));
- memcpy(newmesh->texcoord2f, oldmesh->texcoord2f, oldmesh->numverts * sizeof(float[2]));
- }
- memcpy(newmesh->element3i, oldmesh->element3i, oldmesh->numtriangles * sizeof(int[3]));
- return newmesh;
-}
-
-int Mod_ShadowMesh_AddVertex(shadowmesh_t *mesh, float *vertex14f)
+int Mod_ShadowMesh_AddVertex(shadowmesh_t *mesh, const float *vertex3f)
{
int hashindex, vnum;
shadowmeshvertexhash_t *hash;
// this uses prime numbers intentionally
- hashindex = (unsigned int) (vertex14f[0] * 2003 + vertex14f[1] * 4001 + vertex14f[2] * 7919) % SHADOWMESHVERTEXHASH;
+ hashindex = (unsigned int) (vertex3f[0] * 2003 + vertex3f[1] * 4001 + vertex3f[2] * 7919) % SHADOWMESHVERTEXHASH;
for (hash = mesh->vertexhashtable[hashindex];hash;hash = hash->next)
{
vnum = (hash - mesh->vertexhashentries);
- if ((mesh->vertex3f == NULL || (mesh->vertex3f[vnum * 3 + 0] == vertex14f[0] && mesh->vertex3f[vnum * 3 + 1] == vertex14f[1] && mesh->vertex3f[vnum * 3 + 2] == vertex14f[2]))
- && (mesh->svector3f == NULL || (mesh->svector3f[vnum * 3 + 0] == vertex14f[3] && mesh->svector3f[vnum * 3 + 1] == vertex14f[4] && mesh->svector3f[vnum * 3 + 2] == vertex14f[5]))
- && (mesh->tvector3f == NULL || (mesh->tvector3f[vnum * 3 + 0] == vertex14f[6] && mesh->tvector3f[vnum * 3 + 1] == vertex14f[7] && mesh->tvector3f[vnum * 3 + 2] == vertex14f[8]))
- && (mesh->normal3f == NULL || (mesh->normal3f[vnum * 3 + 0] == vertex14f[9] && mesh->normal3f[vnum * 3 + 1] == vertex14f[10] && mesh->normal3f[vnum * 3 + 2] == vertex14f[11]))
- && (mesh->texcoord2f == NULL || (mesh->texcoord2f[vnum * 2 + 0] == vertex14f[12] && mesh->texcoord2f[vnum * 2 + 1] == vertex14f[13])))
+ if (mesh->vertex3f[vnum * 3 + 0] == vertex3f[0] && mesh->vertex3f[vnum * 3 + 1] == vertex3f[1] && mesh->vertex3f[vnum * 3 + 2] == vertex3f[2])
return hash - mesh->vertexhashentries;
}
vnum = mesh->numverts++;
hash = mesh->vertexhashentries + vnum;
hash->next = mesh->vertexhashtable[hashindex];
mesh->vertexhashtable[hashindex] = hash;
- if (mesh->vertex3f) {mesh->vertex3f[vnum * 3 + 0] = vertex14f[0];mesh->vertex3f[vnum * 3 + 1] = vertex14f[1];mesh->vertex3f[vnum * 3 + 2] = vertex14f[2];}
- if (mesh->svector3f) {mesh->svector3f[vnum * 3 + 0] = vertex14f[3];mesh->svector3f[vnum * 3 + 1] = vertex14f[4];mesh->svector3f[vnum * 3 + 2] = vertex14f[5];}
- if (mesh->tvector3f) {mesh->tvector3f[vnum * 3 + 0] = vertex14f[6];mesh->tvector3f[vnum * 3 + 1] = vertex14f[7];mesh->tvector3f[vnum * 3 + 2] = vertex14f[8];}
- if (mesh->normal3f) {mesh->normal3f[vnum * 3 + 0] = vertex14f[9];mesh->normal3f[vnum * 3 + 1] = vertex14f[10];mesh->normal3f[vnum * 3 + 2] = vertex14f[11];}
- if (mesh->texcoord2f) {mesh->texcoord2f[vnum * 2 + 0] = vertex14f[12];mesh->texcoord2f[vnum * 2 + 1] = vertex14f[13];}
+ mesh->vertex3f[vnum * 3 + 0] = vertex3f[0];
+ mesh->vertex3f[vnum * 3 + 1] = vertex3f[1];
+ mesh->vertex3f[vnum * 3 + 2] = vertex3f[2];
return vnum;
}
-void Mod_ShadowMesh_AddTriangle(mempool_t *mempool, shadowmesh_t *mesh, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, float *vertex14f)
+void Mod_ShadowMesh_AddMesh(shadowmesh_t *mesh, const float *vertex3f, int numtris, const int *element3i)
{
- if (mesh->numtriangles == 0)
- {
- // set the properties on this empty mesh to be more favorable...
- // (note: this case only occurs for the first triangle added to a new mesh chain)
- mesh->map_diffuse = map_diffuse;
- mesh->map_specular = map_specular;
- mesh->map_normal = map_normal;
- }
- while (mesh->map_diffuse != map_diffuse || mesh->map_specular != map_specular || mesh->map_normal != map_normal || mesh->numverts + 3 > mesh->maxverts || mesh->numtriangles + 1 > mesh->maxtriangles)
- {
- if (mesh->next == NULL)
- mesh->next = Mod_ShadowMesh_Alloc(mempool, max(mesh->maxverts, 300), max(mesh->maxtriangles, 100), map_diffuse, map_specular, map_normal, mesh->svector3f != NULL, true);
- mesh = mesh->next;
- }
- mesh->element3i[mesh->numtriangles * 3 + 0] = Mod_ShadowMesh_AddVertex(mesh, vertex14f + 14 * 0);
- mesh->element3i[mesh->numtriangles * 3 + 1] = Mod_ShadowMesh_AddVertex(mesh, vertex14f + 14 * 1);
- mesh->element3i[mesh->numtriangles * 3 + 2] = Mod_ShadowMesh_AddVertex(mesh, vertex14f + 14 * 2);
- mesh->numtriangles++;
-}
+ int i;
-void Mod_ShadowMesh_AddMesh(mempool_t *mempool, shadowmesh_t *mesh, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, int numtris, const int *element3i)
-{
- int i, j, e;
- float vbuf[3*14], *v;
- memset(vbuf, 0, sizeof(vbuf));
for (i = 0;i < numtris;i++)
{
- for (j = 0, v = vbuf;j < 3;j++, v += 14)
- {
- e = *element3i++;
- if (vertex3f)
- {
- v[0] = vertex3f[e * 3 + 0];
- v[1] = vertex3f[e * 3 + 1];
- v[2] = vertex3f[e * 3 + 2];
- }
- if (svector3f)
- {
- v[3] = svector3f[e * 3 + 0];
- v[4] = svector3f[e * 3 + 1];
- v[5] = svector3f[e * 3 + 2];
- }
- if (tvector3f)
- {
- v[6] = tvector3f[e * 3 + 0];
- v[7] = tvector3f[e * 3 + 1];
- v[8] = tvector3f[e * 3 + 2];
- }
- if (normal3f)
- {
- v[9] = normal3f[e * 3 + 0];
- v[10] = normal3f[e * 3 + 1];
- v[11] = normal3f[e * 3 + 2];
- }
- if (texcoord2f)
- {
- v[12] = texcoord2f[e * 2 + 0];
- v[13] = texcoord2f[e * 2 + 1];
- }
- }
- Mod_ShadowMesh_AddTriangle(mempool, mesh, map_diffuse, map_specular, map_normal, vbuf);
+ mesh->element3i[mesh->numtriangles * 3 + 0] = Mod_ShadowMesh_AddVertex(mesh, vertex3f + 3 * element3i[i * 3 + 0]);
+ mesh->element3i[mesh->numtriangles * 3 + 1] = Mod_ShadowMesh_AddVertex(mesh, vertex3f + 3 * element3i[i * 3 + 1]);
+ mesh->element3i[mesh->numtriangles * 3 + 2] = Mod_ShadowMesh_AddVertex(mesh, vertex3f + 3 * element3i[i * 3 + 2]);
+ mesh->numtriangles++;
}
// the triangle calculation can take a while, so let's do a keepalive here
CL_KeepaliveMessage(false);
}
-shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles, rtexture_t *map_diffuse, rtexture_t *map_specular, rtexture_t *map_normal, int light, int expandable)
+shadowmesh_t *Mod_ShadowMesh_Begin(mempool_t *mempool, int maxverts, int maxtriangles)
{
// the preparation before shadow mesh initialization can take a while, so let's do a keepalive here
CL_KeepaliveMessage(false);
- return Mod_ShadowMesh_Alloc(mempool, maxverts, maxtriangles, map_diffuse, map_specular, map_normal, light, expandable);
+ return Mod_ShadowMesh_Alloc(mempool, maxverts, maxtriangles);
}
-static void Mod_ShadowMesh_CreateVBOs(shadowmesh_t *mesh, mempool_t *mempool)
+static void Mod_ShadowMesh_CreateVBOs(shadowmesh_t *mesh)
{
if (!mesh->numverts)
return;
// make sure we don't crash inside the driver if something went wrong, as it's annoying to debug
Mod_ValidateElements(mesh->element3i, mesh->element3s, mesh->numtriangles, 0, mesh->numverts, __FILE__, __LINE__);
- // build r_vertexmesh_t array
- // (compressed interleaved array for D3D)
- if (!mesh->vertexmesh && mesh->texcoord2f && vid.useinterleavedarrays)
- {
- int vertexindex;
- int numvertices = mesh->numverts;
- r_vertexmesh_t *vertexmesh;
- mesh->vertexmesh = vertexmesh = (r_vertexmesh_t*)Mem_Alloc(mempool, numvertices * sizeof(*mesh->vertexmesh));
- for (vertexindex = 0;vertexindex < numvertices;vertexindex++, vertexmesh++)
- {
- VectorCopy(mesh->vertex3f + 3*vertexindex, vertexmesh->vertex3f);
- VectorScale(mesh->svector3f + 3*vertexindex, 1.0f, vertexmesh->svector3f);
- VectorScale(mesh->tvector3f + 3*vertexindex, 1.0f, vertexmesh->tvector3f);
- VectorScale(mesh->normal3f + 3*vertexindex, 1.0f, vertexmesh->normal3f);
- Vector2Copy(mesh->texcoord2f + 2*vertexindex, vertexmesh->texcoordtexture2f);
- }
- }
-
// upload short indices as a buffer
if (mesh->element3s && !mesh->element3s_indexbuffer)
mesh->element3s_indexbuffer = R_Mesh_CreateMeshBuffer(mesh->element3s, mesh->numtriangles * sizeof(short[3]), "shadowmesh", true, false, false, true);
// 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 (!mesh->vbo_vertexbuffer && !vid.useinterleavedarrays)
+ if (!mesh->vbo_vertexbuffer)
{
- int size;
- unsigned char *mem;
- size = 0;
- mesh->vbooffset_vertexmesh = size;if (mesh->vertexmesh ) size += mesh->numverts * sizeof(r_vertexmesh_t);
- mesh->vbooffset_vertex3f = size;if (mesh->vertex3f ) size += mesh->numverts * sizeof(float[3]);
- mesh->vbooffset_svector3f = size;if (mesh->svector3f ) size += mesh->numverts * sizeof(float[3]);
- mesh->vbooffset_tvector3f = size;if (mesh->tvector3f ) size += mesh->numverts * sizeof(float[3]);
- mesh->vbooffset_normal3f = size;if (mesh->normal3f ) size += mesh->numverts * sizeof(float[3]);
- mesh->vbooffset_texcoord2f = size;if (mesh->texcoord2f ) size += mesh->numverts * sizeof(float[2]);
- mem = (unsigned char *)Mem_Alloc(tempmempool, size);
- if (mesh->vertexmesh ) memcpy(mem + mesh->vbooffset_vertexmesh , mesh->vertexmesh , mesh->numverts * sizeof(r_vertexmesh_t));
- if (mesh->vertex3f ) memcpy(mem + mesh->vbooffset_vertex3f , mesh->vertex3f , mesh->numverts * sizeof(float[3]));
- if (mesh->svector3f ) memcpy(mem + mesh->vbooffset_svector3f , mesh->svector3f , mesh->numverts * sizeof(float[3]));
- if (mesh->tvector3f ) memcpy(mem + mesh->vbooffset_tvector3f , mesh->tvector3f , mesh->numverts * sizeof(float[3]));
- if (mesh->normal3f ) memcpy(mem + mesh->vbooffset_normal3f , mesh->normal3f , mesh->numverts * sizeof(float[3]));
- if (mesh->texcoord2f ) memcpy(mem + mesh->vbooffset_texcoord2f , mesh->texcoord2f , mesh->numverts * sizeof(float[2]));
- mesh->vbo_vertexbuffer = R_Mesh_CreateMeshBuffer(mem, size, "shadowmesh", false, false, false, false);
- Mem_Free(mem);
+ mesh->vbooffset_vertex3f = 0;
+ mesh->vbo_vertexbuffer = R_Mesh_CreateMeshBuffer(mesh->vertex3f, mesh->numverts * sizeof(float[3]), "shadowmesh", false, false, false, false);
}
}
-shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh, qboolean light, qboolean createvbo)
+shadowmesh_t *Mod_ShadowMesh_Finish(shadowmesh_t *mesh, qboolean createvbo)
{
- shadowmesh_t *mesh, *newmesh, *nextmesh;
- // reallocate meshs to conserve space
- for (mesh = firstmesh, firstmesh = NULL;mesh;mesh = nextmesh)
+ if (mesh->numverts >= 3 && mesh->numtriangles >= 1)
{
- nextmesh = mesh->next;
- if (mesh->numverts >= 3 && mesh->numtriangles >= 1)
+ if (mesh->vertexhashentries)
+ Mem_Free(mesh->vertexhashentries);
+ mesh->vertexhashentries = NULL;
+ if (mesh->vertexhashtable)
+ Mem_Free(mesh->vertexhashtable);
+ mesh->vertexhashtable = NULL;
+ if (mesh->maxverts > mesh->numverts)
{
- newmesh = Mod_ShadowMesh_ReAlloc(mempool, mesh, light);
- newmesh->next = firstmesh;
- firstmesh = newmesh;
- if (newmesh->element3s)
- {
- int i;
- for (i = 0;i < newmesh->numtriangles*3;i++)
- newmesh->element3s[i] = newmesh->element3i[i];
- }
- if (createvbo)
- Mod_ShadowMesh_CreateVBOs(newmesh, mempool);
+ mesh->vertex3f = (float *)Mem_Realloc(mesh->mempool, mesh->vertex3f, mesh->numverts * sizeof(float[3]));
+ mesh->maxverts = mesh->numverts;
+ }
+ if (mesh->maxtriangles > mesh->numtriangles)
+ {
+ mesh->element3i = (int *)Mem_Realloc(mesh->mempool, mesh->element3i, mesh->numtriangles * sizeof(int[3]));
+ mesh->maxtriangles = mesh->numtriangles;
}
- Mem_Free(mesh);
+ if (mesh->numverts <= 65536)
+ {
+ int i;
+ mesh->element3s = (unsigned short *)Mem_Alloc(mesh->mempool, mesh->numtriangles * sizeof(unsigned short[3]));
+ for (i = 0;i < mesh->numtriangles*3;i++)
+ mesh->element3s[i] = mesh->element3i[i];
+ }
+ if (createvbo)
+ Mod_ShadowMesh_CreateVBOs(mesh);
}
// this can take a while, so let's do a keepalive here
CL_KeepaliveMessage(false);
- return firstmesh;
+ return mesh;
}
-void Mod_ShadowMesh_CalcBBox(shadowmesh_t *firstmesh, vec3_t mins, vec3_t maxs, vec3_t center, float *radius)
+void Mod_ShadowMesh_CalcBBox(shadowmesh_t *mesh, vec3_t mins, vec3_t maxs, vec3_t center, float *radius)
{
int i;
- shadowmesh_t *mesh;
vec3_t nmins, nmaxs, ncenter, temp;
float nradius2, dist2, *v;
VectorClear(nmins);
VectorClear(nmaxs);
// calculate bbox
- for (mesh = firstmesh;mesh;mesh = mesh->next)
+ VectorCopy(mesh->vertex3f, nmins);
+ VectorCopy(mesh->vertex3f, nmaxs);
+ for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3)
{
- if (mesh == firstmesh)
- {
- VectorCopy(mesh->vertex3f, nmins);
- VectorCopy(mesh->vertex3f, nmaxs);
- }
- for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3)
- {
- if (nmins[0] > v[0]) nmins[0] = v[0];if (nmaxs[0] < v[0]) nmaxs[0] = v[0];
- if (nmins[1] > v[1]) nmins[1] = v[1];if (nmaxs[1] < v[1]) nmaxs[1] = v[1];
- if (nmins[2] > v[2]) nmins[2] = v[2];if (nmaxs[2] < v[2]) nmaxs[2] = v[2];
- }
+ if (nmins[0] > v[0]) { nmins[0] = v[0]; } if (nmaxs[0] < v[0]) { nmaxs[0] = v[0]; }
+ if (nmins[1] > v[1]) { nmins[1] = v[1]; } if (nmaxs[1] < v[1]) { nmaxs[1] = v[1]; }
+ if (nmins[2] > v[2]) { nmins[2] = v[2]; } if (nmaxs[2] < v[2]) { nmaxs[2] = v[2]; }
}
// calculate center and radius
ncenter[0] = (nmins[0] + nmaxs[0]) * 0.5f;
ncenter[1] = (nmins[1] + nmaxs[1]) * 0.5f;
ncenter[2] = (nmins[2] + nmaxs[2]) * 0.5f;
nradius2 = 0;
- for (mesh = firstmesh;mesh;mesh = mesh->next)
+ for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3)
{
- for (i = 0, v = mesh->vertex3f;i < mesh->numverts;i++, v += 3)
- {
- VectorSubtract(v, ncenter, temp);
- dist2 = DotProduct(temp, temp);
- if (nradius2 < dist2)
- nradius2 = dist2;
- }
+ VectorSubtract(v, ncenter, temp);
+ dist2 = DotProduct(temp, temp);
+ if (nradius2 < dist2)
+ nradius2 = dist2;
}
// return data
if (mins)
void Mod_ShadowMesh_Free(shadowmesh_t *mesh)
{
- shadowmesh_t *nextmesh;
- for (;mesh;mesh = nextmesh)
- {
- if (mesh->element3i_indexbuffer)
- R_Mesh_DestroyMeshBuffer(mesh->element3i_indexbuffer);
- if (mesh->element3s_indexbuffer)
- R_Mesh_DestroyMeshBuffer(mesh->element3s_indexbuffer);
- if (mesh->vbo_vertexbuffer)
- R_Mesh_DestroyMeshBuffer(mesh->vbo_vertexbuffer);
- nextmesh = mesh->next;
- Mem_Free(mesh);
- }
+ if (mesh->element3i_indexbuffer)
+ R_Mesh_DestroyMeshBuffer(mesh->element3i_indexbuffer);
+ if (mesh->element3s_indexbuffer)
+ R_Mesh_DestroyMeshBuffer(mesh->element3s_indexbuffer);
+ if (mesh->vbo_vertexbuffer)
+ R_Mesh_DestroyMeshBuffer(mesh->vbo_vertexbuffer);
+ if (mesh->vertex3f)
+ Mem_Free(mesh->vertex3f);
+ if (mesh->element3i)
+ Mem_Free(mesh->element3i);
+ if (mesh->element3s)
+ Mem_Free(mesh->element3s);
+ if (mesh->vertexhashentries)
+ Mem_Free(mesh->vertexhashentries);
+ if (mesh->vertexhashtable)
+ Mem_Free(mesh->vertexhashtable);
+ Mem_Free(mesh);
}
void Mod_CreateCollisionMesh(dp_model_t *mod)
continue;
numcollisionmeshtriangles += surface->num_triangles;
}
- mod->brush.collisionmesh = Mod_ShadowMesh_Begin(mempool, numcollisionmeshtriangles * 3, numcollisionmeshtriangles, NULL, NULL, NULL, false, true);
+ mod->brush.collisionmesh = Mod_ShadowMesh_Begin(mempool, numcollisionmeshtriangles * 3, numcollisionmeshtriangles);
if (usesinglecollisionmesh)
- Mod_ShadowMesh_AddMesh(mempool, mod->brush.collisionmesh, NULL, NULL, NULL, mod->surfmesh.data_vertex3f, NULL, NULL, NULL, NULL, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
+ Mod_ShadowMesh_AddMesh(mod->brush.collisionmesh, mod->surfmesh.data_vertex3f, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
else
{
for (k = 0;k < mod->nummodelsurfaces;k++)
surface = mod->data_surfaces + mod->firstmodelsurface + k;
if (!(surface->texture->supercontents & SUPERCONTENTS_SOLID))
continue;
- Mod_ShadowMesh_AddMesh(mempool, mod->brush.collisionmesh, NULL, NULL, NULL, mod->surfmesh.data_vertex3f, NULL, NULL, NULL, NULL, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
+ Mod_ShadowMesh_AddMesh(mod->brush.collisionmesh, mod->surfmesh.data_vertex3f, surface->num_triangles, (mod->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
}
}
- mod->brush.collisionmesh = Mod_ShadowMesh_Finish(mempool, mod->brush.collisionmesh, false, false);
+ mod->brush.collisionmesh = Mod_ShadowMesh_Finish(mod->brush.collisionmesh, false);
}
#if 0
memcpy (&entry->shader, shader, sizeof (q3shaderinfo_t));
}
-extern cvar_t mod_noshader_default_offsetmapping;
-extern cvar_t mod_q3shader_default_offsetmapping;
-extern cvar_t mod_q3shader_default_offsetmapping_scale;
-extern cvar_t mod_q3shader_default_offsetmapping_bias;
-extern cvar_t mod_q3shader_default_polygonoffset;
-extern cvar_t mod_q3shader_default_polygonfactor;
-extern cvar_t mod_q3shader_force_addalpha;
-extern cvar_t mod_q3shader_force_terrain_alphaflag;
void Mod_LoadQ3Shaders(void)
{
int j;
// this sets dpshaderkill to true if dpshaderkillifcvarzero was used, and to false if dpnoshaderkillifcvarzero was used
else if (((dpshaderkill = !strcasecmp(parameter[0], "dpshaderkillifcvarzero")) || !strcasecmp(parameter[0], "dpnoshaderkillifcvarzero")) && numparameters >= 2)
{
- if (Cvar_VariableValue(parameter[1]) == 0.0f)
+ if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) == 0.0f)
shader.dpshaderkill = dpshaderkill;
}
// this sets dpshaderkill to true if dpshaderkillifcvar was used, and to false if dpnoshaderkillifcvar was used
op = parameter[2];
if(!op)
{
- if (Cvar_VariableValue(parameter[1]) != 0.0f)
+ if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) != 0.0f)
shader.dpshaderkill = dpshaderkill;
}
else if (numparameters >= 4 && !strcmp(op, "=="))
{
- if (Cvar_VariableValue(parameter[1]) == atof(parameter[3]))
+ if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) == atof(parameter[3]))
shader.dpshaderkill = dpshaderkill;
}
else if (numparameters >= 4 && !strcmp(op, "!="))
{
- if (Cvar_VariableValue(parameter[1]) != atof(parameter[3]))
+ if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) != atof(parameter[3]))
shader.dpshaderkill = dpshaderkill;
}
else if (numparameters >= 4 && !strcmp(op, ">"))
{
- if (Cvar_VariableValue(parameter[1]) > atof(parameter[3]))
+ if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) > atof(parameter[3]))
shader.dpshaderkill = dpshaderkill;
}
else if (numparameters >= 4 && !strcmp(op, "<"))
{
- if (Cvar_VariableValue(parameter[1]) < atof(parameter[3]))
+ if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) < atof(parameter[3]))
shader.dpshaderkill = dpshaderkill;
}
else if (numparameters >= 4 && !strcmp(op, ">="))
{
- if (Cvar_VariableValue(parameter[1]) >= atof(parameter[3]))
+ if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) >= atof(parameter[3]))
shader.dpshaderkill = dpshaderkill;
}
else if (numparameters >= 4 && !strcmp(op, "<="))
{
- if (Cvar_VariableValue(parameter[1]) <= atof(parameter[3]))
+ if (Cvar_VariableValue(&cvars_all, parameter[1], ~0) <= atof(parameter[3]))
shader.dpshaderkill = dpshaderkill;
}
else
firstpostlayer = rgbgenvertexlayer + 1;
// special case for rgbgen vertex if MATERIALFLAG_VERTEXCOLOR is expected on this material
if (defaultmaterialflags & MATERIALFLAG_VERTEXCOLOR)
- texture->basematerialflags |= MATERIALFLAG_VERTEXCOLOR;
+ texture->basematerialflags |= MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX;
}
else if (rgbgendiffuselayer >= 0)
{
texture->specularscalemod = shader->specularscalemod;
texture->specularpowermod = shader->specularpowermod;
texture->rtlightambient = shader->rtlightambient;
+ texture->refractive_index = mod_q3shader_default_refractive_index.value;
if (shader->dpreflectcube[0])
texture->reflectcubetexture = R_GetCubemap(shader->dpreflectcube);
void Mod_BuildVBOs(void)
{
+ if(cls.state == ca_dedicated)
+ return;
+
if (!loadmodel->surfmesh.num_vertices)
return;
}
}
- // build r_vertexmesh_t array
- // (compressed interleaved array for D3D)
- if (!loadmodel->surfmesh.data_vertexmesh && vid.useinterleavedarrays)
- {
- int vertexindex;
- int numvertices = loadmodel->surfmesh.num_vertices;
- r_vertexmesh_t *vertexmesh;
- loadmodel->surfmesh.data_vertexmesh = vertexmesh = (r_vertexmesh_t*)Mem_Alloc(loadmodel->mempool, numvertices * sizeof(r_vertexmesh_t));
- for (vertexindex = 0;vertexindex < numvertices;vertexindex++, vertexmesh++)
- {
- VectorCopy(loadmodel->surfmesh.data_vertex3f + 3*vertexindex, vertexmesh->vertex3f);
- VectorScale(loadmodel->surfmesh.data_svector3f + 3*vertexindex, 1.0f, vertexmesh->svector3f);
- VectorScale(loadmodel->surfmesh.data_tvector3f + 3*vertexindex, 1.0f, vertexmesh->tvector3f);
- VectorScale(loadmodel->surfmesh.data_normal3f + 3*vertexindex, 1.0f, vertexmesh->normal3f);
- if (loadmodel->surfmesh.data_lightmapcolor4f)
- Vector4Copy(loadmodel->surfmesh.data_lightmapcolor4f + 4*vertexindex, vertexmesh->color4f);
- Vector2Copy(loadmodel->surfmesh.data_texcoordtexture2f + 2*vertexindex, vertexmesh->texcoordtexture2f);
- if (loadmodel->surfmesh.data_texcoordlightmap2f)
- Vector2Scale(loadmodel->surfmesh.data_texcoordlightmap2f + 2*vertexindex, 1.0f, vertexmesh->texcoordlightmap2f);
- if (loadmodel->surfmesh.data_skeletalindex4ub)
- Vector4Copy(loadmodel->surfmesh.data_skeletalindex4ub + 4*vertexindex, vertexmesh->skeletalindex4ub);
- if (loadmodel->surfmesh.data_skeletalweight4ub)
- Vector4Copy(loadmodel->surfmesh.data_skeletalweight4ub + 4*vertexindex, vertexmesh->skeletalweight4ub);
- }
- }
-
// upload short indices as a buffer
if (loadmodel->surfmesh.data_element3s && !loadmodel->surfmesh.data_element3s_indexbuffer)
loadmodel->surfmesh.data_element3s_indexbuffer = R_Mesh_CreateMeshBuffer(loadmodel->surfmesh.data_element3s, loadmodel->surfmesh.num_triangles * sizeof(short[3]), loadmodel->name, true, false, false, true);
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 && !vid.useinterleavedarrays)
+ // 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_vertexmesh = size;if (loadmodel->surfmesh.data_vertexmesh ) size += loadmodel->surfmesh.num_vertices * sizeof(r_vertexmesh_t);
- 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_vertexmesh ) memcpy(mem + loadmodel->surfmesh.vbooffset_vertexmesh , loadmodel->surfmesh.data_vertexmesh , loadmodel->surfmesh.num_vertices * sizeof(r_vertexmesh_t));
- 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);
}
}
decompiles a model to editable files
================
*/
-static void Mod_Decompile_f(void)
+static void Mod_Decompile_f(cmd_state_t *cmd)
{
int i, j, k, l, first, count;
dp_model_t *mod;
int framegroupstextsize = 0;
char vabuf[1024];
- if (Cmd_Argc() != 2)
+ if (Cmd_Argc(cmd) != 2)
{
Con_Print("usage: modeldecompile <filename>\n");
return;
}
- strlcpy(inname, Cmd_Argv(1), sizeof(inname));
+ strlcpy(inname, Cmd_Argv(cmd, 1), sizeof(inname));
FS_StripExtension(inname, basename, sizeof(basename));
mod = Mod_ForName(inname, false, true, inname[0] == '*' ? cl.model_name[1] : NULL);
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;
loadmodel = oldloadmodel;
}
-static void Mod_GenerateLightmaps_f(void)
+static void Mod_GenerateLightmaps_f(cmd_state_t *cmd)
{
- if (Cmd_Argc() != 1)
+ if (Cmd_Argc(cmd) != 1)
{
Con_Printf("usage: mod_generatelightmaps\n");
return;
{
int i;
texture_t *t;
- for (i = 0; i < mod->num_textures; i++)
- if (!strcmp(mod->data_textures[i].name, name))
- return mod->data_textures + i;
+ int drawflag = defaultdrawflags & DRAWFLAG_MASK;
+ for (i = 0, t = mod->data_textures; i < mod->num_textures; i++, t++)
+ if (!strcmp(t->name, name) && t->drawflag == drawflag)
+ return t;
if (mod->max_textures <= mod->num_textures)
{
texture_t *oldtextures = mod->data_textures;
}
t = &mod->data_textures[mod->num_textures++];
Mod_LoadTextureFromQ3Shader(mod->mempool, mod->name, t, name, false, true, defaulttexflags, defaultmaterialflags);
+ t->drawflag = drawflag;
switch (defaultdrawflags & DRAWFLAG_MASK)
{
case DRAWFLAG_ADDITIVE:
}
}
+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);
}