extern LPDIRECT3DDEVICE9 vid_d3d9dev;
#endif
+#ifdef WIN32
+// Enable NVIDIA High Performance Graphics while using Integrated Graphics.
+#ifdef __cplusplus
+extern "C" {
+#endif
+__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
+#ifdef __cplusplus
+}
+#endif
+#endif
+
mempool_t *r_main_mempool;
rtexturepool_t *r_main_texturepool;
cvar_t r_glsl_postprocess_uservec4_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec4_enable", "1", "enables postprocessing uservec4 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
cvar_t r_water = {CVAR_SAVE, "r_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"};
+cvar_t r_water_cameraentitiesonly = {CVAR_SAVE, "r_water_cameraentitiesonly", "0", "whether to only show QC-defined reflections/refractions (typically used for camera- or portal-like effects)"};
cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
cvar_t r_water_resolutionmultiplier = {CVAR_SAVE, "r_water_resolutionmultiplier", "0.5", "multiplier for screen resolution when rendering refracted/reflected scenes, 1 is full quality, lower values are faster"};
cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
0
};
-char *glslshaderstring = NULL;
-char *hlslshaderstring = NULL;
-
//=======================================================================================================================================================
typedef struct shaderpermutationinfo_s
typedef struct shadermodeinfo_s
{
- const char *filename;
+ const char *sourcebasename;
+ const char *extension;
+ const char **builtinshaderstrings;
const char *pretext;
const char *name;
+ char *filename;
+ char *builtinstring;
+ int builtincrc;
}
shadermodeinfo_t;
};
// NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
-shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
-{
- {"glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
- {"glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
- {"glsl/default.glsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
- {"glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
- {"glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
- {"glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
- {"glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
- {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
- {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
- {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
- {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
- {"glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
- {"glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
- {"glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
- {"glsl/default.glsl", "#define MODE_WATER\n", " water"},
- {"glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
- {"glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
-};
-
-shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] =
-{
- {"hlsl/default.hlsl", "#define MODE_GENERIC\n", " generic"},
- {"hlsl/default.hlsl", "#define MODE_POSTPROCESS\n", " postprocess"},
- {"hlsl/default.hlsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
- {"hlsl/default.hlsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
- {"hlsl/default.hlsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
- {"hlsl/default.hlsl", "#define MODE_LIGHTMAP\n", " lightmap"},
- {"hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
- {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
- {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
- {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
- {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
- {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
- {"hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
- {"hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
- {"hlsl/default.hlsl", "#define MODE_WATER\n", " water"},
- {"hlsl/default.hlsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
- {"hlsl/default.hlsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
+shadermodeinfo_t shadermodeinfo[SHADERLANGUAGE_COUNT][SHADERMODE_COUNT] =
+{
+ // SHADERLANGUAGE_GLSL
+ {
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_GENERIC\n", " generic"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_POSTPROCESS\n", " postprocess"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_FLATCOLOR\n", " flatcolor"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTMAP\n", " lightmap"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_FAKELIGHT\n", " fakelight"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTSOURCE\n", " lightsource"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_REFRACTION\n", " refraction"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_WATER\n", " water"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
+ {"combined", "glsl", builtinshaderstrings, "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
+ },
+ // SHADERLANGUAGE_HLSL
+ {
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_GENERIC\n", " generic"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_POSTPROCESS\n", " postprocess"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_FLATCOLOR\n", " flatcolor"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTMAP\n", " lightmap"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_FAKELIGHT\n", " fakelight"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTSOURCE\n", " lightsource"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_REFRACTION\n", " refraction"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_WATER\n", " water"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
+ {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
+ },
};
struct r_glsl_permutation_s;
return string;
}
-static char *R_GetShaderText(const char *filename, qboolean printfromdisknotice, qboolean builtinonly)
+static char *R_ShaderStrCat(const char **strings);
+static void R_InitShaderModeInfo(void)
{
- char *shaderstring;
- if (!filename || !filename[0])
- return NULL;
- // LordHavoc: note that FS_LoadFile appends a 0 byte to make it a valid string, so does R_ShaderStrCat
- if (!strcmp(filename, "glsl/default.glsl"))
- {
- if (builtinonly)
- return R_ShaderStrCat(builtinshaderstrings);
- if (!glslshaderstring)
- {
- glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
- if (glslshaderstring)
- Con_DPrintf("Loading shaders from file %s...\n", filename);
- else
- glslshaderstring = R_ShaderStrCat(builtinshaderstrings);
- }
- shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1);
- memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1);
- return shaderstring;
- }
- if (!strcmp(filename, "hlsl/default.hlsl"))
+ int i, language;
+ shadermodeinfo_t *modeinfo;
+ // we have a bunch of things to compute that weren't calculated at engine compile time - all filenames should have a crc of the builtin strings to prevent accidental overrides (any customization must be updated to match engine)
+ for (language = 0; language < SHADERLANGUAGE_COUNT; language++)
{
- if (builtinonly)
- return R_ShaderStrCat(builtinhlslshaderstrings);
- if (!hlslshaderstring)
+ for (i = 0; i < SHADERMODE_COUNT; i++)
{
- hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
- if (hlslshaderstring)
- Con_DPrintf("Loading shaders from file %s...\n", filename);
- else
- hlslshaderstring = R_ShaderStrCat(builtinhlslshaderstrings);
+ char filename[MAX_QPATH];
+ modeinfo = &shadermodeinfo[language][i];
+ modeinfo->builtinstring = R_ShaderStrCat(modeinfo->builtinshaderstrings);
+ modeinfo->builtincrc = CRC_Block((const unsigned char *)modeinfo->builtinstring, strlen(modeinfo->builtinstring));
+ dpsnprintf(filename, sizeof(filename), "%s/%s_crc%i.%s", modeinfo->extension, modeinfo->sourcebasename, modeinfo->builtincrc, modeinfo->extension);
+ modeinfo->filename = Mem_strdup(r_main_mempool, filename);
}
- shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1);
- memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1);
- return shaderstring;
}
- // we don't have builtin strings for any other files
- if (builtinonly)
- return NULL;
- shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
+}
+
+static char *ShaderModeInfo_GetShaderText(shadermodeinfo_t *modeinfo, qboolean printfromdisknotice, qboolean builtinonly)
+{
+ char *shaderstring;
+ // if the mode has no filename we have to return the builtin string
+ if (builtinonly || !modeinfo->filename)
+ return Mem_strdup(r_main_mempool, modeinfo->builtinstring);
+ // note that FS_LoadFile appends a 0 byte to make it a valid string
+ shaderstring = (char *)FS_LoadFile(modeinfo->filename, r_main_mempool, false, NULL);
if (shaderstring)
{
if (printfromdisknotice)
- Con_DPrintf("from disk %s... ", filename);
+ Con_DPrintf("Loading shaders from file %s...\n", modeinfo->filename);
return shaderstring;
}
- return shaderstring;
+ // fall back to builtinstring
+ return Mem_strdup(r_main_mempool, modeinfo->builtinstring);
}
static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
int i;
int ubibind;
int sampler;
- shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode;
+ shadermodeinfo_t *modeinfo = &shadermodeinfo[SHADERLANGUAGE_GLSL][mode];
char *sourcestring;
char permutationname[256];
int vertstrings_count = 0;
p->program = 0;
permutationname[0] = 0;
- sourcestring = R_GetShaderText(modeinfo->filename, true, false);
+ sourcestring = ShaderModeInfo_GetShaderText(modeinfo, true, false);
strlcat(permutationname, modeinfo->filename, sizeof(permutationname));
static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, unsigned int permutation)
{
int i;
- shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
+ shadermodeinfo_t *modeinfo = &shadermodeinfo[SHADERLANGUAGE_HLSL][mode];
int vertstring_length = 0;
int geomstring_length = 0;
int fragstring_length = 0;
permutationname[0] = 0;
cachename[0] = 0;
- sourcestring = R_GetShaderText(modeinfo->filename, true, false);
+ sourcestring = ShaderModeInfo_GetShaderText(modeinfo, true, false);
strlcat(permutationname, modeinfo->filename, sizeof(permutationname));
strlcat(cachename, "hlsl/", sizeof(cachename));
void R_GLSL_Restart_f(void)
{
unsigned int i, limit;
- if (glslshaderstring)
- Mem_Free(glslshaderstring);
- glslshaderstring = NULL;
- if (hlslshaderstring)
- Mem_Free(hlslshaderstring);
- hlslshaderstring = NULL;
switch(vid.renderpath)
{
case RENDERPATH_D3D9:
shadermodeinfo_t *modeinfo;
qfile_t *file;
- for (language = 0;language < 2;language++)
+ for (language = 0;language < SHADERLANGUAGE_COUNT;language++)
{
- modeinfo = (language == 0 ? glslshadermodeinfo : hlslshadermodeinfo);
+ modeinfo = shadermodeinfo[language];
for (mode = 0;mode < SHADERMODE_COUNT;mode++)
{
// don't dump the same file multiple times (most or all shaders come from the same file)
break;
if (dupe >= 0)
continue;
- text = R_GetShaderText(modeinfo[mode].filename, false, true);
+ text = modeinfo[mode].builtinstring;
if (!text)
continue;
file = FS_OpenRealFile(modeinfo[mode].filename, "w", false);
}
else
Con_Printf("failed to write to %s\n", modeinfo[mode].filename);
- Mem_Free(text);
}
}
}
extern rtexture_t *r_shadow_attenuation3dtexture;
extern qboolean r_shadow_usingshadowmap2d;
extern qboolean r_shadow_usingshadowmaportho;
-extern float r_shadow_shadowmap_texturescale[2];
-extern float r_shadow_shadowmap_parameters[4];
+extern float r_shadow_modelshadowmap_texturescale[4];
+extern float r_shadow_modelshadowmap_parameters[4];
+extern float r_shadow_lightshadowmap_texturescale[4];
+extern float r_shadow_lightshadowmap_parameters[4];
extern qboolean r_shadow_shadowmapvsdct;
extern rtexture_t *r_shadow_shadowmap2ddepthbuffer;
extern rtexture_t *r_shadow_shadowmap2ddepthtexture;
extern rtexture_t *r_shadow_shadowmapvsdcttexture;
extern matrix4x4_t r_shadow_shadowmapmatrix;
-extern int r_shadow_shadowmaplod; // changes for each light based on distance
extern int r_shadow_prepass_width;
extern int r_shadow_prepass_height;
extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
- if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
+ if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld)
{
permutation |= SHADERPERMUTATION_BOUNCEGRID;
- if (r_shadow_bouncegriddirectional)
+ if (r_shadow_bouncegrid_state.directional)
permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
}
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
- if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
+ if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld)
{
permutation |= SHADERPERMUTATION_BOUNCEGRID;
- if (r_shadow_bouncegriddirectional)
+ if (r_shadow_bouncegrid_state.directional)
permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
}
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
// ordinary vertex coloring (q3bsp)
mode = SHADERMODE_VERTEXCOLOR;
}
- if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
+ if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld)
{
permutation |= SHADERPERMUTATION_BOUNCEGRID;
- if (r_shadow_bouncegriddirectional)
+ if (r_shadow_bouncegrid_state.directional)
permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
}
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
if (mode == SHADERMODE_WATER)
hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
}
- hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
- hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
+ {
+ hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_modelshadowmap_texturescale[0], r_shadow_modelshadowmap_texturescale[1], r_shadow_modelshadowmap_texturescale[2], r_shadow_modelshadowmap_texturescale[3]);
+ hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_modelshadowmap_parameters[0], r_shadow_modelshadowmap_parameters[1], r_shadow_modelshadowmap_parameters[2], r_shadow_modelshadowmap_parameters[3]);
+ }
+ else
+ {
+ hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]);
+ hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]);
+ }
hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
- if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
- if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
+ {
+ if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_modelshadowmap_texturescale[0], r_shadow_modelshadowmap_texturescale[1], r_shadow_modelshadowmap_texturescale[2], r_shadow_modelshadowmap_texturescale[3]);
+ if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_modelshadowmap_parameters[0], r_shadow_modelshadowmap_parameters[1], r_shadow_modelshadowmap_parameters[2], r_shadow_modelshadowmap_parameters[3]);
+ }
+ else
+ {
+ if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]);
+ if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]);
+ }
if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
- if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegridmatrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);}
- if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale);
+ if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegrid_state.matrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);}
+ if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegrid_state.intensity*r_refdef.view.colorscale);
if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_texture_white );
if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_texture_white );
if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
}
}
- if (r_glsl_permutation->tex_Texture_BounceGrid >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegridtexture);
+ if (r_glsl_permutation->tex_Texture_BounceGrid >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegrid_state.texture);
CHECKGLERROR
break;
case RENDERPATH_GL11:
{Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
{Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
{Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
- DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
- DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
+ {
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_modelshadowmap_texturescale[0], r_shadow_modelshadowmap_texturescale[1], r_shadow_modelshadowmap_texturescale[2], r_shadow_modelshadowmap_texturescale[3]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_modelshadowmap_parameters[0], r_shadow_modelshadowmap_parameters[1], r_shadow_modelshadowmap_parameters[2], r_shadow_modelshadowmap_parameters[3]);
+ }
+ else
+ {
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]);
+ }
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
GL_AlphaToCoverage(false);
Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
- Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
+ Matrix4x4_Invert_Full(&viewtolight, &lighttoview);
Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
switch(vid.renderpath)
{
hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
- hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
- hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]);
+ hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]);
hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
if (r_glsl_permutation->loc_DeferredColor_Ambient >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
if (r_glsl_permutation->loc_DeferredColor_Diffuse >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
if (r_glsl_permutation->loc_DeferredColor_Specular >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Specular , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
- if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f( r_glsl_permutation->loc_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
- if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_TextureScale , r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]);
+ if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]);
if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f( r_glsl_permutation->loc_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f( r_glsl_permutation->loc_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height);
DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Specular , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
- DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
- DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]);
+ DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_Parameters , r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]);
DPSOFTRAST_Uniform1f( DPSOFTRAST_UNIFORM_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, qboolean sRGB)
{
int i;
- unsigned char *temp1, *temp2;
skinframe_t *skinframe;
char vabuf[1024];
if (r_loadnormalmap && r_shadow_bumpscale_basetexture.value > 0)
{
- temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
- temp2 = temp1 + width * height * 4;
- Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
- skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
- Mem_Free(temp1);
+ unsigned char *a = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
+ unsigned char *b = a + width * height * 4;
+ Image_HeightmapToNormalmap_BGRA(skindata, b, width, height, false, r_shadow_bumpscale_basetexture.value);
+ skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, b, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
+ Mem_Free(a);
}
skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, sRGB ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags, -1, NULL);
if (textureflags & TEXF_ALPHA)
featuresmask |= palette_featureflags[skindata[i]];
skinframe->hasalpha = false;
+ // fence textures
+ if (name[0] == '{')
+ skinframe->hasalpha = true;
skinframe->qhascolormapping = loadpantsandshirt && (featuresmask & (PALETTEFEATURE_PANTS | PALETTEFEATURE_SHIRT));
skinframe->qgeneratenmap = r_shadow_bumpscale_basetexture.value > 0;
skinframe->qgeneratemerged = true;
if (skinframe->qgeneratenmap)
{
- unsigned char *temp1, *temp2;
+ unsigned char *a, *b;
skinframe->qgeneratenmap = false;
- temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
- temp2 = temp1 + width * height * 4;
+ a = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
+ b = a + width * height * 4;
// use either a custom palette or the quake palette
- Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete);
- Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
- skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
- Mem_Free(temp1);
+ Image_Copy8bitBGRA(skindata, a, width * height, palette_bgra_complete);
+ Image_HeightmapToNormalmap_BGRA(a, b, width, height, false, r_shadow_bumpscale_basetexture.value);
+ skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, b, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
+ Mem_Free(a);
}
if (skinframe->qgenerateglow)
{
skinframe->qgenerateglow = false;
- skinframe->glow = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow
+ if (skinframe->hasalpha) // fence textures
+ skinframe->glow = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags | TEXF_ALPHA, -1, palette_bgra_onlyfullbrights_transparent); // glow
+ else
+ skinframe->glow = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow
}
if (colormapped)
else
{
skinframe->qgeneratemerged = false;
- skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nofullbrights : palette_bgra_complete);
+ if (skinframe->hasalpha) // fence textures
+ skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags | TEXF_ALPHA, -1, skinframe->glow ? palette_bgra_nofullbrights_transparent : palette_bgra_transparent);
+ else
+ skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nofullbrights : palette_bgra_complete);
}
if (!skinframe->qgeneratemerged && !skinframe->qgeneratebase)
r_glsl_permutation = NULL;
memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
Mem_ExpandableArray_NewArray(&r_glsl_permutationarray, r_main_mempool, sizeof(r_glsl_permutation_t), 256);
- glslshaderstring = NULL;
#ifdef SUPPORTD3D
r_hlsl_permutation = NULL;
memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
Mem_ExpandableArray_NewArray(&r_hlsl_permutationarray, r_main_mempool, sizeof(r_hlsl_permutation_t), 256);
#endif
- hlslshaderstring = NULL;
memset(&r_svbsp, 0, sizeof (r_svbsp));
memset(r_texture_cubemaps, 0, sizeof(r_texture_cubemaps));
r_glsl_permutation = NULL;
memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
Mem_ExpandableArray_FreeArray(&r_glsl_permutationarray);
- glslshaderstring = NULL;
#ifdef SUPPORTD3D
r_hlsl_permutation = NULL;
memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
Mem_ExpandableArray_FreeArray(&r_hlsl_permutationarray);
#endif
- hlslshaderstring = NULL;
}
static void gl_main_newmap(void)
{
int i;
r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
+ R_InitShaderModeInfo();
Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed");
Cmd_AddCommand("r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl");
Cvar_RegisterVariable(&r_celoutlines);
Cvar_RegisterVariable(&r_water);
+ Cvar_RegisterVariable(&r_water_cameraentitiesonly);
Cvar_RegisterVariable(&r_water_resolutionmultiplier);
Cvar_RegisterVariable(&r_water_clippingplanebias);
Cvar_RegisterVariable(&r_water_refractdistort);
while (!r_framedata_mem || r_framedata_mem->current + size > r_framedata_mem->size)
{
// emergency - we ran out of space, allocate more memory
- newvalue = bound(0.25f, r_framedatasize.value * 2.0f, 256.0f);
+ // note: this has no upper-bound, we'll fail to allocate memory eventually and just die
+ newvalue = r_framedatasize.value * 2.0f;
+ // upper bound based on architecture - if we try to allocate more than this we could overflow, better to loop until we error out on allocation failure
+ if (sizeof(size_t) >= 8)
+ newvalue = bound(0.25f, newvalue, (float)(1ll << 42));
+ else
+ newvalue = bound(0.25f, newvalue, (float)(1 << 10));
// this might not be a growing it, but we'll allocate another buffer every time
Cvar_SetValueQuick(&r_framedatasize, newvalue);
R_FrameData_Resize(true);
Matrix4x4_ToVectors(&r_refdef.view.matrix, r_refdef.view.forward, r_refdef.view.left, r_refdef.view.up, r_refdef.view.origin);
VectorNegate(r_refdef.view.left, r_refdef.view.right);
// make an inverted copy of the view matrix for tracking sprites
- Matrix4x4_Invert_Simple(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix);
+ Matrix4x4_Invert_Full(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix);
}
void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture);
if(!(p->materialflags & MATERIALFLAG_CAMERA))
{
// merge this surface's PVS into the waterplane
- if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS
+ if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS
&& r_refdef.scene.worldmodel->brush.PointInLeaf && r_refdef.scene.worldmodel->brush.PointInLeaf(r_refdef.scene.worldmodel, center)->clusterindex >= 0)
{
r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, center, 2, p->pvsbits, sizeof(p->pvsbits), p->pvsvalid);
// make sure enough textures are allocated
for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++)
{
+ if (r_water_cameraentitiesonly.value != 0 && !p->camera_entity)
+ continue;
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
{
if (!p->texture_refraction)
r_fb.water.renderingscene = true;
for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++)
{
+ if (r_water_cameraentitiesonly.value != 0 && !p->camera_entity)
+ continue;
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
{
r_refdef.view = myview;
r_fb.bloomindex = 0;
R_Mesh_SetRenderTargets(r_fb.bloomfbo[r_fb.bloomindex], NULL, r_fb.bloomtexture[r_fb.bloomindex], NULL, NULL, NULL);
R_SetViewport(&r_fb.bloomviewport);
+ GL_CullFace(GL_NONE);
GL_DepthTest(false);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_Color(colorscale, colorscale, colorscale, 1);
static void R_DrawModelDecals(void);
extern cvar_t cl_decals_newsystem;
extern qboolean r_shadow_usingdeferredprepass;
+extern int r_shadow_shadowmapatlas_modelshadows_size;
void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
{
qboolean shadowmapping = false;
}
}
+ R_Shadow_PrepareModelShadows();
R_Shadow_PrepareLights(fbo, depthtexture, colortexture);
- if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0)
- R_Shadow_PrepareModelShadows();
if (r_timereport_active)
R_TimeReport("preparelights");
- if (R_Shadow_ShadowMappingEnabled())
- shadowmapping = true;
+ // render all the shadowmaps that will be used for this view
+ shadowmapping = R_Shadow_ShadowMappingEnabled();
+ if (shadowmapping || r_shadow_shadowmapatlas_modelshadows_size)
+ {
+ R_Shadow_DrawShadowMaps();
+ if (r_timereport_active)
+ R_TimeReport("shadowmaps");
+ }
+ // render prepass deferred lighting if r_shadow_deferred is on, this produces light buffers that will be sampled in forward pass
if (r_shadow_usingdeferredprepass)
R_Shadow_DrawPrepass();
+ // now we begin the forward pass of the view render
if (r_depthfirst.integer >= 1 && cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawDepth)
{
r_refdef.scene.worldmodel->DrawDepth(r_refdef.scene.worldentity);
R_TimeReport("modeldepth");
}
- if (r_shadows.integer >= 2 && shadowmapping && r_refdef.lightmapintensity > 0)
- {
- R_ResetViewRendering3D(fbo, depthtexture, colortexture);
- R_DrawModelShadowMaps(fbo, depthtexture, colortexture);
- R_ResetViewRendering3D(fbo, depthtexture, colortexture);
- // don't let sound skip if going slow
- if (r_refdef.scene.extraupdate)
- S_ExtraUpdate ();
- }
-
if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->Draw)
{
r_refdef.scene.worldmodel->Draw(r_refdef.scene.worldentity);
if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
{
R_ResetViewRendering3D(fbo, depthtexture, colortexture);
- R_DrawModelShadows(fbo, depthtexture, colortexture);
+ R_Shadow_DrawModelShadows();
R_ResetViewRendering3D(fbo, depthtexture, colortexture);
// don't let sound skip if going slow
if (r_refdef.scene.extraupdate)
if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
{
R_ResetViewRendering3D(fbo, depthtexture, colortexture);
- R_DrawModelShadows(fbo, depthtexture, colortexture);
+ R_Shadow_DrawModelShadows();
R_ResetViewRendering3D(fbo, depthtexture, colortexture);
// don't let sound skip if going slow
if (r_refdef.scene.extraupdate)
if (strcmp(r_qwskincache[i].name, cl.scores[i].qw_skin))
R_LoadQWSkin(&r_qwskincache[i], cl.scores[i].qw_skin);
t->currentskinframe = r_qwskincache[i].skinframe;
- if (t->currentskinframe == NULL)
- t->currentskinframe = t->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->skinframerate, t->numskinframes)];
+ if (t->materialshaderpass && t->currentskinframe == NULL)
+ t->currentskinframe = t->materialshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->materialshaderpass->framerate, t->materialshaderpass->numframes)];
}
- else if (t->numskinframes >= 2)
- t->currentskinframe = t->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->skinframerate, t->numskinframes)];
- if (t->backgroundnumskinframes >= 2)
- t->backgroundcurrentskinframe = t->backgroundskinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->backgroundskinframerate, t->backgroundnumskinframes)];
+ else if (t->materialshaderpass && t->materialshaderpass->numframes >= 2)
+ t->currentskinframe = t->materialshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->materialshaderpass->framerate, t->materialshaderpass->numframes)];
+ if (t->backgroundshaderpass && t->backgroundshaderpass->numframes >= 2)
+ t->backgroundcurrentskinframe = t->backgroundshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->backgroundshaderpass->framerate, t->backgroundshaderpass->numframes)];
t->currentmaterialflags = t->basematerialflags;
t->currentalpha = rsurface.colormod[3] * t->basealpha;
t->currentmaterialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
if (rsurface.ent_flags & (RENDER_NODEPTHTEST | RENDER_VIEWMODEL))
t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE;
- if (t->backgroundnumskinframes)
+ if (t->backgroundshaderpass)
t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
if (t->currentmaterialflags & MATERIALFLAG_BLENDED)
{
Matrix4x4_CreateIdentity(&t->currentbackgroundtexmatrix);
}
- for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
- R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags);
- for (i = 0, tcmod = t->backgroundtcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
- R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags);
+ if (t->materialshaderpass)
+ for (i = 0, tcmod = t->materialshaderpass->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
+ R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags);
t->colormapping = VectorLength2(rsurface.colormap_pantscolor) + VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f);
if (t->currentskinframe->qpixels)
t->glowtexture = t->currentskinframe->glow;
t->fogtexture = t->currentskinframe->fog;
t->reflectmasktexture = t->currentskinframe->reflect;
- if (t->backgroundnumskinframes)
+ if (t->backgroundshaderpass)
{
+ for (i = 0, tcmod = t->backgroundshaderpass->tcmods; i < Q3MAXTCMODS && tcmod->tcmod; i++, tcmod++)
+ R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags);
t->backgroundbasetexture = (!t->colormapping && t->backgroundcurrentskinframe->merged) ? t->backgroundcurrentskinframe->merged : t->backgroundcurrentskinframe->base;
t->backgroundnmaptexture = t->backgroundcurrentskinframe->nmap;
t->backgroundglosstexture = r_texture_black;
qboolean dynamicvertex;
float amplitude;
float animpos;
- float scale;
float center[3], forward[3], right[3], up[3], v[3], newforward[3], newright[3], newup[3];
float waveparms[4];
unsigned char *ub;
break;
}
}
- switch(rsurface.texture->tcgen.tcgen)
+ if (rsurface.texture->materialshaderpass)
{
- default:
- case Q3TCGEN_TEXTURE:
- break;
- case Q3TCGEN_LIGHTMAP:
- if (!dynamicvertex)
- {
- r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_lightmap] += 1;
- r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_lightmap] += batchnumsurfaces;
- r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_lightmap] += batchnumvertices;
- r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_lightmap] += batchnumtriangles;
- }
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_LIGHTMAP;
- needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP;
- break;
- case Q3TCGEN_VECTOR:
- if (!dynamicvertex)
+ switch (rsurface.texture->materialshaderpass->tcgen.tcgen)
{
- r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_vector] += 1;
- r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_vector] += batchnumsurfaces;
- r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_vector] += batchnumvertices;
- r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_vector] += batchnumtriangles;
- }
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_VERTEX;
- needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
- break;
- case Q3TCGEN_ENVIRONMENT:
- if (!dynamicvertex)
- {
- r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_environment] += 1;
- r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_environment] += batchnumsurfaces;
- r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_environment] += batchnumvertices;
- r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_environment] += batchnumtriangles;
+ default:
+ case Q3TCGEN_TEXTURE:
+ break;
+ case Q3TCGEN_LIGHTMAP:
+ if (!dynamicvertex)
+ {
+ r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_lightmap] += 1;
+ r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_lightmap] += batchnumsurfaces;
+ r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_lightmap] += batchnumvertices;
+ r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_lightmap] += batchnumtriangles;
+ }
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_LIGHTMAP;
+ needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP;
+ break;
+ case Q3TCGEN_VECTOR:
+ if (!dynamicvertex)
+ {
+ r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_vector] += 1;
+ r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_vector] += batchnumsurfaces;
+ r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_vector] += batchnumvertices;
+ r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_vector] += batchnumtriangles;
+ }
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_VERTEX;
+ needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
+ break;
+ case Q3TCGEN_ENVIRONMENT:
+ if (!dynamicvertex)
+ {
+ r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_environment] += 1;
+ r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_environment] += batchnumsurfaces;
+ r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_environment] += batchnumvertices;
+ r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_environment] += batchnumtriangles;
+ }
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL;
+ needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
+ break;
}
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL;
- needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
- break;
- }
- if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
- {
- if (!dynamicvertex)
+ if (rsurface.texture->materialshaderpass->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
{
- r_refdef.stats[r_stat_batch_dynamic_batches_because_tcmod_turbulent] += 1;
- r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcmod_turbulent] += batchnumsurfaces;
- r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcmod_turbulent] += batchnumvertices;
- r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcmod_turbulent] += batchnumtriangles;
+ if (!dynamicvertex)
+ {
+ r_refdef.stats[r_stat_batch_dynamic_batches_because_tcmod_turbulent] += 1;
+ r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcmod_turbulent] += batchnumsurfaces;
+ r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcmod_turbulent] += batchnumvertices;
+ r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcmod_turbulent] += batchnumtriangles;
+ }
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD;
+ needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
}
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD;
- needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
}
if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
// in place
for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform && r_deformvertexes.integer;deformindex++, deform++)
{
+ float scale;
switch (deform->deform)
{
default:
}
}
- if (rsurface.batchtexcoordtexture2f)
+ if (rsurface.batchtexcoordtexture2f && rsurface.texture->materialshaderpass)
{
// generate texcoords based on the chosen texcoord source
- switch(rsurface.texture->tcgen.tcgen)
+ switch(rsurface.texture->materialshaderpass->tcgen.tcgen)
{
default:
case Q3TCGEN_TEXTURE:
// rsurface.batchtexcoordtexture2f_bufferoffset = 0;
for (j = 0;j < batchnumvertices;j++)
{
- rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms);
- rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3);
+ rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->materialshaderpass->tcgen.parms);
+ rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->materialshaderpass->tcgen.parms + 3);
}
break;
case Q3TCGEN_ENVIRONMENT:
// and we only support that as the first one
// (handling a mixture of turbulent and other tcmods would be problematic
// without punting it entirely to a software path)
- if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
+ if (rsurface.texture->materialshaderpass->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
{
- amplitude = rsurface.texture->tcmods[0].parms[1];
- animpos = rsurface.texture->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->tcmods[0].parms[3];
+ amplitude = rsurface.texture->materialshaderpass->tcmods[0].parms[1];
+ animpos = rsurface.texture->materialshaderpass->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->materialshaderpass->tcmods[0].parms[3];
// rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
// rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
// rsurface.batchtexcoordtexture2f_bufferoffset = 0;
batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchnumvertices);
for (j = 0, vi = 0;j < rsurface.batchnumvertices;j++, vi++)
{
- unsigned char c = (vi << 3) * (1.0f / 256.0f);
+ unsigned char d = (vi << 3) * (1.0f / 256.0f);
VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
- Vector4Set(batchvertex[vi].color4f, c, c, c, 1);
+ Vector4Set(batchvertex[vi].color4f, d, d, d, 1);
}
R_Mesh_PrepareVertices_Generic_Unlock();
RSurf_DrawBatch();
batchvertex = R_Mesh_PrepareVertices_Generic_Lock(3*rsurface.batchnumtriangles);
for (j = 0, e = rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle;j < rsurface.batchnumtriangles;j++, e += 3)
{
- unsigned char c = ((j + rsurface.batchfirsttriangle) << 3) * (1.0f / 256.0f);
+ unsigned char d = ((j + rsurface.batchfirsttriangle) << 3) * (1.0f / 256.0f);
VectorCopy(rsurface.batchvertex3f + 3*e[0], batchvertex[j*3+0].vertex3f);
VectorCopy(rsurface.batchvertex3f + 3*e[1], batchvertex[j*3+1].vertex3f);
VectorCopy(rsurface.batchvertex3f + 3*e[2], batchvertex[j*3+2].vertex3f);
- Vector4Set(batchvertex[j*3+0].color4f, c, c, c, 1);
- Vector4Set(batchvertex[j*3+1].color4f, c, c, c, 1);
- Vector4Set(batchvertex[j*3+2].color4f, c, c, c, 1);
+ Vector4Set(batchvertex[j*3+0].color4f, d, d, d, 1);
+ Vector4Set(batchvertex[j*3+1].color4f, d, d, d, 1);
+ Vector4Set(batchvertex[j*3+2].color4f, d, d, d, 1);
}
R_Mesh_PrepareVertices_Generic_Unlock();
R_Mesh_Draw(0, rsurface.batchnumtriangles*3, 0, rsurface.batchnumtriangles, NULL, NULL, 0, NULL, NULL, 0);