#include "r_shadow.h"
#include "polygon.h"
+cvar_t r_enableshadowvolumes = {CVAR_SAVE, "r_enableshadowvolumes", "1", "Enables use of Stencil Shadow Volume shadowing methods, saves some memory if turned off"};
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"};
Mod_AliasInit();
Mod_SpriteInit();
+ Cvar_RegisterVariable(&r_enableshadowvolumes);
Cvar_RegisterVariable(&r_mipskins);
+ Cvar_RegisterVariable(&r_mipnormalmaps);
Cvar_RegisterVariable(&mod_generatelightmaps_unitspersample);
Cvar_RegisterVariable(&mod_generatelightmaps_borderpixels);
Cvar_RegisterVariable(&mod_generatelightmaps_texturesize);
used = mod->used;
if (mod->mempool)
{
- if (mod->surfmesh.vertexpositionbuffer)
- R_Mesh_DestroyMeshBuffer(mod->surfmesh.vertexpositionbuffer);
- mod->surfmesh.vertexpositionbuffer = NULL;
+ if (mod->surfmesh.vertex3fbuffer)
+ R_Mesh_DestroyMeshBuffer(mod->surfmesh.vertex3fbuffer);
+ mod->surfmesh.vertex3fbuffer = NULL;
if (mod->surfmesh.vertexmeshbuffer)
R_Mesh_DestroyMeshBuffer(mod->surfmesh.vertexmeshbuffer);
mod->surfmesh.vertexmeshbuffer = NULL;
return;
// build r_vertexmesh_t array
- // (compressed interleaved array for faster rendering)
- if (!mesh->vertexmesh && mesh->texcoord2f)
+ // (compressed interleaved array for D3D)
+ if (!mesh->vertexmesh && mesh->texcoord2f && vid.useinterleavedarrays)
{
int vertexindex;
int numvertices = mesh->numverts;
}
}
- // build r_vertexposition_t array
- if (!mesh->vertexposition)
- {
- int vertexindex;
- int numvertices = mesh->numverts;
- r_vertexposition_t *vertexposition;
- mesh->vertexposition = vertexposition = (r_vertexposition_t*)Mem_Alloc(loadmodel->mempool, numvertices * sizeof(*mesh->vertexposition));
- for (vertexindex = 0;vertexindex < numvertices;vertexindex++, vertexposition++)
- VectorCopy(mesh->vertex3f + 3*vertexindex, vertexposition->vertex3f);
- }
-
// upload r_vertexmesh_t array as a buffer
if (mesh->vertexmesh && !mesh->vertexmeshbuffer)
mesh->vertexmeshbuffer = R_Mesh_CreateMeshBuffer(mesh->vertexmesh, mesh->numverts * sizeof(*mesh->vertexmesh), loadmodel->name, false, false, false);
- // upload r_vertexposition_t array as a buffer
- if (mesh->vertexposition && !mesh->vertexpositionbuffer)
- mesh->vertexpositionbuffer = R_Mesh_CreateMeshBuffer(mesh->vertexposition, mesh->numverts * sizeof(*mesh->vertexposition), loadmodel->name, false, false, false);
+ // upload vertex3f array as a buffer
+ if (mesh->vertex3f && !mesh->vertex3fbuffer)
+ mesh->vertex3fbuffer = R_Mesh_CreateMeshBuffer(mesh->vertex3f, mesh->numverts * sizeof(float[3]), loadmodel->name, false, false, false);
// upload short indices as a buffer
if (mesh->element3s && !mesh->element3s_indexbuffer)
// 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)
+ if (!mesh->vbo_vertexbuffer && !vid.useinterleavedarrays)
{
size_t size;
unsigned char *mem;
shadowmesh_t *nextmesh;
for (;mesh;mesh = nextmesh)
{
- if (mesh->vertexpositionbuffer)
- R_Mesh_DestroyMeshBuffer(mesh->vertexpositionbuffer);
+ if (mesh->vertex3fbuffer)
+ R_Mesh_DestroyMeshBuffer(mesh->vertex3fbuffer);
if (mesh->vertexmeshbuffer)
R_Mesh_DestroyMeshBuffer(mesh->vertexmeshbuffer);
if (mesh->element3i_indexbuffer)
void Mod_CreateCollisionMesh(dp_model_t *mod)
{
- int k;
- int numcollisionmeshtriangles;
- const msurface_t *surface;
+ int k, numcollisionmeshtriangles;
+ qboolean usesinglecollisionmesh = false;
+ const msurface_t *surface = NULL;
+
mempool_t *mempool = mod->mempool;
if (!mempool && mod->brush.parentmodel)
mempool = mod->brush.parentmodel->mempool;
for (k = 0;k < mod->nummodelsurfaces;k++)
{
surface = mod->data_surfaces + mod->firstmodelsurface + k;
+ if (!strcmp(surface->texture->name, "collision")) // found collision mesh
+ {
+ usesinglecollisionmesh = true;
+ numcollisionmeshtriangles = surface->num_triangles;
+ break;
+ }
if (!(surface->texture->supercontents & SUPERCONTENTS_SOLID))
continue;
numcollisionmeshtriangles += surface->num_triangles;
}
mod->brush.collisionmesh = Mod_ShadowMesh_Begin(mempool, numcollisionmeshtriangles * 3, numcollisionmeshtriangles, NULL, NULL, NULL, false, false, true);
- for (k = 0;k < mod->nummodelsurfaces;k++)
- {
- surface = mod->data_surfaces + mod->firstmodelsurface + k;
- if (!(surface->texture->supercontents & SUPERCONTENTS_SOLID))
- continue;
+ 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));
+ 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->brush.collisionmesh = Mod_ShadowMesh_Finish(mempool, mod->brush.collisionmesh, false, true, false);
+ mod->brush.collisionmesh = Mod_ShadowMesh_Finish(mempool, mod->brush.collisionmesh, false, false, false);
}
void Mod_GetTerrainVertex3fTexCoord2fFromBGRA(const unsigned char *imagepixels, int imagewidth, int imageheight, int ix, int iy, float *vertex3f, float *texcoord2f, matrix4x4_t *pixelstepmatrix, matrix4x4_t *pixeltexturestepmatrix)
{
if (strcasecmp (entry->shader.name, shader->name) == 0)
{
- unsigned char *start, *end, *start2;
- start = (unsigned char *) (&shader->Q3SHADERINFO_COMPARE_START);
- end = ((unsigned char *) (&shader->Q3SHADERINFO_COMPARE_END)) + sizeof(shader->Q3SHADERINFO_COMPARE_END);
- start2 = (unsigned char *) (&entry->shader.Q3SHADERINFO_COMPARE_START);
- if(memcmp(start, start2, end - start))
- Con_DPrintf("Shader '%s' already defined, ignoring mismatching redeclaration\n", shader->name);
+ // redeclaration
+ if(shader->dpshaderkill)
+ {
+ // killed shader is a redeclarion? we can safely ignore it
+ return;
+ }
+ else if(entry->shader.dpshaderkill)
+ {
+ // replace the old shader!
+ // this will skip the entry allocating part
+ // below and just replace the shader
+ break;
+ }
else
- Con_DPrintf("Shader '%s' already defined\n", shader->name);
- return;
+ {
+ unsigned char *start, *end, *start2;
+ start = (unsigned char *) (&shader->Q3SHADERINFO_COMPARE_START);
+ end = ((unsigned char *) (&shader->Q3SHADERINFO_COMPARE_END)) + sizeof(shader->Q3SHADERINFO_COMPARE_END);
+ start2 = (unsigned char *) (&entry->shader.Q3SHADERINFO_COMPARE_START);
+ if(memcmp(start, start2, end - start))
+ Con_DPrintf("Shader '%s' already defined, ignoring mismatching redeclaration\n", shader->name);
+ else
+ Con_DPrintf("Shader '%s' already defined\n", shader->name);
+ return;
+ }
}
lastEntry = entry;
entry = entry->chain;
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;
void Mod_LoadQ3Shaders(void)
{
int j;
char *custsurfaceparmnames[256]; // VorteX: q3map2 has 64 but well, someone will need more
unsigned long custsurfaceparms[256];
int numcustsurfaceparms;
+ qboolean dpshaderkill;
Mod_FreeQ3Shaders();
Vector4Set(shader.reflectcolor4f, 1, 1, 1, 1);
shader.r_water_wateralpha = 1;
shader.offsetmapping = (mod_q3shader_default_offsetmapping.value) ? OFFSETMAPPING_DEFAULT : OFFSETMAPPING_OFF;
- shader.offsetscale = 1;
+ shader.offsetscale = mod_q3shader_default_offsetmapping_scale.value;
+ shader.offsetbias = mod_q3shader_default_offsetmapping_bias.value;
shader.specularscalemod = 1;
shader.specularpowermod = 1;
+ shader.biaspolygonoffset = mod_q3shader_default_polygonoffset.value;
+ shader.biaspolygonfactor = mod_q3shader_default_polygonfactor.value;
strlcpy(shader.name, com_token, sizeof(shader.name));
if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{"))
layer->blendfunc[0] = GL_ONE;
layer->blendfunc[1] = GL_ONE;
}
+ else if (!strcasecmp(parameter[1], "addalpha"))
+ {
+ layer->blendfunc[0] = GL_SRC_ALPHA;
+ layer->blendfunc[1] = GL_ONE;
+ }
else if (!strcasecmp(parameter[1], "filter"))
{
layer->blendfunc[0] = GL_DST_COLOR;
else if (!strcasecmp(parameter[k+1], "GL_DST_COLOR"))
layer->blendfunc[k] = GL_DST_COLOR;
else if (!strcasecmp(parameter[k+1], "GL_DST_ALPHA"))
- layer->blendfunc[k] = GL_ONE_MINUS_DST_ALPHA;
+ layer->blendfunc[k] = GL_DST_ALPHA;
else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_SRC_COLOR"))
layer->blendfunc[k] = GL_ONE_MINUS_SRC_COLOR;
else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_SRC_ALPHA"))
shader.textureblendalpha = true;
}
}
- layer->texflags = TEXF_ALPHA;
+
+ if(mod_q3shader_force_addalpha.integer)
+ {
+ // for a long while, DP treated GL_ONE GL_ONE as GL_SRC_ALPHA GL_ONE
+ // this cvar brings back this behaviour
+ if(layer->blendfunc[0] == GL_ONE && layer->blendfunc[1] == GL_ONE)
+ layer->blendfunc[0] = GL_SRC_ALPHA;
+ }
+
+ layer->texflags = 0;
+ if (layer->alphatest)
+ layer->texflags |= TEXF_ALPHA;
+ switch(layer->blendfunc[0])
+ {
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ layer->texflags |= TEXF_ALPHA;
+ break;
+ }
+ switch(layer->blendfunc[1])
+ {
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ layer->texflags |= TEXF_ALPHA;
+ break;
+ }
if (!(shader.surfaceparms & Q3SURFACEPARM_NOMIPMAPS))
layer->texflags |= TEXF_MIPMAP;
if (!(shader.textureflags & Q3TEXTUREFLAG_NOPICMIP))
shader.dpshadow = true;
else if (!strcasecmp(parameter[0], "dpnoshadow"))
shader.dpnoshadow = true;
+ else if (!strcasecmp(parameter[0], "dpnortlight"))
+ shader.dpnortlight = true;
else if (!strcasecmp(parameter[0], "dpreflectcube"))
strlcpy(shader.dpreflectcube, parameter[1], sizeof(shader.dpreflectcube));
else if (!strcasecmp(parameter[0], "dpmeshcollisions"))
shader.dpmeshcollisions = true;
+ // 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)
+ shader.dpshaderkill = dpshaderkill;
+ }
+ // this sets dpshaderkill to true if dpshaderkillifcvar was used, and to false if dpnoshaderkillifcvar was used
+ else if (((dpshaderkill = !strcasecmp(parameter[0], "dpshaderkillifcvar")) || !strcasecmp(parameter[0], "dpnoshaderkillifcvar")) && numparameters >= 2)
+ {
+ const char *op = NULL;
+ if (numparameters >= 3)
+ op = parameter[2];
+ if(!op)
+ {
+ if (Cvar_VariableValue(parameter[1]) != 0.0f)
+ shader.dpshaderkill = dpshaderkill;
+ }
+ else if (numparameters >= 4 && !strcmp(op, "=="))
+ {
+ if (Cvar_VariableValue(parameter[1]) == atof(parameter[3]))
+ shader.dpshaderkill = dpshaderkill;
+ }
+ else if (numparameters >= 4 && !strcmp(op, "!="))
+ {
+ if (Cvar_VariableValue(parameter[1]) != atof(parameter[3]))
+ shader.dpshaderkill = dpshaderkill;
+ }
+ else if (numparameters >= 4 && !strcmp(op, ">"))
+ {
+ if (Cvar_VariableValue(parameter[1]) > atof(parameter[3]))
+ shader.dpshaderkill = dpshaderkill;
+ }
+ else if (numparameters >= 4 && !strcmp(op, "<"))
+ {
+ if (Cvar_VariableValue(parameter[1]) < atof(parameter[3]))
+ shader.dpshaderkill = dpshaderkill;
+ }
+ else if (numparameters >= 4 && !strcmp(op, ">="))
+ {
+ if (Cvar_VariableValue(parameter[1]) >= atof(parameter[3]))
+ shader.dpshaderkill = dpshaderkill;
+ }
+ else if (numparameters >= 4 && !strcmp(op, "<="))
+ {
+ if (Cvar_VariableValue(parameter[1]) <= atof(parameter[3]))
+ shader.dpshaderkill = dpshaderkill;
+ }
+ else
+ {
+ Con_DPrintf("%s parsing warning: unknown dpshaderkillifcvar op \"%s\", or not enough arguments\n", search->filenames[fileindex], op);
+ }
+ }
else if (!strcasecmp(parameter[0], "sky") && numparameters >= 2)
{
// some q3 skies don't have the sky parm set
shader.textureflags |= Q3TEXTUREFLAG_NOPICMIP;
else if (!strcasecmp(parameter[0], "polygonoffset"))
shader.textureflags |= Q3TEXTUREFLAG_POLYGONOFFSET;
+ else if (!strcasecmp(parameter[0], "dppolygonoffset"))
+ {
+ shader.textureflags |= Q3TEXTUREFLAG_POLYGONOFFSET;
+ if(numparameters >= 2)
+ {
+ shader.biaspolygonfactor = atof(parameter[1]);
+ if(numparameters >= 3)
+ shader.biaspolygonoffset = atof(parameter[2]);
+ else
+ shader.biaspolygonoffset = 0;
+ }
+ }
else if (!strcasecmp(parameter[0], "dprefract") && numparameters >= 5)
{
shader.textureflags |= Q3TEXTUREFLAG_REFRACTION;
Vector4Set(shader.reflectcolor4f, atof(parameter[8]), atof(parameter[9]), atof(parameter[10]), 1);
shader.r_water_wateralpha = atof(parameter[11]);
}
+ else if (!strcasecmp(parameter[0], "dpwaterscroll") && numparameters >= 3)
+ {
+ shader.r_water_waterscroll[0] = 1/atof(parameter[1]);
+ shader.r_water_waterscroll[1] = 1/atof(parameter[2]);
+ }
else if (!strcasecmp(parameter[0], "dpglossintensitymod") && numparameters >= 2)
{
shader.specularscalemod = atof(parameter[1]);
{
shader.specularpowermod = atof(parameter[1]);
}
- else if (!strcasecmp(parameter[0], "dpoffsetmapping") && numparameters >= 3)
+ else if (!strcasecmp(parameter[0], "dprtlightambient") && numparameters >= 2)
+ {
+ shader.rtlightambient = atof(parameter[1]);
+ }
+ else if (!strcasecmp(parameter[0], "dpoffsetmapping") && numparameters >= 2)
{
if (!strcasecmp(parameter[1], "disable") || !strcasecmp(parameter[1], "none") || !strcasecmp(parameter[1], "off"))
shader.offsetmapping = OFFSETMAPPING_OFF;
- else if (!strcasecmp(parameter[1], "default"))
+ else if (!strcasecmp(parameter[1], "default") || !strcasecmp(parameter[1], "normal"))
shader.offsetmapping = OFFSETMAPPING_DEFAULT;
else if (!strcasecmp(parameter[1], "linear"))
shader.offsetmapping = OFFSETMAPPING_LINEAR;
else if (!strcasecmp(parameter[1], "relief"))
shader.offsetmapping = OFFSETMAPPING_RELIEF;
- shader.offsetscale = atof(parameter[2]);
+ if (numparameters >= 3)
+ shader.offsetscale = atof(parameter[2]);
+ if (numparameters >= 5)
+ {
+ if(!strcasecmp(parameter[3], "bias"))
+ shader.offsetbias = atof(parameter[4]);
+ else if(!strcasecmp(parameter[3], "match"))
+ shader.offsetbias = 1.0f - atof(parameter[4]);
+ else if(!strcasecmp(parameter[3], "match8"))
+ shader.offsetbias = 1.0f - atof(parameter[4]) / 255.0f;
+ else if(!strcasecmp(parameter[3], "match16"))
+ shader.offsetbias = 1.0f - atof(parameter[4]) / 65535.0f;
+ }
}
else if (!strcasecmp(parameter[0], "deformvertexes") && numparameters >= 2)
{
}
}
}
+ // hide this shader if a cvar said it should be killed
+ if (shader.dpshaderkill)
+ shader.numlayers = 0;
// pick the primary layer to render with
if (shader.numlayers)
{
qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qboolean warnmissing, qboolean fallback, int defaulttexflags)
{
int j;
- int texflagsmask;
+ int texflagsmask, texflagsor;
qboolean success = true;
q3shaderinfo_t *shader;
if (!name)
texflagsmask &= ~TEXF_PICMIP;
if(!(defaulttexflags & TEXF_COMPRESS))
texflagsmask &= ~TEXF_COMPRESS;
+ texflagsor = 0;
+ if(defaulttexflags & TEXF_ISWORLD)
+ texflagsor |= TEXF_ISWORLD;
+ if(defaulttexflags & TEXF_ISSPRITE)
+ texflagsor |= TEXF_ISSPRITE;
// unless later loaded from the shader
- texture->offsetmapping = (mod_q3shader_default_offsetmapping.value) ? OFFSETMAPPING_DEFAULT : OFFSETMAPPING_OFF;
+ texture->offsetmapping = (mod_noshader_default_offsetmapping.value) ? OFFSETMAPPING_DEFAULT : OFFSETMAPPING_OFF;
texture->offsetscale = 1;
+ texture->offsetbias = 0;
texture->specularscalemod = 1;
texture->specularpowermod = 1;
+ texture->rtlightambient = 0;
// WHEN ADDING DEFAULTS HERE, REMEMBER TO SYNC TO SHADER LOADING ABOVE
// HERE, AND Q1BSP LOADING
// JUST GREP FOR "specularscalemod = 1".
texture->surfaceparms = shader->surfaceparms;
// allow disabling of picmip or compression by defaulttexflags
- texture->textureflags = shader->textureflags & texflagsmask;
+ texture->textureflags = (shader->textureflags & texflagsmask) | texflagsor;
if (shader->surfaceparms & Q3SURFACEPARM_SKY)
{
if (shader->textureflags & Q3TEXTUREFLAG_TWOSIDED)
texture->basematerialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
if (shader->textureflags & Q3TEXTUREFLAG_POLYGONOFFSET)
- texture->biaspolygonoffset -= 2;
+ {
+ texture->biaspolygonoffset += shader->biaspolygonoffset;
+ texture->biaspolygonfactor += shader->biaspolygonfactor;
+ }
if (shader->textureflags & Q3TEXTUREFLAG_REFRACTION)
texture->basematerialflags |= MATERIALFLAG_REFRACTION;
if (shader->textureflags & Q3TEXTUREFLAG_REFLECTION)
{
texture->skinframes[j] = NULL;
}
- else if (!(texture->skinframes[j] = R_SkinFrame_LoadExternal(primarylayer->texturename[j], primarylayer->texflags & texflagsmask, false)))
+ else if (!(texture->skinframes[j] = R_SkinFrame_LoadExternal(primarylayer->texturename[j], (primarylayer->texflags & texflagsmask) | texflagsor, false)))
{
Con_Printf("^1%s:^7 could not load texture ^3\"%s\"^7 (frame %i) for shader ^2\"%s\"\n", loadmodel->name, primarylayer->texturename[j], j, texture->name);
texture->skinframes[j] = R_SkinFrame_LoadMissing();
{
texture->skinframes[j] = NULL;
}
- else if (!(texture->backgroundskinframes[j] = R_SkinFrame_LoadExternal(backgroundlayer->texturename[j], backgroundlayer->texflags & texflagsmask, false)))
+ else if (!(texture->backgroundskinframes[j] = R_SkinFrame_LoadExternal(backgroundlayer->texturename[j], (backgroundlayer->texflags & texflagsmask) | texflagsor, false)))
{
Con_Printf("^1%s:^7 could not load texture ^3\"%s\"^7 (background frame %i) for shader ^2\"%s\"\n", loadmodel->name, backgroundlayer->texturename[j], j, texture->name);
texture->backgroundskinframes[j] = R_SkinFrame_LoadMissing();
texture->basematerialflags &= ~MATERIALFLAG_NOSHADOW;
if (shader->dpnoshadow)
texture->basematerialflags |= MATERIALFLAG_NOSHADOW;
+ if (shader->dpnortlight)
+ texture->basematerialflags |= MATERIALFLAG_NORTLIGHT;
memcpy(texture->deforms, shader->deforms, sizeof(texture->deforms));
texture->reflectmin = shader->reflectmin;
texture->reflectmax = shader->reflectmax;
texture->reflectfactor = shader->reflectfactor;
Vector4Copy(shader->reflectcolor4f, texture->reflectcolor4f);
texture->r_water_wateralpha = shader->r_water_wateralpha;
+ Vector2Copy(shader->r_water_waterscroll, texture->r_water_waterscroll);
texture->offsetmapping = shader->offsetmapping;
texture->offsetscale = shader->offsetscale;
+ texture->offsetbias = shader->offsetbias;
texture->specularscalemod = shader->specularscalemod;
texture->specularpowermod = shader->specularpowermod;
+ texture->rtlightambient = shader->rtlightambient;
if (shader->dpreflectcube[0])
texture->reflectcubetexture = R_GetCubemap(shader->dpreflectcube);
if (shader->dpmeshcollisions)
texture->basematerialflags |= MATERIALFLAG_MESHCOLLISIONS;
+ if (shader->dpshaderkill && developer_extra.integer)
+ Con_DPrintf("^1%s:^7 killing shader ^3\"%s\" because of cvar\n", loadmodel->name, name);
}
else if (!strcmp(texture->name, "noshader") || !texture->name[0])
{
if(cls.state == ca_dedicated)
{
texture->skinframes[0] = NULL;
+ success = false;
}
else
{
}
// build r_vertexmesh_t array
- // (compressed interleaved array for faster rendering)
- if (!loadmodel->surfmesh.vertexmesh)
+ // (compressed interleaved array for D3D)
+ if (!loadmodel->surfmesh.vertexmesh && vid.useinterleavedarrays)
{
int vertexindex;
int numvertices = loadmodel->surfmesh.num_vertices;
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)
- Vector4Scale(loadmodel->surfmesh.data_lightmapcolor4f + 4*vertexindex, 255.0f, vertexmesh->color4ub);
+ 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);
}
}
- // build r_vertexposition_t array
- if (!loadmodel->surfmesh.vertexposition)
- {
- int vertexindex;
- int numvertices = loadmodel->surfmesh.num_vertices;
- r_vertexposition_t *vertexposition;
- loadmodel->surfmesh.vertexposition = vertexposition = (r_vertexposition_t*)Mem_Alloc(loadmodel->mempool, numvertices * sizeof(*loadmodel->surfmesh.vertexposition));
- for (vertexindex = 0;vertexindex < numvertices;vertexindex++, vertexposition++)
- VectorCopy(loadmodel->surfmesh.data_vertex3f + 3*vertexindex, vertexposition->vertex3f);
- }
-
// upload r_vertexmesh_t array as a buffer
if (loadmodel->surfmesh.vertexmesh && !loadmodel->surfmesh.vertexmeshbuffer)
loadmodel->surfmesh.vertexmeshbuffer = R_Mesh_CreateMeshBuffer(loadmodel->surfmesh.vertexmesh, loadmodel->surfmesh.num_vertices * sizeof(*loadmodel->surfmesh.vertexmesh), loadmodel->name, false, false, false);
- // upload r_vertexposition_t array as a buffer
- if (loadmodel->surfmesh.vertexposition && !loadmodel->surfmesh.vertexpositionbuffer)
- loadmodel->surfmesh.vertexpositionbuffer = R_Mesh_CreateMeshBuffer(loadmodel->surfmesh.vertexposition, loadmodel->surfmesh.num_vertices * sizeof(*loadmodel->surfmesh.vertexposition), loadmodel->name, false, false, false);
+ // upload vertex3f array as a buffer
+ if (loadmodel->surfmesh.data_vertex3f && !loadmodel->surfmesh.vertex3fbuffer)
+ loadmodel->surfmesh.vertex3fbuffer = R_Mesh_CreateMeshBuffer(loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.num_vertices * sizeof(float[3]), loadmodel->name, false, false, false);
// upload short indices as a buffer
if (loadmodel->surfmesh.data_element3s && !loadmodel->surfmesh.data_element3s_indexbuffer)
// 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)
+ if (!loadmodel->surfmesh.vbo_vertexbuffer && !vid.useinterleavedarrays)
{
size_t size;
unsigned char *mem;
continue;
lightiradius = 1.0f / lightradius;
dist = sqrt(dist2) * lightiradius;
- intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
- if (intensity <= 0)
+ intensity = (1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist);
+ if (intensity <= 0.0f)
continue;
if (model && model->TraceLine)
{
if (model->surfmesh.num_vertices > 65536)
model->surfmesh.data_element3s = NULL;
- if (model->surfmesh.vertexposition)
- Mem_Free(model->surfmesh.vertexposition);
- model->surfmesh.vertexposition = NULL;
if (model->surfmesh.vertexmesh)
Mem_Free(model->surfmesh.vertexmesh);
model->surfmesh.vertexmesh = NULL;
- if (model->surfmesh.vertexpositionbuffer)
- R_Mesh_DestroyMeshBuffer(model->surfmesh.vertexpositionbuffer);
- model->surfmesh.vertexpositionbuffer = NULL;
+ if (model->surfmesh.vertex3fbuffer)
+ R_Mesh_DestroyMeshBuffer(model->surfmesh.vertex3fbuffer);
+ model->surfmesh.vertex3fbuffer = NULL;
if (model->surfmesh.vertexmeshbuffer)
R_Mesh_DestroyMeshBuffer(model->surfmesh.vertexmeshbuffer);
model->surfmesh.vertexmeshbuffer = NULL;