- Added .mtr file support. .mtr files are just .shader files that are accessed first.

- Added support for q3gl2_sun shaderparm in sky shaders to control sun shadows
- Added r_shadowFilter 0/1/2 for cascaded shadow maps.
- Added sun shadow support cvars.
- Changed r_testSunlight to r_forceSun 0/1/2 and r_sunShadows 0/1.
This commit is contained in:
James Canete 2012-10-17 10:02:11 +00:00
parent 4f57e94d05
commit 982eab2003
17 changed files with 4002 additions and 3597 deletions

View file

@ -1,3 +1,8 @@
- Added .mtr file support. .mtr files are just .shader files that are accessed first.
- Added support for q3gl2_sun shaderparm in sky shaders to control sun shadows
- Added r_shadowFilter 0/1/2 for cascaded shadow maps.
- Added sun shadow support cvars.
- Changed r_testSunlight to r_forceSun 0/1/2 and r_sunShadows 0/1.
- Spread in automatic weapons should be reduced in 3 burst mode. - Spread in automatic weapons should be reduced in 3 burst mode.
- Updated the ioq3 base Reaction is based on to ioq3 svn version 2322 - Updated the ioq3 base Reaction is based on to ioq3 svn version 2322
- Scale map lights by 0.66 and sunlight by 0.33 when r_testSunlight 1 - Scale map lights by 0.66 and sunlight by 0.33 when r_testSunlight 1

View file

@ -129,11 +129,15 @@ void GL_BindToTMU( image_t *image, int tmu )
int texnum; int texnum;
int oldtmu = glState.currenttmu; int oldtmu = glState.currenttmu;
texnum = image->texnum; if (!image)
texnum = 0;
else
texnum = image->texnum;
if ( glState.currenttextures[tmu] != texnum ) { if ( glState.currenttextures[tmu] != texnum ) {
GL_SelectTexture( tmu ); GL_SelectTexture( tmu );
image->frameUsed = tr.frameCount; if (image)
image->frameUsed = tr.frameCount;
glState.currenttextures[tmu] = texnum; glState.currenttextures[tmu] = texnum;
qglBindTexture( GL_TEXTURE_2D, texnum ); qglBindTexture( GL_TEXTURE_2D, texnum );
GL_SelectTexture( oldtmu ); GL_SelectTexture( oldtmu );
@ -582,7 +586,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
FBO_t* fbo = NULL; FBO_t* fbo = NULL;
qboolean inQuery = qfalse; qboolean inQuery = qfalse;
#ifdef REACTION #if 1 //def REACTION
float depth[2]; float depth[2];
#endif #endif
@ -604,7 +608,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
oldSort = -1; oldSort = -1;
depthRange = qfalse; depthRange = qfalse;
#ifdef REACTION #if 1 //def REACTION
depth[0] = 0.f; depth[0] = 0.f;
depth[1] = 1.f; depth[1] = 1.f;
#endif #endif
@ -754,7 +758,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
} }
} }
#ifdef REACTION #if 1 //def REACTION
if(!oldDepthRange) if(!oldDepthRange)
{ {
depth[0] = 0; depth[0] = 0;
@ -772,7 +776,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
if (!sunflare) if (!sunflare)
qglDepthRange (0, 1); qglDepthRange (0, 1);
#ifdef REACTION #if 1 //def REACTION
depth[0] = 0; depth[0] = 0;
depth[1] = 1; depth[1] = 1;
#endif #endif
@ -876,6 +880,9 @@ void RB_SetGL2D (void) {
// set time for 2D shaders // set time for 2D shaders
backEnd.refdef.time = ri.Milliseconds(); backEnd.refdef.time = ri.Milliseconds();
backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f; backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f;
// reset color scaling
backEnd.refdef.colorScale = 1.0f;
} }
@ -1198,6 +1205,72 @@ const void *RB_DrawSurfs( const void *data ) {
RB_RenderDrawSurfList( cmd->drawSurfs, cmd->numDrawSurfs ); RB_RenderDrawSurfList( cmd->drawSurfs, cmd->numDrawSurfs );
qglColorMask(!backEnd.colorMask[0], !backEnd.colorMask[1], !backEnd.colorMask[2], !backEnd.colorMask[3]); qglColorMask(!backEnd.colorMask[0], !backEnd.colorMask[1], !backEnd.colorMask[2], !backEnd.colorMask[3]);
backEnd.depthFill = qfalse; backEnd.depthFill = qfalse;
if (backEnd.viewParms.flags & VPF_USESUNLIGHT)
{
vec4_t quadVerts[4];
vec2_t texCoords[4];
FBO_t *oldFbo = glState.currentFBO;
// If we're using multisampling, resolve the depth first
if (tr.msaaResolveFbo)
{
FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
}
FBO_Bind(tr.screenShadowFbo);
VectorSet4(quadVerts[0], -1, 1, 0, 1);
VectorSet4(quadVerts[1], 1, 1, 0, 1);
VectorSet4(quadVerts[2], 1, -1, 0, 1);
VectorSet4(quadVerts[3], -1, -1, 0, 1);
texCoords[0][0] = 0; texCoords[0][1] = 1;
texCoords[1][0] = 1; texCoords[1][1] = 1;
texCoords[2][0] = 1; texCoords[2][1] = 0;
texCoords[3][0] = 0; texCoords[3][1] = 0;
GL_State( GLS_DEPTHTEST_DISABLE );
GLSL_BindProgram(&tr.shadowmaskShader);
GL_BindToTMU(tr.renderDepthImage, TB_COLORMAP);
GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP);
GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2);
GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3);
GLSL_SetUniformMatrix16(&tr.shadowmaskShader, SHADOWMASK_UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]);
GLSL_SetUniformMatrix16(&tr.shadowmaskShader, SHADOWMASK_UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]);
GLSL_SetUniformMatrix16(&tr.shadowmaskShader, SHADOWMASK_UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]);
GLSL_SetUniformVec3(&tr.shadowmaskShader, SHADOWMASK_UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg);
{
vec4_t viewInfo;
vec3_t viewVector;
float zmax = backEnd.viewParms.zFar;
float ymax = zmax * tan(backEnd.viewParms.fovY * M_PI / 360.0f);
float xmax = zmax * tan(backEnd.viewParms.fovX * M_PI / 360.0f);
float zmin = r_znear->value;
VectorScale(backEnd.refdef.viewaxis[0], zmax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, SHADOWMASK_UNIFORM_VIEWFORWARD, viewVector);
VectorScale(backEnd.refdef.viewaxis[1], xmax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, SHADOWMASK_UNIFORM_VIEWLEFT, viewVector);
VectorScale(backEnd.refdef.viewaxis[2], ymax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, SHADOWMASK_UNIFORM_VIEWUP, viewVector);
VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
GLSL_SetUniformVec4(&tr.shadowmaskShader, SHADOWMASK_UNIFORM_VIEWINFO, viewInfo);
}
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
FBO_Bind(oldFbo);
}
} }
if ((backEnd.viewParms.flags & VPF_DEPTHCLAMP) && glRefConfig.depthClamp) if ((backEnd.viewParms.flags & VPF_DEPTHCLAMP) && glRefConfig.depthClamp)
@ -1556,6 +1629,15 @@ const void *RB_PostProcess(const void *data)
FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
} }
if (0)
{
vec4i_t dstBox;
VectorSet4(dstBox, 256, tr.screenScratchFbo->height - 256, 256, 256);
FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
VectorSet4(dstBox, 512, tr.screenScratchFbo->height - 256, 256, 256);
FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
}
backEnd.framePostProcessed = qtrue; backEnd.framePostProcessed = qtrue;
return (const void *)(cmd + 1); return (const void *)(cmd + 1);

