// r_main.c
#include "quakedef.h"
-#include "cl_dyntexture.h"
#include "r_shadow.h"
#include "polygon.h"
#include "image.h"
cvar_t r_usedepthtextures = {CVAR_SAVE, "r_usedepthtextures", "1", "use depth texture instead of depth renderbuffer where possible, uses less video memory but may render slower (or faster) depending on hardware"};
cvar_t r_viewfbo = {CVAR_SAVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode"};
+cvar_t r_rendertarget_debug = {0, "r_rendertarget_debug", "-1", "replaces the view with the contents of the specified render target (by number - note that these can fluctuate depending on scene)"};
cvar_t r_viewscale = {CVAR_SAVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"};
cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"};
cvar_t r_viewscale_fpsscaling_min = {CVAR_SAVE, "r_viewscale_fpsscaling_min", "0.0625", "worst acceptable quality"};
cvar_t r_water_scissormode = {0, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
cvar_t r_water_lowquality = {0, "r_water_lowquality", "0", "special option to accelerate water rendering, 1 disables shadows and particles, 2 disables all dynamic lights"};
cvar_t r_water_hideplayer = {CVAR_SAVE, "r_water_hideplayer", "0", "if set to 1 then player will be hidden in refraction views, if set to 2 then player will also be hidden in reflection views, player is always visible in camera views"};
-cvar_t r_water_fbo = {CVAR_SAVE, "r_water_fbo", "1", "enables use of render to texture for water effects, otherwise copy to texture is used (slower)"};
cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
{CVAR_SAVE, "r_buffermegs_uniform", "0.25", "uniform buffer size for one frame"},
};
-extern cvar_t v_glslgamma;
extern cvar_t v_glslgamma_2d;
extern qboolean v_flipped_state;
/// vertex coordinates for a quad that covers the screen exactly
extern const float r_screenvertex3f[12];
-extern const float r_d3dscreenvertex3f[12];
const float r_screenvertex3f[12] =
{
0, 0, 0,
1, 1, 0,
0, 1, 0
};
-const float r_d3dscreenvertex3f[12] =
-{
- 0, 1, 0,
- 1, 1, 0,
- 1, 0, 0,
- 0, 0, 0
-};
void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
{
permutation |= SHADERPERMUTATION_GLOW;
else if (texturemode == GL_DECAL)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
+ if (usegamma && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
permutation |= SHADERPERMUTATION_GAMMARAMPS;
if (suppresstexalpha)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
R_Mesh_TexBind(GL20TU_FIRST , first );
R_Mesh_TexBind(GL20TU_SECOND, second);
if (permutation & SHADERPERMUTATION_GAMMARAMPS)
- R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
+ R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps);
#endif
break;
case RENDERPATH_D3D10:
}
}
-extern qboolean r_shadow_usingdeferredprepass;
-extern rtexture_t *r_shadow_attenuationgradienttexture;
-extern rtexture_t *r_shadow_attenuation2dtexture;
-extern rtexture_t *r_shadow_attenuation3dtexture;
-extern qboolean r_shadow_usingshadowmap2d;
-extern qboolean r_shadow_usingshadowmaportho;
-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_prepass_width;
-extern int r_shadow_prepass_height;
-extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
-extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
-extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
-extern rtexture_t *r_shadow_prepasslightingspeculartexture;
-
#define BLENDFUNC_ALLOWS_COLORMOD 1
#define BLENDFUNC_ALLOWS_FOG 2
#define BLENDFUNC_ALLOWS_FOG_HACK0 4
return r;
}
-void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy)
+void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdiffuse[3], const float rtlightspecular[3], rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy)
{
// select a permutation of the lighting shader appropriate to this
// combination of texture, entity, light source, and fogging, only use the
dpuint64 permutation = 0;
unsigned int mode = 0;
int blendfuncflags;
- static float dummy_colormod[3] = {1, 1, 1};
- float *colormod = rsurface.colormod;
+ texture_t *t = rsurface.texture;
float m16f[16];
matrix4x4_t tempmatrix;
r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
if (r_trippy.integer && !notrippy)
permutation |= SHADERPERMUTATION_TRIPPY;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
+ if (t->currentmaterialflags & MATERIALFLAG_ALPHATEST)
permutation |= SHADERPERMUTATION_ALPHAKILL;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_OCCLUDE)
+ if (t->currentmaterialflags & MATERIALFLAG_OCCLUDE)
permutation |= SHADERPERMUTATION_OCCLUDE;
- if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
+ if (t->r_water_waterscroll[0] && t->r_water_waterscroll[1])
permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
if (rsurfacepass == RSURFPASS_BACKGROUND)
{
// distorted background
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
+ if (t->currentmaterialflags & MATERIALFLAG_WATERSHADER)
{
mode = SHADERMODE_WATER;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+ if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
- if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
+ if((r_wateralpha.value < 1) && (t->currentmaterialflags & MATERIALFLAG_WATERALPHA))
{
// this is the right thing to do for wateralpha
GL_BlendFunc(GL_ONE, GL_ZERO);
blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
- else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
+ else if (t->currentmaterialflags & MATERIALFLAG_REFRACTION)
{
mode = SHADERMODE_REFRACTION;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+ if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
{
- if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f))
{
- switch(rsurface.texture->offsetmapping)
+ switch(t->offsetmapping)
{
case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
case OFFSETMAPPING_OFF: break;
}
}
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
// normalmap (deferred prepass), may use alpha test on diffuse
mode = SHADERMODE_DEFERREDGEOMETRY;
}
else if (rsurfacepass == RSURFPASS_RTLIGHT)
{
- if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f))
{
- switch(rsurface.texture->offsetmapping)
+ switch(t->offsetmapping)
{
case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
case OFFSETMAPPING_OFF: break;
}
}
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+ if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
// light source
mode = SHADERMODE_LIGHTSOURCE;
if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
permutation |= SHADERPERMUTATION_CUBEFILTER;
- if (diffusescale > 0)
+ if (VectorLength2(rtlightdiffuse) > 0)
permutation |= SHADERPERMUTATION_DIFFUSE;
- if (specularscale > 0)
+ if (VectorLength2(rtlightspecular) > 0)
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
if (r_refdef.fogenabled)
permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
- if (rsurface.texture->colormapping)
+ if (t->colormapping)
permutation |= SHADERPERMUTATION_COLORMAPPING;
if (r_shadow_usingshadowmap2d)
{
if (r_shadow_shadowmap2ddepthbuffer)
permutation |= SHADERPERMUTATION_DEPTHRGB;
}
- if (rsurface.texture->reflectmasktexture)
+ if (t->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
if (vid.allowalphatocoverage)
GL_AlphaToCoverage(false);
}
- else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
- {
- if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
- {
- switch(rsurface.texture->offsetmapping)
- {
- case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
- case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
- case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
- case OFFSETMAPPING_OFF: break;
- }
- }
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
- permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
- permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
- // unshaded geometry (fullbright or ambient model lighting)
- mode = SHADERMODE_FLATCOLOR;
- ambientscale = diffusescale = specularscale = 0;
- if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
- permutation |= SHADERPERMUTATION_GLOW;
- if (r_refdef.fogenabled)
- permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
- if (rsurface.texture->colormapping)
- permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
- {
- permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
- permutation |= SHADERPERMUTATION_SHADOWMAP2D;
-
- if (r_shadow_shadowmap2ddepthbuffer)
- permutation |= SHADERPERMUTATION_DEPTHRGB;
- }
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
- permutation |= SHADERPERMUTATION_REFLECTION;
- if (rsurface.texture->reflectmasktexture)
- permutation |= SHADERPERMUTATION_REFLECTCUBE;
- GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- // when using alphatocoverage, we don't need alphakill
- if (vid.allowalphatocoverage)
- {
- if (r_transparent_alphatocoverage.integer)
- {
- GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
- permutation &= ~SHADERPERMUTATION_ALPHAKILL;
- }
- else
- GL_AlphaToCoverage(false);
- }
- }
- else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
+ else if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
{
- if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f))
{
- switch(rsurface.texture->offsetmapping)
+ switch(t->offsetmapping)
{
case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
case OFFSETMAPPING_OFF: break;
}
}
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+ if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
// directional model lighting
mode = SHADERMODE_LIGHTDIRECTION;
- if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
+ if ((t->glowtexture || t->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
permutation |= SHADERPERMUTATION_GLOW;
- permutation |= SHADERPERMUTATION_DIFFUSE;
- if (specularscale > 0)
+ if (VectorLength2(t->render_modellight_diffuse))
+ permutation |= SHADERPERMUTATION_DIFFUSE;
+ if (VectorLength2(t->render_modellight_specular) > 0)
permutation |= SHADERPERMUTATION_SPECULAR;
if (r_refdef.fogenabled)
permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
- if (rsurface.texture->colormapping)
- permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
- {
- permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
- permutation |= SHADERPERMUTATION_SHADOWMAP2D;
-
- if (r_shadow_shadowmap2ddepthbuffer)
- permutation |= SHADERPERMUTATION_DEPTHRGB;
- }
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
- permutation |= SHADERPERMUTATION_REFLECTION;
- if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
- permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
- if (rsurface.texture->reflectmasktexture)
- permutation |= SHADERPERMUTATION_REFLECTCUBE;
- if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld)
- {
- permutation |= SHADERPERMUTATION_BOUNCEGRID;
- if (r_shadow_bouncegrid_state.directional)
- permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
- }
- GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- // when using alphatocoverage, we don't need alphakill
- if (vid.allowalphatocoverage)
- {
- if (r_transparent_alphatocoverage.integer)
- {
- GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
- permutation &= ~SHADERPERMUTATION_ALPHAKILL;
- }
- else
- GL_AlphaToCoverage(false);
- }
- }
- else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
- {
- if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
- {
- switch(rsurface.texture->offsetmapping)
- {
- case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
- case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
- case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
- case OFFSETMAPPING_OFF: break;
- }
- }
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
- permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
- permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
- // ambient model lighting
- mode = SHADERMODE_LIGHTDIRECTION;
- if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
- permutation |= SHADERPERMUTATION_GLOW;
- if (r_refdef.fogenabled)
- permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
- if (rsurface.texture->colormapping)
+ if (t->colormapping)
permutation |= SHADERPERMUTATION_COLORMAPPING;
if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
if (r_shadow_shadowmap2ddepthbuffer)
permutation |= SHADERPERMUTATION_DEPTHRGB;
}
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
+ if (t->currentmaterialflags & MATERIALFLAG_REFLECTION)
permutation |= SHADERPERMUTATION_REFLECTION;
- if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
+ if (r_shadow_usingdeferredprepass && !(t->currentmaterialflags & MATERIALFLAG_BLENDED))
permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
- if (rsurface.texture->reflectmasktexture)
+ if (t->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld)
{
if (r_shadow_bouncegrid_state.directional)
permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
}
- GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ GL_BlendFunc(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2);
// when using alphatocoverage, we don't need alphakill
if (vid.allowalphatocoverage)
{
if (r_transparent_alphatocoverage.integer)
{
- GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ GL_AlphaToCoverage((t->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
permutation &= ~SHADERPERMUTATION_ALPHAKILL;
}
else
}
else
{
- if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
+ if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f))
{
- switch(rsurface.texture->offsetmapping)
+ switch(t->offsetmapping)
{
case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
case OFFSETMAPPING_OFF: break;
}
}
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
+ if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
+ if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
// lightmapped wall
- if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
+ if ((t->glowtexture || t->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
permutation |= SHADERPERMUTATION_GLOW;
if (r_refdef.fogenabled)
permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
- if (rsurface.texture->colormapping)
+ if (t->colormapping)
permutation |= SHADERPERMUTATION_COLORMAPPING;
if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
if (r_shadow_shadowmap2ddepthbuffer)
permutation |= SHADERPERMUTATION_DEPTHRGB;
}
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
+ if (t->currentmaterialflags & MATERIALFLAG_REFLECTION)
permutation |= SHADERPERMUTATION_REFLECTION;
- if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
+ if (r_shadow_usingdeferredprepass && !(t->currentmaterialflags & MATERIALFLAG_BLENDED))
permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
- if (rsurface.texture->reflectmasktexture)
+ if (t->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
if (FAKELIGHT_ENABLED)
{
// fake lightmapping (q1bsp, q3bsp, fullbright map)
mode = SHADERMODE_FAKELIGHT;
permutation |= SHADERPERMUTATION_DIFFUSE;
- if (specularscale > 0)
+ if (VectorLength2(t->render_lightmap_specular) > 0)
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
}
else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
else
mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
permutation |= SHADERPERMUTATION_DIFFUSE;
- if (specularscale > 0)
+ if (VectorLength2(t->render_lightmap_specular) > 0)
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
}
else if (r_glsl_deluxemapping.integer >= 2)
else
mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR;
permutation |= SHADERPERMUTATION_DIFFUSE;
- if (specularscale > 0)
+ if (VectorLength2(t->render_lightmap_specular) > 0)
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
}
else if (rsurface.uselightmaptexture)
if (r_shadow_bouncegrid_state.directional)
permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
}
- GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
- blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ GL_BlendFunc(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2);
// when using alphatocoverage, we don't need alphakill
if (vid.allowalphatocoverage)
{
if (r_transparent_alphatocoverage.integer)
{
- GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ GL_AlphaToCoverage((t->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
permutation &= ~SHADERPERMUTATION_ALPHAKILL;
}
else
GL_AlphaToCoverage(false);
}
}
- if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
- colormod = dummy_colormod;
if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
{
if (mode == SHADERMODE_LIGHTDIRECTION)
{
- hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ hlslVSSetParameter3f(D3DVSREGISTER_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]);
}
}
- Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
- Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
+ Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
+ Matrix4x4_ToArrayFloatGL(&t->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
if (mode == SHADERMODE_LIGHTSOURCE)
{
hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
- hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
+ hlslPSSetParameter3f(D3DPSREGISTER_LightColor, 1, 1, 1); // DEPRECATED
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]);
// additive passes are only darkened by fog, not tinted
hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
- hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
}
else
{
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]);
if (mode == SHADERMODE_FLATCOLOR)
{
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]);
}
else if (mode == SHADERMODE_LIGHTDIRECTION)
{
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]);
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
- hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
- hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
- hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
- hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_LightColor, 1, 1, 1); // DEPRECATED
+ hlslPSSetParameter3f(D3DPSREGISTER_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]);
}
else
{
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
- hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
- hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]);
}
// additive passes are only darkened by fog, not tinted
if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
else
hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
- hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
+ hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor);
hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
- hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
- hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
- hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
- hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
- hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha);
+ hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha);
+ hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, t->reflectmax - t->reflectmin);
+ hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, t->reflectmin);
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (t->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
if (mode == SHADERMODE_WATER)
- hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
+ hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]);
}
if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
{
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_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]);
+ hlslPSSetParameter1f(D3DPSREGISTER_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1));
hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
- if (rsurface.texture->pantstexture)
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
+ if (t->pantstexture)
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]);
else
hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
- if (rsurface.texture->shirttexture)
- hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
+ if (t->shirttexture)
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]);
else
hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps,
- r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
+ r_glsl_offsetmapping_scale.value*t->offsetscale,
max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
);
hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
- hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
+ hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, t->offsetbias);
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);
- R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
- R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
- R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
- R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
- if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
- if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
- if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
- if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
- if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
- if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
- if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
- if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
+ R_Mesh_TexBind(GL20TU_NORMAL , t->nmaptexture );
+ R_Mesh_TexBind(GL20TU_COLOR , t->basetexture );
+ R_Mesh_TexBind(GL20TU_GLOSS , t->glosstexture );
+ R_Mesh_TexBind(GL20TU_GLOW , t->glowtexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , t->backgroundnmaptexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , t->backgroundbasetexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , t->backgroundglosstexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , t->backgroundglowtexture );
+ if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , t->pantstexture );
+ if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , t->shirttexture );
+ if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , t->reflectmasktexture );
+ if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube);
if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
if (rsurfacepass == RSURFPASS_BACKGROUND)
{
- R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
- if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
- R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->rt_refraction ? waterplane->rt_refraction->colortexture[0] : r_texture_black);
+ if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->rt_camera ? waterplane->rt_camera->colortexture[0] : r_texture_black);
+ R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->rt_reflection ? waterplane->rt_reflection->colortexture[0] : r_texture_black);
}
else
{
- if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->rt_reflection ? waterplane->rt_reflection->colortexture[0] : r_texture_black);
}
// if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
{
if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
- if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
- if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
- if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
- if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
+ if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, 1, 1, 1); // DEPRECATED
+ if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]);
+ if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]);
+ if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]);
// additive passes are only darkened by fog, not tinted
if (r_glsl_permutation->loc_FogColor >= 0)
qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
}
else
{
if (mode == SHADERMODE_FLATCOLOR)
{
- if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
+ if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]);
}
else if (mode == SHADERMODE_LIGHTDIRECTION)
{
- if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
- if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
- if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
- if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
- if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
- if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
- if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]);
+ if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]);
+ if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]);
+ if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]);
+ if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]);
+ if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, 1, 1, 1); // DEPRECATED
+ if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]);
}
else
{
- if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
- if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
- if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
- if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
- if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
+ if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]);
+ if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]);
+ if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]);
+ if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]);
+ if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]);
}
// additive passes are only darkened by fog, not tinted
if (r_glsl_permutation->loc_FogColor >= 0)
else
qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
}
- if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
+ if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor);
if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
- if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
- if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
- if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
- if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
- if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
- }
- 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_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha);
+ if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha);
+ if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, t->reflectmax - t->reflectmin);
+ if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, t->reflectmin);
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
+ if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]);
+ }
+ if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
+ if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&t->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 (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
{
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_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]);
+ if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1));
if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
if (r_glsl_permutation->loc_Color_Pants >= 0)
{
- if (rsurface.texture->pantstexture)
- qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
+ if (t->pantstexture)
+ qglUniform3f(r_glsl_permutation->loc_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]);
else
qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
}
if (r_glsl_permutation->loc_Color_Shirt >= 0)
{
- if (rsurface.texture->shirttexture)
- qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
+ if (t->shirttexture)
+ qglUniform3f(r_glsl_permutation->loc_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]);
else
qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
}
if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps,
- r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
+ r_glsl_offsetmapping_scale.value*t->offsetscale,
max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
);
if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
- if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
+ if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, t->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_bouncegrid_state.matrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);}
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_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps , r_texture_gammaramps );
- if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , rsurface.texture->nmaptexture );
- if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , rsurface.texture->basetexture );
- if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , rsurface.texture->glosstexture );
- if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , rsurface.texture->glowtexture );
- if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , rsurface.texture->backgroundnmaptexture );
- if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture );
- if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture );
- if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );
- if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , rsurface.texture->pantstexture );
- if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , rsurface.texture->shirttexture );
- if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , rsurface.texture->reflectmasktexture );
- if (r_glsl_permutation->tex_Texture_ReflectCube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
+ if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , t->nmaptexture );
+ if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , t->basetexture );
+ if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , t->glosstexture );
+ if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , t->glowtexture );
+ if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , t->backgroundnmaptexture );
+ if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , t->backgroundbasetexture );
+ if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , t->backgroundglosstexture );
+ if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , t->backgroundglowtexture );
+ if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , t->pantstexture );
+ if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , t->shirttexture );
+ if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , t->reflectmasktexture );
+ if (r_glsl_permutation->tex_Texture_ReflectCube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube);
if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture );
if (r_glsl_permutation->tex_Texture_FogMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask , r_texture_fogattenuation );
if (r_glsl_permutation->tex_Texture_Lightmap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
if (rsurfacepass == RSURFPASS_BACKGROUND)
{
- if (r_glsl_permutation->tex_Texture_Refraction >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Refraction , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
- if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
- if (r_glsl_permutation->tex_Texture_Reflection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ if (r_glsl_permutation->tex_Texture_Refraction >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Refraction , waterplane->rt_refraction ? waterplane->rt_refraction->colortexture[0] : r_texture_black);
+ if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , waterplane->rt_camera ? waterplane->rt_camera->colortexture[0] : r_texture_black);
+ if (r_glsl_permutation->tex_Texture_Reflection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->rt_reflection ? waterplane->rt_reflection->colortexture[0] : r_texture_black);
}
else
{
- if (r_glsl_permutation->tex_Texture_Reflection >= 0 && waterplane) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ if (r_glsl_permutation->tex_Texture_Reflection >= 0 && waterplane) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->rt_reflection ? waterplane->rt_reflection->colortexture[0] : r_texture_black);
}
if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
if (r_glsl_permutation->tex_Texture_ScreenDiffuse >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );
{
{Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);}
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, 1, 1, 1); // DEPRECATED
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]);
// additive passes are only darkened by fog, not tinted
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
- DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
}
else
{
if (mode == SHADERMODE_FLATCOLOR)
{
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]);
}
else if (mode == SHADERMODE_LIGHTDIRECTION)
{
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, 1, 1, 1); // DEPRECATED
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]);
}
else
{
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]);
}
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]);
// additive passes are only darkened by fog, not tinted
if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
else
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
- DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor);
DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
- DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
- DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
- DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
- DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
- DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
- DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
- }
- {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);}
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, t->reflectmax - t->reflectmin);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, t->reflectmin);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
+ DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]);
+ }
+ {Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
+ {Matrix4x4_ToArrayFloatGL(&t->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
{Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
{
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));
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1));
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
if (DPSOFTRAST_UNIFORM_Color_Pants >= 0)
{
- if (rsurface.texture->pantstexture)
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
+ if (t->pantstexture)
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]);
else
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0);
}
if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0)
{
- if (rsurface.texture->shirttexture)
- DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
+ if (t->shirttexture)
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]);
else
DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0);
}
DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip);
DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade);
DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps,
- r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
+ r_glsl_offsetmapping_scale.value*t->offsetscale,
max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
);
DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
- DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, rsurface.texture->offsetbias);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, t->offsetbias);
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);
- R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
- R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
- R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
- R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
- if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
- if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
- if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
- if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
- if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
- if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
- if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
- if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
+ R_Mesh_TexBind(GL20TU_NORMAL , t->nmaptexture );
+ R_Mesh_TexBind(GL20TU_COLOR , t->basetexture );
+ R_Mesh_TexBind(GL20TU_GLOSS , t->glosstexture );
+ R_Mesh_TexBind(GL20TU_GLOW , t->glowtexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , t->backgroundnmaptexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , t->backgroundbasetexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , t->backgroundglosstexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , t->backgroundglowtexture );
+ if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , t->pantstexture );
+ if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , t->shirttexture );
+ if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , t->reflectmasktexture );
+ if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube);
if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
if (rsurfacepass == RSURFPASS_BACKGROUND)
{
- R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
- if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
- R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->rt_refraction ? waterplane->rt_refraction->colortexture[0] : r_texture_black);
+ if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->rt_camera ? waterplane->rt_camera->colortexture[0] : r_texture_black);
+ R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->rt_reflection ? waterplane->rt_reflection->colortexture[0] : r_texture_black);
}
else
{
- if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->rt_reflection ? waterplane->rt_reflection->colortexture[0] : r_texture_black);
}
// if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
skinframe->loadsequence = r_skinframe.loadsequence;
}
+void R_SkinFrame_PurgeSkinFrame(skinframe_t *s)
+{
+ if (s->merged == s->base)
+ s->merged = NULL;
+ R_PurgeTexture(s->stain); s->stain = NULL;
+ R_PurgeTexture(s->merged); s->merged = NULL;
+ R_PurgeTexture(s->base); s->base = NULL;
+ R_PurgeTexture(s->pants); s->pants = NULL;
+ R_PurgeTexture(s->shirt); s->shirt = NULL;
+ R_PurgeTexture(s->nmap); s->nmap = NULL;
+ R_PurgeTexture(s->gloss); s->gloss = NULL;
+ R_PurgeTexture(s->glow); s->glow = NULL;
+ R_PurgeTexture(s->fog); s->fog = NULL;
+ R_PurgeTexture(s->reflect); s->reflect = NULL;
+ s->loadsequence = 0;
+}
+
void R_SkinFrame_Purge(void)
{
int i;
for (s = r_skinframe.hash[i];s;s = s->next)
{
if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
- {
- if (s->merged == s->base)
- s->merged = NULL;
- // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
- R_PurgeTexture(s->stain );s->stain = NULL;
- R_PurgeTexture(s->merged);s->merged = NULL;
- R_PurgeTexture(s->base );s->base = NULL;
- R_PurgeTexture(s->pants );s->pants = NULL;
- R_PurgeTexture(s->shirt );s->shirt = NULL;
- R_PurgeTexture(s->nmap );s->nmap = NULL;
- R_PurgeTexture(s->gloss );s->gloss = NULL;
- R_PurgeTexture(s->glow );s->glow = NULL;
- R_PurgeTexture(s->fog );s->fog = NULL;
- R_PurgeTexture(s->reflect);s->reflect = NULL;
- s->loadsequence = 0;
- }
+ R_SkinFrame_PurgeSkinFrame(s);
}
}
}
if (!strcmp(item->basename, basename) && (comparecrc < 0 || (item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)))
break;
- if (!item) {
- rtexture_t *dyntexture;
- // check whether its a dynamic texture
- dyntexture = CL_GetDynTexture( basename );
- if (!add && !dyntexture)
+ if (!item)
+ {
+ if (!add)
return NULL;
item = (skinframe_t *)Mem_ExpandableArray_AllocRecord(&r_skinframe.array);
memset(item, 0, sizeof(*item));
strlcpy(item->basename, basename, sizeof(item->basename));
- item->base = dyntexture; // either NULL or dyntexture handle
item->textureflags = textureflags & ~TEXF_FORCE_RELOAD;
item->comparewidth = comparewidth;
item->compareheight = compareheight;
}
else if (textureflags & TEXF_FORCE_RELOAD)
{
- rtexture_t *dyntexture;
- // check whether its a dynamic texture
- dyntexture = CL_GetDynTexture( basename );
- if (!add && !dyntexture)
+ if (!add)
return NULL;
- if (item->merged == item->base)
- item->merged = NULL;
- // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
- R_PurgeTexture(item->stain );item->stain = NULL;
- R_PurgeTexture(item->merged);item->merged = NULL;
- R_PurgeTexture(item->base );item->base = NULL;
- R_PurgeTexture(item->pants );item->pants = NULL;
- R_PurgeTexture(item->shirt );item->shirt = NULL;
- R_PurgeTexture(item->nmap );item->nmap = NULL;
- R_PurgeTexture(item->gloss );item->gloss = NULL;
- R_PurgeTexture(item->glow );item->glow = NULL;
- R_PurgeTexture(item->fog );item->fog = NULL;
- R_PurgeTexture(item->reflect);item->reflect = NULL;
- item->loadsequence = 0;
- }
- else if( item->base == NULL )
- {
- rtexture_t *dyntexture;
- // check whether its a dynamic texture
- // this only needs to be done because Purge doesnt delete skinframes - only sets the texture pointers to NULL and we need to restore it before returing.. [11/29/2007 Black]
- dyntexture = CL_GetDynTexture( basename );
- item->base = dyntexture; // either NULL or dyntexture handle
+ R_SkinFrame_PurgeSkinFrame(item);
}
R_SkinFrame_MarkUsed(item);
}
extern cvar_t gl_picmip;
-skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain)
+skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain, qboolean fallbacknotexture)
{
int j;
unsigned char *pixels;
if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s.dds", basename), vid.sRGB3D, textureflags, &ddshasalpha, ddsavgcolor, miplevel, false)))
{
basepixels = loadimagepixelsbgra(name, complain, true, false, &miplevel);
+ if (basepixels == NULL && fallbacknotexture)
+ basepixels = Image_GenerateNoTexture();
if (basepixels == NULL)
return NULL;
}
Con_Printf("loading embedded 8bit image \"%s\"\n", name);
skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, palette);
- if (textureflags & TEXF_ALPHA)
+ if ((textureflags & TEXF_ALPHA) && alphapalette)
{
for (i = 0;i < width * height;i++)
{
return skinframe;
}
+skinframe_t *R_SkinFrame_LoadNoTexture(void)
+{
+ int x, y;
+ static unsigned char pix[16][16][4];
+
+ if (cls.state == ca_dedicated)
+ return NULL;
+
+ // this makes a light grey/dark grey checkerboard texture
+ if (!pix[0][0][3])
+ {
+ for (y = 0; y < 16; y++)
+ {
+ for (x = 0; x < 16; x++)
+ {
+ if ((y < 8) ^ (x < 8))
+ {
+ pix[y][x][0] = 128;
+ pix[y][x][1] = 128;
+ pix[y][x][2] = 128;
+ pix[y][x][3] = 255;
+ }
+ else
+ {
+ pix[y][x][0] = 64;
+ pix[y][x][1] = 64;
+ pix[y][x][2] = 64;
+ pix[y][x][3] = 255;
+ }
+ }
+ }
+ }
+
+ return R_SkinFrame_LoadInternalBGRA("notexture", TEXF_FORCENEAREST, pix[0][0], 16, 16, false);
+}
+
+skinframe_t *R_SkinFrame_LoadInternalUsingTexture(const char *name, int textureflags, rtexture_t *tex, int width, int height, qboolean sRGB)
+{
+ skinframe_t *skinframe;
+ if (cls.state == ca_dedicated)
+ return NULL;
+ // if already loaded just return it, otherwise make a new skinframe
+ skinframe = R_SkinFrame_Find(name, textureflags, width, height, (textureflags & TEXF_FORCE_RELOAD) ? -1 : 0, true);
+ if (skinframe->base)
+ return skinframe;
+ textureflags &= ~TEXF_FORCE_RELOAD;
+ skinframe->stain = NULL;
+ skinframe->merged = NULL;
+ skinframe->base = NULL;
+ skinframe->pants = NULL;
+ skinframe->shirt = NULL;
+ skinframe->nmap = NULL;
+ skinframe->gloss = NULL;
+ skinframe->glow = NULL;
+ skinframe->fog = NULL;
+ skinframe->reflect = NULL;
+ skinframe->hasalpha = (textureflags & TEXF_ALPHA) != 0;
+ // if no data was provided, then clearly the caller wanted to get a blank skinframe
+ if (!tex)
+ return NULL;
+ if (developer_loading.integer)
+ Con_Printf("loading 32bit skin \"%s\"\n", name);
+ skinframe->base = skinframe->merged = tex;
+ Vector4Set(skinframe->avgcolor, 1, 1, 1, 1); // bogus placeholder
+ return skinframe;
+}
+
//static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
typedef struct suffixinfo_s
{
r_texture_gammaramps = NULL;
//r_texture_fogintensity = NULL;
memset(&r_fb, 0, sizeof(r_fb));
+ Mem_ExpandableArray_NewArray(&r_fb.rendertargets, r_main_mempool, sizeof(r_rendertarget_t), 128);
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);
static void gl_main_shutdown(void)
{
+ R_RenderTarget_FreeUnused(true);
+ Mem_ExpandableArray_FreeArray(&r_fb.rendertargets);
R_AnimCache_Free();
R_FrameData_Reset();
R_BufferData_Reset();
Cvar_RegisterVariable(&gl_combine);
Cvar_RegisterVariable(&r_usedepthtextures);
Cvar_RegisterVariable(&r_viewfbo);
+ Cvar_RegisterVariable(&r_rendertarget_debug);
Cvar_RegisterVariable(&r_viewscale);
Cvar_RegisterVariable(&r_viewscale_fpsscaling);
Cvar_RegisterVariable(&r_viewscale_fpsscaling_min);
Cvar_RegisterVariable(&r_water_scissormode);
Cvar_RegisterVariable(&r_water_lowquality);
Cvar_RegisterVariable(&r_water_hideplayer);
- Cvar_RegisterVariable(&r_water_fbo);
Cvar_RegisterVariable(&r_lerpsprites);
Cvar_RegisterVariable(&r_lerpmodels);
//==================================================================================
-extern cvar_t r_overheadsprites_pushback;
-
-static void R_GetDirectedFullbright(vec3_t ambient, vec3_t diffuse, vec3_t worldspacenormal)
-{
- vec3_t angles;
-
- VectorSet(ambient, r_fullbright_directed_ambient.value, r_fullbright_directed_ambient.value, r_fullbright_directed_ambient.value);
- VectorSet(diffuse, r_fullbright_directed_diffuse.value, r_fullbright_directed_diffuse.value, r_fullbright_directed_diffuse.value);
-
- // Use cl.viewangles and not r_refdef.view.forward here so it is the
- // same for all stereo views, and to better handle pitches outside
- // [-90, 90] (in_pitch_* cvars allow that).
- VectorCopy(cl.viewangles, angles);
- if (r_fullbright_directed_pitch_relative.integer) {
- angles[PITCH] += r_fullbright_directed_pitch.value;
- } else {
- angles[PITCH] = r_fullbright_directed_pitch.value;
- }
- AngleVectors(angles, worldspacenormal, NULL, NULL);
- VectorNegate(worldspacenormal, worldspacenormal);
-}
-
-static void R_View_UpdateEntityLighting (void)
-{
- int i;
- entity_render_t *ent;
- vec3_t tempdiffusenormal, avg;
- vec_t f, fa, fd, fdd;
- qboolean skipunseen = r_shadows.integer != 1; //|| R_Shadow_ShadowMappingEnabled();
-
- for (i = 0;i < r_refdef.scene.numentities;i++)
- {
- ent = r_refdef.scene.entities[i];
-
- // skip unseen models
- if ((!r_refdef.viewcache.entityvisible[i] && skipunseen))
- continue;
-
- // skip bsp models
- if (ent->model && ent->model == cl.worldmodel)
- {
- // TODO: use modellight for r_ambient settings on world?
- // The logic here currently matches RSurf_ActiveWorldEntity.
- if (r_fullbright_directed.integer && (r_fullbright.integer || !ent->model || !ent->model->lit))
- {
- R_GetDirectedFullbright(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
- Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
- if(VectorLength2(ent->modellight_lightdir) == 0)
- VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here
- VectorNormalize(ent->modellight_lightdir);
- }
- else
- {
- VectorSet(ent->modellight_ambient, 0, 0, 0);
- VectorSet(ent->modellight_diffuse, 0, 0, 0);
- VectorSet(ent->modellight_lightdir, 0, 0, 1);
- }
- continue;
- }
-
- if (ent->flags & RENDER_CUSTOMIZEDMODELLIGHT)
- {
- // aleady updated by CSQC
- // TODO: force modellight on BSP models in this case?
- VectorCopy(ent->modellight_lightdir, tempdiffusenormal);
- }
- else
- {
- // fetch the lighting from the worldmodel data
- VectorClear(ent->modellight_ambient);
- VectorClear(ent->modellight_diffuse);
- VectorClear(tempdiffusenormal);
- if (ent->flags & RENDER_LIGHT)
- {
- vec3_t org;
- Matrix4x4_OriginFromMatrix(&ent->matrix, org);
-
- // complete lightning for lit sprites
- // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)?
- if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT))
- {
- if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites
- org[2] = org[2] + r_overheadsprites_pushback.value;
- R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
- }
- else if (!r_fullbright.integer && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->lit && r_refdef.scene.worldmodel->brush.LightPoint)
- {
- R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP);
- }
- else if (r_fullbright_directed.integer)
- {
- R_GetDirectedFullbright(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
- }
- else
- {
- VectorSet(ent->modellight_ambient, 1, 1, 1);
- }
-
- if(ent->flags & RENDER_EQUALIZE)
- {
- // first fix up ambient lighting...
- if(r_equalize_entities_minambient.value > 0)
- {
- fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
- if(fd > 0)
- {
- fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]);
- if(fa < r_equalize_entities_minambient.value * fd)
- {
- // solve:
- // fa'/fd' = minambient
- // fa'+0.25*fd' = fa+0.25*fd
- // ...
- // fa' = fd' * minambient
- // fd'*(0.25+minambient) = fa+0.25*fd
- // ...
- // fd' = (fa+0.25*fd) * 1 / (0.25+minambient)
- // fa' = (fa+0.25*fd) * minambient / (0.25+minambient)
- // ...
- fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value);
- f = fdd / fd; // f>0 because all this is additive; f<1 because fdd<fd because this follows from fa < r_equalize_entities_minambient.value * fd
- VectorMA(ent->modellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient);
- VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse);
- }
- }
- }
-
- if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0)
- {
- fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2];
- fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
- f = fa + 0.25 * fd;
- if(f > 0)
- {
- // adjust brightness and saturation to target
- avg[0] = avg[1] = avg[2] = fa / f;
- VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient);
- avg[0] = avg[1] = avg[2] = fd / f;
- VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse);
- }
- }
- }
- }
- else
- {
- // EF_FULLBRIGHT entity.
- if (r_fullbright_directed.integer)
- {
- R_GetDirectedFullbright(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
- }
- else
- {
- VectorSet(ent->modellight_ambient, 1, 1, 1);
- }
- }
- }
-
- // move the light direction into modelspace coordinates for lighting code
- Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
- if(VectorLength2(ent->modellight_lightdir) == 0)
- VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here
- VectorNormalize(ent->modellight_lightdir);
- }
-}
-
qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
{
int i;
p[0] = point[0] + irisvecs[c][0] * r_hdr_irisadaptation_radius.value;
p[1] = point[1] + irisvecs[c][1] * r_hdr_irisadaptation_radius.value;
p[2] = point[2] + irisvecs[c][2] * r_hdr_irisadaptation_radius.value;
- R_CompleteLightPoint(ambient, diffuse, diffusenormal, p, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
+ R_CompleteLightPoint(ambient, diffuse, diffusenormal, p, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity);
d = DotProduct(forward, diffusenormal);
brightness += VectorLength(ambient);
if (d > 0)
R_View_SetFrustum(myscissor);
R_View_WorldVisibility(r_refdef.view.useclipplane);
R_View_UpdateEntityVisible();
- R_View_UpdateEntityLighting();
}
static void R_View_Update(void)
R_View_SetFrustum(NULL);
R_View_WorldVisibility(r_refdef.view.useclipplane);
R_View_UpdateEntityVisible();
- R_View_UpdateEntityLighting();
}
float viewscalefpsadjusted = 1.0f;
*outheight = (int)ceil(height * scale);
}
-void R_SetupView(qboolean allowwaterclippingplane, int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+void R_SetupView(qboolean allowwaterclippingplane, int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
{
const float *customclipplane = NULL;
float plane[4];
- int /*rtwidth,*/ rtheight, scaledwidth, scaledheight;
+ int /*rtwidth,*/ rtheight;
if (r_refdef.view.useclipplane && allowwaterclippingplane)
{
- // LordHavoc: couldn't figure out how to make this approach the
+ // LadyHavoc: couldn't figure out how to make this approach work the same in DPSOFTRAST
vec_t dist = r_refdef.view.clipplane.dist - r_water_clippingplanebias.value;
vec_t viewdist = DotProduct(r_refdef.view.origin, r_refdef.view.clipplane.normal);
if (viewdist < r_refdef.view.clipplane.dist + r_water_clippingplanebias.value)
if(vid.renderpath != RENDERPATH_SOFT) customclipplane = plane;
}
- //rtwidth = fbo ? R_TextureWidth(depthtexture ? depthtexture : colortexture) : vid.width;
- rtheight = fbo ? R_TextureHeight(depthtexture ? depthtexture : colortexture) : vid.height;
+ //rtwidth = viewfbo ? R_TextureWidth(viewdepthtexture ? viewdepthtexture : viewcolortexture) : vid.width;
+ rtheight = viewfbo ? R_TextureHeight(viewdepthtexture ? viewdepthtexture : viewcolortexture) : vid.height;
- R_GetScaledViewSize(r_refdef.view.width, r_refdef.view.height, &scaledwidth, &scaledheight);
if (!r_refdef.view.useperspective)
- R_Viewport_InitOrtho(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, rtheight - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, -r_refdef.view.ortho_x, -r_refdef.view.ortho_y, r_refdef.view.ortho_x, r_refdef.view.ortho_y, -r_refdef.farclip, r_refdef.farclip, customclipplane);
+ R_Viewport_InitOrtho(&r_refdef.view.viewport, &r_refdef.view.matrix, viewx, rtheight - viewheight - viewy, viewwidth, viewheight, -r_refdef.view.ortho_x, -r_refdef.view.ortho_y, r_refdef.view.ortho_x, r_refdef.view.ortho_y, -r_refdef.farclip, r_refdef.farclip, customclipplane);
else if (vid.stencil && r_useinfinitefarclip.integer)
- R_Viewport_InitPerspectiveInfinite(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, rtheight - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, customclipplane);
+ R_Viewport_InitPerspectiveInfinite(&r_refdef.view.viewport, &r_refdef.view.matrix, viewx, rtheight - viewheight - viewy, viewwidth, viewheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, customclipplane);
else
- R_Viewport_InitPerspective(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, rtheight - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip, customclipplane);
- R_Mesh_SetRenderTargets(fbo, depthtexture, colortexture, NULL, NULL, NULL);
+ R_Viewport_InitPerspective(&r_refdef.view.viewport, &r_refdef.view.matrix, viewx, rtheight - viewheight - viewy, viewwidth, viewheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip, customclipplane);
+ R_Mesh_SetRenderTargets(viewfbo, viewdepthtexture, viewcolortexture, NULL, NULL, NULL);
R_SetViewport(&r_refdef.view.viewport);
if (r_refdef.view.useclipplane && allowwaterclippingplane && vid.renderpath == RENDERPATH_SOFT)
{
}
}
-void R_ResetViewRendering2D_Common(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, float x2, float y2)
+void R_ResetViewRendering2D_Common(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight, float x2, float y2)
{
r_viewport_t viewport;
CHECKGLERROR
// GL is weird because it's bottom to top, r_refdef.view.y is top to bottom
- R_Viewport_InitOrtho(&viewport, &identitymatrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, 0, 0, x2, y2, -10, 100, NULL);
- R_Mesh_SetRenderTargets(fbo, depthtexture, colortexture, NULL, NULL, NULL);
+ R_Viewport_InitOrtho(&viewport, &identitymatrix, viewx, vid.height - viewheight - viewy, viewwidth, viewheight, 0, 0, x2, y2, -10, 100, NULL);
+ R_Mesh_SetRenderTargets(viewfbo, viewdepthtexture, viewcolortexture, NULL, NULL, NULL);
R_SetViewport(&viewport);
GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
GL_Color(1, 1, 1, 1);
CHECKGLERROR
}
-void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+void R_ResetViewRendering2D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
{
DrawQ_Finish();
- R_ResetViewRendering2D_Common(fbo, depthtexture, colortexture, 1, 1);
+ R_ResetViewRendering2D_Common(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight, 1.0f, 1.0f);
}
-void R_ResetViewRendering3D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+void R_ResetViewRendering3D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
{
DrawQ_Finish();
- R_SetupView(true, fbo, depthtexture, colortexture);
+ R_SetupView(true, viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
GL_Color(1, 1, 1, 1);
GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
Matrix4x4_Invert_Full(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix);
}
-void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture);
-void R_RenderWaterPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture);
+void R_RenderTarget_FreeUnused(qboolean force)
+{
+ int i, j, end;
+ end = Mem_ExpandableArray_IndexRange(&r_fb.rendertargets);
+ for (i = 0; i < end; i++)
+ {
+ r_rendertarget_t *r = (r_rendertarget_t *)Mem_ExpandableArray_RecordAtIndex(&r_fb.rendertargets, i);
+ // free resources for rendertargets that have not been used for a while
+ // (note: this check is run after the frame render, so any targets used
+ // this frame will not be affected even at low framerates)
+ if (r && (realtime - r->lastusetime > 0.2 || force))
+ {
+ if (r->fbo)
+ R_Mesh_DestroyFramebufferObject(r->fbo);
+ for (j = 0; j < sizeof(r->colortexture) / sizeof(r->colortexture[0]); j++)
+ if (r->colortexture[j])
+ R_FreeTexture(r->colortexture[j]);
+ if (r->depthtexture)
+ R_FreeTexture(r->depthtexture);
+ Mem_ExpandableArray_FreeRecord(&r_fb.rendertargets, r);
+ }
+ }
+}
+
+static void R_CalcTexCoordsForView(float x, float y, float w, float h, float tw, float th, float *texcoord2f)
+{
+ float iw = 1.0f / tw, ih = 1.0f / th, x1, y1, x2, y2;
+ switch (vid.renderpath)
+ {
+ case RENDERPATH_D3D9:
+ x1 = (x + 0.5f) * iw;
+ x2 = (x + 0.5f + w) * iw;
+ y1 = (y + 0.5f) * ih;
+ y2 = (y + 0.5f + h) * ih;
+ break;
+ default:
+ x1 = x * iw;
+ x2 = (x + w) * iw;
+ y1 = (th - y) * ih;
+ y2 = (th - y - h) * ih;
+ break;
+ }
+ texcoord2f[0] = x1;
+ texcoord2f[2] = x2;
+ texcoord2f[4] = x2;
+ texcoord2f[6] = x1;
+ texcoord2f[1] = y1;
+ texcoord2f[3] = y1;
+ texcoord2f[5] = y2;
+ texcoord2f[7] = y2;
+}
+
+r_rendertarget_t *R_RenderTarget_Get(int texturewidth, int textureheight, textype_t depthtextype, qboolean depthisrenderbuffer, textype_t colortextype0, textype_t colortextype1, textype_t colortextype2, textype_t colortextype3)
+{
+ int i, j, end;
+ r_rendertarget_t *r = NULL;
+ char vabuf[256];
+ // first try to reuse an existing slot if possible
+ end = Mem_ExpandableArray_IndexRange(&r_fb.rendertargets);
+ for (i = 0; i < end; i++)
+ {
+ r = (r_rendertarget_t *)Mem_ExpandableArray_RecordAtIndex(&r_fb.rendertargets, i);
+ if (r && r->lastusetime != realtime && r->texturewidth == texturewidth && r->textureheight == textureheight && r->depthtextype == depthtextype && r->colortextype[0] == colortextype0 && r->colortextype[1] == colortextype1 && r->colortextype[2] == colortextype2 && r->colortextype[3] == colortextype3)
+ break;
+ }
+ if (i == end)
+ {
+ // no unused exact match found, so we have to make one in the first unused slot
+ r = (r_rendertarget_t *)Mem_ExpandableArray_AllocRecord(&r_fb.rendertargets);
+ r->texturewidth = texturewidth;
+ r->textureheight = textureheight;
+ r->colortextype[0] = colortextype0;
+ r->colortextype[1] = colortextype1;
+ r->colortextype[2] = colortextype2;
+ r->colortextype[3] = colortextype3;
+ r->depthtextype = depthtextype;
+ r->depthisrenderbuffer = depthisrenderbuffer;
+ for (j = 0; j < 4; j++)
+ if (r->colortextype[j])
+ r->colortexture[j] = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "rendertarget%i_%i_type%i", i, j, (int)r->colortextype[j]), r->texturewidth, r->textureheight, NULL, r->colortextype[j], TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
+ if (r->depthtextype)
+ {
+ if (r->depthisrenderbuffer)
+ r->depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, va(vabuf, sizeof(vabuf), "renderbuffer%i_depth_type%i", i, (int)r->depthtextype), r->texturewidth, r->textureheight, r->depthtextype);
+ else
+ r->depthtexture = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "rendertarget%i_depth_type%i", i, j, (int)r->depthtextype), r->texturewidth, r->textureheight, NULL, r->depthtextype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
+ }
+ r->fbo = R_Mesh_CreateFramebufferObject(r->depthtexture, r->colortexture[0], r->colortexture[1], r->colortexture[2], r->colortexture[3]);
+ }
+ r_refdef.stats[r_stat_rendertargets_used]++;
+ r_refdef.stats[r_stat_rendertargets_pixels] += r->texturewidth * r->textureheight;
+ r->lastusetime = realtime;
+ R_CalcTexCoordsForView(0, 0, r->texturewidth, r->textureheight, r->texturewidth, r->textureheight, r->texcoord2f);
+ return r;
+}
static void R_Water_StartFrame(void)
{
- int i;
- int waterwidth, waterheight, texturewidth, textureheight, camerawidth, cameraheight;
- r_waterstate_waterplane_t *p;
- qboolean usewaterfbo = (r_viewfbo.integer >= 1 || r_water_fbo.integer >= 1) && vid.support.ext_framebuffer_object && vid.support.arb_texture_non_power_of_two && vid.samples < 2;
+ int waterwidth, waterheight;
if (vid.width > (int)vid.maxtexturesize_2d || vid.height > (int)vid.maxtexturesize_2d)
return;
// set waterwidth and waterheight to the water resolution that will be
// used (often less than the screen resolution for faster rendering)
- R_GetScaledViewSize(bound(1, vid.width * r_water_resolutionmultiplier.value, vid.width), bound(1, vid.height * r_water_resolutionmultiplier.value, vid.height), &waterwidth, &waterheight);
+ waterwidth = (int)bound(1, r_refdef.view.width * r_water_resolutionmultiplier.value, r_refdef.view.width);
+ waterheight = (int)bound(1, r_refdef.view.height * r_water_resolutionmultiplier.value, r_refdef.view.height);
+ R_GetScaledViewSize(waterwidth, waterheight, &waterwidth, &waterheight);
- // calculate desired texture sizes
- // can't use water if the card does not support the texture size
if (!r_water.integer || r_showsurfaces.integer)
- texturewidth = textureheight = waterwidth = waterheight = camerawidth = cameraheight = 0;
- else if (vid.support.arb_texture_non_power_of_two)
- {
- texturewidth = waterwidth;
- textureheight = waterheight;
- camerawidth = waterwidth;
- cameraheight = waterheight;
- }
- else
- {
- for (texturewidth = 1;texturewidth < waterwidth ;texturewidth *= 2);
- for (textureheight = 1;textureheight < waterheight;textureheight *= 2);
- for (camerawidth = 1;camerawidth * 2 <= waterwidth ;camerawidth *= 2);
- for (cameraheight = 1;cameraheight * 2 <= waterheight;cameraheight *= 2);
- }
+ waterwidth = waterheight = 0;
+
+ // set up variables that will be used in shader setup
+ r_fb.water.waterwidth = waterwidth;
+ r_fb.water.waterheight = waterheight;
+ r_fb.water.texturewidth = waterwidth;
+ r_fb.water.textureheight = waterheight;
+ r_fb.water.camerawidth = waterwidth;
+ r_fb.water.cameraheight = waterheight;
+ r_fb.water.screenscale[0] = 0.5f;
+ r_fb.water.screenscale[1] = 0.5f;
+ r_fb.water.screencenter[0] = 0.5f;
+ r_fb.water.screencenter[1] = 0.5f;
+ r_fb.water.enabled = waterwidth != 0;
- // allocate textures as needed
- if (r_fb.water.texturewidth != texturewidth || r_fb.water.textureheight != textureheight || r_fb.water.camerawidth != camerawidth || r_fb.water.cameraheight != cameraheight || (r_fb.depthtexture && !usewaterfbo))
- {
- r_fb.water.maxwaterplanes = MAX_WATERPLANES;
- for (i = 0, p = r_fb.water.waterplanes;i < r_fb.water.maxwaterplanes;i++, p++)
- {
- if (p->texture_refraction)
- R_FreeTexture(p->texture_refraction);
- p->texture_refraction = NULL;
- if (p->fbo_refraction)
- R_Mesh_DestroyFramebufferObject(p->fbo_refraction);
- p->fbo_refraction = 0;
- if (p->texture_reflection)
- R_FreeTexture(p->texture_reflection);
- p->texture_reflection = NULL;
- if (p->fbo_reflection)
- R_Mesh_DestroyFramebufferObject(p->fbo_reflection);
- p->fbo_reflection = 0;
- if (p->texture_camera)
- R_FreeTexture(p->texture_camera);
- p->texture_camera = NULL;
- if (p->fbo_camera)
- R_Mesh_DestroyFramebufferObject(p->fbo_camera);
- p->fbo_camera = 0;
- }
- memset(&r_fb.water, 0, sizeof(r_fb.water));
- r_fb.water.texturewidth = texturewidth;
- r_fb.water.textureheight = textureheight;
- r_fb.water.camerawidth = camerawidth;
- r_fb.water.cameraheight = cameraheight;
- }
-
- if (r_fb.water.texturewidth)
- {
- int scaledwidth, scaledheight;
-
- r_fb.water.enabled = true;
-
- // water resolution is usually reduced
- r_fb.water.waterwidth = (int)bound(1, r_refdef.view.width * r_water_resolutionmultiplier.value, r_refdef.view.width);
- r_fb.water.waterheight = (int)bound(1, r_refdef.view.height * r_water_resolutionmultiplier.value, r_refdef.view.height);
- R_GetScaledViewSize(r_fb.water.waterwidth, r_fb.water.waterheight, &scaledwidth, &scaledheight);
-
- // set up variables that will be used in shader setup
- r_fb.water.screenscale[0] = 0.5f * (float)scaledwidth / (float)r_fb.water.texturewidth;
- r_fb.water.screenscale[1] = 0.5f * (float)scaledheight / (float)r_fb.water.textureheight;
- r_fb.water.screencenter[0] = 0.5f * (float)scaledwidth / (float)r_fb.water.texturewidth;
- r_fb.water.screencenter[1] = 0.5f * (float)scaledheight / (float)r_fb.water.textureheight;
- }
-
- r_fb.water.maxwaterplanes = MAX_WATERPLANES;
- r_fb.water.numwaterplanes = 0;
-}
+ r_fb.water.maxwaterplanes = MAX_WATERPLANES;
+ r_fb.water.numwaterplanes = 0;
+}
void R_Water_AddWaterPlane(msurface_t *surface, int entno)
{
extern cvar_t r_drawparticles;
extern cvar_t r_drawdecals;
-static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int viewx, int viewy, int viewwidth, int viewheight)
{
int myscissor[4];
r_refdef_view_t originalview;
int planeindex, qualityreduction = 0, old_r_dynamic = 0, old_r_shadows = 0, old_r_worldrtlight = 0, old_r_dlight = 0, old_r_particles = 0, old_r_decals = 0;
r_waterstate_waterplane_t *p;
vec3_t visorigin;
- qboolean usewaterfbo = (r_viewfbo.integer >= 1 || r_water_fbo.integer >= 1) && vid.support.ext_framebuffer_object && vid.support.arb_texture_non_power_of_two && vid.samples < 2;
- char vabuf[1024];
+ r_rendertarget_t *rt;
originalview = r_refdef.view;
}
}
- // make sure enough textures are allocated
- for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++)
+ 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)
- p->texture_refraction = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "waterplane%i_refraction", planeindex), r_fb.water.texturewidth, r_fb.water.textureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
- if (!p->texture_refraction)
- goto error;
- if (usewaterfbo)
- {
- if (r_fb.water.depthtexture == NULL)
- r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8);
- if (p->fbo_refraction == 0)
- p->fbo_refraction = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_refraction, NULL, NULL, NULL);
- }
- }
- else if (p->materialflags & MATERIALFLAG_CAMERA)
- {
- if (!p->texture_camera)
- p->texture_camera = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "waterplane%i_camera", planeindex), r_fb.water.camerawidth, r_fb.water.cameraheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR, -1, NULL);
- if (!p->texture_camera)
- goto error;
- if (usewaterfbo)
- {
- if (r_fb.water.depthtexture == NULL)
- r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8);
- if (p->fbo_camera == 0)
- p->fbo_camera = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_camera, NULL, NULL, NULL);
- }
- }
-
- if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
- {
- if (!p->texture_reflection)
- p->texture_reflection = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "waterplane%i_reflection", planeindex), r_fb.water.texturewidth, r_fb.water.textureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
- if (!p->texture_reflection)
- goto error;
- if (usewaterfbo)
- {
- if (r_fb.water.depthtexture == NULL)
- r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8);
- if (p->fbo_reflection == 0)
- p->fbo_reflection = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_reflection, NULL, NULL, NULL);
- }
- }
+ p->rt_reflection = NULL;
+ p->rt_refraction = NULL;
+ p->rt_camera = NULL;
}
// render views
{
if (r_water_cameraentitiesonly.value != 0 && !p->camera_entity)
continue;
+
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
{
+ rt = R_RenderTarget_Get(r_fb.water.waterwidth, r_fb.water.waterheight, TEXTYPE_DEPTHBUFFER24STENCIL8, true, r_fb.rt_screen->colortextype[0], TEXTYPE_UNUSED, TEXTYPE_UNUSED, TEXTYPE_UNUSED);
+ if (rt->colortexture[0] == NULL || rt->depthtexture == NULL)
+ goto error;
r_refdef.view = myview;
+ Matrix4x4_Reflect(&r_refdef.view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2);
+ Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, r_refdef.view.origin);
if(r_water_scissormode.integer)
{
- R_SetupView(true, p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection);
- if(R_ScissorForBBox(p->mins, p->maxs, myscissor))
- continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
+ R_SetupView(true, rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, r_fb.water.waterwidth, r_fb.water.waterheight);
+ if (R_ScissorForBBox(p->mins, p->maxs, myscissor))
+ {
+ p->rt_reflection = NULL;
+ p->rt_refraction = NULL;
+ p->rt_camera = NULL;
+ continue;
+ }
}
- // render reflected scene and copy into texture
- Matrix4x4_Reflect(&r_refdef.view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2);
- // update the r_refdef.view.origin because otherwise the sky renders at the wrong location (amongst other problems)
- Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, r_refdef.view.origin);
r_refdef.view.clipplane = p->plane;
// reverse the cullface settings for this render
r_refdef.view.cullface_front = GL_FRONT;
}
r_fb.water.hideplayer = ((r_water_hideplayer.integer >= 2) && !chase_active.integer);
- R_ResetViewRendering3D(p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection);
+ R_ResetViewRendering3D(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
+ GL_ScissorTest(false);
R_ClearScreen(r_refdef.fogenabled);
+ GL_ScissorTest(true);
if(r_water_scissormode.integer & 2)
R_View_UpdateWithScissor(myscissor);
else
R_AnimCache_CacheVisibleEntities();
if(r_water_scissormode.integer & 1)
GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
- R_RenderScene(p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection);
+ R_RenderScene(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
- if (!p->fbo_reflection)
- R_Mesh_CopyToTexture(p->texture_reflection, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
r_fb.water.hideplayer = false;
+ p->rt_reflection = rt;
}
// render the normal view scene and copy into texture
// (except that a clipping plane should be used to hide everything on one side of the water, and the viewer's weapon model should be omitted)
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
{
+ rt = R_RenderTarget_Get(r_fb.water.waterwidth, r_fb.water.waterheight, TEXTYPE_DEPTHBUFFER24STENCIL8, true, r_fb.rt_screen->colortextype[0], TEXTYPE_UNUSED, TEXTYPE_UNUSED, TEXTYPE_UNUSED);
+ if (rt->colortexture[0] == NULL || rt->depthtexture == NULL)
+ goto error;
r_refdef.view = myview;
if(r_water_scissormode.integer)
{
- R_SetupView(true, p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction);
- if(R_ScissorForBBox(p->mins, p->maxs, myscissor))
- continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
+ R_SetupView(true, rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, r_fb.water.waterwidth, r_fb.water.waterheight);
+ if (R_ScissorForBBox(p->mins, p->maxs, myscissor))
+ {
+ p->rt_reflection = NULL;
+ p->rt_refraction = NULL;
+ p->rt_camera = NULL;
+ continue;
+ }
}
r_fb.water.hideplayer = ((r_water_hideplayer.integer >= 1) && !chase_active.integer);
PlaneClassify(&r_refdef.view.clipplane);
- R_ResetViewRendering3D(p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction);
+ R_ResetViewRendering3D(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
+ GL_ScissorTest(false);
R_ClearScreen(r_refdef.fogenabled);
+ GL_ScissorTest(true);
if(r_water_scissormode.integer & 2)
R_View_UpdateWithScissor(myscissor);
else
R_AnimCache_CacheVisibleEntities();
if(r_water_scissormode.integer & 1)
GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
- R_RenderScene(p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction);
+ R_RenderScene(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
- if (!p->fbo_refraction)
- R_Mesh_CopyToTexture(p->texture_refraction, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
r_fb.water.hideplayer = false;
+ p->rt_refraction = rt;
}
else if (p->materialflags & MATERIALFLAG_CAMERA)
{
+ rt = R_RenderTarget_Get(r_fb.water.waterwidth, r_fb.water.waterheight, TEXTYPE_DEPTHBUFFER24STENCIL8, true, r_fb.rt_screen->colortextype[0], TEXTYPE_UNUSED, TEXTYPE_UNUSED, TEXTYPE_UNUSED);
+ if (rt->colortexture[0] == NULL || rt->depthtexture == NULL)
+ goto error;
r_refdef.view = myview;
r_refdef.view.clipplane = p->plane;
r_fb.water.hideplayer = false;
- R_ResetViewRendering3D(p->fbo_camera, r_fb.water.depthtexture, p->texture_camera);
+ R_ResetViewRendering3D(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
+ GL_ScissorTest(false);
R_ClearScreen(r_refdef.fogenabled);
+ GL_ScissorTest(true);
R_View_Update();
R_AnimCache_CacheVisibleEntities();
- R_RenderScene(p->fbo_camera, r_fb.water.depthtexture, p->texture_camera);
+ R_RenderScene(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
- if (!p->fbo_camera)
- R_Mesh_CopyToTexture(p->texture_camera, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
r_fb.water.hideplayer = false;
+ p->rt_camera = rt;
}
}
if(vid.renderpath==RENDERPATH_SOFT) DPSOFTRAST_ClipPlane(0, 0, 0, 1);
r_fb.water.renderingscene = false;
r_refdef.view = originalview;
- R_ResetViewRendering3D(fbo, depthtexture, colortexture);
- if (!r_fb.water.depthtexture)
- R_ClearScreen(r_refdef.fogenabled);
+ R_ResetViewRendering3D(fbo, depthtexture, colortexture, viewx, viewy, viewwidth, viewheight);
R_View_Update();
R_AnimCache_CacheVisibleEntities();
goto finish;
static void R_Bloom_StartFrame(void)
{
- int i;
int bloomtexturewidth, bloomtextureheight, screentexturewidth, screentextureheight;
int viewwidth, viewheight;
- qboolean useviewfbo = r_viewfbo.integer >= 1 && vid.support.ext_framebuffer_object && vid.support.arb_texture_non_power_of_two && vid.samples < 2;
textype_t textype = TEXTYPE_COLORBUFFER;
+ // clear the pointers to rendertargets from last frame as they're stale
+ r_fb.rt_screen = NULL;
+ r_fb.rt_bloom = NULL;
+
switch (vid.renderpath)
{
case RENDERPATH_GL20:
r_fb.usedepthtextures = r_usedepthtextures.integer != 0;
- if (vid.support.ext_framebuffer_object && vid.support.arb_texture_non_power_of_two)
- {
- if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F;
- if (r_viewfbo.integer == 3) textype = TEXTYPE_COLORBUFFER32F;
- }
+ if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F;
+ if (r_viewfbo.integer == 3) textype = TEXTYPE_COLORBUFFER32F;
+ // for simplicity, bloom requires FBO render to texture, which basically all video drivers support now
+ if (!vid.support.ext_framebuffer_object)
+ return;
break;
case RENDERPATH_GL11:
case RENDERPATH_GL13:
case RENDERPATH_GLES1:
+ return; // don't bother
case RENDERPATH_GLES2:
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
R_GetScaledViewSize(r_refdef.view.width, r_refdef.view.height, &viewwidth, &viewheight);
- switch(vid.renderpath)
- {
- case RENDERPATH_GL20:
- case RENDERPATH_D3D9:
- case RENDERPATH_D3D10:
- case RENDERPATH_D3D11:
- case RENDERPATH_SOFT:
- case RENDERPATH_GLES2:
- break;
- case RENDERPATH_GL11:
- case RENDERPATH_GL13:
- case RENDERPATH_GLES1:
- return;
- }
-
// set bloomwidth and bloomheight to the bloom resolution that will be
// used (often less than the screen resolution for faster rendering)
r_fb.bloomwidth = bound(1, r_bloom_resolution.integer, vid.width);
r_fb.bloomheight = bound(1, r_fb.bloomheight, (int)vid.maxtexturesize_2d);
// calculate desired texture sizes
- if (vid.support.arb_texture_non_power_of_two)
- {
- screentexturewidth = vid.width;
- screentextureheight = vid.height;
- bloomtexturewidth = r_fb.bloomwidth;
- bloomtextureheight = r_fb.bloomheight;
- }
- else
- {
- for (screentexturewidth = 1;screentexturewidth < vid.width ;screentexturewidth *= 2);
- for (screentextureheight = 1;screentextureheight < vid.height ;screentextureheight *= 2);
- for (bloomtexturewidth = 1;bloomtexturewidth < r_fb.bloomwidth ;bloomtexturewidth *= 2);
- for (bloomtextureheight = 1;bloomtextureheight < r_fb.bloomheight;bloomtextureheight *= 2);
- }
+ screentexturewidth = viewwidth;
+ screentextureheight = viewheight;
+ bloomtexturewidth = r_fb.bloomwidth;
+ bloomtextureheight = r_fb.bloomheight;
if ((r_bloom.integer || (!R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0))) && ((r_bloom_resolution.integer < 4 || r_bloom_blur.value < 1 || r_bloom_blur.value >= 512) || r_refdef.view.width > (int)vid.maxtexturesize_2d || r_refdef.view.height > (int)vid.maxtexturesize_2d))
{
Cvar_SetValueQuick(&r_damageblur, 0);
}
- if (!((r_glsl_postprocess.integer || r_fxaa.integer) || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || (v_glslgamma.integer && !vid_gammatables_trivial))
- && !r_bloom.integer
- && (R_Stereo_Active() || (r_motionblur.value <= 0 && r_damageblur.value <= 0))
- && !useviewfbo
- && r_viewscale.value == 1.0f
- && !r_viewscale_fpsscaling.integer)
- screentexturewidth = screentextureheight = 0;
- if (!r_bloom.integer)
- bloomtexturewidth = bloomtextureheight = 0;
-
- // allocate textures as needed
- if (r_fb.screentexturewidth != screentexturewidth
- || r_fb.screentextureheight != screentextureheight
- || r_fb.bloomtexturewidth != bloomtexturewidth
- || r_fb.bloomtextureheight != bloomtextureheight
- || r_fb.textype != textype
- || useviewfbo != (r_fb.fbo != 0))
+ // allocate motionblur ghost texture if needed - this is the only persistent texture and is only useful on the main view
+ if (r_refdef.view.ismain && (r_fb.screentexturewidth != screentexturewidth || r_fb.screentextureheight != screentextureheight || r_fb.textype != textype))
{
- for (i = 0;i < (int)(sizeof(r_fb.bloomtexture)/sizeof(r_fb.bloomtexture[i]));i++)
- {
- if (r_fb.bloomtexture[i])
- R_FreeTexture(r_fb.bloomtexture[i]);
- r_fb.bloomtexture[i] = NULL;
-
- if (r_fb.bloomfbo[i])
- R_Mesh_DestroyFramebufferObject(r_fb.bloomfbo[i]);
- r_fb.bloomfbo[i] = 0;
- }
-
- if (r_fb.fbo)
- R_Mesh_DestroyFramebufferObject(r_fb.fbo);
- r_fb.fbo = 0;
-
- if (r_fb.colortexture)
- R_FreeTexture(r_fb.colortexture);
- r_fb.colortexture = NULL;
-
- if (r_fb.depthtexture)
- R_FreeTexture(r_fb.depthtexture);
- r_fb.depthtexture = NULL;
-
if (r_fb.ghosttexture)
R_FreeTexture(r_fb.ghosttexture);
r_fb.ghosttexture = NULL;
r_fb.screentexturewidth = screentexturewidth;
r_fb.screentextureheight = screentextureheight;
- r_fb.bloomtexturewidth = bloomtexturewidth;
- r_fb.bloomtextureheight = bloomtextureheight;
r_fb.textype = textype;
if (r_fb.screentexturewidth && r_fb.screentextureheight)
if (r_motionblur.value > 0 || r_damageblur.value > 0)
r_fb.ghosttexture = R_LoadTexture2D(r_main_texturepool, "framebuffermotionblur", r_fb.screentexturewidth, r_fb.screentextureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
r_fb.ghosttexture_valid = false;
- r_fb.colortexture = R_LoadTexture2D(r_main_texturepool, "framebuffercolor", r_fb.screentexturewidth, r_fb.screentextureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
- if (useviewfbo)
- {
- r_fb.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "framebufferdepth", r_fb.screentexturewidth, r_fb.screentextureheight, TEXTYPE_DEPTHBUFFER24STENCIL8);
- r_fb.fbo = R_Mesh_CreateFramebufferObject(r_fb.depthtexture, r_fb.colortexture, NULL, NULL, NULL);
- R_Mesh_SetRenderTargets(r_fb.fbo, r_fb.depthtexture, r_fb.colortexture, NULL, NULL, NULL);
- }
- }
-
- if (r_fb.bloomtexturewidth && r_fb.bloomtextureheight)
- {
- for (i = 0;i < (int)(sizeof(r_fb.bloomtexture)/sizeof(r_fb.bloomtexture[i]));i++)
- {
- r_fb.bloomtexture[i] = R_LoadTexture2D(r_main_texturepool, "framebufferbloom", r_fb.bloomtexturewidth, r_fb.bloomtextureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
- if (useviewfbo)
- r_fb.bloomfbo[i] = R_Mesh_CreateFramebufferObject(NULL, r_fb.bloomtexture[i], NULL, NULL, NULL);
- }
}
}
- // bloom texture is a different resolution
- r_fb.bloomwidth = bound(1, r_bloom_resolution.integer, r_refdef.view.width);
- r_fb.bloomheight = r_fb.bloomwidth * r_refdef.view.height / r_refdef.view.width;
- r_fb.bloomheight = bound(1, r_fb.bloomheight, r_refdef.view.height);
- r_fb.bloomwidth = bound(1, r_fb.bloomwidth, r_fb.bloomtexturewidth);
- r_fb.bloomheight = bound(1, r_fb.bloomheight, r_fb.bloomtextureheight);
-
- // set up a texcoord array for the full resolution screen image
- // (we have to keep this around to copy back during final render)
- r_fb.screentexcoord2f[0] = 0;
- r_fb.screentexcoord2f[1] = (float)viewheight / (float)r_fb.screentextureheight;
- r_fb.screentexcoord2f[2] = (float)viewwidth / (float)r_fb.screentexturewidth;
- r_fb.screentexcoord2f[3] = (float)viewheight / (float)r_fb.screentextureheight;
- r_fb.screentexcoord2f[4] = (float)viewwidth / (float)r_fb.screentexturewidth;
- r_fb.screentexcoord2f[5] = 0;
- r_fb.screentexcoord2f[6] = 0;
- r_fb.screentexcoord2f[7] = 0;
-
- if(r_fb.fbo)
+ if (r_bloom.integer)
{
- for (i = 1;i < 8;i += 2)
- {
- r_fb.screentexcoord2f[i] += 1 - (float)(viewheight + r_refdef.view.y) / (float)r_fb.screentextureheight;
- }
- }
-
- // set up a texcoord array for the reduced resolution bloom image
- // (which will be additive blended over the screen image)
- r_fb.bloomtexcoord2f[0] = 0;
- r_fb.bloomtexcoord2f[1] = (float)r_fb.bloomheight / (float)r_fb.bloomtextureheight;
- r_fb.bloomtexcoord2f[2] = (float)r_fb.bloomwidth / (float)r_fb.bloomtexturewidth;
- r_fb.bloomtexcoord2f[3] = (float)r_fb.bloomheight / (float)r_fb.bloomtextureheight;
- r_fb.bloomtexcoord2f[4] = (float)r_fb.bloomwidth / (float)r_fb.bloomtexturewidth;
- r_fb.bloomtexcoord2f[5] = 0;
- r_fb.bloomtexcoord2f[6] = 0;
- r_fb.bloomtexcoord2f[7] = 0;
-
- switch(vid.renderpath)
- {
- case RENDERPATH_GL11:
- case RENDERPATH_GL13:
- case RENDERPATH_GL20:
- case RENDERPATH_SOFT:
- case RENDERPATH_GLES1:
- case RENDERPATH_GLES2:
- break;
- case RENDERPATH_D3D9:
- case RENDERPATH_D3D10:
- case RENDERPATH_D3D11:
- for (i = 0;i < 4;i++)
- {
- r_fb.screentexcoord2f[i*2+0] += 0.5f / (float)r_fb.screentexturewidth;
- r_fb.screentexcoord2f[i*2+1] += 0.5f / (float)r_fb.screentextureheight;
- r_fb.bloomtexcoord2f[i*2+0] += 0.5f / (float)r_fb.bloomtexturewidth;
- r_fb.bloomtexcoord2f[i*2+1] += 0.5f / (float)r_fb.bloomtextureheight;
- }
- break;
+ // bloom texture is a different resolution
+ r_fb.bloomwidth = bound(1, r_bloom_resolution.integer, r_refdef.view.width);
+ r_fb.bloomheight = r_fb.bloomwidth * r_refdef.view.height / r_refdef.view.width;
+ r_fb.bloomheight = bound(1, r_fb.bloomheight, r_refdef.view.height);
}
+ else
+ r_fb.bloomwidth = r_fb.bloomheight = 0;
- R_Viewport_InitOrtho(&r_fb.bloomviewport, &identitymatrix, 0, 0, r_fb.bloomwidth, r_fb.bloomheight, 0, 0, 1, 1, -10, 100, NULL);
+ r_fb.rt_screen = R_RenderTarget_Get(screentexturewidth, screentextureheight, TEXTYPE_DEPTHBUFFER24STENCIL8, true, textype, TEXTYPE_UNUSED, TEXTYPE_UNUSED, TEXTYPE_UNUSED);
- if (r_fb.fbo)
- r_refdef.view.clear = true;
+ r_refdef.view.clear = true;
}
static void R_Bloom_MakeTexture(void)
{
int x, range, dir;
float xoffset, yoffset, r, brighten;
- rtexture_t *intex;
float colorscale = r_bloom_colorscale.value;
+ r_viewport_t bloomviewport;
+ r_rendertarget_t *prev, *cur;
+ textype_t textype = r_fb.rt_screen->colortextype[0];
r_refdef.stats[r_stat_bloom]++;
-
-#if 0
- // this copy is unnecessary since it happens in R_BlendView already
- if (!r_fb.fbo)
- {
- R_Mesh_CopyToTexture(r_fb.colortexture, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
- r_refdef.stats[r_stat_bloom_copypixels] += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
- }
-#endif
+
+ R_Viewport_InitOrtho(&bloomviewport, &identitymatrix, 0, 0, r_fb.bloomwidth, r_fb.bloomheight, 0, 0, 1, 1, -10, 100, NULL);
// scale down screen texture to the bloom texture size
CHECKGLERROR
- 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);
+ prev = r_fb.rt_screen;
+ cur = R_RenderTarget_Get(r_fb.bloomwidth, r_fb.bloomheight, TEXTYPE_UNUSED, false, textype, TEXTYPE_UNUSED, TEXTYPE_UNUSED, TEXTYPE_UNUSED);
+ R_Mesh_SetRenderTargets(cur->fbo, NULL, cur->colortexture[0], NULL, NULL, NULL);
+ R_SetViewport(&bloomviewport);
GL_CullFace(GL_NONE);
GL_DepthTest(false);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_Color(colorscale, colorscale, colorscale, 1);
- // D3D has upside down Y coords, the easiest way to flip this is to flip the screen vertices rather than the texcoords, so we just use a different array for that...
- switch(vid.renderpath)
- {
- case RENDERPATH_GL11:
- case RENDERPATH_GL13:
- case RENDERPATH_GL20:
- case RENDERPATH_GLES1:
- case RENDERPATH_GLES2:
- case RENDERPATH_SOFT:
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_fb.screentexcoord2f);
- break;
- case RENDERPATH_D3D9:
- case RENDERPATH_D3D10:
- case RENDERPATH_D3D11:
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_d3dscreenvertex3f, NULL, r_fb.screentexcoord2f);
- break;
- }
+ R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, prev->texcoord2f);
// TODO: do boxfilter scale-down in shader?
- R_SetupShader_Generic(r_fb.colortexture, NULL, GL_MODULATE, 1, false, true, true);
+ R_SetupShader_Generic(prev->colortexture[0], NULL, GL_MODULATE, 1, false, true, true);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
r_refdef.stats[r_stat_bloom_drawpixels] += r_fb.bloomwidth * r_fb.bloomheight;
-
// we now have a properly scaled bloom image
- if (!r_fb.bloomfbo[r_fb.bloomindex])
- {
- // copy it into the bloom texture
- R_Mesh_CopyToTexture(r_fb.bloomtexture[r_fb.bloomindex], 0, 0, r_fb.bloomviewport.x, r_fb.bloomviewport.y, r_fb.bloomviewport.width, r_fb.bloomviewport.height);
- r_refdef.stats[r_stat_bloom_copypixels] += r_fb.bloomviewport.width * r_fb.bloomviewport.height;
- }
- // multiply bloom image by itself as many times as desired
+ // multiply bloom image by itself as many times as desired to darken it
+ // TODO: if people actually use this it could be done more quickly in the previous shader pass
for (x = 1;x < min(r_bloom_colorexponent.value, 32);)
{
- intex = r_fb.bloomtexture[r_fb.bloomindex];
- r_fb.bloomindex ^= 1;
- R_Mesh_SetRenderTargets(r_fb.bloomfbo[r_fb.bloomindex], NULL, r_fb.bloomtexture[r_fb.bloomindex], NULL, NULL, NULL);
+ prev = cur;
+ cur = R_RenderTarget_Get(r_fb.bloomwidth, r_fb.bloomheight, TEXTYPE_UNUSED, false, textype, TEXTYPE_UNUSED, TEXTYPE_UNUSED, TEXTYPE_UNUSED);
+ R_Mesh_SetRenderTargets(cur->fbo, NULL, cur->colortexture[0], NULL, NULL, NULL);
x *= 2;
r = bound(0, r_bloom_colorexponent.value / x, 1); // always 0.5 to 1
- if (!r_fb.bloomfbo[r_fb.bloomindex])
- {
- GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR); // square it and multiply by two
- GL_Color(r,r,r,1); // apply fix factor
- }
- else
- {
- if(x <= 2)
- GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
- GL_BlendFunc(GL_SRC_COLOR, GL_ZERO); // square it
- GL_Color(1,1,1,1); // no fix factor supported here
- }
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_fb.bloomtexcoord2f);
- R_SetupShader_Generic(intex, NULL, GL_MODULATE, 1, false, true, false);
+ if(x <= 2)
+ GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
+ GL_BlendFunc(GL_SRC_COLOR, GL_ZERO); // square it
+ GL_Color(1,1,1,1); // no fix factor supported here
+ R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, prev->texcoord2f);
+ R_SetupShader_Generic(prev->colortexture[0], NULL, GL_MODULATE, 1, false, true, false);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
r_refdef.stats[r_stat_bloom_drawpixels] += r_fb.bloomwidth * r_fb.bloomheight;
-
- if (!r_fb.bloomfbo[r_fb.bloomindex])
- {
- // copy the darkened image to a texture
- R_Mesh_CopyToTexture(r_fb.bloomtexture[r_fb.bloomindex], 0, 0, r_fb.bloomviewport.x, r_fb.bloomviewport.y, r_fb.bloomviewport.width, r_fb.bloomviewport.height);
- r_refdef.stats[r_stat_bloom_copypixels] += r_fb.bloomviewport.width * r_fb.bloomviewport.height;
- }
}
range = r_bloom_blur.integer * r_fb.bloomwidth / 320;
for (dir = 0;dir < 2;dir++)
{
- intex = r_fb.bloomtexture[r_fb.bloomindex];
- r_fb.bloomindex ^= 1;
- R_Mesh_SetRenderTargets(r_fb.bloomfbo[r_fb.bloomindex], NULL, r_fb.bloomtexture[r_fb.bloomindex], NULL, NULL, NULL);
+ prev = cur;
+ cur = R_RenderTarget_Get(r_fb.bloomwidth, r_fb.bloomheight, TEXTYPE_UNUSED, false, textype, TEXTYPE_UNUSED, TEXTYPE_UNUSED, TEXTYPE_UNUSED);
+ R_Mesh_SetRenderTargets(cur->fbo, NULL, cur->colortexture[0], NULL, NULL, NULL);
// blend on at multiple vertical offsets to achieve a vertical blur
// TODO: do offset blends using GLSL
// TODO instead of changing the texcoords, change the target positions to prevent artifacts at edges
GL_BlendFunc(GL_ONE, GL_ZERO);
- R_SetupShader_Generic(intex, NULL, GL_MODULATE, 1, false, true, false);
+ R_SetupShader_Generic(prev->colortexture[0], NULL, GL_MODULATE, 1, false, true, false);
for (x = -range;x <= range;x++)
{
if (!dir){xoffset = 0;yoffset = x;}
else {xoffset = x;yoffset = 0;}
- xoffset /= (float)r_fb.bloomtexturewidth;
- yoffset /= (float)r_fb.bloomtextureheight;
+ xoffset /= (float)prev->texturewidth;
+ yoffset /= (float)prev->textureheight;
// compute a texcoord array with the specified x and y offset
- r_fb.offsettexcoord2f[0] = xoffset+r_fb.bloomtexcoord2f[0];
- r_fb.offsettexcoord2f[1] = yoffset+r_fb.bloomtexcoord2f[1];
- r_fb.offsettexcoord2f[2] = xoffset+r_fb.bloomtexcoord2f[2];
- r_fb.offsettexcoord2f[3] = yoffset+r_fb.bloomtexcoord2f[3];
- r_fb.offsettexcoord2f[4] = xoffset+r_fb.bloomtexcoord2f[4];
- r_fb.offsettexcoord2f[5] = yoffset+r_fb.bloomtexcoord2f[5];
- r_fb.offsettexcoord2f[6] = xoffset+r_fb.bloomtexcoord2f[6];
- r_fb.offsettexcoord2f[7] = yoffset+r_fb.bloomtexcoord2f[7];
+ r_fb.offsettexcoord2f[0] = xoffset+prev->texcoord2f[0];
+ r_fb.offsettexcoord2f[1] = yoffset+prev->texcoord2f[1];
+ r_fb.offsettexcoord2f[2] = xoffset+prev->texcoord2f[2];
+ r_fb.offsettexcoord2f[3] = yoffset+prev->texcoord2f[3];
+ r_fb.offsettexcoord2f[4] = xoffset+prev->texcoord2f[4];
+ r_fb.offsettexcoord2f[5] = yoffset+prev->texcoord2f[5];
+ r_fb.offsettexcoord2f[6] = xoffset+prev->texcoord2f[6];
+ r_fb.offsettexcoord2f[7] = yoffset+prev->texcoord2f[7];
// this r value looks like a 'dot' particle, fading sharply to
// black at the edges
// (probably not realistic but looks good enough)
//r = brighten/(range*2+1);
r = brighten / (range * 2 + 1);
if(range >= 1)
- r *= (1 - x*x/(float)(range*range));
+ r *= (1 - x*x/(float)((range+1)*(range+1)));
+ if (r <= 0)
+ continue;
GL_Color(r, r, r, 1);
R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_fb.offsettexcoord2f);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
r_refdef.stats[r_stat_bloom_drawpixels] += r_fb.bloomwidth * r_fb.bloomheight;
GL_BlendFunc(GL_ONE, GL_ONE);
}
-
- if (!r_fb.bloomfbo[r_fb.bloomindex])
- {
- // copy the vertically or horizontally blurred bloom view to a texture
- R_Mesh_CopyToTexture(r_fb.bloomtexture[r_fb.bloomindex], 0, 0, r_fb.bloomviewport.x, r_fb.bloomviewport.y, r_fb.bloomviewport.width, r_fb.bloomviewport.height);
- r_refdef.stats[r_stat_bloom_copypixels] += r_fb.bloomviewport.width * r_fb.bloomviewport.height;
- }
}
+
+ // now we have the bloom image, so keep track of it
+ r_fb.rt_bloom = cur;
}
-static void R_BlendView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+static void R_BlendView(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
{
dpuint64 permutation;
float uservecs[4][4];
+ rtexture_t *viewtexture;
+ rtexture_t *bloomtexture;
R_EntityMatrix(&identitymatrix);
case RENDERPATH_SOFT:
case RENDERPATH_GLES2:
permutation =
- (r_fb.bloomtexture[r_fb.bloomindex] ? SHADERPERMUTATION_BLOOM : 0)
+ (r_fb.bloomwidth ? SHADERPERMUTATION_BLOOM : 0)
| (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VIEWTINT : 0)
- | ((v_glslgamma.value && !vid_gammatables_trivial) ? SHADERPERMUTATION_GAMMARAMPS : 0)
+ | (!vid_gammatables_trivial ? SHADERPERMUTATION_GAMMARAMPS : 0)
| (r_glsl_postprocess.integer ? SHADERPERMUTATION_POSTPROCESSING : 0)
| ((!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) ? SHADERPERMUTATION_SATURATION : 0);
- if (r_fb.colortexture)
- {
- if (!r_fb.fbo)
+ if(r_refdef.view.ismain && !R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0) && r_fb.ghosttexture)
+ {
+ // declare variables
+ float blur_factor, blur_mouseaccel, blur_velocity;
+ static float blur_average;
+ static vec3_t blur_oldangles; // used to see how quickly the mouse is moving
+
+ // set a goal for the factoring
+ blur_velocity = bound(0, (VectorLength(cl.movement_velocity) - r_motionblur_velocityfactor_minspeed.value)
+ / max(1, r_motionblur_velocityfactor_maxspeed.value - r_motionblur_velocityfactor_minspeed.value), 1);
+ blur_mouseaccel = bound(0, ((fabs(VectorLength(cl.viewangles) - VectorLength(blur_oldangles)) * 10) - r_motionblur_mousefactor_minspeed.value)
+ / max(1, r_motionblur_mousefactor_maxspeed.value - r_motionblur_mousefactor_minspeed.value), 1);
+ blur_factor = ((blur_velocity * r_motionblur_velocityfactor.value)
+ + (blur_mouseaccel * r_motionblur_mousefactor.value));
+
+ // from the goal, pick an averaged value between goal and last value
+ cl.motionbluralpha = bound(0, (cl.time - cl.oldtime) / max(0.001, r_motionblur_averaging.value), 1);
+ blur_average = blur_average * (1 - cl.motionbluralpha) + blur_factor * cl.motionbluralpha;
+
+ // enforce minimum amount of blur
+ blur_factor = blur_average * (1 - r_motionblur_minblur.value) + r_motionblur_minblur.value;
+
+ //Con_Printf("motionblur: direct factor: %f, averaged factor: %f, velocity: %f, mouse accel: %f \n", blur_factor, blur_average, blur_velocity, blur_mouseaccel);
+
+ // calculate values into a standard alpha
+ cl.motionbluralpha = 1 - exp(-
+ (
+ (r_motionblur.value * blur_factor / 80)
+ +
+ (r_damageblur.value * (cl.cshifts[CSHIFT_DAMAGE].percent / 1600))
+ )
+ /
+ max(0.0001, cl.time - cl.oldtime) // fps independent
+ );
+
+ // randomization for the blur value to combat persistent ghosting
+ cl.motionbluralpha *= lhrandom(1 - r_motionblur_randomize.value, 1 + r_motionblur_randomize.value);
+ cl.motionbluralpha = bound(0, cl.motionbluralpha, r_motionblur_maxblur.value);
+
+ // apply the blur
+ R_ResetViewRendering2D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
+ if (cl.motionbluralpha > 0 && !r_refdef.envmap && r_fb.ghosttexture_valid)
{
- R_Mesh_CopyToTexture(r_fb.colortexture, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
- r_refdef.stats[r_stat_bloom_copypixels] += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
- }
-
- if(!R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0) && r_fb.ghosttexture)
- {
- // declare variables
- float blur_factor, blur_mouseaccel, blur_velocity;
- static float blur_average;
- static vec3_t blur_oldangles; // used to see how quickly the mouse is moving
-
- // set a goal for the factoring
- blur_velocity = bound(0, (VectorLength(cl.movement_velocity) - r_motionblur_velocityfactor_minspeed.value)
- / max(1, r_motionblur_velocityfactor_maxspeed.value - r_motionblur_velocityfactor_minspeed.value), 1);
- blur_mouseaccel = bound(0, ((fabs(VectorLength(cl.viewangles) - VectorLength(blur_oldangles)) * 10) - r_motionblur_mousefactor_minspeed.value)
- / max(1, r_motionblur_mousefactor_maxspeed.value - r_motionblur_mousefactor_minspeed.value), 1);
- blur_factor = ((blur_velocity * r_motionblur_velocityfactor.value)
- + (blur_mouseaccel * r_motionblur_mousefactor.value));
-
- // from the goal, pick an averaged value between goal and last value
- cl.motionbluralpha = bound(0, (cl.time - cl.oldtime) / max(0.001, r_motionblur_averaging.value), 1);
- blur_average = blur_average * (1 - cl.motionbluralpha) + blur_factor * cl.motionbluralpha;
-
- // enforce minimum amount of blur
- blur_factor = blur_average * (1 - r_motionblur_minblur.value) + r_motionblur_minblur.value;
-
- //Con_Printf("motionblur: direct factor: %f, averaged factor: %f, velocity: %f, mouse accel: %f \n", blur_factor, blur_average, blur_velocity, blur_mouseaccel);
-
- // calculate values into a standard alpha
- cl.motionbluralpha = 1 - exp(-
- (
- (r_motionblur.value * blur_factor / 80)
- +
- (r_damageblur.value * (cl.cshifts[CSHIFT_DAMAGE].percent / 1600))
- )
- /
- max(0.0001, cl.time - cl.oldtime) // fps independent
- );
-
- // randomization for the blur value to combat persistent ghosting
- cl.motionbluralpha *= lhrandom(1 - r_motionblur_randomize.value, 1 + r_motionblur_randomize.value);
- cl.motionbluralpha = bound(0, cl.motionbluralpha, r_motionblur_maxblur.value);
-
- // apply the blur
- R_ResetViewRendering2D(fbo, depthtexture, colortexture);
- if (cl.motionbluralpha > 0 && !r_refdef.envmap && r_fb.ghosttexture_valid)
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- GL_Color(1, 1, 1, cl.motionbluralpha);
- switch(vid.renderpath)
- {
- case RENDERPATH_GL11:
- case RENDERPATH_GL13:
- case RENDERPATH_GL20:
- case RENDERPATH_GLES1:
- case RENDERPATH_GLES2:
- case RENDERPATH_SOFT:
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_fb.screentexcoord2f);
- break;
- case RENDERPATH_D3D9:
- case RENDERPATH_D3D10:
- case RENDERPATH_D3D11:
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_d3dscreenvertex3f, NULL, r_fb.screentexcoord2f);
- break;
- }
- R_SetupShader_Generic(r_fb.ghosttexture, NULL, GL_MODULATE, 1, false, true, true);
- R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
- r_refdef.stats[r_stat_bloom_drawpixels] += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
- }
-
- // updates old view angles for next pass
- VectorCopy(cl.viewangles, blur_oldangles);
-
- // copy view into the ghost texture
- R_Mesh_CopyToTexture(r_fb.ghosttexture, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
- r_refdef.stats[r_stat_bloom_copypixels] += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
- r_fb.ghosttexture_valid = true;
- }
- }
- else
- {
- // no r_fb.colortexture means we're rendering to the real fb
- // we may still have to do view tint...
- if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
- {
- // apply a color tint to the whole view
- R_ResetViewRendering2D(0, NULL, NULL);
- GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
- R_SetupShader_Generic_NoTexture(false, true);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_Color(1, 1, 1, cl.motionbluralpha);
+ R_CalcTexCoordsForView(0, 0, viewwidth, viewheight, viewwidth, viewheight, r_fb.ghosttexcoord2f);
+ R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_fb.ghosttexcoord2f);
+ R_SetupShader_Generic(r_fb.ghosttexture, NULL, GL_MODULATE, 1, false, true, true);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
+ r_refdef.stats[r_stat_bloom_drawpixels] += viewwidth * viewheight;
}
- break; // no screen processing, no bloom, skip it
+
+ // updates old view angles for next pass
+ VectorCopy(cl.viewangles, blur_oldangles);
+
+ // copy view into the ghost texture
+ R_Mesh_CopyToTexture(r_fb.ghosttexture, 0, 0, viewx, viewy, viewwidth, viewheight);
+ r_refdef.stats[r_stat_bloom_copypixels] += viewwidth * viewheight;
+ r_fb.ghosttexture_valid = true;
}
- if (r_fb.bloomtexture[0])
+ if (r_fb.bloomwidth)
{
// make the bloom texture
R_Bloom_MakeTexture();
if (r_glsl_postprocess_uservec4_enable.integer)
sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &uservecs[3][0], &uservecs[3][1], &uservecs[3][2], &uservecs[3][3]);
- R_ResetViewRendering2D(0, NULL, NULL); // here we render to the real framebuffer!
+ // render to the screen fbo
+ R_ResetViewRendering2D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
GL_Color(1, 1, 1, 1);
GL_BlendFunc(GL_ONE, GL_ZERO);
+ viewtexture = r_fb.rt_screen->colortexture[0];
+ bloomtexture = r_fb.rt_bloom ? r_fb.rt_bloom->colortexture[0] : NULL;
+
+ if (r_rendertarget_debug.integer >= 0)
+ {
+ r_rendertarget_t *rt = (r_rendertarget_t *)Mem_ExpandableArray_RecordAtIndex(&r_fb.rendertargets, r_rendertarget_debug.integer);
+ if (rt && rt->colortexture[0])
+ {
+ viewtexture = rt->colortexture[0];
+ bloomtexture = NULL;
+ }
+ }
+
+ R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_fb.rt_screen->texcoord2f, bloomtexture ? r_fb.rt_bloom->texcoord2f : NULL);
switch(vid.renderpath)
{
case RENDERPATH_GL20:
case RENDERPATH_GLES2:
- R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_fb.screentexcoord2f, r_fb.bloomtexcoord2f);
R_SetupShader_SetPermutationGLSL(SHADERMODE_POSTPROCESS, permutation);
- if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_fb.colortexture);
- if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_fb.bloomtexture[r_fb.bloomindex]);
+ if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , viewtexture);
+ if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , bloomtexture);
if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps );
if (r_glsl_permutation->loc_ViewTintColor >= 0) qglUniform4f(r_glsl_permutation->loc_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
if (r_glsl_permutation->loc_PixelSize >= 0) qglUniform2f(r_glsl_permutation->loc_PixelSize , 1.0/r_fb.screentexturewidth, 1.0/r_fb.screentextureheight);
break;
case RENDERPATH_D3D9:
#ifdef SUPPORTD3D
- // D3D has upside down Y coords, the easiest way to flip this is to flip the screen vertices rather than the texcoords, so we just use a different array for that...
- R_Mesh_PrepareVertices_Mesh_Arrays(4, r_d3dscreenvertex3f, NULL, NULL, NULL, NULL, r_fb.screentexcoord2f, r_fb.bloomtexcoord2f);
R_SetupShader_SetPermutationHLSL(SHADERMODE_POSTPROCESS, permutation);
- R_Mesh_TexBind(GL20TU_FIRST , r_fb.colortexture);
- R_Mesh_TexBind(GL20TU_SECOND , r_fb.bloomtexture[r_fb.bloomindex]);
+ R_Mesh_TexBind(GL20TU_FIRST , viewtexture);
+ R_Mesh_TexBind(GL20TU_SECOND , bloomtexture);
R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
hlslPSSetParameter4f(D3DPSREGISTER_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
hlslPSSetParameter2f(D3DPSREGISTER_PixelSize , 1.0/r_fb.screentexturewidth, 1.0/r_fb.screentextureheight);
Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
break;
case RENDERPATH_SOFT:
- R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_fb.screentexcoord2f, r_fb.bloomtexcoord2f);
R_SetupShader_SetPermutationSoft(SHADERMODE_POSTPROCESS, permutation);
- R_Mesh_TexBind(GL20TU_FIRST , r_fb.colortexture);
- R_Mesh_TexBind(GL20TU_SECOND , r_fb.bloomtexture[r_fb.bloomindex]);
+ R_Mesh_TexBind(GL20TU_FIRST , viewtexture);
+ R_Mesh_TexBind(GL20TU_SECOND , bloomtexture);
R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelSize , 1.0/r_fb.screentexturewidth, 1.0/r_fb.screentextureheight);
if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
{
// apply a color tint to the whole view
- R_ResetViewRendering2D(0, NULL, NULL);
+ R_ResetViewRendering2D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
R_SetupShader_Generic_NoTexture(false, true);
{
R_Textures_Frame();
- r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f);
+ r_refdef.scene.ambientintensity = r_ambient.value * (1.0f / 64.0f);
r_refdef.farclip = r_farclip_base.value;
if (r_refdef.scene.worldmodel)
r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil;
r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
- r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+ r_refdef.scene.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
if (FAKELIGHT_ENABLED)
{
- r_refdef.lightmapintensity *= r_fakelight_intensity.value;
+ r_refdef.scene.lightmapintensity *= r_fakelight_intensity.value;
}
else if (r_refdef.scene.worldmodel)
{
- r_refdef.lightmapintensity *= r_refdef.scene.worldmodel->lightmapscale;
+ r_refdef.scene.lightmapintensity *= r_refdef.scene.worldmodel->lightmapscale;
}
if (r_showsurfaces.integer)
{
r_refdef.scene.rtworldshadows = false;
r_refdef.scene.rtdlight = false;
r_refdef.scene.rtdlightshadows = false;
- r_refdef.lightmapintensity = 0;
+ r_refdef.scene.lightmapintensity = 0;
}
r_gpuskeletal = false;
case RENDERPATH_D3D11:
case RENDERPATH_SOFT:
case RENDERPATH_GLES2:
- if(v_glslgamma.integer && !vid_gammatables_trivial)
+ if(!vid_gammatables_trivial)
{
if(!r_texture_gammaramps || vid_gammatables_serial != r_texture_gammaramps_serial)
{
*/
int dpsoftrast_test;
extern cvar_t r_shadow_bouncegrid;
-void R_RenderView(void)
+void R_RenderView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int x, int y, int width, int height)
{
matrix4x4_t originalmatrix = r_refdef.view.matrix, offsetmatrix;
- int fbo;
- rtexture_t *depthtexture;
- rtexture_t *colortexture;
+ int viewfbo = 0;
+ rtexture_t *viewdepthtexture = NULL;
+ rtexture_t *viewcolortexture = NULL;
+ int viewx = r_refdef.view.x, viewy = r_refdef.view.y, viewwidth = r_refdef.view.width, viewheight = r_refdef.view.height;
dpsoftrast_test = r_test.integer;
if (r_timereport_active)
R_TimeReport("start");
r_textureframe++; // used only by R_GetCurrentTexture
- rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
+ rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
if(R_CompileShader_CheckStaticParms())
R_GLSL_Restart_f();
r_fb.water.enabled = false;
r_fb.water.numwaterplanes = 0;
- R_RenderScene(0, NULL, NULL);
+ R_RenderScene(0, NULL, NULL, r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
r_refdef.view.matrix = originalmatrix;
R_Shadow_UpdateWorldLightSelection();
+ // this will set up r_fb.rt_screen
R_Bloom_StartFrame();
// apply bloom brightness offset
- if(r_fb.bloomtexture[0])
+ if(r_fb.rt_bloom)
r_refdef.view.colorscale *= r_bloom_scenebrightness.value;
- R_Water_StartFrame();
+ // R_Bloom_StartFrame probably set up an fbo for us to render into, it will be rendered to the window later in R_BlendView
+ if (r_fb.rt_screen)
+ {
+ viewfbo = r_fb.rt_screen->fbo;
+ viewdepthtexture = r_fb.rt_screen->depthtexture;
+ viewcolortexture = r_fb.rt_screen->colortexture[0];
+ viewx = 0;
+ viewy = 0;
+ viewwidth = width;
+ viewheight = height;
+ }
- // now we probably have an fbo to render into
- fbo = r_fb.fbo;
- depthtexture = r_fb.depthtexture;
- colortexture = r_fb.colortexture;
+ R_Water_StartFrame();
CHECKGLERROR
if (r_timereport_active)
R_TimeReport("viewsetup");
- R_ResetViewRendering3D(fbo, depthtexture, colortexture);
+ R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
+
+ // clear the whole fbo every frame - otherwise the driver will consider
+ // it to be an inter-frame texture and stall in multi-gpu configurations
+ if (r_fb.rt_screen)
+ GL_ScissorTest(false);
+ R_ClearScreen(r_refdef.fogenabled);
+ if (r_timereport_active)
+ R_TimeReport("viewclear");
- if (r_refdef.view.clear || r_refdef.fogenabled || fbo)
- {
- R_ClearScreen(r_refdef.fogenabled);
- if (r_timereport_active)
- R_TimeReport("viewclear");
- }
r_refdef.view.clear = true;
r_refdef.view.showdebug = true;
r_fb.water.numwaterplanes = 0;
if (r_fb.water.enabled)
- R_RenderWaterPlanes(fbo, depthtexture, colortexture);
-
- R_RenderScene(fbo, depthtexture, colortexture);
+ R_RenderWaterPlanes(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
+
+ // for the actual view render we use scissoring a fair amount, so scissor
+ // test needs to be on
+ if (r_fb.rt_screen)
+ GL_ScissorTest(true);
+ GL_Scissor(viewx, viewy, viewwidth, viewheight);
+ R_RenderScene(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
r_fb.water.numwaterplanes = 0;
- R_BlendView(fbo, depthtexture, colortexture);
+ // postprocess uses textures that are not aligned with the viewport we're rendering, so no scissoring
+ GL_ScissorTest(false);
+
+ R_BlendView(fbo, depthtexture, colortexture, x, y, width, height);
if (r_timereport_active)
R_TimeReport("blendview");
- GL_Scissor(0, 0, vid.width, vid.height);
- GL_ScissorTest(false);
-
r_refdef.view.matrix = originalmatrix;
CHECKGLERROR
}
-void R_RenderWaterPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture)
+void R_RenderWaterPlanes(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
{
if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawAddWaterPlanes)
{
if (r_fb.water.numwaterplanes)
{
- R_Water_ProcessPlanes(fbo, depthtexture, colortexture);
+ R_Water_ProcessPlanes(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
if (r_timereport_active)
R_TimeReport("waterscenes");
}
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)
+void R_RenderScene(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
{
qboolean shadowmapping = false;
if (skyrendermasked && skyrenderlater)
{
// we have to force off the water clipping plane while rendering sky
- R_SetupView(false, fbo, depthtexture, colortexture);
+ R_SetupView(false, viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
R_Sky();
- R_SetupView(true, fbo, depthtexture, colortexture);
+ R_SetupView(true, viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
if (r_timereport_active)
R_TimeReport("sky");
}
}
+ // save the framebuffer info for R_Shadow_RenderMode_Reset during this view render
+ r_shadow_viewfbo = viewfbo;
+ r_shadow_viewdepthtexture = viewdepthtexture;
+ r_shadow_viewcolortexture = viewcolortexture;
+ r_shadow_viewx = viewx;
+ r_shadow_viewy = viewy;
+ r_shadow_viewwidth = viewwidth;
+ r_shadow_viewheight = viewheight;
+
R_Shadow_PrepareModelShadows();
- R_Shadow_PrepareLights(fbo, depthtexture, colortexture);
+ R_Shadow_PrepareLights();
if (r_timereport_active)
R_TimeReport("preparelights");
if (r_refdef.scene.extraupdate)
S_ExtraUpdate ();
- if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
+ if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0)
{
- R_ResetViewRendering3D(fbo, depthtexture, colortexture);
+ R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
R_Shadow_DrawModelShadows();
- R_ResetViewRendering3D(fbo, depthtexture, colortexture);
+ R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
// don't let sound skip if going slow
if (r_refdef.scene.extraupdate)
S_ExtraUpdate ();
if (r_refdef.scene.extraupdate)
S_ExtraUpdate ();
- if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
+ if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0)
{
- R_ResetViewRendering3D(fbo, depthtexture, colortexture);
+ R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
R_Shadow_DrawModelShadows();
- R_ResetViewRendering3D(fbo, depthtexture, colortexture);
+ R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight);
// don't let sound skip if going slow
if (r_refdef.scene.extraupdate)
S_ExtraUpdate ();
R_TimeReport("explosions");
}
- if (cl.csqc_loaded)
- VM_CL_AddPolygonsToMeshQueue(CLVM_prog);
-
if (r_refdef.view.showdebug)
{
if (cl_locs_show.integer)
int i, edge;
float *v, *c, f1, f2, edgemins[3], edgemaxs[3];
- RSurf_ActiveWorldEntity();
+ RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_DepthMask(false);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
GL_DepthMask(false);
}
- else if (rsurface.colormod[3] < 1)
+ else if (ent->alpha < 1)
{
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_DepthMask(false);
memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
for (i = 0, c = color4f;i < 6;i++, c += 4)
{
- c[0] *= rsurface.colormod[0];
- c[1] *= rsurface.colormod[1];
- c[2] *= rsurface.colormod[2];
- c[3] *= rsurface.colormod[3];
+ c[0] *= ent->render_fullbright[0] * r_refdef.view.colorscale;
+ c[1] *= ent->render_fullbright[1] * r_refdef.view.colorscale;
+ c[2] *= ent->render_fullbright[2] * r_refdef.view.colorscale;
+ c[3] *= ent->alpha;
}
if (r_refdef.fogenabled)
{
texture_t *R_GetCurrentTexture(texture_t *t)
{
- int i;
+ int i, q;
const entity_render_t *ent = rsurface.entity;
dp_model_t *model = ent->model; // when calling this, ent must not be NULL
q3shaderinfo_layer_tcmod_t *tcmod;
+ float specularscale = 0.0f;
if (t->update_lastrenderframe == r_textureframe && t->update_lastrenderentity == (void *)ent && !rsurface.forcecurrenttextureupdate)
return t->currentframe;
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->currentalpha = rsurface.entity->alpha * t->basealpha;
if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer || r_trippy.integer))
t->currentalpha *= r_wateralpha.value;
if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay)
t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; // we apply wateralpha later
if(!r_fb.water.enabled || r_refdef.view.isoverlay)
t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA);
- if (!(rsurface.ent_flags & RENDER_LIGHT))
- t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
+
+ // decide on which type of lighting to use for this surface
+ if (rsurface.entity->render_modellight_forced)
+ t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT;
+ if (rsurface.entity->render_rtlight_disabled)
+ t->currentmaterialflags |= MATERIALFLAG_NORTLIGHT;
+ if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND && !(R_BlendFuncFlags(t->customblendfunc[0], t->customblendfunc[1]) & BLENDFUNC_ALLOWS_COLORMOD))
+ {
+ // some CUSTOMBLEND blendfuncs are too weird, we have to ignore colormod and view colorscale
+ t->currentmaterialflags = t->currentmaterialflags | MATERIALFLAG_NORTLIGHT;
+ for (q = 0; q < 3; q++)
+ {
+ t->render_glowmod[q] = rsurface.entity->glowmod[q];
+ t->render_modellight_lightdir[q] = q == 2;
+ t->render_modellight_ambient[q] = 1;
+ t->render_modellight_diffuse[q] = 0;
+ t->render_modellight_specular[q] = 0;
+ t->render_lightmap_ambient[q] = 0;
+ t->render_lightmap_diffuse[q] = 0;
+ t->render_lightmap_specular[q] = 0;
+ t->render_rtlight_diffuse[q] = 0;
+ t->render_rtlight_specular[q] = 0;
+ }
+ }
+ else if ((t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) || !(rsurface.ent_flags & RENDER_LIGHT))
+ {
+ // fullbright is basically MATERIALFLAG_MODELLIGHT but with ambient locked to 1,1,1 and no shading
+ t->currentmaterialflags = t->currentmaterialflags | MATERIALFLAG_NORTLIGHT | MATERIALFLAG_MODELLIGHT;
+ for (q = 0; q < 3; q++)
+ {
+ t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale;
+ t->render_modellight_ambient[q] = rsurface.entity->render_fullbright[q] * r_refdef.view.colorscale;
+ t->render_modellight_lightdir[q] = q == 2;
+ t->render_modellight_diffuse[q] = 0;
+ t->render_modellight_specular[q] = 0;
+ t->render_lightmap_ambient[q] = 0;
+ t->render_lightmap_diffuse[q] = 0;
+ t->render_lightmap_specular[q] = 0;
+ t->render_rtlight_diffuse[q] = 0;
+ t->render_rtlight_specular[q] = 0;
+ }
+ }
else if (FAKELIGHT_ENABLED)
{
// no modellight if using fakelight for the map
+ t->currentmaterialflags = (t->currentmaterialflags | MATERIALFLAG_NORTLIGHT) & ~(MATERIALFLAG_MODELLIGHT);
+ for (q = 0; q < 3; q++)
+ {
+ t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale;
+ t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q];
+ t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale;
+ t->render_modellight_diffuse[q] = rsurface.entity->render_modellight_diffuse[q] * r_refdef.view.colorscale;
+ t->render_modellight_specular[q] = rsurface.entity->render_modellight_specular[q] * r_refdef.view.colorscale;
+ t->render_lightmap_ambient[q] = 0;
+ t->render_lightmap_diffuse[q] = 0;
+ t->render_lightmap_specular[q] = 0;
+ t->render_rtlight_diffuse[q] = 0;
+ t->render_rtlight_specular[q] = 0;
+ }
+ }
+ else if ((rsurface.ent_flags & (RENDER_DYNAMICMODELLIGHT | RENDER_CUSTOMIZEDMODELLIGHT)) || rsurface.modeltexcoordlightmap2f == NULL)
+ {
+ // ambient + single direction light (modellight)
+ t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT;
+ for (q = 0; q < 3; q++)
+ {
+ t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale;
+ t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q];
+ t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale;
+ t->render_modellight_diffuse[q] = rsurface.entity->render_modellight_diffuse[q] * r_refdef.view.colorscale;
+ t->render_modellight_specular[q] = rsurface.entity->render_modellight_specular[q] * r_refdef.view.colorscale;
+ t->render_lightmap_ambient[q] = 0;
+ t->render_lightmap_diffuse[q] = 0;
+ t->render_lightmap_specular[q] = 0;
+ t->render_rtlight_diffuse[q] = rsurface.entity->render_rtlight_diffuse[q] * r_refdef.view.colorscale;
+ t->render_rtlight_specular[q] = rsurface.entity->render_rtlight_specular[q] * r_refdef.view.colorscale;
+ }
}
- else if ((rsurface.modeltexcoordlightmap2f == NULL || (rsurface.ent_flags & (RENDER_DYNAMICMODELLIGHT | RENDER_CUSTOMIZEDMODELLIGHT))) && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
+ else
{
- // pick a model lighting mode
- if (VectorLength2(rsurface.modellight_diffuse) >= (1.0f / 256.0f))
- t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL;
- else
- t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT;
+ // lightmap - 2x diffuse and specular brightness because bsp files have 0-2 colors as 0-1
+ for (q = 0; q < 3; q++)
+ {
+ t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale;
+ t->render_modellight_lightdir[q] = q == 2;
+ t->render_modellight_ambient[q] = 0;
+ t->render_modellight_diffuse[q] = 0;
+ t->render_modellight_specular[q] = 0;
+ t->render_lightmap_ambient[q] = rsurface.entity->render_lightmap_ambient[q] * r_refdef.view.colorscale;
+ t->render_lightmap_diffuse[q] = rsurface.entity->render_lightmap_diffuse[q] * 2 * r_refdef.view.colorscale;
+ t->render_lightmap_specular[q] = rsurface.entity->render_lightmap_specular[q] * 2 * r_refdef.view.colorscale;
+ t->render_rtlight_diffuse[q] = rsurface.entity->render_rtlight_diffuse[q] * r_refdef.view.colorscale;
+ t->render_rtlight_specular[q] = rsurface.entity->render_rtlight_specular[q] * r_refdef.view.colorscale;
+ }
+ }
+
+ if (t->currentmaterialflags & MATERIALFLAG_VERTEXCOLOR)
+ {
+ // since MATERIALFLAG_VERTEXCOLOR uses the lightmapcolor4f vertex
+ // attribute, we punt it to the lightmap path and hope for the best,
+ // but lighting doesn't work.
+ //
+ // FIXME: this is fine for effects but CSQC polygons should be subject
+ // to lighting.
+ t->currentmaterialflags &= ~MATERIALFLAG_MODELLIGHT;
+ for (q = 0; q < 3; q++)
+ {
+ t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale;
+ t->render_modellight_lightdir[q] = q == 2;
+ t->render_modellight_ambient[q] = 0;
+ t->render_modellight_diffuse[q] = 0;
+ t->render_modellight_specular[q] = 0;
+ t->render_lightmap_ambient[q] = 0;
+ t->render_lightmap_diffuse[q] = rsurface.entity->render_fullbright[q] * r_refdef.view.colorscale;
+ t->render_lightmap_specular[q] = 0;
+ t->render_rtlight_diffuse[q] = 0;
+ t->render_rtlight_specular[q] = 0;
+ }
}
+
+ for (q = 0; q < 3; q++)
+ {
+ t->render_colormap_pants[q] = rsurface.entity->colormap_pantscolor[q];
+ t->render_colormap_shirt[q] = rsurface.entity->colormap_shirtcolor[q];
+ }
+
if (rsurface.ent_flags & RENDER_ADDITIVE)
t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
else if (t->currentalpha < 1)
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);
+ t->colormapping = VectorLength2(t->render_colormap_pants) + VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f);
if (t->currentskinframe->qpixels)
R_SkinFrame_GenerateTexturesFromQPixels(t->currentskinframe, t->colormapping);
t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base;
}
t->specularpower = r_shadow_glossexponent.value;
// TODO: store reference values for these in the texture?
- t->specularscale = 0;
if (r_shadow_gloss.integer > 0)
{
if (t->currentskinframe->gloss || (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss))
{
t->glosstexture = t->currentskinframe->gloss ? t->currentskinframe->gloss : r_texture_white;
t->backgroundglosstexture = (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss) ? t->backgroundcurrentskinframe->gloss : r_texture_white;
- t->specularscale = r_shadow_glossintensity.value;
+ specularscale = r_shadow_glossintensity.value;
}
}
else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
{
t->glosstexture = r_texture_white;
t->backgroundglosstexture = r_texture_white;
- t->specularscale = r_shadow_gloss2intensity.value;
+ specularscale = r_shadow_gloss2intensity.value;
t->specularpower = r_shadow_gloss2exponent.value;
}
}
- t->specularscale *= t->specularscalemod;
+ specularscale *= t->specularscalemod;
t->specularpower *= t->specularpowermod;
- t->rtlightambient = 0;
// lightmaps mode looks bad with dlights using actual texturing, so turn
// off the colormap and glossmap, but leave the normalmap on as it still
t->backgroundnmaptexture = r_texture_blanknormalmap;
t->backgroundglosstexture = r_texture_black;
t->backgroundglowtexture = NULL;
- t->specularscale = 0;
- t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE));
+ specularscale = 0;
+ t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE));
+ }
+
+ if (specularscale != 1.0f)
+ {
+ for (q = 0; q < 3; q++)
+ {
+ t->render_modellight_specular[q] *= specularscale;
+ t->render_lightmap_specular[q] *= specularscale;
+ t->render_rtlight_specular[q] *= specularscale;
+ }
}
- Vector4Set(t->lightmapcolor, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2], t->currentalpha);
- VectorClear(t->dlightcolor);
t->currentnumlayers = 0;
if (t->currentmaterialflags & MATERIALFLAG_WALL)
{
blendfunc1 = GL_ONE;
blendfunc2 = GL_ZERO;
}
- // don't colormod evilblend textures
- if(!(R_BlendFuncFlags(blendfunc1, blendfunc2) & BLENDFUNC_ALLOWS_COLORMOD))
- VectorSet(t->lightmapcolor, 1, 1, 1);
depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
- if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
+ if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
{
- // fullbright is not affected by r_refdef.lightmapintensity
- R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]);
- if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * t->lightmapcolor[0], rsurface.colormap_pantscolor[1] * t->lightmapcolor[1], rsurface.colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]);
- if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * t->lightmapcolor[0], rsurface.colormap_shirtcolor[1] * t->lightmapcolor[1], rsurface.colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]);
- }
- else
- {
- vec3_t ambientcolor;
- float colorscale;
- // set the color tint used for lights affecting this surface
- VectorSet(t->dlightcolor, t->lightmapcolor[0] * t->lightmapcolor[3], t->lightmapcolor[1] * t->lightmapcolor[3], t->lightmapcolor[2] * t->lightmapcolor[3]);
- colorscale = 2;
- // q3bsp has no lightmap updates, so the lightstylevalue that
- // would normally be baked into the lightmap must be
- // applied to the color
- // FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright)
- if (model->type == mod_brushq3)
- colorscale *= r_refdef.scene.rtlightstylevalue[0];
- colorscale *= r_refdef.lightmapintensity;
- VectorScale(t->lightmapcolor, r_refdef.scene.ambient, ambientcolor);
- VectorScale(t->lightmapcolor, colorscale, t->lightmapcolor);
// basic lit geometry
- R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]);
+ R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2], t->currentalpha);
// add pants/shirt if needed
- if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * t->lightmapcolor[0], rsurface.colormap_pantscolor[1] * t->lightmapcolor[1], rsurface.colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]);
- if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * t->lightmapcolor[0], rsurface.colormap_shirtcolor[1] * t->lightmapcolor[1], rsurface.colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]);
- // now add ambient passes if needed
- if (VectorLength2(ambientcolor) >= (1.0f/1048576.0f))
- {
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, ambientcolor[0], ambientcolor[1], ambientcolor[2], t->lightmapcolor[3]);
- if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * ambientcolor[0], rsurface.colormap_pantscolor[1] * ambientcolor[1], rsurface.colormap_pantscolor[2] * ambientcolor[2], t->lightmapcolor[3]);
- if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * ambientcolor[0], rsurface.colormap_shirtcolor[1] * ambientcolor[1], rsurface.colormap_shirtcolor[2] * ambientcolor[2], t->lightmapcolor[3]);
- }
+ if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture)
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_diffuse[0], t->render_colormap_pants[1] * t->render_lightmap_diffuse[1], t->render_colormap_pants[2] * t->render_lightmap_diffuse[2], t->currentalpha);
+ if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture)
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_diffuse[0], t->render_colormap_shirt[1] * t->render_lightmap_diffuse[1], t->render_colormap_shirt[2] * t->render_lightmap_diffuse[2], t->currentalpha);
}
- if (t->glowtexture != NULL && !gl_lightmaps.integer)
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->glowtexture, &t->currenttexmatrix, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2], t->lightmapcolor[3]);
- if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
- {
- // if this is opaque use alpha blend which will darken the earlier
- // passes cheaply.
- //
- // if this is an alpha blended material, all the earlier passes
- // were darkened by fog already, so we only need to add the fog
- // color ontop through the fog mask texture
- //
- // if this is an additive blended material, all the earlier passes
- // were darkened by fog already, and we should not add fog color
- // (because the background was not darkened, there is no fog color
- // that was lost behind it).
- R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->fogtexture, &t->currenttexmatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->lightmapcolor[3]);
- }
- }
-
- return t;
-}
-
-rsurfacestate_t rsurface;
-
-void RSurf_ActiveWorldEntity(void)
-{
- dp_model_t *model = r_refdef.scene.worldmodel;
- //if (rsurface.entity == r_refdef.scene.worldentity)
- // return;
- rsurface.entity = r_refdef.scene.worldentity;
- rsurface.skeleton = NULL;
- memset(rsurface.userwavefunc_param, 0, sizeof(rsurface.userwavefunc_param));
- rsurface.ent_skinnum = 0;
- rsurface.ent_qwskin = -1;
- rsurface.ent_flags = r_refdef.scene.worldentity->flags;
- rsurface.shadertime = r_refdef.scene.time;
- rsurface.matrix = identitymatrix;
- rsurface.inversematrix = identitymatrix;
- rsurface.matrixscale = 1;
- rsurface.inversematrixscale = 1;
- R_EntityMatrix(&identitymatrix);
- VectorCopy(r_refdef.view.origin, rsurface.localvieworigin);
- Vector4Copy(r_refdef.fogplane, rsurface.fogplane);
- rsurface.fograngerecip = r_refdef.fograngerecip;
- rsurface.fogheightfade = r_refdef.fogheightfade;
- rsurface.fogplaneviewdist = r_refdef.fogplaneviewdist;
- rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
- if (r_fullbright_directed.integer && (r_fullbright.integer || !model->lit))
- {
- R_GetDirectedFullbright(rsurface.modellight_ambient, rsurface.modellight_diffuse, rsurface.modellight_lightdir);
- rsurface.ent_flags |= RENDER_LIGHT | RENDER_DYNAMICMODELLIGHT;
- }
- else
- {
- VectorSet(rsurface.modellight_ambient, 0, 0, 0);
- VectorSet(rsurface.modellight_diffuse, 0, 0, 0);
- VectorSet(rsurface.modellight_lightdir, 0, 0, 1);
- }
- VectorSet(rsurface.colormap_pantscolor, 0, 0, 0);
- VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0);
- VectorSet(rsurface.colormod, r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale);
- rsurface.colormod[3] = 1;
- VectorSet(rsurface.glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value);
- memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend));
- rsurface.frameblend[0].lerp = 1;
- rsurface.ent_alttextures = false;
- rsurface.basepolygonfactor = r_refdef.polygonfactor;
- rsurface.basepolygonoffset = r_refdef.polygonoffset;
- rsurface.entityskeletaltransform3x4 = NULL;
- rsurface.entityskeletaltransform3x4buffer = NULL;
- rsurface.entityskeletaltransform3x4offset = 0;
- rsurface.entityskeletaltransform3x4size = 0;;
- rsurface.entityskeletalnumtransforms = 0;
- rsurface.modelvertex3f = model->surfmesh.data_vertex3f;
- rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f;
- rsurface.modelsvector3f = model->surfmesh.data_svector3f;
- rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f;
- rsurface.modeltvector3f = model->surfmesh.data_tvector3f;
- rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f;
- rsurface.modelnormal3f = model->surfmesh.data_normal3f;
- rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f;
- rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f;
- rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f;
- rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f;
- rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f;
- rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f;
- rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f;
- rsurface.modelskeletalindex4ub = model->surfmesh.data_skeletalindex4ub;
- rsurface.modelskeletalindex4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelskeletalindex4ub_bufferoffset = model->surfmesh.vbooffset_skeletalindex4ub;
- rsurface.modelskeletalweight4ub = model->surfmesh.data_skeletalweight4ub;
- rsurface.modelskeletalweight4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelskeletalweight4ub_bufferoffset = model->surfmesh.vbooffset_skeletalweight4ub;
- rsurface.modelelement3i = model->surfmesh.data_element3i;
- rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer;
- rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset;
- rsurface.modelelement3s = model->surfmesh.data_element3s;
- rsurface.modelelement3s_indexbuffer = model->surfmesh.data_element3s_indexbuffer;
- rsurface.modelelement3s_bufferoffset = model->surfmesh.data_element3s_bufferoffset;
- rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets;
- rsurface.modelnumvertices = model->surfmesh.num_vertices;
- rsurface.modelnumtriangles = model->surfmesh.num_triangles;
- rsurface.modelsurfaces = model->data_surfaces;
- rsurface.modelvertexmesh = model->surfmesh.data_vertexmesh;
- rsurface.modelvertexmesh_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
- rsurface.modelvertexmesh_bufferoffset = model->surfmesh.vbooffset_vertex3f;
- rsurface.modelgeneratedvertex = false;
- rsurface.batchgeneratedvertex = false;
- rsurface.batchfirstvertex = 0;
- rsurface.batchnumvertices = 0;
- rsurface.batchfirsttriangle = 0;
- rsurface.batchnumtriangles = 0;
- rsurface.batchvertex3f = NULL;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
- rsurface.batchsvector3f = NULL;
- rsurface.batchsvector3f_vertexbuffer = NULL;
- rsurface.batchsvector3f_bufferoffset = 0;
- rsurface.batchtvector3f = NULL;
- rsurface.batchtvector3f_vertexbuffer = NULL;
- rsurface.batchtvector3f_bufferoffset = 0;
- rsurface.batchnormal3f = NULL;
- rsurface.batchnormal3f_vertexbuffer = NULL;
- rsurface.batchnormal3f_bufferoffset = 0;
- rsurface.batchlightmapcolor4f = NULL;
- rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
- rsurface.batchlightmapcolor4f_bufferoffset = 0;
- rsurface.batchtexcoordtexture2f = NULL;
- rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
- rsurface.batchtexcoordtexture2f_bufferoffset = 0;
- rsurface.batchtexcoordlightmap2f = NULL;
- rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
- rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
- rsurface.batchskeletalindex4ub = NULL;
- rsurface.batchskeletalindex4ub_vertexbuffer = NULL;
- rsurface.batchskeletalindex4ub_bufferoffset = 0;
- rsurface.batchskeletalweight4ub = NULL;
- rsurface.batchskeletalweight4ub_vertexbuffer = NULL;
- rsurface.batchskeletalweight4ub_bufferoffset = 0;
- rsurface.batchvertexmesh = NULL;
- rsurface.batchvertexmesh_vertexbuffer = NULL;
- rsurface.batchvertexmesh_bufferoffset = 0;
- rsurface.batchelement3i = NULL;
- rsurface.batchelement3i_indexbuffer = NULL;
- rsurface.batchelement3i_bufferoffset = 0;
- rsurface.batchelement3s = NULL;
- rsurface.batchelement3s_indexbuffer = NULL;
- rsurface.batchelement3s_bufferoffset = 0;
- rsurface.passcolor4f = NULL;
- rsurface.passcolor4f_vertexbuffer = NULL;
- rsurface.passcolor4f_bufferoffset = 0;
- rsurface.forcecurrenttextureupdate = false;
+ else
+ {
+ // basic lit geometry
+ R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2], t->currentalpha);
+ // add pants/shirt if needed
+ if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture)
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_diffuse[0], t->render_colormap_pants[1] * t->render_lightmap_diffuse[1], t->render_colormap_pants[2] * t->render_lightmap_diffuse[2], t->currentalpha);
+ if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture)
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_diffuse[0], t->render_colormap_shirt[1] * t->render_lightmap_diffuse[1], t->render_colormap_shirt[2] * t->render_lightmap_diffuse[2], t->currentalpha);
+ // now add ambient passes if needed
+ if (VectorLength2(t->render_lightmap_ambient) >= (1.0f/1048576.0f))
+ {
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2], t->currentalpha);
+ if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture)
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_ambient[0], t->render_colormap_pants[1] * t->render_lightmap_ambient[1], t->render_colormap_pants[2] * t->render_lightmap_ambient[2], t->currentalpha);
+ if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture)
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_ambient[0], t->render_colormap_shirt[1] * t->render_lightmap_ambient[1], t->render_colormap_shirt[2] * t->render_lightmap_ambient[2], t->currentalpha);
+ }
+ }
+ if (t->glowtexture != NULL && !gl_lightmaps.integer)
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->glowtexture, &t->currenttexmatrix, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2], t->currentalpha);
+ if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
+ {
+ // if this is opaque use alpha blend which will darken the earlier
+ // passes cheaply.
+ //
+ // if this is an alpha blended material, all the earlier passes
+ // were darkened by fog already, so we only need to add the fog
+ // color ontop through the fog mask texture
+ //
+ // if this is an additive blended material, all the earlier passes
+ // were darkened by fog already, and we should not add fog color
+ // (because the background was not darkened, there is no fog color
+ // that was lost behind it).
+ R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->fogtexture, &t->currenttexmatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->currentalpha);
+ }
+ }
+
+ return t;
}
+rsurfacestate_t rsurface;
+
void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass)
{
dp_model_t *model = ent->model;
rsurface.ent_qwskin = (ent->entitynumber <= cl.maxclients && ent->entitynumber >= 1 && cls.protocol == PROTOCOL_QUAKEWORLD && cl.scores[ent->entitynumber - 1].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) ? (ent->entitynumber - 1) : -1;
rsurface.ent_flags = ent->flags;
if (r_fullbright_directed.integer && (r_fullbright.integer || !model->lit))
- {
rsurface.ent_flags |= RENDER_LIGHT | RENDER_DYNAMICMODELLIGHT;
- }
rsurface.shadertime = r_refdef.scene.time - ent->shadertime;
rsurface.matrix = ent->matrix;
rsurface.inversematrix = ent->inversematrix;
rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale;
rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale;
rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
- VectorCopy(ent->modellight_ambient, rsurface.modellight_ambient);
- VectorCopy(ent->modellight_diffuse, rsurface.modellight_diffuse);
- VectorCopy(ent->modellight_lightdir, rsurface.modellight_lightdir);
- VectorCopy(ent->colormap_pantscolor, rsurface.colormap_pantscolor);
- VectorCopy(ent->colormap_shirtcolor, rsurface.colormap_shirtcolor);
- VectorScale(ent->colormod, r_refdef.view.colorscale, rsurface.colormod);
- rsurface.colormod[3] = ent->alpha;
- VectorScale(ent->glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, rsurface.glowmod);
memcpy(rsurface.frameblend, ent->frameblend, sizeof(ent->frameblend));
rsurface.ent_alttextures = ent->framegroupblend[0].frame != 0;
rsurface.basepolygonfactor = r_refdef.polygonfactor;
rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale;
rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale;
rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
- VectorSet(rsurface.modellight_ambient, 0, 0, 0);
- VectorSet(rsurface.modellight_diffuse, 0, 0, 0);
- VectorSet(rsurface.modellight_lightdir, 0, 0, 1);
- VectorSet(rsurface.colormap_pantscolor, 0, 0, 0);
- VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0);
- Vector4Set(rsurface.colormod, r * r_refdef.view.colorscale, g * r_refdef.view.colorscale, b * r_refdef.view.colorscale, a);
- VectorSet(rsurface.glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value);
memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend));
rsurface.frameblend[0].lerp = 1;
rsurface.ent_alttextures = false;
rsurface.passcolor4f_bufferoffset = 0;
for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
{
- c2[0] = c[0] + r_refdef.scene.ambient;
- c2[1] = c[1] + r_refdef.scene.ambient;
- c2[2] = c[2] + r_refdef.scene.ambient;
+ c2[0] = c[0] + rsurface.texture->render_lightmap_ambient[0];
+ c2[1] = c[1] + rsurface.texture->render_lightmap_ambient[1];
+ c2[2] = c[2] + rsurface.texture->render_lightmap_ambient[2];
c2[3] = c[3];
}
}
}
}
-static void RSurf_DrawBatch_GL11_ApplyFakeLight(void)
+static void RSurf_DrawBatch_GL11_ApplyFakeLight(float fakelightintensity)
{
int i;
float f;
f = -DotProduct(r_refdef.view.forward, n);
f = max(0, f);
f = f * 0.85 + 0.15; // work around so stuff won't get black
- f *= r_refdef.lightmapintensity;
+ f *= fakelightintensity;
Vector4Set(c, f, f, f, 1);
}
}
static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
{
- RSurf_DrawBatch_GL11_ApplyFakeLight();
+ RSurf_DrawBatch_GL11_ApplyFakeLight(r_refdef.scene.lightmapintensity * r_fakelight_intensity.value);
if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
RSurf_DrawBatch();
}
-static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, qboolean *applycolor)
+static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, float lightmapintensity, qboolean *applycolor)
{
int i;
float f;
vec3_t lightdir;
// TODO: optimize
// model lighting
- VectorCopy(rsurface.modellight_lightdir, lightdir);
- f = 0.5f * r_refdef.lightmapintensity;
- ambientcolor[0] = rsurface.modellight_ambient[0] * *r * f;
- ambientcolor[1] = rsurface.modellight_ambient[1] * *g * f;
- ambientcolor[2] = rsurface.modellight_ambient[2] * *b * f;
- diffusecolor[0] = rsurface.modellight_diffuse[0] * *r * f;
- diffusecolor[1] = rsurface.modellight_diffuse[1] * *g * f;
- diffusecolor[2] = rsurface.modellight_diffuse[2] * *b * f;
+ VectorCopy(rsurface.texture->render_modellight_lightdir, lightdir);
+ f = 0.5f * lightmapintensity;
+ ambientcolor[0] = rsurface.texture->render_modellight_ambient[0] * *r * f;
+ ambientcolor[1] = rsurface.texture->render_modellight_ambient[1] * *g * f;
+ ambientcolor[2] = rsurface.texture->render_modellight_ambient[2] * *b * f;
+ diffusecolor[0] = rsurface.texture->render_modellight_diffuse[0] * *r * f;
+ diffusecolor[1] = rsurface.texture->render_modellight_diffuse[1] * *g * f;
+ diffusecolor[2] = rsurface.texture->render_modellight_diffuse[2] * *b * f;
alpha = *a;
if (VectorLength2(diffusecolor) > 0)
{
static void RSurf_DrawBatch_GL11_VertexShade(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
{
- RSurf_DrawBatch_GL11_ApplyVertexShade(&r, &g, &b, &a, &applycolor);
+ RSurf_DrawBatch_GL11_ApplyVertexShade(&r, &g, &b, &a, r_refdef.scene.lightmapintensity, &applycolor);
if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_t **texturesurfacelist)
{
+ int i, j;
// transparent sky would be ridiculous
if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
return;
skyrenderlater = true;
RSurf_SetupDepthAndCulling();
GL_DepthMask(true);
- // LordHavoc: HalfLife maps have freaky skypolys so don't use
+
+ // add the vertices of the surfaces to a world bounding box so we can scissor the sky render later
+ if (r_sky_scissor.integer)
+ {
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
+ for (i = 0; i < texturenumsurfaces; i++)
+ {
+ const msurface_t *surf = texturesurfacelist[i];
+ const float *v;
+ float p[3];
+ float mins[3], maxs[3];
+ int scissor[4];
+ for (j = 0, v = rsurface.batchvertex3f + 3 * surf->num_firstvertex; j < surf->num_vertices; j++, v += 3)
+ {
+ Matrix4x4_Transform(&rsurface.matrix, v, p);
+ if (j > 0)
+ {
+ if (mins[0] > p[0]) mins[0] = p[0];
+ if (mins[1] > p[1]) mins[1] = p[1];
+ if (mins[2] > p[2]) mins[2] = p[2];
+ if (maxs[0] < p[0]) maxs[0] = p[0];
+ if (maxs[1] < p[1]) maxs[1] = p[1];
+ if (maxs[2] < p[2]) maxs[2] = p[2];
+ }
+ else
+ {
+ VectorCopy(p, mins);
+ VectorCopy(p, maxs);
+ }
+ }
+ if (!R_ScissorForBBox(mins, maxs, scissor))
+ {
+ if (skyscissor[2])
+ {
+ if (skyscissor[0] > scissor[0])
+ {
+ skyscissor[2] += skyscissor[0] - scissor[0];
+ skyscissor[0] = scissor[0];
+ }
+ if (skyscissor[1] > scissor[1])
+ {
+ skyscissor[3] += skyscissor[1] - scissor[1];
+ skyscissor[1] = scissor[1];
+ }
+ if (skyscissor[0] + skyscissor[2] < scissor[0] + scissor[2])
+ skyscissor[2] = scissor[0] + scissor[2] - skyscissor[0];
+ if (skyscissor[1] + skyscissor[3] < scissor[1] + scissor[3])
+ skyscissor[3] = scissor[1] + scissor[3] - skyscissor[1];
+ }
+ else
+ Vector4Copy(scissor, skyscissor);
+ }
+ }
+ }
+
+ // LadyHavoc: HalfLife maps have freaky skypolys so don't use
// skymasking on them, and Quake3 never did sky masking (unlike
// software Quake and software Quake2), so disable the sky masking
// in Quake3 maps as it causes problems with q3map2 sky tricks,
// and skymasking also looks very bad when noclipping outside the
// level, so don't use it then either.
- if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.skymasking && r_q1bsp_skymasking.integer && !r_refdef.viewcache.world_novis && !r_trippy.integer)
+ if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.skymasking && (r_refdef.scene.worldmodel->brush.isq3bsp ? r_q3bsp_renderskydepth.integer : r_q1bsp_skymasking.integer) && !r_refdef.viewcache.world_novis && !r_trippy.integer)
{
R_Mesh_ResetTextureState();
if (skyrendermasked)
{
R_SetupShader_DepthOrShadow(false, false, false);
// depth-only (masking)
- GL_ColorMask(0,0,0,0);
+ GL_ColorMask(0, 0, 0, 0);
// just to make sure that braindead drivers don't draw
// anything despite that colormask...
GL_BlendFunc(GL_ZERO, GL_ONE);
{
// render screenspace normalmap to texture
GL_DepthMask(true);
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL, false);
+ R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL, false);
RSurf_DrawBatch();
return;
}
{
// render water or distortion background
GL_DepthMask(true);
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false);
+ R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false);
RSurf_DrawBatch();
// blend surface on top
GL_DepthMask(false);
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL, false);
+ R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL, false);
RSurf_DrawBatch();
}
else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION))
{
// render surface with reflection texture as input
GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false);
+ R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false);
RSurf_DrawBatch();
}
}
// render surface batch normally
GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) != 0);
+ R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) != 0);
RSurf_DrawBatch();
}
qboolean applyfog;
int layerindex;
const texturelayer_t *layer;
- RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++)
qboolean applyfog;
int layerindex;
const texturelayer_t *layer;
- RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++)
int j;
r_vertexgeneric_t *batchvertex;
float c[4];
+ texture_t *t = rsurface.texture;
// R_Mesh_ResetTextureState();
R_SetupShader_Generic_NoTexture(false, false);
- if(rsurface.texture && rsurface.texture->currentskinframe)
+ if(t && t->currentskinframe)
{
- memcpy(c, rsurface.texture->currentskinframe->avgcolor, sizeof(c));
- c[3] *= rsurface.texture->currentalpha;
+ memcpy(c, t->currentskinframe->avgcolor, sizeof(c));
+ c[3] *= t->currentalpha;
}
else
{
c[3] = 1;
}
- if (rsurface.texture->pantstexture || rsurface.texture->shirttexture)
+ if (t->pantstexture || t->shirttexture)
{
- c[0] = 0.5 * (rsurface.colormap_pantscolor[0] * 0.3 + rsurface.colormap_shirtcolor[0] * 0.7);
- c[1] = 0.5 * (rsurface.colormap_pantscolor[1] * 0.3 + rsurface.colormap_shirtcolor[1] * 0.7);
- c[2] = 0.5 * (rsurface.colormap_pantscolor[2] * 0.3 + rsurface.colormap_shirtcolor[2] * 0.7);
+ c[0] = 0.5 * (t->render_colormap_pants[0] * 0.3 + t->render_colormap_shirt[0] * 0.7);
+ c[1] = 0.5 * (t->render_colormap_pants[1] * 0.3 + t->render_colormap_shirt[1] * 0.7);
+ c[2] = 0.5 * (t->render_colormap_pants[2] * 0.3 + t->render_colormap_shirt[2] * 0.7);
}
// brighten it up (as texture value 127 means "unlit")
c[1] *= 2 * r_refdef.view.colorscale;
c[2] *= 2 * r_refdef.view.colorscale;
- if(rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA)
+ if(t->currentmaterialflags & MATERIALFLAG_WATERALPHA)
c[3] *= r_wateralpha.value;
- if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1)
+ if(t->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1)
{
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_DepthMask(false);
}
- else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
+ else if(t->currentmaterialflags & MATERIALFLAG_ADD)
{
GL_BlendFunc(GL_ONE, GL_ONE);
GL_DepthMask(false);
}
- else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
+ else if(t->currentmaterialflags & MATERIALFLAG_ALPHATEST)
{
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // can't do alpha test without texture, so let's blend instead
GL_DepthMask(false);
}
- else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
+ else if(t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
{
- GL_BlendFunc(rsurface.texture->customblendfunc[0], rsurface.texture->customblendfunc[1]);
+ GL_BlendFunc(t->customblendfunc[0], t->customblendfunc[1]);
GL_DepthMask(false);
}
else
{
rsurface.passcolor4f = NULL;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
- {
- RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
-
- rsurface.passcolor4f = NULL;
- rsurface.passcolor4f_vertexbuffer = 0;
- rsurface.passcolor4f_bufferoffset = 0;
- }
- else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
+ if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
{
qboolean applycolor = true;
float one = 1.0;
RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
- r_refdef.lightmapintensity = 1;
- RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, &applycolor);
- r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
+ RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, 1.0f, &applycolor);
}
else if (FAKELIGHT_ENABLED)
{
RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
- r_refdef.lightmapintensity = r_fakelight_intensity.value;
- RSurf_DrawBatch_GL11_ApplyFakeLight();
- r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
+ RSurf_DrawBatch_GL11_ApplyFakeLight(r_fakelight_intensity.value);
}
else
{
rsurface.passcolor4f = rsurface.batchlightmapcolor4f;
rsurface.passcolor4f_vertexbuffer = rsurface.batchlightmapcolor4f_vertexbuffer;
rsurface.passcolor4f_bufferoffset = rsurface.batchlightmapcolor4f_bufferoffset;
+ RSurf_DrawBatch_GL11_ApplyAmbient();
}
if(!rsurface.passcolor4f)
RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray();
- RSurf_DrawBatch_GL11_ApplyAmbient();
RSurf_DrawBatch_GL11_ApplyColor(c[0], c[1], c[2], c[3]);
if(r_refdef.fogenabled)
RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors();
}
}
-static void R_DrawWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass)
-{
- CHECKGLERROR
- RSurf_SetupDepthAndCulling();
- if (r_showsurfaces.integer)
- {
- R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist, writedepth);
- return;
- }
- switch (vid.renderpath)
- {
- case RENDERPATH_GL20:
- case RENDERPATH_D3D9:
- case RENDERPATH_D3D10:
- case RENDERPATH_D3D11:
- case RENDERPATH_SOFT:
- case RENDERPATH_GLES2:
- R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
- break;
- case RENDERPATH_GL13:
- case RENDERPATH_GLES1:
- R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth);
- break;
- case RENDERPATH_GL11:
- R_DrawTextureSurfaceList_GL11(texturenumsurfaces, texturesurfacelist, writedepth);
- break;
- }
- CHECKGLERROR
-}
-
static void R_DrawModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass)
{
CHECKGLERROR
const msurface_t *surface;
const msurface_t *texturesurfacelist[MESHQUEUE_TRANSPARENT_BATCHSIZE];
- // if the model is static it doesn't matter what value we give for
- // wantnormals and wanttangents, so this logic uses only rules applicable
- // to a model, knowing that they are meaningless otherwise
- if (ent == r_refdef.scene.worldentity)
- RSurf_ActiveWorldEntity();
- else if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
+ if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
RSurf_ActiveModelEntity(ent, false, false, false);
else
{
}
}
// render the range of surfaces
- if (ent == r_refdef.scene.worldentity)
- R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
- else
- R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
+ R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
}
- rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
+ rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
}
static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist)
RSurf_DrawBatch();
}
-static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass)
-{
- CHECKGLERROR
- if (depthonly)
- R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist);
- else if (prepass)
- {
- if (!rsurface.texture->currentnumlayers)
- return;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
- R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
- else
- R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
- }
- else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && (!r_showsurfaces.integer || r_showsurfaces.integer == 3))
- R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
- else if (!rsurface.texture->currentnumlayers)
- return;
- else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))))
- {
- // in the deferred case, transparent surfaces were queued during prepass
- if (!r_shadow_usingdeferredprepass)
- R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
- }
- else
- {
- // the alphatest check is to make sure we write depth for anything we skipped on the depth-only pass earlier
- R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST), prepass);
- }
- CHECKGLERROR
-}
-
-static void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
-{
- int i, j;
- texture_t *texture;
- R_FrameData_SetMark();
- // break the surface list down into batches by texture and use of lightmapping
- for (i = 0;i < numsurfaces;i = j)
- {
- j = i + 1;
- // texture is the base texture pointer, rsurface.texture is the
- // current frame/skin the texture is directing us to use (for example
- // if a model has 2 skins and it is on skin 1, then skin 0 tells us to
- // use skin 1 instead)
- texture = surfacelist[i]->texture;
- rsurface.texture = R_GetCurrentTexture(texture);
- if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))
- {
- // if this texture is not the kind we want, skip ahead to the next one
- for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
- ;
- continue;
- }
- if(FAKELIGHT_ENABLED || depthonly || prepass)
- {
- rsurface.lightmaptexture = NULL;
- rsurface.deluxemaptexture = NULL;
- rsurface.uselightmaptexture = false;
- // simply scan ahead until we find a different texture or lightmap state
- for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
- ;
- }
- else
- {
- rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
- rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
- rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL;
- // simply scan ahead until we find a different texture or lightmap state
- for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
- ;
- }
- // render the range of surfaces
- R_ProcessWorldTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass);
- }
- R_FrameData_ReturnToMark();
-}
-
static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass)
{
CHECKGLERROR
// if the model is static it doesn't matter what value we give for
// wantnormals and wanttangents, so this logic uses only rules applicable
// to a model, knowing that they are meaningless otherwise
- if (ent == r_refdef.scene.worldentity)
- RSurf_ActiveWorldEntity();
- else
- RSurf_ActiveModelEntity(ent, false, false, false);
+ RSurf_ActiveModelEntity(ent, false, false, false);
decalsystem->lastupdatetime = r_refdef.scene.time;
int r_maxsurfacelist = 0;
const msurface_t **r_surfacelist = NULL;
-void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass)
-{
- int i, j, endj, flagsmask;
- dp_model_t *model = r_refdef.scene.worldmodel;
- msurface_t *surfaces;
- unsigned char *update;
- int numsurfacelist = 0;
- if (model == NULL)
- return;
-
- if (r_maxsurfacelist < model->num_surfaces)
- {
- r_maxsurfacelist = model->num_surfaces;
- if (r_surfacelist)
- Mem_Free((msurface_t**)r_surfacelist);
- r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist));
- }
-
- RSurf_ActiveWorldEntity();
-
- surfaces = model->data_surfaces;
- update = model->brushq1.lightmapupdateflags;
-
- // update light styles on this submodel
- if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
- {
- model_brush_lightstyleinfo_t *style;
- for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
- {
- if (style->value != r_refdef.scene.lightstylevalue[style->style])
- {
- int *list = style->surfacelist;
- style->value = r_refdef.scene.lightstylevalue[style->style];
- for (j = 0;j < style->numsurfaces;j++)
- update[list[j]] = true;
- }
- }
- }
-
- flagsmask = skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL;
-
- if (debug)
- {
- R_DrawDebugModel();
- rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
- return;
- }
-
- rsurface.lightmaptexture = NULL;
- rsurface.deluxemaptexture = NULL;
- rsurface.uselightmaptexture = false;
- rsurface.texture = NULL;
- rsurface.rtlight = NULL;
- numsurfacelist = 0;
- // add visible surfaces to draw list
- for (i = 0;i < model->nummodelsurfaces;i++)
- {
- j = model->sortedmodelsurfaces[i];
- if (r_refdef.viewcache.world_surfacevisible[j])
- r_surfacelist[numsurfacelist++] = surfaces + j;
- }
- // update lightmaps if needed
- if (model->brushq1.firstrender)
- {
- model->brushq1.firstrender = false;
- for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
- if (update[j])
- R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j);
- }
- else if (update)
- {
- for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
- if (r_refdef.viewcache.world_surfacevisible[j])
- if (update[j])
- R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j);
- }
- // don't do anything if there were no surfaces
- if (!numsurfacelist)
- {
- rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
- return;
- }
- R_QueueWorldSurfaceList(numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
-
- // add to stats if desired
- if (r_speeds.integer && !skysurfaces && !depthonly)
- {
- r_refdef.stats[r_stat_world_surfaces] += numsurfacelist;
- for (j = 0;j < numsurfacelist;j++)
- r_refdef.stats[r_stat_world_triangles] += r_surfacelist[j]->num_triangles;
- }
-
- rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
-}
-
void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass)
{
int i, j, endj, flagsmask;
r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist));
}
- // if the model is static it doesn't matter what value we give for
- // wantnormals and wanttangents, so this logic uses only rules applicable
- // to a model, knowing that they are meaningless otherwise
- if (ent == r_refdef.scene.worldentity)
- RSurf_ActiveWorldEntity();
- else if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
+ if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
RSurf_ActiveModelEntity(ent, false, false, false);
else if (prepass)
RSurf_ActiveModelEntity(ent, true, true, true);
update = model->brushq1.lightmapupdateflags;
// update light styles
- if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
+ if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.scene.lightmapintensity > 0)
{
model_brush_lightstyleinfo_t *style;
for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
if (debug)
{
R_DrawDebugModel();
- rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
+ rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
return;
}
rsurface.rtlight = NULL;
numsurfacelist = 0;
// add visible surfaces to draw list
- for (i = 0;i < model->nummodelsurfaces;i++)
- r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i];
+ if (ent == r_refdef.scene.worldentity)
+ {
+ // for the world entity, check surfacevisible
+ for (i = 0;i < model->nummodelsurfaces;i++)
+ {
+ j = model->sortedmodelsurfaces[i];
+ if (r_refdef.viewcache.world_surfacevisible[j])
+ r_surfacelist[numsurfacelist++] = surfaces + j;
+ }
+ }
+ else
+ {
+ // add all surfaces
+ for (i = 0; i < model->nummodelsurfaces; i++)
+ r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i];
+ }
// don't do anything if there were no surfaces
if (!numsurfacelist)
{
- rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
+ rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
return;
}
// update lightmaps if needed
r_refdef.stats[r_stat_entities_triangles] += r_surfacelist[j]->num_triangles;
}
- rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
+ rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
}
void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass)
{
+ int q;
static texture_t texture;
static msurface_t surface;
const msurface_t *surfacelist = &surface;
// WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS
// JUST GREP FOR "specularscalemod = 1".
+ for (q = 0; q < 3; q++)
+ {
+ texture.render_glowmod[q] = r_refdef.view.colorscale * r_hdr_glowintensity.value;
+ texture.render_modellight_lightdir[q] = q == 2;
+ texture.render_modellight_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity;
+ texture.render_modellight_diffuse[q] = r_refdef.view.colorscale;
+ texture.render_modellight_specular[q] = r_refdef.view.colorscale;
+ texture.render_lightmap_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity;
+ texture.render_lightmap_diffuse[q] = r_refdef.view.colorscale * r_refdef.scene.lightmapintensity;
+ texture.render_lightmap_specular[q] = r_refdef.view.colorscale;
+ texture.render_rtlight_diffuse[q] = r_refdef.view.colorscale;
+ texture.render_rtlight_specular[q] = r_refdef.view.colorscale;
+ }
+ texture.currentalpha = 1.0f;
+
surface.texture = &texture;
surface.num_triangles = numtriangles;
surface.num_firsttriangle = firsttriangle;