View file

@ -107,14 +107,53 @@ void Matrix16Translation( vec3_t vec, matrix_t out )
void Matrix16Ortho( float left, float right, float bottom, float top, float znear, float zfar, matrix_t out ) void Matrix16Ortho( float left, float right, float bottom, float top, float znear, float zfar, matrix_t out )
{ {
Matrix16Zero(out); out[ 0] = 2.0f / (right - left); out[ 4] = 0.0f; out[ 8] = 0.0f; out[12] = -(right + left) / (right - left);
out[ 0] = 2.0f / (right - left); out[ 1] = 0.0f; out[ 5] = 2.0f / (top - bottom); out[ 9] = 0.0f; out[13] = -(top + bottom) / (top - bottom);
out[ 5] = 2.0f / (top - bottom); out[ 2] = 0.0f; out[ 6] = 0.0f; out[10] = 2.0f / (zfar - znear); out[14] = -(zfar + znear) / (zfar - znear);
out[10] = 2.0f / (zfar - znear); out[ 3] = 0.0f; out[ 7] = 0.0f; out[11] = 0.0f; out[15] = 1.0f;
out[12] = -(right + left) / (right - left); }
out[13] = -(top + bottom) / (top - bottom);
out[14] = -(zfar + znear) / (zfar - znear); void Matrix16View(vec3_t axes[3], vec3_t origin, matrix_t out)
out[15] = 1.0f; {
out[0] = axes[0][0];
out[1] = axes[1][0];
out[2] = axes[2][0];
out[3] = 0;
out[4] = axes[0][1];
out[5] = axes[1][1];
out[6] = axes[2][1];
out[7] = 0;
out[8] = axes[0][2];
out[9] = axes[1][2];
out[10] = axes[2][2];
out[11] = 0;
out[12] = -DotProduct(origin, axes[0]);
out[13] = -DotProduct(origin, axes[1]);
out[14] = -DotProduct(origin, axes[2]);
out[15] = 1;
}
void Matrix16SimpleInverse( const matrix_t in, matrix_t out)
{
vec3_t v;
float invSqrLen;
VectorCopy(in + 0, v);
invSqrLen = 1.0f / DotProduct(v, v); VectorScale(v, invSqrLen, v);
out[ 0] = v[0]; out[ 4] = v[1]; out[ 8] = v[2]; out[12] = -DotProduct(v, &in[12]);
VectorCopy(in + 4, v);
invSqrLen = 1.0f / DotProduct(v, v); VectorScale(v, invSqrLen, v);
out[ 1] = v[0]; out[ 5] = v[1]; out[ 9] = v[2]; out[13] = -DotProduct(v, &in[12]);
VectorCopy(in + 8, v);
invSqrLen = 1.0f / DotProduct(v, v); VectorScale(v, invSqrLen, v);
out[ 2] = v[0]; out[ 6] = v[1]; out[10] = v[2]; out[14] = -DotProduct(v, &in[12]);
out[ 3] = 0.0f; out[ 7] = 0.0f; out[11] = 0.0f; out[15] = 1.0f;
} }
void VectorLerp( vec3_t a, vec3_t b, float lerp, vec3_t c) void VectorLerp( vec3_t a, vec3_t b, float lerp, vec3_t c)

View file

@ -38,6 +38,8 @@ qboolean Matrix16Compare(const matrix_t a, const matrix_t b);
void Matrix16Dump( const matrix_t in ); void Matrix16Dump( const matrix_t in );
void Matrix16Translation( vec3_t vec, matrix_t out ); void Matrix16Translation( vec3_t vec, matrix_t out );
void Matrix16Ortho( float left, float right, float bottom, float top, float znear, float zfar, matrix_t out ); void Matrix16Ortho( float left, float right, float bottom, float top, float znear, float zfar, matrix_t out );
void Matrix16View(vec3_t axes[3], vec3_t origin, matrix_t out);
void Matrix16SimpleInverse( const matrix_t in, matrix_t out);
#define VectorCopy2(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1]) #define VectorCopy2(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1])

View file

@ -1,43 +1,44 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2009-2011 Andrei Drexler, Richard Allen, James Canete Copyright (C) 2009-2011 Andrei Drexler, Richard Allen, James Canete
This file is part of Reaction source code. This file is part of Reaction source code.
Reaction source code is free software; you can redistribute it Reaction source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License, published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version. or (at your option) any later version.
Reaction source code is distributed in the hope that it will be Reaction source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Reaction source code; if not, write to the Free Software along with Reaction source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=========================================================================== ===========================================================================
*/ */
#ifndef __TR_EXTRATYPES_H__ #ifndef __TR_EXTRATYPES_H__
#define __TR_EXTRATYPES_H__ #define __TR_EXTRATYPES_H__
// tr_extratypes.h, for mods that want to extend tr_types.h without losing compatibility with original VMs // tr_extratypes.h, for mods that want to extend tr_types.h without losing compatibility with original VMs
// extra renderfx flags start at 0x0400 // extra renderfx flags start at 0x0400
#define RF_SUNFLARE 0x0400 #define RF_SUNFLARE 0x0400
// extra refdef flags start at 0x0008 // extra refdef flags start at 0x0008
#define RDF_NOFOG 0x0008 // don't apply fog #define RDF_NOFOG 0x0008 // don't apply fog
#define RDF_EXTRA 0x0010 // Makro - refdefex_t to follow after refdef_t #define RDF_EXTRA 0x0010 // Makro - refdefex_t to follow after refdef_t
#define RDF_SUNLIGHT 0x0020 // SmileTheory - render sunlight and shadows #define RDF_SUNLIGHT 0x0020 // SmileTheory - render sunlight and shadows
typedef struct { typedef struct {
float blurFactor; float blurFactor;
float sunDir[3]; float sunDir[3];
float sunCol[3]; float sunCol[3];
} refdefex_t; float sunAmbCol[3];
} refdefex_t;
#endif
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2278,6 +2278,22 @@ static void EmptyTexture( int width, int height, imgType_t type, imgFlags_t flag
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
} }
// Fix for sampling depth buffer on old nVidia cards
// from http://www.idevgames.com/forums/thread-4141-post-34844.html#pid34844
switch(internalFormat)
{
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16_ARB:
case GL_DEPTH_COMPONENT24_ARB:
case GL_DEPTH_COMPONENT32_ARB:
qglTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
break;
default:
break;
}
GL_CheckErrors(); GL_CheckErrors();
} }
@ -2977,6 +2993,8 @@ void R_CreateBuiltinImages( void ) {
{ {
tr.quarterImage[x] = R_CreateImage(va("*quarter%d", x), NULL, 512, 512, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); tr.quarterImage[x] = R_CreateImage(va("*quarter%d", x), NULL, 512, 512, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
} }
tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
} }
for( x = 0; x < MAX_DRAWN_PSHADOWS; x++) for( x = 0; x < MAX_DRAWN_PSHADOWS; x++)
@ -2987,7 +3005,7 @@ void R_CreateBuiltinImages( void ) {
//tr.sunShadowImage = R_CreateImage("*sunshadowmap", NULL, SUNSHADOW_MAP_SIZE, SUNSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); //tr.sunShadowImage = R_CreateImage("*sunshadowmap", NULL, SUNSHADOW_MAP_SIZE, SUNSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
for ( x = 0; x < 3; x++) for ( x = 0; x < 3; x++)
{ {
tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, SUNSHADOW_MAP_SIZE, SUNSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT16_ARB); tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB);
} }
} }

View file

@ -128,7 +128,16 @@ cvar_t *r_imageUpsample;
cvar_t *r_imageUpsampleMaxSize; cvar_t *r_imageUpsampleMaxSize;
cvar_t *r_imageUpsampleType; cvar_t *r_imageUpsampleType;
cvar_t *r_genNormalMaps; cvar_t *r_genNormalMaps;
cvar_t *r_testSunlight; cvar_t *r_forceSun;
cvar_t *r_forceSunMapLightScale;
cvar_t *r_forceSunLightScale;
cvar_t *r_forceSunAmbientScale;
cvar_t *r_sunShadows;
cvar_t *r_shadowFilter;
cvar_t *r_shadowMapSize;
cvar_t *r_shadowCascadeZNear;
cvar_t *r_shadowCascadeZFar;
cvar_t *r_shadowCascadeZBias;
cvar_t *r_ignoreGLErrors; cvar_t *r_ignoreGLErrors;
cvar_t *r_logFile; cvar_t *r_logFile;
@ -1137,7 +1146,7 @@ void R_Register( void )
r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT ); r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT );
r_srgb = ri.Cvar_Get( "r_srgb", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_srgb = ri.Cvar_Get( "r_srgb", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE );
r_normalMapping = ri.Cvar_Get( "r_normalMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_normalMapping = ri.Cvar_Get( "r_normalMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
@ -1152,7 +1161,17 @@ void R_Register( void )
r_imageUpsampleMaxSize = ri.Cvar_Get( "r_imageUpsampleMaxSize", "1024", CVAR_ARCHIVE | CVAR_LATCH ); r_imageUpsampleMaxSize = ri.Cvar_Get( "r_imageUpsampleMaxSize", "1024", CVAR_ARCHIVE | CVAR_LATCH );
r_imageUpsampleType = ri.Cvar_Get( "r_imageUpsampleType", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_imageUpsampleType = ri.Cvar_Get( "r_imageUpsampleType", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_genNormalMaps = ri.Cvar_Get( "r_genNormalMaps", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_genNormalMaps = ri.Cvar_Get( "r_genNormalMaps", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_testSunlight = ri.Cvar_Get( "r_testSunlight", "0", CVAR_CHEAT );
r_forceSun = ri.Cvar_Get( "r_forceSun", "0", CVAR_CHEAT );
r_forceSunMapLightScale = ri.Cvar_Get( "r_forceSunMapLightScale", "0.5", CVAR_CHEAT );
r_forceSunLightScale = ri.Cvar_Get( "r_forceSunLightScale", "0.5", CVAR_CHEAT );
r_forceSunAmbientScale = ri.Cvar_Get( "r_forceSunAmbientScale", "0.2", CVAR_CHEAT );
r_sunShadows = ri.Cvar_Get( "r_sunShadows", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowFilter = ri.Cvar_Get( "r_shadowFilter", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowMapSize = ri.Cvar_Get( "r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "4", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "3072", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "-320", CVAR_ARCHIVE | CVAR_LATCH );
// //
// temporary latched variables that can only change over a restart // temporary latched variables that can only change over a restart

View file

@ -67,7 +67,6 @@ typedef unsigned int glIndex_t;
#define MAX_CALC_PSHADOWS 64 #define MAX_CALC_PSHADOWS 64
#define MAX_DRAWN_PSHADOWS 16 // do not increase past 32, because bit flags are used on surfaces #define MAX_DRAWN_PSHADOWS 16 // do not increase past 32, because bit flags are used on surfaces
#define PSHADOW_MAP_SIZE 512 #define PSHADOW_MAP_SIZE 512
#define SUNSHADOW_MAP_SIZE 1024
#define USE_VERT_TANGENT_SPACE #define USE_VERT_TANGENT_SPACE
@ -743,11 +742,10 @@ enum
LIGHTDEF_USE_DELUXEMAP = 0x0010, LIGHTDEF_USE_DELUXEMAP = 0x0010,
LIGHTDEF_USE_PARALLAXMAP = 0x0020, LIGHTDEF_USE_PARALLAXMAP = 0x0020,
LIGHTDEF_USE_SHADOWMAP = 0x0040, LIGHTDEF_USE_SHADOWMAP = 0x0040,
LIGHTDEF_USE_SHADOW_CASCADE= 0x0080, LIGHTDEF_TCGEN_ENVIRONMENT = 0x0080,
LIGHTDEF_TCGEN_ENVIRONMENT = 0x0100, LIGHTDEF_ENTITY = 0x0100,
LIGHTDEF_ENTITY = 0x0200, LIGHTDEF_ALL = 0x01FF,
LIGHTDEF_ALL = 0x03FF, LIGHTDEF_COUNT = 0x0200
LIGHTDEF_COUNT = 0x0400
}; };
enum enum
@ -843,8 +841,6 @@ enum
GENERIC_UNIFORM_DELUXEMAP, GENERIC_UNIFORM_DELUXEMAP,
GENERIC_UNIFORM_SPECULARMAP, GENERIC_UNIFORM_SPECULARMAP,
GENERIC_UNIFORM_SHADOWMAP, GENERIC_UNIFORM_SHADOWMAP,
GENERIC_UNIFORM_SHADOWMAP2,
GENERIC_UNIFORM_SHADOWMAP3,
GENERIC_UNIFORM_DIFFUSETEXMATRIX, GENERIC_UNIFORM_DIFFUSETEXMATRIX,
//GENERIC_UNIFORM_NORMALTEXMATRIX, //GENERIC_UNIFORM_NORMALTEXMATRIX,
//GENERIC_UNIFORM_SPECULARTEXMATRIX, //GENERIC_UNIFORM_SPECULARTEXMATRIX,
@ -873,13 +869,26 @@ enum
GENERIC_UNIFORM_TIME, GENERIC_UNIFORM_TIME,
GENERIC_UNIFORM_VERTEXLERP, GENERIC_UNIFORM_VERTEXLERP,
GENERIC_UNIFORM_MATERIALINFO, GENERIC_UNIFORM_MATERIALINFO,
GENERIC_UNIFORM_SHADOWMVP,
GENERIC_UNIFORM_SHADOWMVP2,
GENERIC_UNIFORM_SHADOWMVP3,
GENERIC_UNIFORM_MAPLIGHTSCALE,
GENERIC_UNIFORM_COUNT GENERIC_UNIFORM_COUNT
}; };
enum
{
SHADOWMASK_UNIFORM_SCREENDEPTHMAP = 0,
SHADOWMASK_UNIFORM_SHADOWMAP,
SHADOWMASK_UNIFORM_SHADOWMAP2,
SHADOWMASK_UNIFORM_SHADOWMAP3,
SHADOWMASK_UNIFORM_SHADOWMVP,
SHADOWMASK_UNIFORM_SHADOWMVP2,
SHADOWMASK_UNIFORM_SHADOWMVP3,
SHADOWMASK_UNIFORM_VIEWORIGIN,
SHADOWMASK_UNIFORM_VIEWINFO, // znear, zfar, width/2, height/2
SHADOWMASK_UNIFORM_VIEWFORWARD,
SHADOWMASK_UNIFORM_VIEWLEFT,
SHADOWMASK_UNIFORM_VIEWUP,
SHADOWMASK_UNIFORM_COUNT
};
// //
// Tr3B: these are fire wall functions to avoid expensive redundant glUniform* calls // Tr3B: these are fire wall functions to avoid expensive redundant glUniform* calls
//#define USE_UNIFORM_FIREWALL 1 //#define USE_UNIFORM_FIREWALL 1
@ -928,7 +937,8 @@ typedef struct {
float sunShadowMvp[3][16]; float sunShadowMvp[3][16];
float sunDir[4]; float sunDir[4];
float sunCol[4]; float sunCol[4];
float mapLightScale; float sunAmbCol[4];
float colorScale;
} trRefdef_t; } trRefdef_t;
@ -961,11 +971,12 @@ typedef struct {
} fog_t; } fog_t;
typedef enum { typedef enum {
VPF_NONE = 0x00, VPF_NONE = 0x00,
VPF_SHADOWMAP = 0x01, VPF_SHADOWMAP = 0x01,
VPF_DEPTHSHADOW = 0x02, VPF_DEPTHSHADOW = 0x02,
VPF_DEPTHCLAMP = 0x04, VPF_DEPTHCLAMP = 0x04,
VPF_ORTHOGRAPHIC = 0x08, VPF_ORTHOGRAPHIC = 0x08,
VPF_USESUNLIGHT = 0x10,
} viewParmFlags_t; } viewParmFlags_t;
typedef struct { typedef struct {
@ -1601,7 +1612,7 @@ typedef struct {
// the renderer front end should never modify glstate_t // the renderer front end should never modify glstate_t
typedef struct { typedef struct {
int currenttextures[2]; int currenttextures[NUM_TEXTURE_BUNDLES];
int currenttmu; int currenttmu;
qboolean finishCalled; qboolean finishCalled;
int texEnv[2]; int texEnv[2];
@ -1780,6 +1791,7 @@ typedef struct {
image_t *targetLevelsImage; image_t *targetLevelsImage;
image_t *fixedLevelsImage; image_t *fixedLevelsImage;
image_t *sunShadowDepthImage[3]; image_t *sunShadowDepthImage[3];
image_t *screenShadowImage;
image_t *textureDepthImage; image_t *textureDepthImage;
@ -1794,6 +1806,7 @@ typedef struct {
FBO_t *calcLevelsFbo; FBO_t *calcLevelsFbo;
FBO_t *targetLevelsFbo; FBO_t *targetLevelsFbo;
FBO_t *sunShadowFbo[3]; FBO_t *sunShadowFbo[3];
FBO_t *screenShadowFbo;
shader_t *defaultShader; shader_t *defaultShader;
shader_t *shadowShader; shader_t *shadowShader;
@ -1830,6 +1843,7 @@ typedef struct {
shaderProgram_t bokehShader; shaderProgram_t bokehShader;
shaderProgram_t tonemapShader; shaderProgram_t tonemapShader;
shaderProgram_t calclevels4xShader[2]; shaderProgram_t calclevels4xShader[2];
shaderProgram_t shadowmaskShader;
// ----------------------------------------- // -----------------------------------------
@ -1850,6 +1864,7 @@ typedef struct {
qboolean sunShadows; qboolean sunShadows;
vec3_t sunLight; // from the sky shader for this level vec3_t sunLight; // from the sky shader for this level
vec3_t sunAmbient;
vec3_t sunDirection; vec3_t sunDirection;
frontEndCounters_t pc; frontEndCounters_t pc;
@ -2052,7 +2067,16 @@ extern cvar_t *r_imageUpsample;
extern cvar_t *r_imageUpsampleMaxSize; extern cvar_t *r_imageUpsampleMaxSize;
extern cvar_t *r_imageUpsampleType; extern cvar_t *r_imageUpsampleType;
extern cvar_t *r_genNormalMaps; extern cvar_t *r_genNormalMaps;
extern cvar_t *r_testSunlight; extern cvar_t *r_forceSun;
extern cvar_t *r_forceSunMapLightScale;
extern cvar_t *r_forceSunLightScale;
extern cvar_t *r_forceSunAmbientScale;
extern cvar_t *r_sunShadows;
extern cvar_t *r_shadowFilter;
extern cvar_t *r_shadowMapSize;
extern cvar_t *r_shadowCascadeZNear;
extern cvar_t *r_shadowCascadeZFar;
extern cvar_t *r_shadowCascadeZBias;
extern cvar_t *r_greyscale; extern cvar_t *r_greyscale;
@ -2334,7 +2358,8 @@ void RB_StageIteratorLightmappedMultitexture( void );
void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, float color[4] ); void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, float color[4] );
void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], float s1, float t1, float s2, float t2 ); void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], float s1, float t1, float s2, float t2 );
void RB_InstantQuad( vec4_t quadVerts[4] ); void RB_InstantQuad( vec4_t quadVerts[4] );
void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4], vec4_t color, shaderProgram_t *sp, vec2_t invTexRes); //void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4], vec4_t color, shaderProgram_t *sp, vec2_t invTexRes);
void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4]);
void RB_ShowImages( void ); void RB_ShowImages( void );

View file

@ -1905,7 +1905,7 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
R_RadixSort( drawSurfs, numDrawSurfs ); R_RadixSort( drawSurfs, numDrawSurfs );
// skip pass through drawing if rendering a shadow map // skip pass through drawing if rendering a shadow map
if ((tr.viewParms.flags & VPF_SHADOWMAP) || (tr.viewParms.flags & VPF_DEPTHSHADOW)) if (tr.viewParms.flags & (VPF_SHADOWMAP | VPF_DEPTHSHADOW))
{ {
R_AddDrawSurfCmd( drawSurfs, numDrawSurfs ); R_AddDrawSurfCmd( drawSurfs, numDrawSurfs );
return; return;
@ -1958,7 +1958,7 @@ static void R_AddEntitySurface (int entityNum)
// mirrors, because the true body position will already be drawn // mirrors, because the true body position will already be drawn
// //
if ( (ent->e.renderfx & RF_FIRST_PERSON) && (tr.viewParms.isPortal if ( (ent->e.renderfx & RF_FIRST_PERSON) && (tr.viewParms.isPortal
|| (tr.viewParms.flags & VPF_SHADOWMAP) || (tr.viewParms.flags & VPF_DEPTHSHADOW))) { || (tr.viewParms.flags & (VPF_SHADOWMAP | VPF_DEPTHSHADOW))) ) {
return; return;
} }
@ -2587,18 +2587,24 @@ void R_RenderPshadowMaps(const refdef_t *fd)
} }
} }
static float CalcSplit(float n, float f, float i, float m)
{
return (n * pow(f / n, i / m) + (f - n) * i / m) / 2.0f;
}
void R_RenderSunShadowMaps(const refdef_t *fd, int level) void R_RenderSunShadowMaps(const refdef_t *fd, int level)
{ {
viewParms_t shadowParms; viewParms_t shadowParms;
vec4_t lightDir, lightCol; vec4_t lightDir, lightCol;
vec3_t up;
vec3_t lightViewAxis[3]; vec3_t lightViewAxis[3];
vec3_t lightOrigin; vec3_t lightOrigin;
float viewznear, viewzfar; float splitZNear, splitZFar, splitBias;
float viewZNear, viewZFar;
vec3_t lightviewBounds[2]; vec3_t lightviewBounds[2];
qboolean lightViewIndependentOfCameraView = qfalse;
if (r_testSunlight->integer == 2) if (r_forceSun->integer == 2)
{ {
int scale = 32768; int scale = 32768;
float angle = (fd->time % scale) / (float)scale * M_PI; float angle = (fd->time % scale) / (float)scale * M_PI;
@ -2624,58 +2630,90 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
VectorCopy4(lightDir, tr.refdef.sunDir); VectorCopy4(lightDir, tr.refdef.sunDir);
VectorCopy4(lightCol, tr.refdef.sunCol); VectorCopy4(lightCol, tr.refdef.sunCol);
VectorScale4(lightCol, 0.2f, tr.refdef.sunAmbCol);
} }
else else
{ {
VectorCopy4(tr.refdef.sunDir, lightDir); VectorCopy4(tr.refdef.sunDir, lightDir);
} }
viewZNear = r_shadowCascadeZNear->value;
viewZFar = r_shadowCascadeZFar->value;
splitBias = r_shadowCascadeZBias->value;
switch(level) switch(level)
{ {
case 0: case 0:
default: default:
//viewznear = r_znear->value; //splitZNear = r_znear->value;
//viewzfar = 256; //splitZFar = 256;
viewznear = r_znear->value; splitZNear = viewZNear;
viewzfar = 128; splitZFar = CalcSplit(viewZNear, viewZFar, 1, 3) + splitBias;
break; break;
case 1: case 1:
viewznear = 128; splitZNear = CalcSplit(viewZNear, viewZFar, 1, 3) + splitBias;
viewzfar = 384; splitZFar = CalcSplit(viewZNear, viewZFar, 2, 3) + splitBias;
//viewznear = 256; //splitZNear = 256;
//viewzfar = 896; //splitZFar = 896;
break; break;
case 2: case 2:
viewznear = 384; splitZNear = CalcSplit(viewZNear, viewZFar, 2, 3) + splitBias;
viewzfar = 1024; splitZFar = viewZFar;
//viewznear = 896; //splitZNear = 896;
//viewzfar = 3072; //splitZFar = 3072;
break; break;
} }
VectorCopy(fd->vieworg, lightOrigin); VectorCopy(fd->vieworg, lightOrigin);
// make up a projection // Make up a projection
VectorScale(lightDir, -1.0f, lightViewAxis[0]); VectorScale(lightDir, -1.0f, lightViewAxis[0]);
// try to use halfway between player right and player forward as up if (lightViewIndependentOfCameraView)
//VectorCopy(fd->viewaxis[1], up);
VectorScale(fd->viewaxis[0], 0.5f, up);
VectorMA(up, 0.5f, fd->viewaxis[1], up);
if ( abs(DotProduct(up, lightViewAxis[0])) > 0.9f )
{ {
// if not, halfway between player up and player forward // Use world up as light view up
//VectorCopy(fd->viewaxis[2], up); VectorSet(lightViewAxis[2], 0, 0, 1);
VectorScale(fd->viewaxis[0], 0.5f, up); }
VectorMA(up, 0.5f, fd->viewaxis[2], up); else if (level == 0)
{
// Level 0 tries to use a diamond texture orientation relative to camera view
// Use halfway between camera view forward and left for light view up
VectorAdd(fd->viewaxis[0], fd->viewaxis[1], lightViewAxis[2]);
}
else
{
// Use camera view up as light view up
VectorCopy(fd->viewaxis[2], lightViewAxis[2]);
} }
CrossProduct(lightViewAxis[0], up, lightViewAxis[1]); // Check if too close to parallel to light direction
if (abs(DotProduct(lightViewAxis[2], lightViewAxis[0])) > 0.9f)
{
if (lightViewIndependentOfCameraView)
{
// Use world left as light view up
VectorSet(lightViewAxis[2], 0, 1, 0);
}
else if (level == 0)
{
// Level 0 tries to use a diamond texture orientation relative to camera view
// Use halfway between camera view forward and up for light view up
VectorAdd(fd->viewaxis[0], fd->viewaxis[2], lightViewAxis[2]);
}
else
{
// Use camera view left as light view up
VectorCopy(fd->viewaxis[1], lightViewAxis[2]);
}
}
// clean axes
CrossProduct(lightViewAxis[2], lightViewAxis[0], lightViewAxis[1]);
VectorNormalize(lightViewAxis[1]); VectorNormalize(lightViewAxis[1]);
CrossProduct(lightViewAxis[0], lightViewAxis[1], lightViewAxis[2]); CrossProduct(lightViewAxis[0], lightViewAxis[1], lightViewAxis[2]);
// Create bounds for light projection using slice of view projection
{ {
matrix_t lightViewMatrix; matrix_t lightViewMatrix;
vec4_t point, base, lightViewPoint; vec4_t point, base, lightViewPoint;
@ -2685,32 +2723,14 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
point[3] = 1; point[3] = 1;
lightViewPoint[3] = 1; lightViewPoint[3] = 1;
lightViewMatrix[0] = lightViewAxis[0][0]; Matrix16View(lightViewAxis, lightOrigin, lightViewMatrix);
lightViewMatrix[1] = lightViewAxis[1][0];
lightViewMatrix[2] = lightViewAxis[2][0];
lightViewMatrix[3] = 0;
lightViewMatrix[4] = lightViewAxis[0][1];
lightViewMatrix[5] = lightViewAxis[1][1];
lightViewMatrix[6] = lightViewAxis[2][1];
lightViewMatrix[7] = 0;
lightViewMatrix[8] = lightViewAxis[0][2];
lightViewMatrix[9] = lightViewAxis[1][2];
lightViewMatrix[10] = lightViewAxis[2][2];
lightViewMatrix[11] = 0;
lightViewMatrix[12] = -DotProduct(lightOrigin, lightViewAxis[0]);
lightViewMatrix[13] = -DotProduct(lightOrigin, lightViewAxis[1]);
lightViewMatrix[14] = -DotProduct(lightOrigin, lightViewAxis[2]);
lightViewMatrix[15] = 1;
ClearBounds(lightviewBounds[0], lightviewBounds[1]); ClearBounds(lightviewBounds[0], lightviewBounds[1]);
// add view near plane // add view near plane
lx = viewznear * tan(fd->fov_x * M_PI / 360.0f); lx = splitZNear * tan(fd->fov_x * M_PI / 360.0f);
ly = viewznear * tan(fd->fov_y * M_PI / 360.0f); ly = splitZNear * tan(fd->fov_y * M_PI / 360.0f);
VectorMA(fd->vieworg, viewznear, fd->viewaxis[0], base); VectorMA(fd->vieworg, splitZNear, fd->viewaxis[0], base);
VectorMA(base, lx, fd->viewaxis[1], point); VectorMA(base, lx, fd->viewaxis[1], point);
VectorMA(point, ly, fd->viewaxis[2], point); VectorMA(point, ly, fd->viewaxis[2], point);
@ -2734,9 +2754,9 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
// add view far plane // add view far plane
lx = viewzfar * tan(fd->fov_x * M_PI / 360.0f); lx = splitZFar * tan(fd->fov_x * M_PI / 360.0f);
ly = viewzfar * tan(fd->fov_y * M_PI / 360.0f); ly = splitZFar * tan(fd->fov_y * M_PI / 360.0f);
VectorMA(fd->vieworg, viewzfar, fd->viewaxis[0], base); VectorMA(fd->vieworg, splitZFar, fd->viewaxis[0], base);
VectorMA(base, lx, fd->viewaxis[1], point); VectorMA(base, lx, fd->viewaxis[1], point);
VectorMA(point, ly, fd->viewaxis[2], point); VectorMA(point, ly, fd->viewaxis[2], point);
@ -2761,6 +2781,31 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
if (!glRefConfig.depthClamp) if (!glRefConfig.depthClamp)
lightviewBounds[0][0] = lightviewBounds[1][0] - 8192; lightviewBounds[0][0] = lightviewBounds[1][0] - 8192;
// Moving the Light in Texel-Sized Increments
// from http://msdn.microsoft.com/en-us/library/windows/desktop/ee416324%28v=vs.85%29.aspx
//
if (lightViewIndependentOfCameraView)
{
float cascadeBound, worldUnitsPerTexel, invWorldUnitsPerTexel;
cascadeBound = MAX(lightviewBounds[1][0] - lightviewBounds[0][0], lightviewBounds[1][1] - lightviewBounds[0][1]);
cascadeBound = MAX(cascadeBound, lightviewBounds[1][2] - lightviewBounds[0][2]);
worldUnitsPerTexel = cascadeBound / tr.sunShadowFbo[level]->width;
invWorldUnitsPerTexel = 1.0f / worldUnitsPerTexel;
VectorScale(lightviewBounds[0], invWorldUnitsPerTexel, lightviewBounds[0]);
lightviewBounds[0][0] = floor(lightviewBounds[0][0]);
lightviewBounds[0][1] = floor(lightviewBounds[0][1]);
lightviewBounds[0][2] = floor(lightviewBounds[0][2]);
VectorScale(lightviewBounds[0], worldUnitsPerTexel, lightviewBounds[0]);
VectorScale(lightviewBounds[1], invWorldUnitsPerTexel, lightviewBounds[1]);
lightviewBounds[1][0] = floor(lightviewBounds[1][0]);
lightviewBounds[1][1] = floor(lightviewBounds[1][1]);
lightviewBounds[1][2] = floor(lightviewBounds[1][2]);
VectorScale(lightviewBounds[1], worldUnitsPerTexel, lightviewBounds[1]);
}
//ri.Printf(PRINT_ALL, "znear %f zfar %f\n", lightviewBounds[0][0], lightviewBounds[1][0]); //ri.Printf(PRINT_ALL, "znear %f zfar %f\n", lightviewBounds[0][0], lightviewBounds[1][0]);
//ri.Printf(PRINT_ALL, "fovx %f fovy %f xmin %f xmax %f ymin %f ymax %f\n", fd->fov_x, fd->fov_y, xmin, xmax, ymin, ymax); //ri.Printf(PRINT_ALL, "fovx %f fovy %f xmin %f xmax %f ymin %f ymax %f\n", fd->fov_x, fd->fov_y, xmin, xmax, ymin, ymax);
} }
@ -2779,10 +2824,10 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
else else
{ {
shadowParms.viewportX = tr.refdef.x; shadowParms.viewportX = tr.refdef.x;
shadowParms.viewportY = glConfig.vidHeight - ( tr.refdef.y + SUNSHADOW_MAP_SIZE ); shadowParms.viewportY = glConfig.vidHeight - ( tr.refdef.y + tr.sunShadowFbo[level]->height );
} }
shadowParms.viewportWidth = SUNSHADOW_MAP_SIZE; shadowParms.viewportWidth = tr.sunShadowFbo[level]->width;
shadowParms.viewportHeight = SUNSHADOW_MAP_SIZE; shadowParms.viewportHeight = tr.sunShadowFbo[level]->height;
shadowParms.isPortal = qfalse; shadowParms.isPortal = qfalse;
shadowParms.isMirror = qfalse; shadowParms.isMirror = qfalse;

View file

@ -296,7 +296,7 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) {
// don't add third_person objects if not in a portal // don't add third_person objects if not in a portal
personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !(tr.viewParms.isPortal personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !(tr.viewParms.isPortal
|| (tr.viewParms.flags & VPF_SHADOWMAP) || (tr.viewParms.flags & VPF_DEPTHSHADOW)); || (tr.viewParms.flags & (VPF_SHADOWMAP | VPF_DEPTHSHADOW)));
if ( ent->e.renderfx & RF_WRAP_FRAMES ) { if ( ent->e.renderfx & RF_WRAP_FRAMES ) {
ent->e.frame %= tr.currentModel->mdv[0]->numFrames; ent->e.frame %= tr.currentModel->mdv[0]->numFrames;

View file

@ -367,17 +367,27 @@ void RE_RenderScene( const refdef_t *fd ) {
tr.refdef.sunDir[3] = 0.0f; tr.refdef.sunDir[3] = 0.0f;
tr.refdef.sunCol[3] = 1.0f; tr.refdef.sunCol[3] = 1.0f;
tr.refdef.sunAmbCol[3] = 1.0f;
VectorCopy(tr.sunDirection, tr.refdef.sunDir); VectorCopy(tr.sunDirection, tr.refdef.sunDir);
if (r_testSunlight->integer == 1) if ( (tr.refdef.rdflags & RDF_NOWORLDMODEL) || !(r_depthPrepass->value) ){
tr.refdef.colorScale = 1.0f;
VectorSet(tr.refdef.sunCol, 0, 0, 0);
VectorSet(tr.refdef.sunAmbCol, 0, 0, 0);
}
else if (r_forceSun->integer == 1)
{ {
tr.refdef.mapLightScale = 0.66f; float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8);
VectorScale(tr.sunLight, pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8) * 0.33f, tr.refdef.sunCol); tr.refdef.colorScale = r_forceSunMapLightScale->value;
VectorScale(tr.sunLight, scale * r_forceSunLightScale->value, tr.refdef.sunCol);
VectorScale(tr.sunLight, scale * r_forceSunAmbientScale->value, tr.refdef.sunAmbCol);
} }
else else
{ {
tr.refdef.mapLightScale = tr.mapLightScale; float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8);
VectorScale(tr.sunLight, pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8), tr.refdef.sunCol); tr.refdef.colorScale = tr.mapLightScale;
VectorScale(tr.sunLight, scale, tr.refdef.sunCol);
VectorScale(tr.sunAmbient, scale, tr.refdef.sunAmbCol);
} }
//#ifdef REACTION //#ifdef REACTION
@ -389,8 +399,9 @@ void RE_RenderScene( const refdef_t *fd ) {
if (fd->rdflags & RDF_SUNLIGHT) if (fd->rdflags & RDF_SUNLIGHT)
{ {
VectorCopy(extra->sunDir, tr.refdef.sunDir); VectorCopy(extra->sunDir, tr.refdef.sunDir);
VectorCopy(extra->sunCol, tr.refdef.sunCol); VectorCopy(extra->sunCol, tr.refdef.sunCol);
VectorCopy(extra->sunAmbCol, tr.refdef.sunAmbCol);
} }
} }
else else
@ -447,7 +458,7 @@ void RE_RenderScene( const refdef_t *fd ) {
} }
// playing with even more shadows // playing with even more shadows
if(!( fd->rdflags & RDF_NOWORLDMODEL ) && (r_testSunlight->integer || tr.sunShadows)) if(!( fd->rdflags & RDF_NOWORLDMODEL ) && (r_forceSun->integer || tr.sunShadows))
{ {
R_RenderSunShadowMaps(fd, 0); R_RenderSunShadowMaps(fd, 0);
R_RenderSunShadowMaps(fd, 1); R_RenderSunShadowMaps(fd, 1);
@ -484,6 +495,11 @@ void RE_RenderScene( const refdef_t *fd ) {
VectorCopy( fd->vieworg, parms.pvsOrigin ); VectorCopy( fd->vieworg, parms.pvsOrigin );
if(!( fd->rdflags & RDF_NOWORLDMODEL ) && r_depthPrepass->value && ((r_forceSun->integer) || tr.sunShadows))
{
parms.flags = VPF_USESUNLIGHT;
}
R_RenderView( &parms ); R_RenderView( &parms );
if(!( fd->rdflags & RDF_NOWORLDMODEL )) if(!( fd->rdflags & RDF_NOWORLDMODEL ))

View file

@ -809,8 +809,7 @@ static void ForwardDlight( void ) {
// where they aren't rendered // where they aren't rendered
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
Matrix16Identity(matrix); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, matrix);
if (pStage->bundle[TB_DIFFUSEMAP].image[0]) if (pStage->bundle[TB_DIFFUSEMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP); R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP);
@ -905,7 +904,7 @@ static void ForwardSunlight( void ) {
{ {
shaderStage_t *pStage = input->xstages[stage]; shaderStage_t *pStage = input->xstages[stage];
shaderProgram_t *sp; shaderProgram_t *sp;
vec4_t vector; //vec4_t vector;
matrix_t matrix; matrix_t matrix;
if ( !pStage ) if ( !pStage )
@ -920,7 +919,12 @@ static void ForwardSunlight( void ) {
int index = pStage->glslShaderIndex; int index = pStage->glslShaderIndex;
index &= ~(LIGHTDEF_LIGHTTYPE_MASK | LIGHTDEF_USE_DELUXEMAP); index &= ~(LIGHTDEF_LIGHTTYPE_MASK | LIGHTDEF_USE_DELUXEMAP);
index |= LIGHTDEF_USE_LIGHT_VECTOR | LIGHTDEF_USE_SHADOWMAP | LIGHTDEF_USE_SHADOW_CASCADE; index |= LIGHTDEF_USE_LIGHT_VECTOR | LIGHTDEF_USE_SHADOWMAP;
if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
{
index |= LIGHTDEF_ENTITY;
}
sp = &tr.lightallShader[index]; sp = &tr.lightallShader[index];
} }
@ -986,12 +990,8 @@ static void ForwardSunlight( void ) {
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, pStage->alphaGen); GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, pStage->alphaGen);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, backEnd.refdef.sunCol); GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, backEnd.refdef.sunCol);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, backEnd.refdef.sunAmbCol);
VectorSet(vector, 0, 0, 0);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, vector);
//VectorSet4(vector, 0, 0, 1, 0);
//VectorSet4(vector, 0.57735f, 0.57735f, 0.57735f, 0);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir); GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_LIGHTRADIUS, 9999999999); GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_LIGHTRADIUS, 9999999999);
@ -1000,8 +1000,7 @@ static void ForwardSunlight( void ) {
GL_State( stageGlState[stage] ); GL_State( stageGlState[stage] );
Matrix16Identity(matrix); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, matrix);
if (pStage->bundle[TB_DIFFUSEMAP].image[0]) if (pStage->bundle[TB_DIFFUSEMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP); R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP);
@ -1012,6 +1011,7 @@ static void ForwardSunlight( void ) {
if (pStage->bundle[TB_SPECULARMAP].image[0]) if (pStage->bundle[TB_SPECULARMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP); R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP);
/*
{ {
GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP); GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP);
GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2); GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2);
@ -1020,6 +1020,8 @@ static void ForwardSunlight( void ) {
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]);
} }
*/
GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix ); ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_DIFFUSETEXMATRIX, matrix); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_DIFFUSETEXMATRIX, matrix);
@ -1312,9 +1314,44 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
{ {
vec4_t baseColor; vec4_t baseColor;
vec4_t vertColor; vec4_t vertColor;
qboolean tint = qtrue;
int stage2;
ComputeShaderColors(pStage, baseColor, vertColor); ComputeShaderColors(pStage, baseColor, vertColor);
for ( stage2 = stage + 1; stage2 < MAX_SHADER_STAGES; stage2++ )
{
shaderStage_t *pStage2 = input->xstages[stage2];
unsigned int srcBlendBits, dstBlendBits;
if ( !pStage2 )
{
break;
}
srcBlendBits = pStage2->stateBits & GLS_SRCBLEND_BITS;
dstBlendBits = pStage2->stateBits & GLS_DSTBLEND_BITS;
if (srcBlendBits == GLS_SRCBLEND_DST_COLOR)
{
tint = qfalse;
break;
}
}
if (!((tr.sunShadows || r_forceSun->integer) && tess.shader->sort <= SS_OPAQUE
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader))
{
tint = qfalse;
}
if (tint)
{
// use vectorscale to only scale first three values, not alpha
VectorScale(baseColor, backEnd.refdef.colorScale, baseColor);
VectorScale(vertColor, backEnd.refdef.colorScale, vertColor);
}
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_BASECOLOR, baseColor); GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_BASECOLOR, baseColor);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_VERTCOLOR, vertColor); GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_VERTCOLOR, vertColor);
} }
@ -1371,7 +1408,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
GLSL_SetUniformVec2(sp, GENERIC_UNIFORM_MATERIALINFO, pStage->materialInfo); GLSL_SetUniformVec2(sp, GENERIC_UNIFORM_MATERIALINFO, pStage->materialInfo);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale); //GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale);
// //
// do multitexture // do multitexture
@ -1496,16 +1533,7 @@ static void RB_RenderShadowmap( shaderCommands_t *input )
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity) GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
{
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
}
else
{
matrix_t matrix;
Matrix16Identity(matrix);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, matrix);
}
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
@ -1592,15 +1620,15 @@ void RB_StageIteratorGeneric( void )
// //
if ((backEnd.viewParms.flags & VPF_DEPTHSHADOW)) if ((backEnd.viewParms.flags & VPF_DEPTHSHADOW))
{ {
GL_Cull( CT_TWO_SIDED ); //GL_Cull( CT_TWO_SIDED );
/*
if (input->shader->cullType == CT_TWO_SIDED) if (input->shader->cullType == CT_TWO_SIDED)
GL_Cull( CT_TWO_SIDED ); GL_Cull( CT_TWO_SIDED );
else if (input->shader->cullType == CT_FRONT_SIDED) else if (input->shader->cullType == CT_FRONT_SIDED)
GL_Cull( CT_BACK_SIDED ); GL_Cull( CT_BACK_SIDED );
else else
GL_Cull( CT_FRONT_SIDED ); GL_Cull( CT_FRONT_SIDED );
*/
} }
else else
GL_Cull( input->shader->cullType ); GL_Cull( input->shader->cullType );
@ -1686,7 +1714,8 @@ void RB_StageIteratorGeneric( void )
} }
} }
if ((tr.sunShadows || r_testSunlight->integer) && tess.shader->sort <= SS_OPAQUE if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && tess.shader->sort <= SS_OPAQUE
//if ((tr.sunShadows || r_forceSunlight->value > 0.0f) && tess.shader->sort <= SS_OPAQUE
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) { && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) {
ForwardSunlight(); ForwardSunlight();
} }

View file

@ -1608,9 +1608,13 @@ static qboolean ParseShader( char **text )
// sun parms // sun parms
else if ( !Q_stricmp( token, "q3map_sun" ) || !Q_stricmp( token, "q3map_sunExt" ) || !Q_stricmp( token, "q3gl2_sun" ) ) { else if ( !Q_stricmp( token, "q3map_sun" ) || !Q_stricmp( token, "q3map_sunExt" ) || !Q_stricmp( token, "q3gl2_sun" ) ) {
float a, b; float a, b;
qboolean isGL2Sun = qfalse;
if (!Q_stricmp( token, "q3gl2_sun" ) ) if (!Q_stricmp( token, "q3gl2_sun" ) && r_sunShadows->integer )
{
isGL2Sun = qtrue;
tr.sunShadows = qtrue; tr.sunShadows = qtrue;
}
token = COM_ParseExt( text, qfalse ); token = COM_ParseExt( text, qfalse );
tr.sunLight[0] = atof( token ); tr.sunLight[0] = atof( token );
@ -1625,6 +1629,8 @@ static qboolean ParseShader( char **text )
a = atof( token ); a = atof( token );
VectorScale( tr.sunLight, a, tr.sunLight); VectorScale( tr.sunLight, a, tr.sunLight);
VectorSet( tr.sunAmbient, 0.0f, 0.0f, 0.0f);
token = COM_ParseExt( text, qfalse ); token = COM_ParseExt( text, qfalse );
a = atof( token ); a = atof( token );
a = a / 180 * M_PI; a = a / 180 * M_PI;
@ -1637,6 +1643,15 @@ static qboolean ParseShader( char **text )
tr.sunDirection[1] = sin( a ) * cos( b ); tr.sunDirection[1] = sin( a ) * cos( b );
tr.sunDirection[2] = sin( b ); tr.sunDirection[2] = sin( b );
if (isGL2Sun)
{
token = COM_ParseExt( text, qfalse );
tr.mapLightScale = atof(token);
token = COM_ParseExt( text, qfalse );
VectorScale( tr.sunLight, atof(token), tr.sunAmbient );
}
SkipRestOfLine( text ); SkipRestOfLine( text );
} }
else if ( !Q_stricmp( token, "deformVertexes" ) ) { else if ( !Q_stricmp( token, "deformVertexes" ) ) {
@ -3511,7 +3526,21 @@ static void ScanAndLoadShaderFiles( void )
{ {
char filename[MAX_QPATH]; char filename[MAX_QPATH];
Com_sprintf( filename, sizeof( filename ), "scripts/%s", shaderFiles[i] ); // look for a .mtr file first
{
char *ext;
Com_sprintf( filename, sizeof( filename ), "scripts/%s", shaderFiles[i] );
if ( (ext = strrchr(filename, '.')) )
{
strcpy(ext, ".mtr");
}
if ( ri.FS_ReadFile( filename, NULL ) <= 0 )
{
Com_sprintf( filename, sizeof( filename ), "scripts/%s", shaderFiles[i] );
}
}
ri.Printf( PRINT_DEVELOPER, "...loading '%s'\n", filename ); ri.Printf( PRINT_DEVELOPER, "...loading '%s'\n", filename );
summand = ri.FS_ReadFile( filename, (void **)&buffers[i] ); summand = ri.FS_ReadFile( filename, (void **)&buffers[i] );

View file

@ -184,9 +184,9 @@ RB_InstantQuad
based on Tess_InstantQuad from xreal based on Tess_InstantQuad from xreal
============== ==============
*/ */
void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4], vec4_t color, shaderProgram_t *sp, vec2_t invTexRes) void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4])
{ {
GLimp_LogComment("--- RB_InstantQuad ---\n"); GLimp_LogComment("--- RB_InstantQuad2 ---\n");
tess.numVertexes = 0; tess.numVertexes = 0;
tess.numIndexes = 0; tess.numIndexes = 0;
@ -218,12 +218,6 @@ void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4], vec4_t color, sha
RB_UpdateVBOs(ATTR_POSITION | ATTR_TEXCOORD); RB_UpdateVBOs(ATTR_POSITION | ATTR_TEXCOORD);
GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD); GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD);
GLSL_BindProgram(sp);
GLSL_SetUniformMatrix16(sp, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color);
GLSL_SetUniformVec2(sp, TEXTURECOLOR_UNIFORM_INVTEXRES, invTexRes);
GLSL_SetUniformVec2(sp, TEXTURECOLOR_UNIFORM_AUTOEXPOSUREMINMAX, tr.autoExposureMinMax);
R_DrawElementsVBO(tess.numIndexes, tess.firstIndex); R_DrawElementsVBO(tess.numIndexes, tess.firstIndex);
@ -256,7 +250,14 @@ void RB_InstantQuad(vec4_t quadVerts[4])
invTexRes[0] = 1.0f / 256.0f; invTexRes[0] = 1.0f / 256.0f;
invTexRes[1] = 1.0f / 256.0f; invTexRes[1] = 1.0f / 256.0f;
RB_InstantQuad2(quadVerts, texCoords, color, &tr.textureColorShader, invTexRes); GLSL_BindProgram(&tr.textureColorShader);
GLSL_SetUniformMatrix16(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
GLSL_SetUniformVec4(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_COLOR, color);
GLSL_SetUniformVec2(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_INVTEXRES, invTexRes);
GLSL_SetUniformVec2(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_AUTOEXPOSUREMINMAX, tr.autoExposureMinMax);
RB_InstantQuad2(quadVerts, texCoords); //, color, &tr.textureColorShader, invTexRes);
} }
@ -362,7 +363,7 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles,
srfTriangle_t *tri; srfTriangle_t *tri;
srfVert_t *dv; srfVert_t *dv;
float *xyz, *normal, *texCoords, *lightCoords, *lightdir; float *xyz, *normal, *texCoords, *lightCoords, *lightdir;
#ifdef USE_VERT_TANGENT_SPACE #ifdef USE_VERT_TANGENT_SPACE
float *tangent, *bitangent; float *tangent, *bitangent;
#endif #endif
glIndex_t *index; glIndex_t *index;
@ -397,7 +398,7 @@ static void RB_SurfaceHelper( int numVerts, srfVert_t *verts, int numTriangles,
VectorCopy(dv->normal, normal); VectorCopy(dv->normal, normal);
} }
#ifdef USE_VERT_TANGENT_SPACE #ifdef USE_VERT_TANGENT_SPACE
if ( tess.shader->vertexAttribs & ATTR_TANGENT ) if ( tess.shader->vertexAttribs & ATTR_TANGENT )
{ {
dv = verts; dv = verts;
@ -1335,7 +1336,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
float *xyz; float *xyz;
float *texCoords, *lightCoords; float *texCoords, *lightCoords;
float *normal; float *normal;
#ifdef USE_VERT_TANGENT_SPACE #ifdef USE_VERT_TANGENT_SPACE
float *tangent, *bitangent; float *tangent, *bitangent;
#endif #endif
float *color, *lightdir; float *color, *lightdir;
@ -1421,7 +1422,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
xyz = tess.xyz[numVertexes]; xyz = tess.xyz[numVertexes];
normal = tess.normal[numVertexes]; normal = tess.normal[numVertexes];
#ifdef USE_VERT_TANGENT_SPACE #ifdef USE_VERT_TANGENT_SPACE
tangent = tess.tangent[numVertexes]; tangent = tess.tangent[numVertexes];
bitangent = tess.bitangent[numVertexes]; bitangent = tess.bitangent[numVertexes];
#endif #endif
@ -1448,7 +1449,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) {
normal += 4; normal += 4;
} }
#ifdef USE_VERT_TANGENT_SPACE #ifdef USE_VERT_TANGENT_SPACE
if ( tess.shader->vertexAttribs & ATTR_TANGENT ) if ( tess.shader->vertexAttribs & ATTR_TANGENT )
{ {
VectorCopy(dv->tangent, tangent); VectorCopy(dv->tangent, tangent);

View file

@ -54,13 +54,15 @@ static qboolean R_CullSurface( msurface_t *surf ) {
} }
// don't cull for depth shadow // don't cull for depth shadow
if ( (tr.viewParms.flags & VPF_DEPTHSHADOW ) ) /*
if ( tr.viewParms.flags & VPF_DEPTHSHADOW )
{ {
return qfalse; return qfalse;
} }
*/
// shadowmaps draw back surfaces // shadowmaps draw back surfaces
if ( (tr.viewParms.flags & VPF_SHADOWMAP) ) if ( tr.viewParms.flags & (VPF_SHADOWMAP | VPF_DEPTHSHADOW) )
{ {
if (ct == CT_FRONT_SIDED) if (ct == CT_FRONT_SIDED)
{ {
@ -811,7 +813,7 @@ void R_AddWorldSurfaces (void) {
{ {
R_RecursiveWorldNode( tr.world->nodes, 31, 0, 0); R_RecursiveWorldNode( tr.world->nodes, 31, 0, 0);
} }
else if ( !tr.viewParms.flags & VPF_SHADOWMAP ) else if ( !(tr.viewParms.flags & VPF_SHADOWMAP) )
{ {
R_RecursiveWorldNode( tr.world->nodes, 15, ( 1 << tr.refdef.num_dlights ) - 1, ( 1 << tr.refdef.num_pshadows ) - 1 ); R_RecursiveWorldNode( tr.world->nodes, 15, ( 1 << tr.refdef.num_dlights ) - 1, ( 1 << tr.refdef.num_pshadows ) - 1 );
} }