Because I can :)

- Implemented soft shadows using PCF hardware shadow mapping

  The implementation uses sampler2DArrayShadow and PCF which usually
  requires Direct3D 10.1 however it is in the OpenGL 3.2 core so it should
  be widely supported.
  All 3 light types are supported which means parallel lights (sun) use
  scene independent cascaded shadow mapping.
  The implementation is very fast with single taps (400 fps average per
  scene on a GTX 660 ti OC) however I defaulted it to 16 taps so the shadows look
  really good which should you give stable 100 fps on todays hardware.

  The shadow filtering algorithm is based on Carmack's research which was
  released in the original Doom 3 GPL release draw_exp.cpp.

- Changed interaction shaders to use Half-Lambert lighting like in HL2 to
  make the game less dark

- Fixed some of the renderer debugging/development tools like r_showTris
This commit is contained in:
Robert Beckebans 2014-05-10 14:40:01 +02:00
parent b983156829
commit 277964f074
47 changed files with 4294 additions and 1160 deletions

View file

@ -27,6 +27,8 @@ return
"color.vertex",
"colorProcess.pixel",
"colorProcess.vertex",
"debug_shadowmap.pixel",
"debug_shadowmap.vertex",
"depth.pixel",
"depth.vertex",
"depth_skinned.pixel",
@ -54,12 +56,12 @@ return
"heatHazeWithMaskAndVertex.vertex",
"interaction.pixel",
"interaction.vertex",
"interactionSM.pixel",
"interactionSM.vertex",
"interactionAmbient.pixel",
"interactionAmbient.vertex",
"interactionAmbient_skinned.pixel",
"interactionAmbient_skinned.vertex",
"interaction_skinned.pixel",
"interaction_skinned.vertex",
"motionBlur.pixel",
"motionBlur.vertex",
"postprocess.pixel",
@ -91,6 +93,8 @@ return
"texture_color_skinned.vertex",
"texture_color_texgen.pixel",
"texture_color_texgen.vertex",
"vertex_color.pixel",
"vertex_color.vertex",
"wobblesky.pixel",
"wobblesky.vertex",
"zcullReconstruct.pixel",

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -28,21 +29,71 @@ If you have questions concerning this license or the applicable additional terms
#include "global.inc"
#if defined(USE_GPU_SKINNING)
uniform matrices_ubo { float4 matrices[408]; };
#endif
struct VS_IN {
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float4 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR0;
float4 color2 : COLOR1;
};
struct VS_OUT {
float4 position : POSITION;
};
void main( VS_IN vertex, out VS_OUT result ) {
void main( VS_IN vertex, out VS_OUT result )
{
#if defined(USE_GPU_SKINNING)
//--------------------------------------------------------------
// GPU transformation of the position
//
// multiplying with 255.1 give us the same result and is faster than floor( w * 255 + 0.5 )
//--------------------------------------------------------------
const float w0 = vertex.color2.x;
const float w1 = vertex.color2.y;
const float w2 = vertex.color2.z;
const float w3 = vertex.color2.w;
float4 matX, matY, matZ; // must be float4 for vec4
float joint = vertex.color.x * 255.1 * 3;
matX = matrices[int(joint+0)] * w0;
matY = matrices[int(joint+1)] * w0;
matZ = matrices[int(joint+2)] * w0;
joint = vertex.color.y * 255.1 * 3;
matX += matrices[int(joint+0)] * w1;
matY += matrices[int(joint+1)] * w1;
matZ += matrices[int(joint+2)] * w1;
joint = vertex.color.z * 255.1 * 3;
matX += matrices[int(joint+0)] * w2;
matY += matrices[int(joint+1)] * w2;
matZ += matrices[int(joint+2)] * w2;
joint = vertex.color.w * 255.1 * 3;
matX += matrices[int(joint+0)] * w3;
matY += matrices[int(joint+1)] * w3;
matZ += matrices[int(joint+2)] * w3;
float4 modelPosition;
modelPosition.x = dot4( matX, vertex.position );
modelPosition.y = dot4( matY, vertex.position );
modelPosition.z = dot4( matZ, vertex.position );
modelPosition.w = 1.0;
result.position.x = dot4( modelPosition, rpMVPmatrixX );
result.position.y = dot4( modelPosition, rpMVPmatrixY );
result.position.z = dot4( modelPosition, rpMVPmatrixZ );
result.position.w = dot4( modelPosition, rpMVPmatrixW );
#else
result.position.x = dot4( vertex.position, rpMVPmatrixX );
result.position.y = dot4( vertex.position, rpMVPmatrixY );
result.position.z = dot4( vertex.position, rpMVPmatrixZ );
result.position.w = dot4( vertex.position, rpMVPmatrixW );
#endif
}

View file

@ -2,9 +2,10 @@
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,8 +26,27 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
#include "../sound/snd_local.h"
#include "renderprogs/global.inc"
uniform sampler2DArray samp0 : register(s0);
struct PS_IN
{
float4 position : VPOS;
float2 texcoord0 : TEXCOORD0_centroid;
};
struct PS_OUT
{
float4 color : COLOR;
};
void main( PS_IN fragment, out PS_OUT result )
{
float3 tc;
tc.xy = fragment.texcoord0.xy;
tc.z = rpScreenCorrectionFactor.x; // layer
result.color = texture( samp0, tc );// * rpColor;
}

View file

@ -0,0 +1,58 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "renderprogs/global.inc"
struct VS_IN {
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float4 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR0;
};
struct VS_OUT {
float4 position : POSITION;
float2 texcoord0 : TEXCOORD0;
};
void main( VS_IN vertex, out VS_OUT result ) {
result.position.x = dot4( vertex.position, rpMVPmatrixX );
result.position.y = dot4( vertex.position, rpMVPmatrixY );
result.position.z = dot4( vertex.position, rpMVPmatrixZ );
result.position.w = dot4( vertex.position, rpMVPmatrixW );
// compute oldschool texgen or multiply by texture matrix
BRANCH if ( rpTexGen0Enabled.x > 0.0 ) {
result.texcoord0.x = dot4( vertex.position, rpTexGen0S );
result.texcoord0.y = dot4( vertex.position, rpTexGen0T );
} else {
result.texcoord0.x = dot4( vertex.texcoord.xy, rpTextureMatrixS );
result.texcoord0.y = dot4( vertex.texcoord.xy, rpTextureMatrixT );
}
}

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -97,6 +97,20 @@ uniform float4 rpOverbright : register(c50);
uniform float4 rpEnableSkinning : register(c51);
uniform float4 rpAlphaTest : register(c52);
// RB begin
uniform float4 rpAmbientColor : register(c53);
uniform float4 rpGlobalLightOrigin : register(c54);
uniform float4 rpJitterTexScale : register(c55);
uniform float4 rpJitterTexOffset : register(c56);
uniform float4 rpCascadeDistances : register(c57);
#if defined( USE_UNIFORM_ARRAYS )
uniform float4 rpShadowMatrices : register(c58);
#else
uniform float4 rpShadowMatrices[6*4] : register(c59);
#endif
// RB end
static float dot2( float2 a, float2 b ) { return dot( a, b ); }
static float dot3( float3 a, float3 b ) { return dot( a, b ); }
static float dot3( float3 a, float4 b ) { return dot( a, b.xyz ); }
@ -180,6 +194,5 @@ static float4 idtex2Dproj( sampler2D samp, float4 texCoords ) { return tex2Dproj
static float4 swizzleColor( float4 c ) { return c; }
static float2 vposToScreenPosTexCoord( float2 vpos ) { return vpos.xy * rpWindowCoord.xy; }
#define BRANCH
#define IFANY

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -26,7 +27,7 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#include "global.inc"
#include "renderprogs/global.inc"
uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface bump map
uniform sampler2D samp1 : register(s1); // texture 2 is the light falloff texture
@ -64,15 +65,28 @@ void main( PS_IN fragment, out PS_OUT result ) {
localNormal.xy = bumpMap.wy - 0.5;
localNormal.z = sqrt( abs( dot( localNormal.xy, localNormal.xy ) - 0.25 ) );
localNormal = normalize( localNormal );
// RB: http://developer.valvesoftware.com/wiki/Half_Lambert
float halfLdotN = dot3( localNormal, lightVector ) * 0.5 + 0.5;
halfLdotN *= halfLdotN;
// traditional very dark Lambert light model used in Doom 3
//float ldotN = clamp( dot3( localNormal, lightVector ), 0.0, 1.0 );
float ldotN = dot3( localNormal, lightVector );
const half specularPower = 10.0f;
half hDotN = dot3( normalize( fragment.texcoord6.xyz ), localNormal );
half3 specularContribution = _half3( pow( hDotN, specularPower ) );
// RB: added abs
half3 specularContribution = _half3( pow( abs( hDotN ), specularPower ) );
half3 diffuseColor = diffuseMap * rpDiffuseModifier.xyz;
half3 specularColor = specMap.xyz * specularContribution * rpSpecularModifier.xyz;
half3 lightColor = dot3( lightVector, localNormal ) * lightProj.xyz * lightFalloff.xyz;
half3 lightColor = lightProj.xyz * lightFalloff.xyz;
half rim = 1.0f - saturate( hDotN );
half rimPower = 16.0f;
half3 rimColor = diffuseColor * lightProj.xyz * lightFalloff.xyz * 1.0f * pow( rim, rimPower ) * fragment.color.rgb;// * halfLdotN;
result.color.xyz = ( diffuseColor + specularColor ) * lightColor * fragment.color.xyz;
result.color.xyz = ( diffuseColor + specularColor ) * halfLdotN * lightColor * fragment.color.rgb;// + rimColor;
result.color.w = 1.0;
}

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -26,7 +27,11 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#include "global.inc"
#include "renderprogs/global.inc"
#if defined( USE_GPU_SKINNING )
uniform matrices_ubo { float4 matrices[408]; };
#endif
struct VS_IN {
float4 position : POSITION;
@ -34,6 +39,7 @@ struct VS_IN {
float4 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR0;
float4 color2 : COLOR1;
};
struct VS_OUT {
@ -50,24 +56,89 @@ struct VS_OUT {
void main( VS_IN vertex, out VS_OUT result ) {
float3 vNormal = vertex.normal.xyz * 2.0 - 1.0;
float4 vNormal = vertex.normal * 2.0 - 1.0;
float4 vTangent = vertex.tangent * 2.0 - 1.0;
float3 vBinormal = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
float3 vBitangent = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
result.position.x = dot4( vertex.position, rpMVPmatrixX );
result.position.y = dot4( vertex.position, rpMVPmatrixY );
result.position.z = dot4( vertex.position, rpMVPmatrixZ );
result.position.w = dot4( vertex.position, rpMVPmatrixW );
#if defined( USE_GPU_SKINNING )
//--------------------------------------------------------------
// GPU transformation of the normal / tangent / bitangent
//
// multiplying with 255.1 give us the same result and is faster than floor( w * 255 + 0.5 )
//--------------------------------------------------------------
const float w0 = vertex.color2.x;
const float w1 = vertex.color2.y;
const float w2 = vertex.color2.z;
const float w3 = vertex.color2.w;
float4 matX, matY, matZ; // must be float4 for vec4
float joint = vertex.color.x * 255.1 * 3;
matX = matrices[int(joint+0)] * w0;
matY = matrices[int(joint+1)] * w0;
matZ = matrices[int(joint+2)] * w0;
joint = vertex.color.y * 255.1 * 3;
matX += matrices[int(joint+0)] * w1;
matY += matrices[int(joint+1)] * w1;
matZ += matrices[int(joint+2)] * w1;
joint = vertex.color.z * 255.1 * 3;
matX += matrices[int(joint+0)] * w2;
matY += matrices[int(joint+1)] * w2;
matZ += matrices[int(joint+2)] * w2;
joint = vertex.color.w * 255.1 * 3;
matX += matrices[int(joint+0)] * w3;
matY += matrices[int(joint+1)] * w3;
matZ += matrices[int(joint+2)] * w3;
float3 normal;
normal.x = dot3( matX, vNormal );
normal.y = dot3( matY, vNormal );
normal.z = dot3( matZ, vNormal );
normal = normalize( normal );
float3 tangent;
tangent.x = dot3( matX, vTangent );
tangent.y = dot3( matY, vTangent );
tangent.z = dot3( matZ, vTangent );
tangent = normalize( tangent );
float3 bitangent;
bitangent.x = dot3( matX, vBitangent );
bitangent.y = dot3( matY, vBitangent );
bitangent.z = dot3( matZ, vBitangent );
bitangent = normalize( bitangent );
float4 modelPosition;
modelPosition.x = dot4( matX, vertex.position );
modelPosition.y = dot4( matY, vertex.position );
modelPosition.z = dot4( matZ, vertex.position );
modelPosition.w = 1.0;
#else
float4 modelPosition = vertex.position;
float3 normal = vNormal.xyz;
float3 tangent = vTangent.xyz;
float3 bitangent = vBitangent.xyz;
#endif
result.position.x = dot4( modelPosition, rpMVPmatrixX );
result.position.y = dot4( modelPosition, rpMVPmatrixY );
result.position.z = dot4( modelPosition, rpMVPmatrixZ );
result.position.w = dot4( modelPosition, rpMVPmatrixW );
float4 defaultTexCoord = float4( 0.0f, 0.5f, 0.0f, 1.0f );
//calculate vector to light in R0
float4 toLight = rpLocalLightOrigin - vertex.position;
//calculate vector to light
float4 toLight = rpLocalLightOrigin - modelPosition;
//result.texcoord0
result.texcoord0.x = dot3( vTangent.xyz, toLight );
result.texcoord0.y = dot3( vBinormal, toLight );
result.texcoord0.z = dot3( vNormal, toLight );
//--------------------------------------------------------------
//result.texcoord0 is the direction to the light in tangent space
result.texcoord0.x = dot3( tangent, toLight );
result.texcoord0.y = dot3( bitangent, toLight );
result.texcoord0.z = dot3( normal, toLight );
result.texcoord0.w = 1.0f;
//textures 1 takes the base coordinates by the texture matrix
@ -77,13 +148,13 @@ void main( VS_IN vertex, out VS_OUT result ) {
//# texture 2 has one texgen
result.texcoord2 = defaultTexCoord;
result.texcoord2.x = dot4( vertex.position, rpLightFalloffS );
result.texcoord2.x = dot4( modelPosition, rpLightFalloffS );
//# texture 3 has three texgens
result.texcoord3.x = dot4( vertex.position, rpLightProjectionS );
result.texcoord3.y = dot4( vertex.position, rpLightProjectionT );
result.texcoord3.x = dot4( modelPosition, rpLightProjectionS );
result.texcoord3.y = dot4( modelPosition, rpLightProjectionT );
result.texcoord3.z = 0.0f;
result.texcoord3.w = dot4( vertex.position, rpLightProjectionQ );
result.texcoord3.w = dot4( modelPosition, rpLightProjectionQ );
//# textures 4 takes the base coordinates by the texture matrix
result.texcoord4 = defaultTexCoord;
@ -101,20 +172,27 @@ void main( VS_IN vertex, out VS_OUT result ) {
toLight = normalize( toLight );
//# calculate normalized vector to viewer in R1
float4 toView = normalize( rpLocalViewOrigin - vertex.position );
float4 toView = normalize( rpLocalViewOrigin - modelPosition );
//# add together to become the half angle vector in object space (non-normalized)
float4 halfAngleVector = toLight + toView;
//# put into texture space
result.texcoord6.x = dot3( vTangent.xyz, halfAngleVector );
result.texcoord6.y = dot3( vBinormal, halfAngleVector );
result.texcoord6.z = dot3( vNormal, halfAngleVector );
result.texcoord6.x = dot3( tangent, halfAngleVector );
result.texcoord6.y = dot3( bitangent, halfAngleVector );
result.texcoord6.z = dot3( normal, halfAngleVector );
result.texcoord6.w = 1.0f;
#if defined( USE_GPU_SKINNING )
// for joint transformation of the tangent space, we use color and
// color2 for weighting information, so hopefully there aren't any
// effects that need vertex color...
result.color = float4( 1.0f, 1.0f, 1.0f, 1.0f );
#else
//# generate the vertex color, which can be 1.0, color, or 1.0 - color
//# for 1.0 : env[16] = 0, env[17] = 1
//# for color : env[16] = 1, env[17] = 0
//# for 1.0-color : env[16] = -1, env[17] = 1
result.color = ( swizzleColor( vertex.color ) * rpVertexColorModulate ) + rpVertexColorAdd;
#endif
}

View file

@ -0,0 +1,260 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "renderprogs/global.inc"
uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface bump map
uniform sampler2D samp1 : register(s1); // texture 2 is the light falloff texture
uniform sampler2D samp2 : register(s2); // texture 3 is the light projection texture
uniform sampler2D samp3 : register(s3); // texture 4 is the per-surface diffuse map
uniform sampler2D samp4 : register(s4); // texture 5 is the per-surface specular map
uniform sampler2DArrayShadow samp5 : register(s5); // texture 6 is the shadowmap array
uniform sampler2D samp6 : register(s6); // texture 7 is the jitter texture
struct PS_IN
{
half4 position : VPOS;
half4 texcoord0 : TEXCOORD0_centroid;
half4 texcoord1 : TEXCOORD1_centroid;
half4 texcoord2 : TEXCOORD2_centroid;
half4 texcoord3 : TEXCOORD3_centroid;
half4 texcoord4 : TEXCOORD4_centroid;
half4 texcoord5 : TEXCOORD5_centroid;
half4 texcoord6 : TEXCOORD6_centroid;
half4 texcoord7 : TEXCOORD7_centroid;
half4 texcoord8 : TEXCOORD8_centroid;
half4 texcoord9 : TEXCOORD9_centroid;
half4 color : COLOR0;
};
struct PS_OUT
{
half4 color : COLOR;
};
void main( PS_IN fragment, out PS_OUT result )
{
half4 bumpMap = tex2D( samp0, fragment.texcoord1.xy );
half4 lightFalloff = idtex2Dproj( samp1, fragment.texcoord2 );
half4 lightProj = idtex2Dproj( samp2, fragment.texcoord3 );
half4 YCoCG = tex2D( samp3, fragment.texcoord4.xy );
half4 specMap = tex2D( samp4, fragment.texcoord5.xy );
half3 lightVector = normalize( fragment.texcoord0.xyz );
half3 diffuseMap = ConvertYCoCgToRGB( YCoCG );
half3 localNormal;
// RB begin
#if defined(GLES2)
localNormal.xy = bumpMap.rg - 0.5;
#else
localNormal.xy = bumpMap.wy - 0.5;
#endif
// RB end
localNormal.z = sqrt( abs( dot( localNormal.xy, localNormal.xy ) - 0.25 ) );
localNormal = normalize( localNormal );
// RB: http://developer.valvesoftware.com/wiki/Half_Lambert
float halfLdotN = dot3( localNormal, lightVector ) * 0.5 + 0.5;
halfLdotN *= halfLdotN;
// traditional very dark Lambert light model used in Doom 3
float ldotN = dot3( localNormal, lightVector );
const half specularPower = 10.0f;
half hDotN = dot3( normalize( fragment.texcoord6.xyz ), localNormal );
// RB: added abs
half3 specularContribution = _half3( pow( abs( hDotN ), specularPower ) );
half3 diffuseColor = diffuseMap * rpDiffuseModifier.xyz;
half3 specularColor = specMap.xyz * specularContribution * rpSpecularModifier.xyz;
half3 lightColor = lightProj.xyz * lightFalloff.xyz;
half rim = 1.0f - saturate( hDotN );
half rimPower = 16.0f;
half3 rimColor = diffuseColor * lightProj.xyz * lightFalloff.xyz * 1.0f * pow( rim, rimPower ) * fragment.color.rgb;// * halfLdotN;
//
// shadow mapping
//
int shadowIndex = 0;
#if defined( LIGHT_POINT )
float3 toLightGlobal = normalize( fragment.texcoord8.xyz );
float axis[6];
axis[0] = -toLightGlobal.x;
axis[1] = toLightGlobal.x;
axis[2] = -toLightGlobal.y;
axis[3] = toLightGlobal.y;
axis[4] = -toLightGlobal.z;
axis[5] = toLightGlobal.z;
for( int i = 0; i < 6; i++ )
{
if( axis[i] > axis[shadowIndex] )
{
shadowIndex = i;
}
}
#endif // #if defined( POINTLIGHT )
#if defined( LIGHT_PARALLEL )
float viewZ = -fragment.texcoord9.z;
shadowIndex = 4;
for( int i = 0; i < 4; i++ )
{
if( viewZ < rpCascadeDistances[i] )
{
shadowIndex = i;
break;
}
}
#endif
#if 0
if( shadowIndex == 0 )
{
result.color = float4( 1.0, 0.0, 0.0, 1.0 );
}
else if( shadowIndex == 1 )
{
result.color = float4( 0.0, 1.0, 0.0, 1.0 );
}
else if( shadowIndex == 2 )
{
result.color = float4( 0.0, 0.0, 1.0, 1.0 );
}
else if( shadowIndex == 3 )
{
result.color = float4( 1.0, 1.0, 0.0, 1.0 );
}
else if( shadowIndex == 4 )
{
result.color = float4( 1.0, 0.0, 1.0, 1.0 );
}
else if( shadowIndex == 5 )
{
result.color = float4( 0.0, 1.0, 1.0, 1.0 );
}
//result.color.xyz *= lightColor;
return;
#endif
float4 shadowMatrixX = rpShadowMatrices[ int ( shadowIndex * 4 + 0 ) ];
float4 shadowMatrixY = rpShadowMatrices[ int ( shadowIndex * 4 + 1 ) ];
float4 shadowMatrixZ = rpShadowMatrices[ int ( shadowIndex * 4 + 2 ) ];
float4 shadowMatrixW = rpShadowMatrices[ int ( shadowIndex * 4 + 3 ) ];
float4 modelPosition = float4( fragment.texcoord7.xyz, 1.0 );
float4 shadowTexcoord;
shadowTexcoord.x = dot4( modelPosition, shadowMatrixX );
shadowTexcoord.y = dot4( modelPosition, shadowMatrixY );
shadowTexcoord.z = dot4( modelPosition, shadowMatrixZ );
shadowTexcoord.w = dot4( modelPosition, shadowMatrixW );
//float bias = 0.001 * tan( acos( ldotN ) );
//bias = clamp( bias, 0, 0.001 );
float bias = 0.001;
shadowTexcoord.xyz /= shadowTexcoord.w;
shadowTexcoord.z = shadowTexcoord.z * 0.9991;
//shadowTexcoord.z = shadowTexcoord.z - bias;
shadowTexcoord.w = shadowIndex;
#if 0
result.color.xyz = float3( shadowTexcoord.z, shadowTexcoord.z, shadowTexcoord.z );
result.color.w = 1.0;
return;
#endif
// multiple taps
#if 0
const float2 poissonDisk2[12] = float2[](
float2(-0.326,-0.406),
float2(-0.840,-0.074),
float2(-0.696, 0.457),
float2(-0.203, 0.621),
float2( 0.962,-0.195),
float2( 0.473,-0.480),
float2( 0.519, 0.767),
float2( 0.185,-0.893),
float2( 0.507, 0.064),
float2( 0.896, 0.412),
float2(-0.322,-0.933),
float2(-0.792,-0.598)
);
float shadow = 0.0;
float shadowTexelSize = ( 1.0 / 1024.0 ) * 0.5;
for( int i = 0; i < 12; i++ )
{
int index = int( rand( shadowTexcoord.xy * 1.0 ) * 12 );
float4 shadowTexcoordOffset = float4( shadowTexcoord.xy + poissonDisk2[index] * shadowTexelSize, shadowTexcoord.z, shadowTexcoord.w );
shadow += texture( samp5, shadowTexcoordOffset.xywz);
}
shadow *= ( 1.0 / 12.0 );
#elif 1
float4 base = shadowTexcoord;
base.xy += rpJitterTexScale.xy * -0.5;
float shadow = 0.0;
float stepSize = 1.0 / 16;
float4 jitterTC = ( fragment.position * rpScreenCorrectionFactor ) + rpJitterTexOffset;
for( int i = 0; i < 16; i++ )
{
float4 jitter = base + tex2D( samp6, jitterTC.xy ) * rpJitterTexScale;
jitter.zw = shadowTexcoord.zw;
shadow += texture( samp5, jitter.xywz );
jitterTC.x += stepSize;
}
shadow *= ( 1.0 / 16 );
#else
float shadow = texture( samp5, shadowTexcoord.xywz );
#endif
result.color.xyz = ( diffuseColor + specularColor ) * halfLdotN * lightColor * fragment.color.rgb * shadow;// + rimColor;
result.color.w = 1.0;
}

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -26,9 +27,11 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#include "global.inc"
#include "renderprogs/global.inc"
#if defined( USE_GPU_SKINNING )
uniform matrices_ubo { float4 matrices[408]; };
#endif
struct VS_IN {
float4 position : POSITION;
@ -48,6 +51,9 @@ struct VS_OUT {
float4 texcoord4 : TEXCOORD4;
float4 texcoord5 : TEXCOORD5;
float4 texcoord6 : TEXCOORD6;
float4 texcoord7 : TEXCOORD7;
float4 texcoord8 : TEXCOORD8;
float4 texcoord9 : TEXCOORD9;
float4 color : COLOR0;
};
@ -55,10 +61,11 @@ void main( VS_IN vertex, out VS_OUT result ) {
float4 vNormal = vertex.normal * 2.0 - 1.0;
float4 vTangent = vertex.tangent * 2.0 - 1.0;
float3 vBinormal = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
float3 vBitangent = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
#if defined( USE_GPU_SKINNING )
//--------------------------------------------------------------
// GPU transformation of the normal / binormal / bitangent
// GPU transformation of the normal / tangent / bitangent
//
// multiplying with 255.1 give us the same result and is faster than floor( w * 255 + 0.5 )
//--------------------------------------------------------------
@ -100,11 +107,11 @@ void main( VS_IN vertex, out VS_OUT result ) {
tangent.z = dot3( matZ, vTangent );
tangent = normalize( tangent );
float3 binormal;
binormal.x = dot3( matX, vBinormal );
binormal.y = dot3( matY, vBinormal );
binormal.z = dot3( matZ, vBinormal );
binormal = normalize( binormal );
float3 bitangent;
bitangent.x = dot3( matX, vBitangent );
bitangent.y = dot3( matY, vBitangent );
bitangent.z = dot3( matZ, vBitangent );
bitangent = normalize( bitangent );
float4 modelPosition;
modelPosition.x = dot4( matX, vertex.position );
@ -112,6 +119,13 @@ void main( VS_IN vertex, out VS_OUT result ) {
modelPosition.z = dot4( matZ, vertex.position );
modelPosition.w = 1.0;
#else
float4 modelPosition = vertex.position;
float3 normal = vNormal.xyz;
float3 tangent = vTangent.xyz;
float3 bitangent = vBitangent.xyz;
#endif
result.position.x = dot4( modelPosition, rpMVPmatrixX );
result.position.y = dot4( modelPosition, rpMVPmatrixY );
result.position.z = dot4( modelPosition, rpMVPmatrixZ );
@ -119,15 +133,15 @@ void main( VS_IN vertex, out VS_OUT result ) {
float4 defaultTexCoord = float4( 0.0f, 0.5f, 0.0f, 1.0f );
//calculate vector to light in R0
float4 toLight = rpLocalLightOrigin - modelPosition;
//calculate vector to light
float4 toLightLocal = rpLocalLightOrigin - modelPosition;
//--------------------------------------------------------------
//result.texcoord0 is the direction to the light in tangent space
result.texcoord0.x = dot3( tangent, toLight );
result.texcoord0.y = dot3( binormal, toLight );
result.texcoord0.z = dot3( normal, toLight );
result.texcoord0.x = dot3( tangent, toLightLocal );
result.texcoord0.y = dot3( bitangent, toLightLocal );
result.texcoord0.z = dot3( normal, toLightLocal );
result.texcoord0.w = 1.0f;
//textures 1 takes the base coordinates by the texture matrix
@ -158,28 +172,50 @@ void main( VS_IN vertex, out VS_OUT result ) {
//# texture 6's texcoords will be the halfangle in texture space
//# calculate normalized vector to light in R0
toLight = normalize( toLight );
toLightLocal = normalize( toLightLocal );
//# calculate normalized vector to viewer in R1
float4 toView = normalize( rpLocalViewOrigin - modelPosition );
//# add together to become the half angle vector in object space (non-normalized)
float4 halfAngleVector = toLight + toView;
float4 halfAngleVector = toLightLocal + toView;
//# put into texture space
result.texcoord6.x = dot3( tangent, halfAngleVector );
result.texcoord6.y = dot3( binormal, halfAngleVector );
result.texcoord6.y = dot3( bitangent, halfAngleVector );
result.texcoord6.z = dot3( normal, halfAngleVector );
result.texcoord6.w = 1.0f;
result.texcoord7 = modelPosition;
float4 worldPosition;
worldPosition.x = dot4( modelPosition, rpModelMatrixX );
worldPosition.y = dot4( modelPosition, rpModelMatrixY );
worldPosition.z = dot4( modelPosition, rpModelMatrixZ );
worldPosition.w = dot4( modelPosition, rpModelMatrixW );
float4 toLightGlobal = rpGlobalLightOrigin - worldPosition;
result.texcoord8 = toLightGlobal;
float4 viewPosition;
viewPosition.x = dot4( modelPosition, rpModelViewMatrixX );
viewPosition.y = dot4( modelPosition, rpModelViewMatrixY );
viewPosition.z = dot4( modelPosition, rpModelViewMatrixZ );
viewPosition.w = dot4( modelPosition, rpModelViewMatrixW );
result.texcoord9 = viewPosition;
#if defined( USE_GPU_SKINNING )
// for joint transformation of the tangent space, we use color and
// color2 for weighting information, so hopefully there aren't any
// effects that need vertex color...
result.color = float4( 1.0f, 1.0f, 1.0f, 1.0f );
#else
//# generate the vertex color, which can be 1.0, color, or 1.0 - color
//# for 1.0 : env[16] = 0, env[17] = 1
//# for color : env[16] = 1, env[17] = 0
//# for 1.0-color : env[16] = -1, env[17] = 1
// result.color = ( swizzleColor( vertex.color ) * rpVertexColorModulate ) + rpVertexColorAdd;
result.color = ( swizzleColor( vertex.color ) * rpVertexColorModulate ) + rpVertexColorAdd;
#endif
}

View file

@ -1,78 +0,0 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "global.inc"
uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface bump map
uniform sampler2D samp1 : register(s1); // texture 2 is the light falloff texture
uniform sampler2D samp2 : register(s2); // texture 3 is the light projection texture
uniform sampler2D samp3 : register(s3); // texture 4 is the per-surface diffuse map
uniform sampler2D samp4 : register(s4); // texture 5 is the per-surface specular map
struct PS_IN {
half4 position : VPOS;
half4 texcoord0 : TEXCOORD0_centroid;
half4 texcoord1 : TEXCOORD1_centroid;
half4 texcoord2 : TEXCOORD2_centroid;
half4 texcoord3 : TEXCOORD3_centroid;
half4 texcoord4 : TEXCOORD4_centroid;
half4 texcoord5 : TEXCOORD5_centroid;
half4 texcoord6 : TEXCOORD6_centroid;
half4 color : COLOR0;
};
struct PS_OUT {
half4 color : COLOR;
};
void main( PS_IN fragment, out PS_OUT result ) {
half4 bumpMap = tex2D( samp0, fragment.texcoord1.xy );
half4 lightFalloff = idtex2Dproj( samp1, fragment.texcoord2 );
half4 lightProj = idtex2Dproj( samp2, fragment.texcoord3 );
half4 YCoCG = tex2D( samp3, fragment.texcoord4.xy );
half4 specMap = tex2D( samp4, fragment.texcoord5.xy );
half3 lightVector = normalize( fragment.texcoord0.xyz );
half3 diffuseMap = ConvertYCoCgToRGB( YCoCG );
half3 localNormal;
localNormal.xy = bumpMap.wy - 0.5;
localNormal.z = sqrt( abs( dot( localNormal.xy, localNormal.xy ) - 0.25 ) );
localNormal = normalize( localNormal );
const half specularPower = 10.0f;
half hDotN = dot3( normalize( fragment.texcoord6.xyz ), localNormal );
half3 specularContribution = _half3( pow( hDotN, specularPower ) );
half3 diffuseColor = diffuseMap * rpDiffuseModifier.xyz;
half3 specularColor = specMap.xyz * specularContribution * rpSpecularModifier.xyz;
half3 lightColor = dot3( lightVector, localNormal ) * lightProj.xyz * lightFalloff.xyz;
result.color.xyz = ( diffuseColor + specularColor ) * lightColor * fragment.color.xyz;
result.color.w = 1.0;
}

View file

@ -2,9 +2,10 @@
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,8 +26,22 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#ifndef __AUTO_RENDER_BINK_H__
#define __AUTO_RENDER_BINK_H__
#include "renderprogs/global.inc"
#endif // __AUTO_RENDER_BINK_H__
uniform sampler2D samp0 : register(s0);
struct PS_IN
{
float4 color : COLOR0;
};
struct PS_OUT
{
float4 color : COLOR;
};
void main( PS_IN fragment, out PS_OUT result )
{
result.color = fragment.color;
}

View file

@ -2,9 +2,10 @@
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,34 +26,30 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#ifndef __AUTO_RENDER_H__
#define __AUTO_RENDER_H__
class idAutoRender : public idSysThread
#include "renderprogs/global.inc"
struct VS_IN
{
public:
idAutoRender();
// idSysThread interface
int Run();
void StartBackgroundAutoSwaps( autoRenderIconType_t iconType );
void EndBackgroundAutoSwaps();
autoRenderIconType_t GetCurrentIcon()
{
return autoRenderIcon;
}
private:
void RenderFrame();
void RenderBackground();
void RenderLoadingIcon( float fracX, float fracY, float size, float speed );
int nextRotateTime;
float currentRotation;
autoRenderIconType_t autoRenderIcon;
float4 position : POSITION;
float2 texcoord : TEXCOORD0;
float4 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR0;
};
extern idAutoRender rAutoRender;
struct VS_OUT
{
float4 position : POSITION;
float4 color : COLOR0;
};
#endif // __AUTO_RENDER_H__
void main( VS_IN vertex, out VS_OUT result )
{
result.position.x = dot4( vertex.position, rpMVPmatrixX );
result.position.y = dot4( vertex.position, rpMVPmatrixY );
result.position.z = dot4( vertex.position, rpMVPmatrixZ );
result.position.w = dot4( vertex.position, rpMVPmatrixW );
result.color = swizzleColor( vertex.color );
}

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2012 Robert Beckebans
Copyright (C) 2012-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -33,7 +33,6 @@ If you have questions concerning this license or the applicable additional terms
#include "Common_local.h"
#include "ConsoleHistory.h"
#include "../renderer/AutoRenderBink.h"
#include "../sound/sound.h"

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -84,6 +85,15 @@ ALIGNTYPE16 const idRenderMatrix renderMatrix_windowSpaceToClipSpace(
0.0f, 0.0f, 0.0f, 1.0f
);
// RB begin
ALIGNTYPE16 const idRenderMatrix renderMatrix_clipSpaceToWindowSpace(
0.5f, 0.0f, 0.0f, 0.5f,
0.0f, 0.5f, 0.0f, 0.5f,
0.0f, 0.0f, 0.5f, 0.5f,
0.0f, 0.0f, 0.0f, 1.0f
);
// RB end
/*
================================================================================================

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -167,6 +168,9 @@ private:
extern const idRenderMatrix renderMatrix_identity;
extern const idRenderMatrix renderMatrix_flipToOpenGL;
extern const idRenderMatrix renderMatrix_windowSpaceToClipSpace;
// RB begin
extern const idRenderMatrix renderMatrix_clipSpaceToWindowSpace;
// RB end
/*
========================

View file

@ -1,304 +0,0 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#pragma hdrstop
#include "precompiled.h"
#include "tr_local.h"
const int AUTO_RENDER_STACK_SIZE = 256 * 1024;
idAutoRender rAutoRender;
/*
============================
idAutoRender::idAutoRender
============================
*/
idAutoRender::idAutoRender()
{
nextRotateTime = 0.0f;
currentRotation = 0.0f;
autoRenderIcon = AUTORENDER_DEFAULTICON;
}
/*
============================
idAutoRender::Run
============================
*/
int idAutoRender::Run()
{
while( !IsTerminating() )
{
RenderFrame();
}
return 0;
}
/*
============================
idAutoRender::StartBackgroundAutoSwaps
============================
*/
void idAutoRender::StartBackgroundAutoSwaps( autoRenderIconType_t iconType )
{
if( IsRunning() )
{
EndBackgroundAutoSwaps();
}
autoRenderIcon = iconType;
idLib::Printf( "Starting Background AutoSwaps\n" );
const bool captureToImage = true;
common->UpdateScreen( captureToImage );
// unbind any shaders prior to entering the background autoswaps so we don't run
// into any problems with cached vertex shader indices from the main thread
renderProgManager.Unbind();
// unbind all texture units so we don't run into a race condition where the device is owned
// by the autorender thread but an image is trying to be unset from the main thread because
// it is getting purged before our our first frame has been rendered.
globalImages->UnbindAll();
// DG: set name to "BGAutoSwaps" because Linux has a 16char (incl. \0) namelimit for threads
StartThread( "BGAutoSwaps", CORE_0B, THREAD_NORMAL, AUTO_RENDER_STACK_SIZE );
// DG end
}
/*
============================
idAutoRender::EndBackgroundAutoSwaps
============================
*/
void idAutoRender::EndBackgroundAutoSwaps()
{
idLib::Printf( "End Background AutoSwaps\n" );
StopThread();
}
/*
============================
idAutoRender::RenderFrame
============================
*/
void idAutoRender::RenderFrame()
{
// values are 0 to 1
float loadingIconPosX = 0.5f;
float loadingIconPosY = 0.6f;
float loadingIconScale = 0.025f;
float loadingIconSpeed = 0.095f;
if( autoRenderIcon == AUTORENDER_HELLICON )
{
loadingIconPosX = 0.85f;
loadingIconPosY = 0.85f;
loadingIconScale = 0.1f;
loadingIconSpeed = 0.095f;
}
else if( autoRenderIcon == AUTORENDER_DIALOGICON )
{
loadingIconPosY = 0.73f;
}
GL_SetDefaultState();
GL_Cull( CT_TWO_SIDED );
const bool stereoRender = false;
const int width = renderSystem->GetWidth();
const int height = renderSystem->GetHeight();
const int guardBand = height / 24;
if( stereoRender )
{
for( int viewNum = 0 ; viewNum < 2; viewNum++ )
{
GL_ViewportAndScissor( 0, viewNum * ( height + guardBand ), width, height );
RenderBackground();
RenderLoadingIcon( loadingIconPosX, loadingIconPosY, loadingIconScale, loadingIconSpeed );
}
}
else
{
GL_ViewportAndScissor( 0, 0, width, height );
RenderBackground();
RenderLoadingIcon( loadingIconPosX, loadingIconPosY, loadingIconScale, loadingIconSpeed );
}
}
/*
============================
idAutoRender::RenderBackground
============================
*/
void idAutoRender::RenderBackground()
{
GL_SelectTexture( 0 );
globalImages->currentRenderImage->Bind();
GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
float mvpMatrix[16] = { 0 };
mvpMatrix[0] = 1;
mvpMatrix[5] = 1;
mvpMatrix[10] = 1;
mvpMatrix[15] = 1;
// Set Parms
float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS );
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT );
// disable texgen
float texGenEnabled[4] = { 0, 0, 0, 0 };
renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled );
// set matrix
renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, mvpMatrix, 4 );
renderProgManager.BindShader_TextureVertexColor();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
}
/*
============================
idAutoRender::RenderLoadingIcon
============================
*/
void idAutoRender::RenderLoadingIcon( float fracX, float fracY, float size, float speed )
{
float s = 0.0f;
float c = 1.0f;
if( autoRenderIcon != AUTORENDER_HELLICON )
{
if( Sys_Milliseconds() >= nextRotateTime )
{
nextRotateTime = Sys_Milliseconds() + 100;
currentRotation -= 90.0f;
}
float angle = DEG2RAD( currentRotation );
idMath::SinCos( angle, s, c );
}
const float pixelAspect = renderSystem->GetPixelAspect();
const float screenWidth = renderSystem->GetWidth();
const float screenHeight = renderSystem->GetHeight();
const float minSize = Min( screenWidth, screenHeight );
if( minSize <= 0.0f )
{
return;
}
float scaleX = size * minSize / screenWidth;
float scaleY = size * minSize / screenHeight;
float scale[16] = { 0 };
scale[0] = c * scaleX / pixelAspect;
scale[1] = -s * scaleY;
scale[4] = s * scaleX / pixelAspect;
scale[5] = c * scaleY;
scale[10] = 1.0f;
scale[15] = 1.0f;
scale[12] = fracX;
scale[13] = fracY;
float ortho[16] = { 0 };
ortho[0] = 2.0f;
ortho[5] = -2.0f;
ortho[10] = -2.0f;
ortho[12] = -1.0f;
ortho[13] = 1.0f;
ortho[14] = -1.0f;
ortho[15] = 1.0f;
float finalOrtho[16];
R_MatrixMultiply( scale, ortho, finalOrtho );
float projMatrixTranspose[16];
R_MatrixTranspose( finalOrtho, projMatrixTranspose );
renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, projMatrixTranspose, 4 );
float a = 1.0f;
if( autoRenderIcon == AUTORENDER_HELLICON )
{
float alpha = DEG2RAD( Sys_Milliseconds() * speed );
a = idMath::Sin( alpha );
a = 0.35f + ( 0.65f * idMath::Fabs( a ) );
}
GL_SelectTexture( 0 );
if( autoRenderIcon == AUTORENDER_HELLICON )
{
globalImages->hellLoadingIconImage->Bind();
}
else
{
globalImages->loadingIconImage->Bind();
}
GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
// Set Parms
float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS );
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT );
if( autoRenderIcon == AUTORENDER_HELLICON )
{
GL_Color( 1.0f, 1.0f, 1.0f, a );
}
// disable texgen
float texGenEnabled[4] = { 0, 0, 0, 0 };
renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled );
renderProgManager.BindShader_TextureVertexColor();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
}

View file

@ -389,7 +389,7 @@ ID_TIME_T idBinaryImage::WriteGeneratedFile( ID_TIME_T sourceFileTime )
idLib::Warning( "idBinaryImage: Could not open file '%s'", binaryFileName.c_str() );
return FILE_NOT_FOUND_TIMESTAMP;
}
idLib::Printf( "Writing %s\n", binaryFileName.c_str() );
idLib::Printf( "Writing %s: %ix%i\n", binaryFileName.c_str(), fileData.width, fileData.height );
fileData.headerMagic = BIMAGE_MAGIC;
fileData.sourceFileTime = sourceFileTime;

View file

@ -112,10 +112,12 @@ struct shortBounds_t
// the maxs are stored negated
for( int i = 0 ; i < 3 ; i++ )
{
// RB: replaced std::min, max
int minv = floor( set[0][i] );
b[0][i] = std::max( -32768, minv );
b[0][i] = Max( -32768, minv );
int maxv = -ceil( set[1][i] );
b[1][i] = std::min( 32767, maxv );
b[1][i] = Min( 32767, maxv );
// RB end
}
b[0][3] = b[1][3] = 0;
}
@ -218,7 +220,9 @@ void idBoundsTrack::ClearAll()
void idBoundsTrack::SetIndex( const int index, const idBounds& bounds )
{
assert( ( unsigned )index < MAX_BOUNDS_TRACK_INDEXES );
maxIndex = std::max( maxIndex, index + 1 );
// RB: replaced std::max
maxIndex = Max( maxIndex, index + 1 );
// RB end
boundsList[index].SetFromReferenceBounds( bounds );
}

View file

@ -0,0 +1,247 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "precompiled.h"
#pragma hdrstop
#include "tr_local.h"
#include "Framebuffer.h"
idList<Framebuffer*> Framebuffer::framebuffers;
globalFramebuffers_t globalFramebuffers;
static void R_ListFramebuffers_f( const idCmdArgs& args )
{
if( !glConfig.framebufferObjectAvailable )
{
common->Printf( "GL_EXT_framebuffer_object is not available.\n" );
return;
}
}
Framebuffer::Framebuffer( const char* name, int w, int h )
{
fboName = name;
frameBuffer = 0;
memset( colorBuffers, 0, sizeof( colorBuffers ) );
colorFormat = 0;
depthBuffer = 0;
depthFormat = 0;
stencilBuffer = 0;
stencilFormat = 0;
width = w;
height = h;
glGenFramebuffers( 1, &frameBuffer );
framebuffers.Append( this );
}
void Framebuffer::Init()
{
cmdSystem->AddCommand( "listFramebuffers", R_ListFramebuffers_f, CMD_FL_RENDERER, "lists framebuffers" );
backEnd.glState.currentFramebuffer = NULL;
int width, height;
width = height = r_shadowMapImageSize.GetInteger();
globalFramebuffers.shadowFBO = new Framebuffer( "_shadowMap" , width, height );
globalFramebuffers.shadowFBO->Bind();
glDrawBuffers( 0, NULL );
// globalFramebuffers.shadowFBO->AddColorBuffer( GL_RGBA8, 0 );
// globalFramebuffers.shadowFBO->AddDepthBuffer( GL_DEPTH_COMPONENT24 );
// globalFramebuffers.shadowFBO->Check();
BindNull();
}
void Framebuffer::Shutdown()
{
// TODO
}
void Framebuffer::Bind()
{
#if 0
if( r_logFile.GetBool() )
{
RB_LogComment( "--- Framebuffer::Bind( name = '%s' ) ---\n", fboName.c_str() );
}
#endif
if( backEnd.glState.currentFramebuffer != this )
{
glBindFramebuffer( GL_FRAMEBUFFER, frameBuffer );
backEnd.glState.currentFramebuffer = this;
}
}
void Framebuffer::BindNull()
{
//if(backEnd.glState.framebuffer != NULL)
{
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glBindRenderbuffer( GL_RENDERBUFFER, 0 );
backEnd.glState.currentFramebuffer = NULL;
}
}
void Framebuffer::AddColorBuffer( int format, int index )
{
if( index < 0 || index >= glConfig.maxColorAttachments )
{
common->Warning( "Framebuffer::AddColorBuffer( %s ): bad index = %i", fboName.c_str(), index );
return;
}
colorFormat = format;
bool notCreatedYet = colorBuffers[index] == 0;
if( notCreatedYet )
{
glGenRenderbuffers( 1, &colorBuffers[index] );
}
glBindRenderbuffer( GL_RENDERBUFFER, colorBuffers[index] );
glRenderbufferStorage( GL_RENDERBUFFER, format, width, height );
if( notCreatedYet )
{
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, GL_RENDERBUFFER, colorBuffers[index] );
}
GL_CheckErrors();
}
void Framebuffer::AddDepthBuffer( int format )
{
depthFormat = format;
bool notCreatedYet = depthBuffer == 0;
if( notCreatedYet )
{
glGenRenderbuffers( 1, &depthBuffer );
}
glBindRenderbuffer( GL_RENDERBUFFER, depthBuffer );
glRenderbufferStorage( GL_RENDERBUFFER, format, width, height );
if( notCreatedYet )
{
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer );
}
GL_CheckErrors();
}
void Framebuffer::AttachImage2D( int target, const idImage* image, int index )
{
if( ( target != GL_TEXTURE_2D ) && ( target < GL_TEXTURE_CUBE_MAP_POSITIVE_X || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) )
{
common->Warning( "Framebuffer::AttachImage2D( %s ): invalid target", fboName.c_str() );
return;
}
if( index < 0 || index >= glConfig.maxColorAttachments )
{
common->Warning( "Framebuffer::AttachImage2D( %s ): bad index = %i", fboName.c_str(), index );
return;
}
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, target, image->texnum, 0 );
}
void Framebuffer::AttachImageDepth( const idImage* image )
{
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, image->texnum, 0 );
}
void Framebuffer::AttachImageDepthLayer( const idImage* image, int layer )
{
glFramebufferTextureLayer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, image->texnum, 0, layer );
}
void Framebuffer::Check()
{
int prev;
glGetIntegerv( GL_FRAMEBUFFER_BINDING, &prev );
glBindFramebuffer( GL_FRAMEBUFFER, frameBuffer );
int status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
if( status == GL_FRAMEBUFFER_COMPLETE )
{
glBindFramebuffer( GL_FRAMEBUFFER, prev );
return;
}
// something went wrong
switch( status )
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
common->Error( "Framebuffer::Check( %s ): Framebuffer incomplete, incomplete attachment", fboName.c_str() );
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
common->Error( "Framebuffer::Check( %s ): Framebuffer incomplete, missing attachment", fboName.c_str() );
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
common->Error( "Framebuffer::Check( %s ): Framebuffer incomplete, missing draw buffer", fboName.c_str() );
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
common->Error( "Framebuffer::Check( %s ): Framebuffer incomplete, missing read buffer", fboName.c_str() );
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
common->Error( "Framebuffer::Check( %s ): Framebuffer incomplete, missing layer targets", fboName.c_str() );
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
common->Error( "Framebuffer::Check( %s ): Framebuffer incomplete, missing multisample", fboName.c_str() );
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
common->Error( "Framebuffer::Check( %s ): Unsupported framebuffer format", fboName.c_str() );
break;
default:
common->Error( "Framebuffer::Check( %s ): Unknown error 0x%X", fboName.c_str(), status );
break;
};
glBindFramebuffer( GL_FRAMEBUFFER, prev );
}

View file

@ -2,7 +2,7 @@
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -25,60 +25,66 @@ If you have questions concerning this license or the applicable additional terms
===========================================================================
*/
#ifndef __RENDERTEXTURE_H__
#define __RENDERTEXTURE_H__
/*
================================================================================================
#ifndef __FRAMEBUFFER_H__
#define __FRAMEBUFFER_H__
Render Texture
================================================================================================
*/
#define CELL_GCM_INVALID_PITCH 64
/*
================================================
idRenderTexture holds both the color and depth images that are made
resident on the video hardware.
================================================
*/
class idRenderTexture
class Framebuffer
{
public:
idRenderTexture();
~idRenderTexture();
Framebuffer( const char* name, int width, int height );
ID_INLINE int GetWidth() const
static void Init();
static void Shutdown();
// deletes OpenGL object but leaves structure intact for reloading
void PurgeFramebuffer();
void Bind();
static void BindNull();
void AddColorBuffer( int format, int index );
void AddDepthBuffer( int format );
void AttachImage2D( int target, const idImage* image, int index );
void AttachImage3D( const idImage* image );
void AttachImageDepth( const idImage* image );
void AttachImageDepthLayer( const idImage* image, int layer );
// check for OpenGL errors
void Check();
uint32_t GetFramebuffer() const
{
return ( colorImage != NULL ) ? colorImage->GetUploadWidth() : depthImage->GetUploadWidth();
return frameBuffer;
}
ID_INLINE int GetHeight() const
{
return ( colorImage != NULL ) ? colorImage->GetUploadHeight() : depthImage->GetUploadHeight();
}
ID_INLINE idImage* GetColorImage() const
{
return colorImage;
}
ID_INLINE idImage* GetDepthImage() const
{
return depthImage;
}
void Resize( int width, int height );
void MakeCurrent( int level = 0, int side = 0 );
private:
idImage* colorImage;
idImage* depthImage;
int targetWidth;
int targetHeight;
idStr fboName;
// FBO object
uint32_t frameBuffer;
uint32_t colorBuffers[16];
int colorFormat;
uint32_t depthBuffer;
int depthFormat;
uint32_t stencilBuffer;
int stencilFormat;
int width;
int height;
static idList<Framebuffer*> framebuffers;
};
#endif //!__RENDERTEXTURE_H__
struct globalFramebuffers_t
{
Framebuffer* shadowFBO;
};
extern globalFramebuffers_t globalFramebuffers;
#endif // __FRAMEBUFFER_H__

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -481,3 +482,95 @@ void R_SetupProjectionMatrix( viewDef_t* viewDef )
viewDef->projectionMatrix[1 * 4 + 3] = -viewDef->projectionMatrix[1 * 4 + 3];
}
}
// RB: standard OpenGL projection matrix
void R_SetupProjectionMatrix2( const viewDef_t* viewDef, const float zNear, const float zFar, float projectionMatrix[16] )
{
float ymax = zNear * tan( viewDef->renderView.fov_y * idMath::PI / 360.0f );
float ymin = -ymax;
float xmax = zNear * tan( viewDef->renderView.fov_x * idMath::PI / 360.0f );
float xmin = -xmax;
const float width = xmax - xmin;
const float height = ymax - ymin;
const int viewWidth = viewDef->viewport.x2 - viewDef->viewport.x1 + 1;
const int viewHeight = viewDef->viewport.y2 - viewDef->viewport.y1 + 1;
float jitterx, jittery;
jitterx = 0.0f;
jittery = 0.0f;
jitterx = jitterx * width / viewWidth;
jitterx += r_centerX.GetFloat();
jitterx += viewDef->renderView.stereoScreenSeparation;
xmin += jitterx * width;
xmax += jitterx * width;
jittery = jittery * height / viewHeight;
jittery += r_centerY.GetFloat();
ymin += jittery * height;
ymax += jittery * height;
float depth = zFar - zNear;
projectionMatrix[0 * 4 + 0] = 2.0f * zNear / width;
projectionMatrix[1 * 4 + 0] = 0.0f;
projectionMatrix[2 * 4 + 0] = ( xmax + xmin ) / width; // normally 0
projectionMatrix[3 * 4 + 0] = 0.0f;
projectionMatrix[0 * 4 + 1] = 0.0f;
projectionMatrix[1 * 4 + 1] = 2.0f * zNear / height;
projectionMatrix[2 * 4 + 1] = ( ymax + ymin ) / height; // normally 0
projectionMatrix[3 * 4 + 1] = 0.0f;
projectionMatrix[0 * 4 + 2] = 0.0f;
projectionMatrix[1 * 4 + 2] = 0.0f;
projectionMatrix[2 * 4 + 2] = -( zFar + zNear ) / depth; // -0.999f; // adjust value to prevent imprecision issues
projectionMatrix[3 * 4 + 2] = -2 * zFar * zNear / depth; // -2.0f * zNear;
projectionMatrix[0 * 4 + 3] = 0.0f;
projectionMatrix[1 * 4 + 3] = 0.0f;
projectionMatrix[2 * 4 + 3] = -1.0f;
projectionMatrix[3 * 4 + 3] = 0.0f;
if( viewDef->renderView.flipProjection )
{
projectionMatrix[1 * 4 + 1] = -viewDef->projectionMatrix[1 * 4 + 1];
projectionMatrix[1 * 4 + 3] = -viewDef->projectionMatrix[1 * 4 + 3];
}
}
void R_MatrixFullInverse( const float a[16], float r[16] )
{
idMat4 am;
for( int i = 0 ; i < 4 ; i++ )
{
for( int j = 0 ; j < 4 ; j++ )
{
am[i][j] = a[j * 4 + i];
}
}
// idVec4 test( 100, 100, 100, 1 );
// idVec4 transformed, inverted;
// transformed = test * am;
if( !am.InverseSelf() )
{
common->Error( "Invert failed" );
}
// inverted = transformed * am;
for( int i = 0 ; i < 4 ; i++ )
{
for( int j = 0 ; j < 4 ; j++ )
{
r[j * 4 + i] = am[i][j];
}
}
}
// RB end

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -61,4 +62,9 @@ void R_LocalPlaneToGlobal( const float modelMatrix[16], const idPlane& in, idPla
void R_SetupViewMatrix( viewDef_t* viewDef );
void R_SetupProjectionMatrix( viewDef_t* viewDef );
// RB begin
void R_SetupProjectionMatrix2( const viewDef_t* viewDef, const float zNear, const float zFar, float out[16] );
void R_MatrixFullInverse( const float in[16], float r[16] );
// RB end
#endif /* !__GLMATRIX_H__ */

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -166,7 +167,11 @@ ID_INLINE void GL_ViewportAndScissor( const idScreenRect& rect )
void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r, float g, float b, float a );
void GL_PolygonOffset( float scale, float bias );
void GL_DepthBoundsTest( const float zmin, const float zmax );
void GL_Color( float* color );
//void GL_Color( float* color );
// RB begin
void GL_Color( const idVec3& color );
void GL_Color( const idVec4& color );
// RB end
void GL_Color( float r, float g, float b );
void GL_Color( float r, float g, float b, float a );
void GL_SelectTexture( int unit );

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -55,13 +56,17 @@ typedef enum
TD_LOOKUP_TABLE_RGBA, // RGBA lookup table
TD_COVERAGE, // coverage map for fill depth pass when YCoCG is used
TD_DEPTH, // depth buffer copy for motion blur
// RB begin
TD_SHADOW_ARRAY, // 2D depth buffer array for shadow mapping
// RB end
} textureUsage_t;
typedef enum
{
CF_2D, // not a cube map
CF_NATIVE, // _px, _nx, _py, etc, directly sent to GL
CF_CAMERA // _forward, _back, etc, rotated and flipped as needed before sending to GL
CF_CAMERA, // _forward, _back, etc, rotated and flipped as needed before sending to GL
CF_2D_ARRAY // not a cube map but not a single 2d texture either
} cubeFiles_t;
#include "ImageOpts.h"
@ -71,6 +76,8 @@ typedef enum
class idImage
{
friend class Framebuffer;
public:
idImage( const char* name );
@ -96,6 +103,10 @@ public:
void GenerateCubeImage( const byte* pic[6], int size,
textureFilter_t filter, textureUsage_t usage );
// RB begin
void GenerateShadowArray( int width, int height, textureFilter_t filter, textureRepeat_t repeat, textureUsage_t usage );
// RB end
void CopyFramebuffer( int x, int y, int width, int height );
void CopyDepthbuffer( int x, int y, int width, int height );
@ -323,6 +334,13 @@ public:
idImage* noFalloffImage; // all 255, but zero clamped
idImage* fogImage; // increasing alpha is denser fog
idImage* fogEnterImage; // adjust fogImage alpha based on terminator plane
// RB begin
idImage* shadowImage;
idImage* jitterImage1; // shadow jitter
idImage* jitterImage4;
idImage* jitterImage16;
idImage* randomImage256;
// RB end
idImage* scratchImage;
idImage* scratchImage2;
idImage* accumImage;

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -33,7 +34,10 @@ enum textureType_t
{
TT_DISABLED,
TT_2D,
TT_CUBIC
TT_CUBIC,
// RB begin
TT_2D_ARRAY
// RB end
};
/*
@ -89,6 +93,11 @@ enum textureFormat_t
FMT_X16, // 16 bpp
FMT_Y16_X16, // 32 bpp
FMT_RGB565, // 16 bpp
// RB: don't change above for legacy .bimage compatibility
FMT_ETC1_RGB8_OES, // 4 bpp
FMT_SHADOW_ARRAY, // 32 bpp * 6
// RB end
};
int BitsForFormat( textureFormat_t format );
@ -103,7 +112,11 @@ enum textureColor_t
CFM_DEFAULT, // RGBA
CFM_NORMAL_DXT5, // XY format and use the fast DXT5 compressor
CFM_YCOCG_DXT5, // convert RGBA to CoCg_Y format
CFM_GREEN_ALPHA // Copy the alpha channel to green
CFM_GREEN_ALPHA, // Copy the alpha channel to green
// RB: don't change above for legacy .bimage compatibility
CFM_YCOCG_RGBA8,
// RB end
};
/*

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -449,6 +450,99 @@ void R_QuadraticImage( idImage* image )
image->GenerateImage( ( byte* )data, QUADRATIC_WIDTH, QUADRATIC_HEIGHT, TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1 );
}
// RB begin
static void R_CreateShadowMapImage( idImage* image )
{
int size = r_shadowMapImageSize.GetInteger();
image->GenerateShadowArray( size, size, TF_LINEAR, TR_CLAMP_TO_ZERO_ALPHA, TD_SHADOW_ARRAY );
}
const static int JITTER_SIZE = 128;
static void R_CreateJitterImage16( idImage* image )
{
static byte data[JITTER_SIZE][JITTER_SIZE * 16][4];
for( int i = 0 ; i < JITTER_SIZE ; i++ )
{
for( int s = 0 ; s < 16 ; s++ )
{
int sOfs = 64 * ( s & 3 );
int tOfs = 64 * ( ( s >> 2 ) & 3 );
for( int j = 0 ; j < JITTER_SIZE ; j++ )
{
data[i][s * JITTER_SIZE + j][0] = ( rand() & 63 ) | sOfs;
data[i][s * JITTER_SIZE + j][1] = ( rand() & 63 ) | tOfs;
data[i][s * JITTER_SIZE + j][2] = rand();
data[i][s * JITTER_SIZE + j][3] = 0;
}
}
}
image->GenerateImage( ( byte* )data, JITTER_SIZE * 16, JITTER_SIZE, TF_NEAREST, TR_REPEAT, TD_LOOKUP_TABLE_RGBA );
}
static void R_CreateJitterImage4( idImage* image )
{
byte data[JITTER_SIZE][JITTER_SIZE * 4][4];
for( int i = 0 ; i < JITTER_SIZE ; i++ )
{
for( int s = 0 ; s < 4 ; s++ )
{
int sOfs = 128 * ( s & 1 );
int tOfs = 128 * ( ( s >> 1 ) & 1 );
for( int j = 0 ; j < JITTER_SIZE ; j++ )
{
data[i][s * JITTER_SIZE + j][0] = ( rand() & 127 ) | sOfs;
data[i][s * JITTER_SIZE + j][1] = ( rand() & 127 ) | tOfs;
data[i][s * JITTER_SIZE + j][2] = rand();
data[i][s * JITTER_SIZE + j][3] = 0;
}
}
}
image->GenerateImage( ( byte* )data, JITTER_SIZE * 4, JITTER_SIZE, TF_NEAREST, TR_REPEAT, TD_LOOKUP_TABLE_RGBA );
}
static void R_CreateJitterImage1( idImage* image )
{
byte data[JITTER_SIZE][JITTER_SIZE][4];
for( int i = 0 ; i < JITTER_SIZE ; i++ )
{
for( int j = 0 ; j < JITTER_SIZE ; j++ )
{
data[i][j][0] = rand();
data[i][j][1] = rand();
data[i][j][2] = rand();
data[i][j][3] = 0;
}
}
image->GenerateImage( ( byte* )data, JITTER_SIZE, JITTER_SIZE, TF_NEAREST, TR_REPEAT, TD_LOOKUP_TABLE_RGBA );
}
static void R_CreateRandom256Image( idImage* image )
{
byte data[256][256][4];
for( int i = 0 ; i < 256 ; i++ )
{
for( int j = 0 ; j < 256 ; j++ )
{
data[i][j][0] = rand();
data[i][j][1] = rand();
data[i][j][2] = rand();
data[i][j][3] = rand();
}
}
image->GenerateImage( ( byte* )data, 256, 256, TF_NEAREST, TR_REPEAT, TD_LOOKUP_TABLE_RGBA );
}
// RB end
/*
================
idImageManager::CreateIntrinsicImages
@ -467,6 +561,16 @@ void idImageManager::CreateIntrinsicImages()
noFalloffImage = ImageFromFunction( "_noFalloff", R_CreateNoFalloffImage );
ImageFromFunction( "_quadratic", R_QuadraticImage );
// RB begin
shadowImage = ImageFromFunction( va( "_shadowMap%i_0", r_shadowMapImageSize.GetInteger() ), R_CreateShadowMapImage );
jitterImage1 = globalImages->ImageFromFunction( "_jitter1", R_CreateJitterImage1 );
jitterImage4 = globalImages->ImageFromFunction( "_jitter4", R_CreateJitterImage4 );
jitterImage16 = globalImages->ImageFromFunction( "_jitter16", R_CreateJitterImage16 );
randomImage256 = globalImages->ImageFromFunction( "_random256", R_CreateRandom256Image );
// RB end
// scratchImage is used for screen wipes/doublevision etc..
scratchImage = ImageFromFunction( "_scratch", R_RGBA8Image );
scratchImage2 = ImageFromFunction( "_scratch2", R_RGBA8Image );

View file

@ -60,6 +60,8 @@ int BitsForFormat( textureFormat_t format )
return 4;
case FMT_DXT5:
return 8;
case FMT_SHADOW_ARRAY:
return ( 32 * 6 );
case FMT_DEPTH:
return 32;
case FMT_X16:
@ -93,6 +95,11 @@ ID_INLINE void idImage::DeriveOpts()
case TD_DEPTH:
opts.format = FMT_DEPTH;
break;
case TD_SHADOW_ARRAY:
opts.format = FMT_SHADOW_ARRAY;
break;
case TD_DIFFUSE:
// TD_DIFFUSE gets only set to when its a diffuse texture for an interaction
opts.gammaMips = true;
@ -266,6 +273,47 @@ void idImage::GenerateCubeImage( const byte* pic[6], int size, textureFilter_t f
}
}
// RB begin
void idImage::GenerateShadowArray( int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = CF_2D_ARRAY;
opts.textureType = TT_2D_ARRAY;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
DeriveOpts();
// if we don't have a rendering context, just return after we
// have filled in the parms. We must have the values set, or
// an image match from a shader before the render starts would miss
// the generated texture
if( !R_IsInitialized() )
{
return;
}
//idBinaryImage im( GetName() );
//im.Load2DFromMemory( width, height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
AllocImage();
/*
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
*/
}
// RB end
/*
===============
GetGeneratedName
@ -323,7 +371,13 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
}
else
{
if( cubeFiles != CF_2D )
// RB begin
if( cubeFiles == CF_2D_ARRAY )
{
opts.textureType = TT_2D_ARRAY;
}
// RB end
else if( cubeFiles != CF_2D )
{
opts.textureType = TT_CUBIC;
repeat = TR_CLAMP;
@ -521,11 +575,11 @@ void idImage::Bind()
// RB begin
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0_ARB + texUnit, GL_TEXTURE_2D, texnum );
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_2D, texnum );
}
else
{
glActiveTextureARB( GL_TEXTURE0_ARB + texUnit );
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_2D, texnum );
}
// RB end
@ -538,14 +592,37 @@ void idImage::Bind()
tmu->currentCubeMap = texnum;
// RB begin
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0_ARB + texUnit, GL_TEXTURE_CUBE_MAP_EXT, texnum );
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_CUBE_MAP, texnum );
}
else
#endif
{
glActiveTextureARB( GL_TEXTURE0_ARB + texUnit );
glBindTexture( GL_TEXTURE_CUBE_MAP_EXT, texnum );
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
}
// RB end
}
}
else if( opts.textureType == TT_2D_ARRAY )
{
if( tmu->current2DArray != texnum )
{
tmu->current2DArray = texnum;
// RB begin
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.directStateAccess )
{
glBindMultiTextureEXT( GL_TEXTURE0 + texUnit, GL_TEXTURE_2D_ARRAY, texnum );
}
else
#endif
{
glActiveTexture( GL_TEXTURE0 + texUnit );
glBindTexture( GL_TEXTURE_2D_ARRAY, texnum );
}
// RB end
}
@ -574,9 +651,7 @@ CopyFramebuffer
*/
void idImage::CopyFramebuffer( int x, int y, int imageWidth, int imageHeight )
{
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP_EXT : GL_TEXTURE_2D, texnum );
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D, texnum );
glReadBuffer( GL_BACK );
@ -601,7 +676,7 @@ CopyDepthbuffer
*/
void idImage::CopyDepthbuffer( int x, int y, int imageWidth, int imageHeight )
{
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP_EXT : GL_TEXTURE_2D, texnum );
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D, texnum );
opts.width = imageWidth;
opts.height = imageHeight;
@ -836,6 +911,6 @@ void idImage::SetSamplerState( textureFilter_t tf, textureRepeat_t tr )
}
filter = tf;
repeat = tr;
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP_EXT : GL_TEXTURE_2D, texnum );
glBindTexture( ( opts.textureType == TT_CUBIC ) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D, texnum );
SetTexParameters();
}

View file

@ -663,12 +663,17 @@ void idInteraction::UnlinkAndFree()
{
// clear the table pointer
idRenderWorldLocal* renderWorld = this->lightDef->world;
int index = this->lightDef->index * renderWorld->interactionTableWidth + this->entityDef->index;
if( renderWorld->interactionTable[index] != this && renderWorld->interactionTable[index] != INTERACTION_EMPTY )
// RB: added check for NULL
if( renderWorld->interactionTable != NULL )
{
common->Error( "idInteraction::UnlinkAndFree: interactionTable wasn't set" );
int index = this->lightDef->index * renderWorld->interactionTableWidth + this->entityDef->index;
if( renderWorld->interactionTable[index] != this && renderWorld->interactionTable[index] != INTERACTION_EMPTY )
{
common->Error( "idInteraction::UnlinkAndFree: interactionTable wasn't set" );
}
renderWorld->interactionTable[index] = NULL;
}
renderWorld->interactionTable[index] = NULL;
// RB end
Unlink();

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -198,6 +199,7 @@ void GL_GetDepthPassRect( idScreenRect& rect )
GL_Color
====================
*/
/*
void GL_Color( float* color )
{
if( color == NULL )
@ -206,6 +208,19 @@ void GL_Color( float* color )
}
GL_Color( color[0], color[1], color[2], color[3] );
}
*/
// RB begin
void GL_Color( const idVec3& color )
{
GL_Color( color[0], color[1], color[2], 1.0f );
}
void GL_Color( const idVec4& color )
{
GL_Color( color[0], color[1], color[2], color[3] );
}
// RB end
/*
====================
@ -275,6 +290,10 @@ void GL_SetDefaultState()
memset( &backEnd.glState, 0, sizeof( backEnd.glState ) );
GL_State( 0, true );
// RB begin
Framebuffer::BindNull();
// RB end
// These are changed by GL_Cull
glCullFace( GL_FRONT_AND_BACK );
glEnable( GL_CULL_FACE );

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -86,8 +87,8 @@ void idImage::SubImageUpload( int mipLevel, int x, int y, int z, int width, int
}
else if( opts.textureType == TT_CUBIC )
{
target = GL_TEXTURE_CUBE_MAP_EXT;
uploadTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT + z;
target = GL_TEXTURE_CUBE_MAP;
uploadTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
}
else
{
@ -168,8 +169,13 @@ void idImage::SetTexParameters()
target = GL_TEXTURE_2D;
break;
case TT_CUBIC:
target = GL_TEXTURE_CUBE_MAP_EXT;
target = GL_TEXTURE_CUBE_MAP;
break;
// RB begin
case TT_2D_ARRAY:
target = GL_TEXTURE_2D_ARRAY;
break;
// RB end
default:
idLib::FatalError( "%s: bad texture type %d", GetName(), opts.textureType );
return;
@ -319,6 +325,15 @@ void idImage::SetTexParameters()
default:
common->FatalError( "%s: bad texture repeat %d", GetName(), repeat );
}
// RB: added shadow compare parameters for shadow map textures
if( opts.format == FMT_SHADOW_ARRAY )
{
//glTexParameteri( target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
glTexParameteri( target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
glTexParameteri( target, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY );
}
}
/*
@ -408,6 +423,13 @@ void idImage::AllocImage()
dataFormat = GL_DEPTH_COMPONENT;
dataType = GL_UNSIGNED_BYTE;
break;
case FMT_SHADOW_ARRAY:
internalFormat = GL_DEPTH_COMPONENT;
dataFormat = GL_DEPTH_COMPONENT;
dataType = GL_UNSIGNED_BYTE;
break;
case FMT_X16:
internalFormat = GL_INTENSITY16;
dataFormat = GL_LUMINANCE;
@ -449,10 +471,18 @@ void idImage::AllocImage()
}
else if( opts.textureType == TT_CUBIC )
{
target = GL_TEXTURE_CUBE_MAP_EXT;
uploadTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT;
target = GL_TEXTURE_CUBE_MAP;
uploadTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
numSides = 6;
}
// RB begin
else if( opts.textureType == TT_2D_ARRAY )
{
target = GL_TEXTURE_2D_ARRAY;
uploadTarget = GL_TEXTURE_2D_ARRAY;
numSides = 6;
}
// RB end
else
{
assert( !"opts.textureType" );
@ -462,64 +492,71 @@ void idImage::AllocImage()
glBindTexture( target, texnum );
for( int side = 0; side < numSides; side++ )
if( opts.textureType == TT_2D_ARRAY )
{
int w = opts.width;
int h = opts.height;
if( opts.textureType == TT_CUBIC )
{
h = w;
}
for( int level = 0; level < opts.numLevels; level++ )
{
// clear out any previous error
GL_CheckErrors();
if( IsCompressed() )
{
int compressedSize = ( ( ( w + 3 ) / 4 ) * ( ( h + 3 ) / 4 ) * int64( 16 ) * BitsForFormat( opts.format ) ) / 8;
// Even though the OpenGL specification allows the 'data' pointer to be NULL, for some
// drivers we actually need to upload data to get it to allocate the texture.
// However, on 32-bit systems we may fail to allocate a large block of memory for large
// textures. We handle this case by using HeapAlloc directly and allowing the allocation
// to fail in which case we simply pass down NULL to glCompressedTexImage2D and hope for the best.
// As of 2011-10-6 using NVIDIA hardware and drivers we have to allocate the memory with HeapAlloc
// with the exact size otherwise large image allocation (for instance for physical page textures)
// may fail on Vista 32-bit.
// RB begin
#if defined(_WIN32)
void* data = HeapAlloc( GetProcessHeap(), 0, compressedSize );
glCompressedTexImage2DARB( uploadTarget + side, level, internalFormat, w, h, 0, compressedSize, data );
if( data != NULL )
{
HeapFree( GetProcessHeap(), 0, data );
}
#else
byte* data = ( byte* )Mem_Alloc( compressedSize, TAG_TEMP );
glCompressedTexImage2DARB( uploadTarget + side, level, internalFormat, w, h, 0, compressedSize, data );
if( data != NULL )
{
Mem_Free( data );
}
#endif
// RB end
}
else
{
glTexImage2D( uploadTarget + side, level, internalFormat, w, h, 0, dataFormat, dataType, NULL );
}
GL_CheckErrors();
w = Max( 1, w >> 1 );
h = Max( 1, h >> 1 );
}
glTexImage3D( uploadTarget, 0, internalFormat, opts.width, opts.height, numSides, 0, dataFormat, GL_UNSIGNED_BYTE, NULL );
}
else
{
for( int side = 0; side < numSides; side++ )
{
int w = opts.width;
int h = opts.height;
if( opts.textureType == TT_CUBIC )
{
h = w;
}
for( int level = 0; level < opts.numLevels; level++ )
{
// clear out any previous error
GL_CheckErrors();
if( IsCompressed() )
{
int compressedSize = ( ( ( w + 3 ) / 4 ) * ( ( h + 3 ) / 4 ) * int64( 16 ) * BitsForFormat( opts.format ) ) / 8;
// Even though the OpenGL specification allows the 'data' pointer to be NULL, for some
// drivers we actually need to upload data to get it to allocate the texture.
// However, on 32-bit systems we may fail to allocate a large block of memory for large
// textures. We handle this case by using HeapAlloc directly and allowing the allocation
// to fail in which case we simply pass down NULL to glCompressedTexImage2D and hope for the best.
// As of 2011-10-6 using NVIDIA hardware and drivers we have to allocate the memory with HeapAlloc
// with the exact size otherwise large image allocation (for instance for physical page textures)
// may fail on Vista 32-bit.
// RB begin
#if defined(_WIN32)
void* data = HeapAlloc( GetProcessHeap(), 0, compressedSize );
glCompressedTexImage2D( uploadTarget + side, level, internalFormat, w, h, 0, compressedSize, data );
if( data != NULL )
{
HeapFree( GetProcessHeap(), 0, data );
}
#else
byte* data = ( byte* )Mem_Alloc( compressedSize, TAG_TEMP );
glCompressedTexImage2D( uploadTarget + side, level, internalFormat, w, h, 0, compressedSize, data );
if( data != NULL )
{
Mem_Free( data );
}
#endif
// RB end
}
else
{
glTexImage2D( uploadTarget + side, level, internalFormat, w, h, 0, dataFormat, dataType, NULL );
}
GL_CheckErrors();
w = Max( 1, w >> 1 );
h = Max( 1, h >> 1 );
}
}
glTexParameteri( target, GL_TEXTURE_MAX_LEVEL, opts.numLevels - 1 );
}
glTexParameteri( target, GL_TEXTURE_MAX_LEVEL, opts.numLevels - 1 );
// see if we messed anything up
GL_CheckErrors();
@ -545,6 +582,7 @@ void idImage::PurgeImage()
for( int i = 0 ; i < MAX_MULTITEXTURE_UNITS ; i++ )
{
backEnd.glState.tmu[i].current2DMap = TEXTURE_NOT_LOADED;
backEnd.glState.tmu[i].current2DArray = TEXTURE_NOT_LOADED;
backEnd.glState.tmu[i].currentCubeMap = TEXTURE_NOT_LOADED;
}
}

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -234,8 +235,8 @@ idRenderLog::idRenderLog()
activeLevel = 0;
indentString[0] = '\0';
indentLevel = 0;
logFile = NULL;
// logFile = NULL;
frameStartTime = 0;
closeBlockTime = 0;
logLevel = 0;
@ -265,8 +266,8 @@ void idRenderLog::StartFrame()
char qpath[128];
sprintf( qpath, "renderlogPC_%04i.txt", r_logFile.GetInteger() );
idStr finalPath = fileSystem->RelativePathToOSPath( qpath );
sprintf( ospath, "%s", finalPath.c_str() );
//idStr finalPath = fileSystem->RelativePathToOSPath( qpath );
sprintf( ospath, "%s", qpath );
/*
for ( int i = 0; i < 9999 ; i++ ) {
char qpath[128];
@ -281,6 +282,7 @@ void idRenderLog::StartFrame()
common->SetRefreshOnPrint( false ); // problems are caused if this print causes a refresh...
/*
if( logFile != NULL )
{
fileSystem->CloseFile( logFile );
@ -301,6 +303,7 @@ void idRenderLog::StartFrame()
const char* str = asctime( newtime );
logFile->Printf( "// %s", str );
logFile->Printf( "// %s\n\n", com_version.GetString() );
*/
frameStartTime = Sys_Microseconds();
closeBlockTime = frameStartTime;
@ -316,15 +319,16 @@ void idRenderLog::EndFrame()
{
PC_EndFrame();
if( logFile != NULL )
//if( logFile != NULL )
if( r_logFile.GetInteger() != 0 )
{
if( r_logFile.GetInteger() == 1 )
{
Close();
}
// log is open, so decrement r_logFile and stop if it is zero
r_logFile.SetInteger( r_logFile.GetInteger() - 1 );
idLib::Printf( "Frame logged.\n" );
//r_logFile.SetInteger( r_logFile.GetInteger() - 1 );
//idLib::Printf( "Frame logged.\n" );
return;
}
}
@ -336,12 +340,13 @@ idRenderLog::Close
*/
void idRenderLog::Close()
{
if( logFile != NULL )
//if( logFile != NULL )
if( r_logFile.GetInteger() != 0 )
{
CloseBlock();
idLib::Printf( "Closing logfile\n" );
fileSystem->CloseFile( logFile );
logFile = NULL;
//idLib::Printf( "Closing logfile\n" );
//fileSystem->CloseFile( logFile );
//logFile = NULL;
activeLevel = 0;
}
}
@ -374,7 +379,8 @@ void idRenderLog::OpenBlock( const char* label )
// Allow the PIX functionality even when logFile is not running.
PC_BeginNamedEvent( label );
if( logFile != NULL )
//if( logFile != NULL )
if( r_logFile.GetInteger() != 0 )
{
LogOpenBlock( RENDER_LOG_INDENT_MAIN_BLOCK, label, NULL );
}
@ -389,7 +395,8 @@ void idRenderLog::CloseBlock()
{
PC_EndNamedEvent();
if( logFile != NULL )
//if( logFile != NULL )
if( r_logFile.GetInteger() != 0 )
{
LogCloseBlock( RENDER_LOG_INDENT_MAIN_BLOCK );
}
@ -402,22 +409,41 @@ idRenderLog::Printf
*/
void idRenderLog::Printf( const char* fmt, ... )
{
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( activeLevel <= LOG_LEVEL_BLOCKS_ONLY )
{
return;
}
if( logFile == NULL )
//if( logFile == NULL )
if( r_logFile.GetInteger() == 0 || !glConfig.gremedyStringMarkerAvailable )
{
return;
}
va_list marker;
logFile->Printf( "%s", indentString );
va_list marker;
char msg[4096];
idStr out = indentString;
va_start( marker, fmt );
logFile->VPrintf( fmt, marker );
idStr::vsnPrintf( msg, sizeof( msg ), fmt, marker );
va_end( marker );
msg[sizeof( msg ) - 1] = '\0';
out.Append( msg );
glStringMarkerGREMEDY( out.Length(), out.c_str() );
//logFile->Printf( "%s", indentString );
//va_start( marker, fmt );
//logFile->VPrintf( fmt, marker );
//va_end( marker );
// logFile->Flush(); this makes it take waaaay too long
#endif
}
/*
@ -427,18 +453,43 @@ idRenderLog::LogOpenBlock
*/
void idRenderLog::LogOpenBlock( renderLogIndentLabel_t label, const char* fmt, va_list args )
{
uint64 now = Sys_Microseconds();
if( logFile != NULL )
//if( logFile != NULL )
if( r_logFile.GetInteger() != 0 )
{
if( now - closeBlockTime >= 1000 )
//if( now - closeBlockTime >= 1000 )
//{
//logFile->Printf( "%s%1.1f msec gap from last closeblock\n", indentString, ( now - closeBlockTime ) * ( 1.0f / 1000.0f ) );
//}
#if !defined(USE_GLES2) && !defined(USE_GLES3)
if( glConfig.gremedyStringMarkerAvailable )
{
logFile->Printf( "%s%1.1f msec gap from last closeblock\n", indentString, ( now - closeBlockTime ) * ( 1.0f / 1000.0f ) );
//Printf( fmt, args );
//Printf( " {\n" );
//logFile->Printf( "%s", indentString );
//logFile->VPrintf( fmt, args );
//logFile->Printf( " {\n" );
va_list marker;
char msg[4096];
idStr out = indentString;
va_start( marker, fmt );
idStr::vsnPrintf( msg, sizeof( msg ), fmt, marker );
va_end( marker );
msg[sizeof( msg ) - 1] = '\0';
out.Append( msg );
out += " {";
glStringMarkerGREMEDY( out.Length(), out.c_str() );
}
logFile->Printf( "%s", indentString );
logFile->VPrintf( fmt, args );
logFile->Printf( " {\n" );
#endif
}
Indent( label );
@ -466,9 +517,9 @@ void idRenderLog::LogCloseBlock( renderLogIndentLabel_t label )
Outdent( label );
if( logFile != NULL )
{
}
//if( logFile != NULL )
//{
//}
}
#else // !STUB_RENDER_LOG

View file

@ -111,8 +111,8 @@ public:
int indentLevel;
const char* lastLabel;
renderLogMainBlock_t lastMainBlock;
idFile* logFile;
// idFile* logFile;
struct logStats_t
{
uint64 startTiming;
@ -136,7 +136,8 @@ idRenderLog::Indent
*/
ID_INLINE void idRenderLog::Indent( renderLogIndentLabel_t label )
{
if( logFile != NULL )
//if( logFile != NULL )
if( r_logFile.GetInteger() != 0 )
{
indentLabel[indentLevel] = label;
indentLevel++;
@ -155,7 +156,8 @@ idRenderLog::Outdent
*/
ID_INLINE void idRenderLog::Outdent( renderLogIndentLabel_t label )
{
if( logFile != NULL && indentLevel > 0 )
//if( logFile != NULL && indentLevel > 0 )
if( r_logFile.GetInteger() != 0 && indentLevel > 0 )
{
indentLevel--;
assert( indentLabel[indentLevel] == label ); // indent and outdent out of sync ?

View file

@ -83,47 +83,67 @@ void idRenderProgManager::Init()
// RB: added checks for GPU skinning
struct builtinShaders_t
{
int index;
int index;
const char* name;
bool requireGPUSkinningSupport;
const char* nameOutSuffix;
uint32 shaderFeatures;
bool requireGPUSkinningSupport;
} builtins[] =
{
{ BUILTIN_GUI, "gui.vfp", false },
{ BUILTIN_COLOR, "color.vfp", false },
// { BUILTIN_SIMPLESHADE, "simpleshade.vfp", false },
{ BUILTIN_TEXTURED, "texture.vfp", false },
{ BUILTIN_TEXTURE_VERTEXCOLOR, "texture_color.vfp", false },
{ BUILTIN_TEXTURE_VERTEXCOLOR_SKINNED, "texture_color_skinned.vfp", true },
{ BUILTIN_TEXTURE_TEXGEN_VERTEXCOLOR, "texture_color_texgen.vfp", false },
{ BUILTIN_INTERACTION, "interaction.vfp", false },
{ BUILTIN_INTERACTION_SKINNED, "interaction_skinned.vfp", true },
{ BUILTIN_INTERACTION_AMBIENT, "interactionAmbient.vfp", false },
{ BUILTIN_INTERACTION_AMBIENT_SKINNED, "interactionAmbient_skinned.vfp", true },
{ BUILTIN_ENVIRONMENT, "environment.vfp", false },
{ BUILTIN_ENVIRONMENT_SKINNED, "environment_skinned.vfp", true },
{ BUILTIN_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp", false },
{ BUILTIN_BUMPY_ENVIRONMENT_SKINNED, "bumpyEnvironment_skinned.vfp", true },
{ BUILTIN_GUI, "gui.vfp", 0, false },
{ BUILTIN_COLOR, "color.vfp", 0, false },
// RB begin
{ BUILTIN_COLOR_SKINNED, "color", "_skinned", BIT( USE_GPU_SKINNING ), true },
{ BUILTIN_VERTEX_COLOR, "vertex_color.vfp", "", 0, false },
// RB end
// { BUILTIN_SIMPLESHADE, "simpleshade.vfp", 0, false },
{ BUILTIN_TEXTURED, "texture.vfp", 0, false },
{ BUILTIN_TEXTURE_VERTEXCOLOR, "texture_color.vfp", 0, false },
{ BUILTIN_TEXTURE_VERTEXCOLOR_SKINNED, "texture_color_skinned.vfp", 0, true },
{ BUILTIN_TEXTURE_TEXGEN_VERTEXCOLOR, "texture_color_texgen.vfp", 0, false },
// RB begin
{ BUILTIN_INTERACTION, "interaction.vfp", "", 0, false },
{ BUILTIN_INTERACTION_SKINNED, "interaction", "_skinned", BIT( USE_GPU_SKINNING ), true },
{ BUILTIN_INTERACTION_AMBIENT, "interactionAmbient.vfp", 0, false },
{ BUILTIN_INTERACTION_AMBIENT_SKINNED, "interactionAmbient_skinned.vfp", 0, true },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT, "interactionSM", "_spot", 0, false },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED, "interactionSM", "_spot_skinned", BIT( USE_GPU_SKINNING ), true },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_POINT, "interactionSM", "_point", BIT( LIGHT_POINT ), false },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED, "interactionSM", "_point_skinned", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_POINT ), true },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL, "interactionSM", "_parallel", BIT( LIGHT_PARALLEL ), false },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, "interactionSM", "_parallel_skinned", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_PARALLEL ), true },
// RB end
{ BUILTIN_ENVIRONMENT, "environment.vfp", 0, false },
{ BUILTIN_ENVIRONMENT_SKINNED, "environment_skinned.vfp", 0, true },
{ BUILTIN_BUMPY_ENVIRONMENT, "bumpyenvironment.vfp", 0, false },
{ BUILTIN_BUMPY_ENVIRONMENT_SKINNED, "bumpyenvironment_skinned.vfp", 0, true },
{ BUILTIN_DEPTH, "depth.vfp", false },
{ BUILTIN_DEPTH_SKINNED, "depth_skinned.vfp", true },
{ BUILTIN_SHADOW_DEBUG, "shadowDebug.vfp", false },
{ BUILTIN_SHADOW_DEBUG_SKINNED, "shadowDebug_skinned.vfp", true },
{ BUILTIN_DEPTH, "depth.vfp", 0, false },
{ BUILTIN_DEPTH_SKINNED, "depth_skinned.vfp", 0, true },
{ BUILTIN_BLENDLIGHT, "blendlight.vfp", false },
{ BUILTIN_FOG, "fog.vfp", false },
{ BUILTIN_FOG_SKINNED, "fog_skinned.vfp", true },
{ BUILTIN_SKYBOX, "skybox.vfp", false },
{ BUILTIN_WOBBLESKY, "wobblesky.vfp", false },
{ BUILTIN_POSTPROCESS, "postprocess.vfp", false },
{ BUILTIN_STEREO_DEGHOST, "stereoDeGhost.vfp", false },
{ BUILTIN_STEREO_WARP, "stereoWarp.vfp", false },
// { BUILTIN_ZCULL_RECONSTRUCT, "zcullReconstruct.vfp", false },
{ BUILTIN_BINK, "bink.vfp", false },
{ BUILTIN_BINK_GUI, "bink_gui.vfp", false },
{ BUILTIN_STEREO_INTERLACE, "stereoInterlace.vfp", false },
// { BUILTIN_MOTION_BLUR, "motionBlur.vfp", false },
{ BUILTIN_SHADOW, "shadow.vfp", false },
{ BUILTIN_SHADOW_SKINNED, "shadow_skinned.vfp", true },
{ BUILTIN_SHADOW, "shadow.vfp", 0, false },
{ BUILTIN_SHADOW_SKINNED, "shadow_skinned.vfp", 0, true },
{ BUILTIN_SHADOW_DEBUG, "shadowDebug.vfp", 0, false },
{ BUILTIN_SHADOW_DEBUG_SKINNED, "shadowDebug_skinned.vfp", 0, true },
{ BUILTIN_BLENDLIGHT, "blendlight.vfp", 0, false },
{ BUILTIN_FOG, "fog.vfp", 0, false },
{ BUILTIN_FOG_SKINNED, "fog_skinned.vfp", 0, true },
{ BUILTIN_SKYBOX, "skybox.vfp", 0, false },
{ BUILTIN_WOBBLESKY, "wobblesky.vfp", 0, false },
{ BUILTIN_POSTPROCESS, "postprocess.vfp", 0, false },
{ BUILTIN_STEREO_DEGHOST, "stereoDeGhost.vfp", 0, false },
{ BUILTIN_STEREO_WARP, "stereoWarp.vfp", 0, false },
// { BUILTIN_ZCULL_RECONSTRUCT, "zcullReconstruct.vfp", 0, false },
{ BUILTIN_BINK, "bink.vfp", 0, false },
{ BUILTIN_BINK_GUI, "bink_gui.vfp", 0, false },
{ BUILTIN_STEREO_INTERLACE, "stereoInterlace.vfp", 0, false },
{ BUILTIN_MOTION_BLUR, "motionBlur.vfp", 0, false },
// RB begin
{ BUILTIN_DEBUG_SHADOWMAP, "debug_shadowmap.vfp", "", 0, false },
// RB end
};
int numBuiltins = sizeof( builtins ) / sizeof( builtins[0] );
vertexShaders.SetNum( numBuiltins );
@ -133,7 +153,15 @@ void idRenderProgManager::Init()
for( int i = 0; i < numBuiltins; i++ )
{
vertexShaders[i].name = builtins[i].name;
vertexShaders[i].nameOutSuffix = builtins[i].nameOutSuffix;
vertexShaders[i].shaderFeatures = builtins[i].shaderFeatures;
vertexShaders[i].builtin = true;
fragmentShaders[i].name = builtins[i].name;
fragmentShaders[i].nameOutSuffix = builtins[i].nameOutSuffix;
fragmentShaders[i].shaderFeatures = builtins[i].shaderFeatures;
fragmentShaders[i].builtin = true;
builtinShaders[builtins[i].index] = i;
if( builtins[i].requireGPUSkinningSupport && !glConfig.gpuSkinningAvailable )
@ -197,6 +225,11 @@ void idRenderProgManager::Init()
vertexShaders[builtinShaders[BUILTIN_SHADOW_SKINNED]].usesJoints = true;
vertexShaders[builtinShaders[BUILTIN_SHADOW_DEBUG_SKINNED]].usesJoints = true;
vertexShaders[builtinShaders[BUILTIN_FOG_SKINNED]].usesJoints = true;
// RB begin
vertexShaders[builtinShaders[BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED]].usesJoints = true;
vertexShaders[builtinShaders[BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED]].usesJoints = true;
vertexShaders[builtinShaders[BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED]].usesJoints = true;
// RB end
}
cmdSystem->AddCommand( "reloadShaders", R_ReloadShaders, CMD_FL_RENDERER, "reloads shaders" );
@ -220,6 +253,12 @@ void idRenderProgManager::LoadAllShaders()
for( int i = 0; i < glslPrograms.Num(); ++i )
{
if( glslPrograms[i].vertexShaderIndex == -1 || glslPrograms[i].fragmentShaderIndex == -1 )
{
// RB: skip reloading because we didn't load it initially
continue;
}
LoadGLSLProgram( i, glslPrograms[i].vertexShaderIndex, glslPrograms[i].fragmentShaderIndex );
}
}
@ -341,7 +380,9 @@ void idRenderProgManager::LoadVertexShader( int index )
{
return; // Already loaded
}
vertexShaders[index].progId = ( GLuint ) LoadGLSLShader( GL_VERTEX_SHADER, vertexShaders[index].name, vertexShaders[index].uniforms );
vertexShader_t& vs = vertexShaders[index];
vertexShaders[index].progId = ( GLuint ) LoadGLSLShader( GL_VERTEX_SHADER, vs.name, vs.nameOutSuffix, vs.shaderFeatures, vs.builtin, vs.uniforms );
}
/*
@ -355,7 +396,9 @@ void idRenderProgManager::LoadFragmentShader( int index )
{
return; // Already loaded
}
fragmentShaders[index].progId = ( GLuint ) LoadGLSLShader( GL_FRAGMENT_SHADER, fragmentShaders[index].name, fragmentShaders[index].uniforms );
fragmentShader_t& fs = fragmentShaders[index];
fragmentShaders[index].progId = ( GLuint ) LoadGLSLShader( GL_FRAGMENT_SHADER, fs.name, fs.nameOutSuffix, fs.shaderFeatures, fs.builtin, fs.uniforms );
}
/*

View file

@ -115,6 +115,45 @@ enum renderParm_t
RENDERPARM_ENABLE_SKINNING,
RENDERPARM_ALPHA_TEST,
// RB begin
RENDERPARM_AMBIENT_COLOR,
RENDERPARM_GLOBALLIGHTORIGIN,
RENDERPARM_JITTERTEXSCALE,
RENDERPARM_JITTERTEXOFFSET,
RENDERPARM_CASCADEDISTANCES,
RENDERPARM_SHADOW_MATRIX_0_X, // rpShadowMatrices[6 * 4]
RENDERPARM_SHADOW_MATRIX_0_Y,
RENDERPARM_SHADOW_MATRIX_0_Z,
RENDERPARM_SHADOW_MATRIX_0_W,
RENDERPARM_SHADOW_MATRIX_1_X,
RENDERPARM_SHADOW_MATRIX_1_Y,
RENDERPARM_SHADOW_MATRIX_1_Z,
RENDERPARM_SHADOW_MATRIX_1_W,
RENDERPARM_SHADOW_MATRIX_2_X,
RENDERPARM_SHADOW_MATRIX_2_Y,
RENDERPARM_SHADOW_MATRIX_2_Z,
RENDERPARM_SHADOW_MATRIX_2_W,
RENDERPARM_SHADOW_MATRIX_3_X,
RENDERPARM_SHADOW_MATRIX_3_Y,
RENDERPARM_SHADOW_MATRIX_3_Z,
RENDERPARM_SHADOW_MATRIX_3_W,
RENDERPARM_SHADOW_MATRIX_4_X,
RENDERPARM_SHADOW_MATRIX_4_Y,
RENDERPARM_SHADOW_MATRIX_4_Z,
RENDERPARM_SHADOW_MATRIX_4_W,
RENDERPARM_SHADOW_MATRIX_5_X,
RENDERPARM_SHADOW_MATRIX_5_Y,
RENDERPARM_SHADOW_MATRIX_5_Z,
RENDERPARM_SHADOW_MATRIX_5_W,
// RB end
RENDERPARM_TOTAL,
RENDERPARM_USER = 128,
};
@ -161,6 +200,19 @@ public:
{
BindShader_Builtin( BUILTIN_COLOR );
}
// RB begin
void BindShader_ColorSkinned( )
{
BindShader_Builtin( BUILTIN_COLOR_SKINNED );
}
void BindShader_VertexColor( )
{
BindShader_Builtin( BUILTIN_VERTEX_COLOR );
}
// RB end
void BindShader_Texture( )
{
BindShader_Builtin( BUILTIN_TEXTURED );
@ -199,6 +251,39 @@ public:
{
BindShader_Builtin( BUILTIN_INTERACTION_AMBIENT_SKINNED );
}
// RB begin
void BindShader_Interaction_ShadowMapping_Spot()
{
BindShader_Builtin( BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT );
}
void BindShader_Interaction_ShadowMapping_Spot_Skinned()
{
BindShader_Builtin( BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED );
}
void BindShader_Interaction_ShadowMapping_Point()
{
BindShader_Builtin( BUILTIN_INTERACTION_SHADOW_MAPPING_POINT );
}
void BindShader_Interaction_ShadowMapping_Point_Skinned()
{
BindShader_Builtin( BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED );
}
void BindShader_Interaction_ShadowMapping_Parallel()
{
BindShader_Builtin( BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL );
}
void BindShader_Interaction_ShadowMapping_Parallel_Skinned()
{
BindShader_Builtin( BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED );
}
// RB end
void BindShader_SimpleShade()
{
BindShader_Builtin( BUILTIN_SIMPLESHADE );
@ -235,15 +320,19 @@ public:
void BindShader_Shadow()
{
// RB begin
BindShader( -1, builtinShaders[BUILTIN_SHADOW], -1, true );
// RB: no FFP fragment rendering anymore
//BindShader( -1, builtinShaders[BUILTIN_SHADOW], -1, true );
BindShader_Builtin( BUILTIN_SHADOW );
// RB end
}
void BindShader_ShadowSkinned()
{
// RB begin
BindShader( -1, builtinShaders[BUILTIN_SHADOW_SKINNED], -1, true );
// RB: no FFP fragment rendering anymore
//BindShader( -1, builtinShaders[BUILTIN_SHADOW_SKINNED], -1, true );
BindShader_Builtin( BUILTIN_SHADOW_SKINNED );
// RB end
}
@ -322,27 +411,33 @@ public:
BindShader_Builtin( BUILTIN_MOTION_BLUR );
}
void BindShader_DebugShadowMap()
{
BindShader_Builtin( BUILTIN_DEBUG_SHADOWMAP );
}
// RB end
// the joints buffer should only be bound for vertex programs that use joints
bool ShaderUsesJoints() const
bool ShaderUsesJoints() const
{
return vertexShaders[currentVertexShader].usesJoints;
}
// the rpEnableSkinning render parm should only be set for vertex programs that use it
bool ShaderHasOptionalSkinning() const
bool ShaderHasOptionalSkinning() const
{
return vertexShaders[currentVertexShader].optionalSkinning;
}
// unbind the currently bound render program
void Unbind();
void Unbind();
// RB begin
bool IsShaderBound() const;
bool IsShaderBound() const;
// RB end
// this should only be called via the reload shader console command
void LoadAllShaders();
void KillAllShaders();
void LoadAllShaders();
void KillAllShaders();
static const int MAX_GLSL_USER_PARMS = 8;
const char* GetGLSLParmName( int rp ) const;
@ -363,6 +458,10 @@ protected:
{
BUILTIN_GUI,
BUILTIN_COLOR,
// RB begin
BUILTIN_COLOR_SKINNED,
BUILTIN_VERTEX_COLOR,
// RB end
BUILTIN_SIMPLESHADE,
BUILTIN_TEXTURED,
BUILTIN_TEXTURE_VERTEXCOLOR,
@ -372,6 +471,14 @@ protected:
BUILTIN_INTERACTION_SKINNED,
BUILTIN_INTERACTION_AMBIENT,
BUILTIN_INTERACTION_AMBIENT_SKINNED,
// RB begin
BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT,
BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED,
BUILTIN_INTERACTION_SHADOW_MAPPING_POINT,
BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED,
BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL,
BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED,
// RB end
BUILTIN_ENVIRONMENT,
BUILTIN_ENVIRONMENT_SKINNED,
BUILTIN_BUMPY_ENVIRONMENT,
@ -398,6 +505,8 @@ protected:
BUILTIN_STEREO_INTERLACE,
BUILTIN_MOTION_BLUR,
BUILTIN_DEBUG_SHADOWMAP,
MAX_BUILTINS
};
int builtinShaders[MAX_BUILTINS];
@ -406,26 +515,44 @@ protected:
BindShader( -1, builtinShaders[i], builtinShaders[i], true );
}
enum shaderFeature_t
{
USE_GPU_SKINNING,
LIGHT_POINT,
LIGHT_PARALLEL,
MAX_SHADER_MACRO_NAMES,
};
static const char* GLSLMacroNames[MAX_SHADER_MACRO_NAMES];
const char* GetGLSLMacroName( shaderFeature_t sf ) const;
bool CompileGLSL( GLenum target, const char* name );
GLuint LoadGLSLShader( GLenum target, const char* name, idList<int>& uniforms );
GLuint LoadGLSLShader( GLenum target, const char* name, const char* nameOutSuffix, uint32 shaderFeatures, bool builtin, idList<int>& uniforms );
void LoadGLSLProgram( const int programIndex, const int vertexShaderIndex, const int fragmentShaderIndex );
static const GLuint INVALID_PROGID = 0xFFFFFFFF;
struct vertexShader_t
{
vertexShader_t() : progId( INVALID_PROGID ), usesJoints( false ), optionalSkinning( false ) {}
vertexShader_t() : progId( INVALID_PROGID ), usesJoints( false ), optionalSkinning( false ), shaderFeatures( 0 ), builtin( false ) {}
idStr name;
idStr nameOutSuffix;
GLuint progId;
bool usesJoints;
bool optionalSkinning;
uint32 shaderFeatures; // RB: Cg compile macros
bool builtin; // RB: part of the core shaders built into the executable
idList<int> uniforms;
};
struct fragmentShader_t
{
fragmentShader_t() : progId( INVALID_PROGID ) {}
fragmentShader_t() : progId( INVALID_PROGID ), shaderFeatures( 0 ), builtin( false ) {}
idStr name;
idStr nameOutSuffix;
GLuint progId;
uint32 shaderFeatures;
bool builtin;
idList<int> uniforms;
};
@ -445,14 +572,14 @@ protected:
idList<glslUniformLocation_t> uniformLocations;
};
int currentRenderProgram;
idList<glslProgram_t, TAG_RENDER> glslPrograms;
idList<glslProgram_t> glslPrograms;
idStaticList < idVec4, RENDERPARM_USER + MAX_GLSL_USER_PARMS > glslUniforms;
int currentVertexShader;
int currentFragmentShader;
idList<vertexShader_t, TAG_RENDER> vertexShaders;
idList<fragmentShader_t, TAG_RENDER> fragmentShaders;
idList<vertexShader_t > vertexShaders;
idList<fragmentShader_t > fragmentShaders;
};
extern idRenderProgManager renderProgManager;

View file

@ -235,15 +235,18 @@ const char* prefixes[] =
"sampler1DShadow", // GLSL
"sampler2DShadow", // GLSL
"sampler2DArrayShadow", // GLSL
"sampler3DShadow", // GLSL
"samplerCubeShadow", // GLSL
"sampler2DArray", // GLSL"
"sampler2DMS", // GLSL
};
static const int numPrefixes = sizeof( prefixes ) / sizeof( prefixes[0] );
// For GLSL we need to have the names for the renderparms so we can look up their run time indices within the renderprograms
static const char* GLSLParmNames[] =
static const char* GLSLParmNames[RENDERPARM_TOTAL] =
{
"rpScreenCorrectionFactor",
"rpWindowCoord",
@ -313,9 +316,58 @@ static const char* GLSLParmNames[] =
"rpOverbright",
"rpEnableSkinning",
"rpAlphaTest"
"rpAlphaTest",
// RB begin
"rpAmbientColor",
"rpGlobalLightOrigin",
"rpJitterTexScale",
"rpJitterTexOffset",
"rpCascadeDistances",
"rpShadowMatrices",
"rpShadowMatrix0Y",
"rpShadowMatrix0Z",
"rpShadowMatrix0W",
"rpShadowMatrix1X",
"rpShadowMatrix1Y",
"rpShadowMatrix1Z",
"rpShadowMatrix1W",
"rpShadowMatrix2X",
"rpShadowMatrix2Y",
"rpShadowMatrix2Z",
"rpShadowMatrix2W",
"rpShadowMatrix3X",
"rpShadowMatrix3Y",
"rpShadowMatrix3Z",
"rpShadowMatrix3W",
"rpShadowMatrix4X",
"rpShadowMatrix4Y",
"rpShadowMatrix4Z",
"rpShadowMatrix4W",
"rpShadowMatrix5X",
"rpShadowMatrix5Y",
"rpShadowMatrix5Z",
"rpShadowMatrix5W",
// RB end
};
// RB begin
const char* idRenderProgManager::GLSLMacroNames[MAX_SHADER_MACRO_NAMES] =
{
"USE_GPU_SKINNING",
"LIGHT_POINT",
"LIGHT_PARALLEL",
};
// RB end
// RB: added embedded Cg shader resources
static const char* FindEmbeddedSourceShader( const char* name )
{
@ -342,6 +394,12 @@ public:
private:
int Directive_include()
{
if( idParser::Directive_include() )
{
// RB: try local shaders in base/renderprogs/ first
return true;
}
idLexer* script;
idToken token;
idStr path;
@ -452,7 +510,7 @@ private:
StripDeadCode
========================
*/
idStr StripDeadCode( const idStr& in, const char* name )
idStr StripDeadCode( const idStr& in, const char* name, const idStrList& compileMacros, bool builtin )
{
if( r_skipStripDeadCode.GetBool() )
{
@ -464,6 +522,11 @@ idStr StripDeadCode( const idStr& in, const char* name )
src.LoadMemory( in.c_str(), in.Length(), name );
src.AddDefine( "PC" );
for( int i = 0; i < compileMacros.Num(); i++ )
{
src.AddDefine( compileMacros[i] );
}
switch( glConfig.driverType )
{
case GLDRV_OPENGL_ES2:
@ -472,11 +535,16 @@ idStr StripDeadCode( const idStr& in, const char* name )
break;
}
if( glConfig.gpuSkinningAvailable )
if( !builtin && glConfig.gpuSkinningAvailable )
{
src.AddDefine( "USE_GPU_SKINNING" );
}
if( r_useUniformArrays.GetBool() )
{
src.AddDefine( "USE_UNIFORM_ARRAYS" );
}
idList< idCGBlock > blocks;
blocks.SetNum( 100 );
@ -1056,12 +1124,13 @@ idStr ConvertCG2GLSL( const idStr& in, const char* name, bool isVertexProgram, i
idToken token;
while( src.ReadToken( &token ) )
{
// check for uniforms
while( token == "uniform" && src.CheckTokenString( "float4" ) )
// RB: added special case for matrix arrays
while( token == "uniform" && ( src.CheckTokenString( "float4" ) || src.CheckTokenString( "float4x4" ) ) )
{
src.ReadToken( &token );
uniformList.Append( token );
idStr uniform = token;
// strip ': register()' from uniforms
if( src.CheckTokenString( ":" ) )
@ -1072,8 +1141,25 @@ idStr ConvertCG2GLSL( const idStr& in, const char* name, bool isVertexProgram, i
}
}
src.ReadToken( & token );
if( src.PeekTokenString( "[" ) )
{
while( src.ReadToken( &token ) )
{
uniform += token;
if( token == "]" )
{
break;
}
}
}
uniformList.Append( uniform );
src.ReadToken( &token );
}
// RB end
// convert the in/out structs
if( token == "struct" )
@ -1283,7 +1369,38 @@ idStr ConvertCG2GLSL( const idStr& in, const char* name, bool isVertexProgram, i
if( token == uniformList[i] )
{
program += ( token.linesCrossed > 0 ) ? newline : ( token.WhiteSpaceBeforeToken() > 0 ? " " : "" );
program += va( "%s[%d /* %s */]", uniformArrayName, i, uniformList[i].c_str() );
// RB: for some unknown reasons has the Nvidia driver problems with regular uniforms when using glUniform4fv
// so we need these uniform arrays
// I added special check rpShadowMatrices so we can still index the uniforms from the shader
if( idStr::Cmp( uniformList[i].c_str(), "rpShadowMatrices" ) == 0 )
{
program += va( "%s[/* %s */ %d + ", uniformArrayName, uniformList[i].c_str(), i );
if( src.ExpectTokenString( "[" ) )
{
idStr uniformIndexing;
while( src.ReadToken( &token ) )
{
if( token == "]" )
{
break;
}
uniformIndexing += token;
uniformIndexing += " ";
}
program += uniformIndexing + "]";
}
}
else
{
program += va( "%s[%d /* %s */]", uniformArrayName, i, uniformList[i].c_str() );
}
// RB end
isUniform = true;
break;
}
@ -1432,7 +1549,16 @@ idStr ConvertCG2GLSL( const idStr& in, const char* name, bool isVertexProgram, i
{
if( r_useUniformArrays.GetBool() )
{
out += va( "\nuniform vec4 %s[%d];\n", uniformArrayName, uniformList.Num() );
int extraSize = 0;
for( int i = 0; i < uniformList.Num(); i++ )
{
if( idStr::Cmp( uniformList[i].c_str(), "rpShadowMatrices" ) == 0 )
{
extraSize += ( 6 * 4 );
}
}
out += va( "\nuniform vec4 %s[%d];\n", uniformArrayName, uniformList.Num() + extraSize );
}
else
{
@ -1463,7 +1589,7 @@ idStr ConvertCG2GLSL( const idStr& in, const char* name, bool isVertexProgram, i
idRenderProgManager::LoadGLSLShader
================================================================================================
*/
GLuint idRenderProgManager::LoadGLSLShader( GLenum target, const char* name, idList<int>& uniforms )
GLuint idRenderProgManager::LoadGLSLShader( GLenum target, const char* name, const char* nameOutSuffix, uint32 shaderFeatures, bool builtin, idList<int>& uniforms )
{
idStr inFile;
@ -1474,7 +1600,7 @@ GLuint idRenderProgManager::LoadGLSLShader( GLenum target, const char* name, idL
// RB: replaced backslashes
inFile.Format( "renderprogs/%s", name );
inFile.StripFileExtension();
outFileHLSL.Format( "renderprogs/hlsl/%s", name );
outFileHLSL.Format( "renderprogs/hlsl/%s%s", name, nameOutSuffix );
outFileHLSL.StripFileExtension();
switch( glConfig.driverType )
@ -1483,15 +1609,15 @@ GLuint idRenderProgManager::LoadGLSLShader( GLenum target, const char* name, idL
case GLDRV_OPENGL_ES3:
case GLDRV_OPENGL_MESA:
{
outFileGLSL.Format( "renderprogs/glsles-1.0/%s", name );
outFileUniforms.Format( "renderprogs/glsles-1.0/%s", name );
outFileGLSL.Format( "renderprogs/glsles-1_0/%s%s", name, nameOutSuffix );
outFileUniforms.Format( "renderprogs/glsles-1_0/%s%s", name, nameOutSuffix );
break;
}
default:
{
outFileGLSL.Format( "renderprogs/glsl-1.50/%s", name );
outFileUniforms.Format( "renderprogs/glsl-1.50/%s", name );
outFileGLSL.Format( "renderprogs/glsl-1_50/%s%s", name, nameOutSuffix );
outFileUniforms.Format( "renderprogs/glsl-1_50/%s%s", name, nameOutSuffix );
}
}
@ -1547,8 +1673,19 @@ GLuint idRenderProgManager::LoadGLSLShader( GLenum target, const char* name, idL
{
return false;
}
idStrList compileMacros;
for( int j = 0; j < MAX_SHADER_MACRO_NAMES; j++ )
{
if( BIT( j ) & shaderFeatures )
{
const char* macroName = GetGLSLMacroName( ( shaderFeature_t ) j );
compileMacros.Append( idStr( macroName ) );
}
}
idStr hlslCode( hlslFileBuffer );
idStr programHLSL = StripDeadCode( hlslCode, inFile );
idStr programHLSL = StripDeadCode( hlslCode, inFile, compileMacros, builtin );
programGLSL = ConvertCG2GLSL( programHLSL, inFile, target == GL_VERTEX_SHADER, programUniforms );
fileSystem->WriteFile( outFileHLSL, programHLSL.c_str(), programHLSL.Length(), "fs_basepath" );
@ -1718,6 +1855,15 @@ const char* idRenderProgManager::GetGLSLParmName( int rp ) const
return GLSLParmNames[ rp ];
}
// RB begin
const char* idRenderProgManager::GetGLSLMacroName( shaderFeature_t sf ) const
{
assert( sf < MAX_SHADER_MACRO_NAMES );
return GLSLMacroNames[ sf ];
}
// RB end
/*
================================================================================================
idRenderProgManager::SetUniformValue
@ -1741,6 +1887,8 @@ void idRenderProgManager::CommitUniforms()
const int progID = GetGLSLCurrentProgram();
const glslProgram_t& prog = glslPrograms[progID];
//GL_CheckErrors();
if( r_useUniformArrays.GetBool() )
{
ALIGNTYPE16 idVec4 localVectors[RENDERPARM_USER + MAX_GLSL_USER_PARMS];
@ -1750,11 +1898,26 @@ void idRenderProgManager::CommitUniforms()
const idList<int>& vertexUniforms = vertexShaders[prog.vertexShaderIndex].uniforms;
if( prog.vertexUniformArray != -1 && vertexUniforms.Num() > 0 )
{
int totalUniforms = 0;
for( int i = 0; i < vertexUniforms.Num(); i++ )
{
localVectors[i] = glslUniforms[vertexUniforms[i]];
// RB: HACK rpShadowMatrices[6 * 4]
if( vertexUniforms[i] == RENDERPARM_SHADOW_MATRIX_0_X )
{
for( int j = 0; j < ( 6 * 4 ); j++ )
{
localVectors[i + j] = glslUniforms[vertexUniforms[i] + j];
totalUniforms++;
}
}
else
{
localVectors[i] = glslUniforms[vertexUniforms[i]];
totalUniforms++;
}
}
glUniform4fv( prog.vertexUniformArray, vertexUniforms.Num(), localVectors->ToFloatPtr() );
glUniform4fv( prog.vertexUniformArray, totalUniforms, localVectors->ToFloatPtr() );
}
}
@ -1763,11 +1926,26 @@ void idRenderProgManager::CommitUniforms()
const idList<int>& fragmentUniforms = fragmentShaders[prog.fragmentShaderIndex].uniforms;
if( prog.fragmentUniformArray != -1 && fragmentUniforms.Num() > 0 )
{
int totalUniforms = 0;
for( int i = 0; i < fragmentUniforms.Num(); i++ )
{
localVectors[i] = glslUniforms[fragmentUniforms[i]];
// RB: HACK rpShadowMatrices[6 * 4]
if( fragmentUniforms[i] == RENDERPARM_SHADOW_MATRIX_0_X )
{
for( int j = 0; j < ( 6 * 4 ); j++ )
{
localVectors[i + j] = glslUniforms[fragmentUniforms[i] + j];
totalUniforms++;
}
}
else
{
localVectors[i] = glslUniforms[fragmentUniforms[i]];
totalUniforms++;
}
}
glUniform4fv( prog.fragmentUniformArray, fragmentUniforms.Num(), localVectors->ToFloatPtr() );
glUniform4fv( prog.fragmentUniformArray, totalUniforms, localVectors->ToFloatPtr() );
}
}
}
@ -1776,9 +1954,31 @@ void idRenderProgManager::CommitUniforms()
for( int i = 0; i < prog.uniformLocations.Num(); i++ )
{
const glslUniformLocation_t& uniformLocation = prog.uniformLocations[i];
glUniform4fv( uniformLocation.uniformIndex, 1, glslUniforms[uniformLocation.parmIndex].ToFloatPtr() );
// RB: HACK rpShadowMatrices[6 * 4]
if( uniformLocation.parmIndex == RENDERPARM_SHADOW_MATRIX_0_X )
{
glUniform4fv( uniformLocation.uniformIndex, 6 * 4, glslUniforms[uniformLocation.parmIndex].ToFloatPtr() );
}
else
{
glUniform4fv( uniformLocation.uniformIndex, 1, glslUniforms[uniformLocation.parmIndex].ToFloatPtr() );
#if 1
if( GL_CheckErrors() )
{
const char* parmName = GetGLSLParmName( uniformLocation.parmIndex );
const char* value = glslUniforms[uniformLocation.parmIndex].ToString();
idLib::Printf( "glUniform4fv( %i = %s, value = %s ) failed for %s\n", uniformLocation.parmIndex, parmName, value, prog.name.c_str() );
}
#endif
}
// RB end
}
}
//GL_CheckErrors();
}
class idSort_QuickUniforms : public idSort_Quick< glslUniformLocation_t, idSort_QuickUniforms >
@ -1927,12 +2127,36 @@ void idRenderProgManager::LoadGLSLProgram( const int programIndex, const int ver
// set the texture unit locations once for the render program. We only need to do this once since we only link the program once
glUseProgram( program );
int numSamplerUniforms = 0;
for( int i = 0; i < MAX_PROG_TEXTURE_PARMS; ++i )
{
GLint loc = glGetUniformLocation( program, va( "samp%d", i ) );
if( loc != -1 )
{
glUniform1i( loc, i );
numSamplerUniforms++;
}
}
// RB: make sure that we collected all uniforms we are interested in
if( !r_useUniformArrays.GetBool() )
{
int numActiveUniforms;
glGetProgramiv( program, GL_ACTIVE_UNIFORMS, &numActiveUniforms );
GL_CheckErrors();
if( ( numActiveUniforms - numSamplerUniforms ) != prog.uniformLocations.Num() )
{
int size;
GLenum type;
char uniformName[1000];
for( int i = 0; i < numActiveUniforms; i++ )
{
glGetActiveUniform( program, i, sizeof( uniformName ), NULL, &size, &type, uniformName );
idLib::Printf( "active uniform: '%s'\n", uniformName );
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -150,6 +150,12 @@ struct glconfig_t
bool gremedyStringMarkerAvailable;
bool vertexHalfFloatAvailable;
bool framebufferObjectAvailable;
int maxRenderbufferSize;
int maxColorAttachments;
// bool framebufferPackedDepthStencilAvailable;
bool framebufferBlitAvailable;
// only true with uniform buffer support and an OpenGL driver that supports GLSL >= 1.50
bool gpuSkinningAvailable;
// RB end

View file

@ -186,6 +186,9 @@ idCVar r_showTangentSpace( "r_showTangentSpace", "0", CVAR_RENDERER | CVAR_INTEG
idCVar r_showDominantTri( "r_showDominantTri", "0", CVAR_RENDERER | CVAR_BOOL, "draw lines from vertexes to center of dominant triangles" );
idCVar r_showTextureVectors( "r_showTextureVectors", "0", CVAR_RENDERER | CVAR_FLOAT, " if > 0 draw each triangles texture (tangent) vectors" );
idCVar r_showOverDraw( "r_showOverDraw", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = geometry overdraw, 2 = light interaction overdraw, 3 = geometry and light interaction overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer<0, 3> );
// RB begin
idCVar r_showShadowMaps( "r_showShadowMaps", "0", CVAR_RENDERER | CVAR_BOOL, "" );
// RB end
idCVar r_useEntityCallbacks( "r_useEntityCallbacks", "1", CVAR_RENDERER | CVAR_BOOL, "if 0, issue the callback immediately at update time, rather than defering" );
@ -208,6 +211,19 @@ idCVar stereoRender_deGhost( "stereoRender_deGhost", "0.05", CVAR_FLOAT | CVAR_A
idCVar r_useVirtualScreenResolution( "r_useVirtualScreenResolution", "1", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "do 2D rendering at 640x480 and stretch to the current resolution" );
// RB: shadow mapping parameters
idCVar r_useShadowMapping( "r_useShadowMapping", "1", CVAR_RENDERER | CVAR_BOOL, "use shadow mapping instead of stencil shadows" );
idCVar r_shadowMapFrustumFOV( "r_shadowMapFrustumFOV", "92", CVAR_RENDERER | CVAR_FLOAT, "oversize FOV for point light side matching" );
idCVar r_shadowMapSingleSide( "r_shadowMapSingleSide", "-1", CVAR_RENDERER | CVAR_INTEGER, "only draw a single side (0-5) of point lights" );
idCVar r_shadowMapImageSize( "r_shadowMapImageSize", "1024", CVAR_RENDERER | CVAR_INTEGER, "", 128, 2048 );
idCVar r_shadowMapJitterScale( "r_shadowMapJitterScale", "0.006", CVAR_RENDERER | CVAR_FLOAT, "scale factor for jitter offset" );
idCVar r_shadowMapBiasScale( "r_shadowMapBiasScale", "0.0001", CVAR_RENDERER | CVAR_FLOAT, "scale factor for jitter bias" );
idCVar r_shadowMapSamples( "r_shadowMapSamples", "16", CVAR_RENDERER | CVAR_INTEGER, "0, 1, 4, or 16" );
idCVar r_shadowMapSplits( "r_shadowMapSplits", "3", CVAR_RENDERER | CVAR_INTEGER, "number of splits for cascaded shadow mapping with parallel lights", 0, 4 );
idCVar r_shadowMapSplitWeight( "r_shadowMapSplitWeight", "0.9", CVAR_RENDERER | CVAR_FLOAT, "" );
// RB end
/*
========================
glBindMultiTextureEXT
@ -263,8 +279,25 @@ static void CALLBACK DebugCallback( unsigned int source, unsigned int type,
#else
printf( "%s\n", message );
#endif
// RB end
}
/*
=================
R_CheckExtension
=================
*/
bool R_CheckExtension( char* name )
{
if( !strstr( glConfig.extensions_string, name ) )
{
common->Printf( "X..%s not found\n", name );
return false;
}
common->Printf( "...using %s\n", name );
return true;
}
// RB end
/*
==================
@ -295,7 +328,7 @@ static void R_CheckPortableExtensions()
}
// RB: Mesa support
if( idStr::Icmpn( glConfig.renderer_string, "Mesa", 4 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "X.org", 5 ) == 0 )
if( idStr::Icmpn( glConfig.renderer_string, "Mesa", 4 ) == 0 || idStr::Icmpn( glConfig.renderer_string, "X.org", 4 ) == 0 )
{
glConfig.driverType = GLDRV_OPENGL_MESA;
}
@ -361,8 +394,8 @@ static void R_CheckPortableExtensions()
glConfig.fragmentProgramAvailable = GLEW_ARB_fragment_program != 0;
if( glConfig.fragmentProgramAvailable )
{
glGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, ( GLint* )&glConfig.maxTextureCoords );
glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, ( GLint* )&glConfig.maxTextureImageUnits );
glGetIntegerv( GL_MAX_TEXTURE_COORDS, ( GLint* )&glConfig.maxTextureCoords );
glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS, ( GLint* )&glConfig.maxTextureImageUnits );
}
// GLSL, core in OpenGL > 2.0
@ -399,6 +432,42 @@ static void R_CheckPortableExtensions()
// GL_ARB_timer_query
glConfig.timerQueryAvailable = ( GLEW_ARB_timer_query != 0 || GLEW_EXT_timer_query != 0 ) && ( glConfig.vendor != VENDOR_INTEL || r_skipIntelWorkarounds.GetBool() ) && glConfig.driverType != GLDRV_OPENGL_MESA;
// GREMEDY_string_marker
glConfig.gremedyStringMarkerAvailable = GLEW_GREMEDY_string_marker != 0;
if( glConfig.gremedyStringMarkerAvailable )
{
common->Printf( "...using %s\n", "GL_GREMEDY_string_marker" );
}
else
{
common->Printf( "X..%s not found\n", "GL_GREMEDY_string_marker" );
}
// GL_EXT_framebuffer_object
glConfig.framebufferObjectAvailable = GLEW_EXT_framebuffer_object != 0;
if( glConfig.framebufferObjectAvailable )
{
glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE, &glConfig.maxRenderbufferSize );
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, &glConfig.maxColorAttachments );
common->Printf( "...using %s\n", "GL_EXT_framebuffer_object" );
}
else
{
common->Printf( "X..%s not found\n", "GL_EXT_framebuffer_object" );
}
// GL_EXT_framebuffer_blit
glConfig.framebufferBlitAvailable = GLEW_EXT_framebuffer_blit != 0;
if( glConfig.framebufferBlitAvailable )
{
common->Printf( "...using %s\n", "GL_EXT_framebuffer_blit" );
}
else
{
common->Printf( "X..%s not found\n", "GL_EXT_framebuffer_object" );
}
// GL_ARB_debug_output
glConfig.debugOutputAvailable = GLEW_ARB_debug_output != 0;
if( glConfig.debugOutputAvailable )
@ -2255,6 +2324,10 @@ void idRenderSystemLocal::Init()
guiModel->Clear();
tr_guiModel = guiModel; // for DeviceContext fast path
// RB begin
Framebuffer::Init();
// RB end
globalImages->Init();
idCinematic::InitCinematic( );
@ -2318,6 +2391,10 @@ void idRenderSystemLocal::Shutdown()
globalImages->Shutdown();
// RB begin
Framebuffer::Shutdown();
// RB end
// free frame memory
R_ShutdownFrameData();

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -798,7 +799,7 @@ void idRenderWorldLocal::FindViewLightsAndEntities()
portalStack_t ps;
for( int i = 0; i < 5; i++ )
{
ps.portalPlanes[i] = tr.viewDef->frustum[i];
ps.portalPlanes[i] = tr.viewDef->frustums[FRUSTUM_PRIMARY][i];
}
ps.numPortalPlanes = 5;
ps.rect = tr.viewDef->scissor;
@ -811,7 +812,7 @@ void idRenderWorldLocal::FindViewLightsAndEntities()
// note that the center of projection for flowing through portals may
// be a different point than initialViewAreaOrigin for subviews that
// may have the viewOrigin in a solid/invalid area
FlowViewThroughPortals( tr.viewDef->renderView.vieworg, 5, tr.viewDef->frustum );
FlowViewThroughPortals( tr.viewDef->renderView.vieworg, 5, tr.viewDef->frustums[FRUSTUM_PRIMARY] );
}
}
@ -1197,6 +1198,10 @@ void idRenderWorldLocal::ShowPortals()
GL_Color( 0, 1, 0 );
}
// RB begin
renderProgManager.CommitUniforms();
// RB end
glBegin( GL_LINE_LOOP );
for( j = 0; j < w->GetNumPoints(); j++ )
{

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -37,7 +38,9 @@ idResolutionScale resolutionScale;
static const float MINIMUM_RESOLUTION_SCALE = 0.5f;
static const float MAXIMUM_RESOLUTION_SCALE = 1.0f;
idCVar rs_enable( "rs_enable", "1", CVAR_INTEGER, "Enable dynamic resolution scaling, 0 - off, 1 - horz only, 2 - vert only, 3 - both" );
// RB: turned this off. It is only useful on mobile devices or consoles
idCVar rs_enable( "rs_enable", "0", CVAR_INTEGER, "Enable dynamic resolution scaling, 0 - off, 1 - horz only, 2 - vert only, 3 - both" );
// Rb end
idCVar rs_forceFractionX( "rs_forceFractionX", "0", CVAR_FLOAT, "Force a specific 0.0 to 1.0 horizontal resolution scale" );
idCVar rs_forceFractionY( "rs_forceFractionY", "0", CVAR_FLOAT, "Force a specific 0.0 to 1.0 vertical resolution scale" );
idCVar rs_showResolutionChanges( "rs_showResolutionChanges", "0", CVAR_INTEGER, "1 = Print whenever the resolution scale changes, 2 = always" );

File diff suppressed because it is too large Load diff

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -136,7 +137,10 @@ static void RB_SimpleSurfaceSetup( const drawSurf_t* drawSurf )
// change the matrix if needed
if( drawSurf->space != backEnd.currentSpace )
{
glLoadMatrixf( drawSurf->space->modelViewMatrix );
// RB begin
RB_SetMVP( drawSurf->space->mvp );
//qglLoadMatrixf( drawSurf->space->modelViewMatrix );
// RB end
backEnd.currentSpace = drawSurf->space;
}
@ -160,8 +164,10 @@ static void RB_SimpleWorldSetup()
{
backEnd.currentSpace = &backEnd.viewDef->worldSpace;
glLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix );
// RB begin
//qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix );
RB_SetMVP( backEnd.viewDef->worldSpace.mvp );
// RB end
GL_Scissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1,
backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1,
@ -289,16 +295,16 @@ stencil buffer. Stencil of 0 = black, 1 = red, 2 = green,
static void R_ColorByStencilBuffer()
{
int i;
static float colors[8][3] =
static idVec3 colors[8] =
{
{0, 0, 0},
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
{0, 1, 1},
{1, 0, 1},
{1, 1, 0},
{1, 1, 1},
idVec3( 0, 0, 0 ),
idVec3( 1, 0, 0 ),
idVec3( 0, 1, 0 ),
idVec3( 0, 0, 1 ),
idVec3( 0, 1, 1 ),
idVec3( 1, 0, 1 ),
idVec3( 1, 1, 0 ),
idVec3( 1, 1, 1 ),
};
// clear color buffer to white (>6 passes)
@ -683,6 +689,17 @@ static void RB_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDr
continue;
}
assert( drawSurf->space != NULL );
// RB begin
#if 1
if( drawSurf->space != backEnd.currentSpace )
{
backEnd.currentSpace = drawSurf->space;
RB_SetMVP( drawSurf->space->mvp );
}
#else
if( drawSurf->space != NULL ) // is it ever NULL? Do we need to check?
{
// Set these values ahead of time so we don't have to reconstruct the matrices on the consoles
@ -690,28 +707,39 @@ static void RB_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDr
{
RB_SetWeaponDepthHack();
}
if( drawSurf->space->modelDepthHack != 0.0f )
{
RB_SetModelDepthHack( drawSurf->space->modelDepthHack );
}
// change the matrix if needed
if( drawSurf->space != backEnd.currentSpace )
{
RB_LoadMatrixWithBypass( drawSurf->space->modelViewMatrix );
}
if( drawSurf->space->weaponDepthHack )
{
RB_EnterWeaponDepthHack();
}
if( drawSurf->space->modelDepthHack != 0.0f )
{
RB_EnterModelDepthHack( drawSurf->space->modelDepthHack );
}
}
#endif
if( drawSurf->jointCache )
{
renderProgManager.BindShader_ColorSkinned();
}
else
{
renderProgManager.BindShader_Color();
}
// RB end
// change the scissor if needed
if( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) )
@ -726,10 +754,12 @@ static void RB_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDr
// render it
triFunc_( drawSurf );
if( drawSurf->space != NULL && ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) )
// RB begin
/*if( drawSurf->space != NULL && ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) )
{
RB_LeaveDepthHack();
}
}*/
// RB end
backEnd.currentSpace = drawSurf->space;
}
@ -756,11 +786,12 @@ static void RB_ShowSilhouette()
return;
}
//
// clear all triangle edges to black
//
globalImages->BindNull();
glDisable( GL_TEXTURE_2D );
// RB begin
renderProgManager.BindShader_Color();
// RB end
GL_Color( 0, 0, 0 );
@ -772,9 +803,7 @@ static void RB_ShowSilhouette()
RB_DrawElementsWithCounters );
//
// now blend in edges that cast silhouettes
//
RB_SimpleWorldSetup();
GL_Color( 0.5, 0, 0 );
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
@ -853,7 +882,7 @@ static void RB_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs )
return;
}
float color[4] = { 1, 1, 1, 1 };
idVec4 color( 1, 1, 1, 1 );
GL_PolygonOffset( -1.0f, -2.0f );
@ -878,7 +907,6 @@ static void RB_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs )
}
GL_Color( color );
renderProgManager.BindShader_Color();
RB_RenderDrawSurfListWithFunction( drawSurfs, numDrawSurfs, RB_DrawElementsWithCounters );
@ -914,7 +942,6 @@ static void RB_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs )
}
globalImages->BindNull();
glDisable( GL_TEXTURE_2D );
GL_Color( 1, 1, 1 );
@ -949,6 +976,7 @@ static void RB_ShowViewEntitys( viewEntity_t* vModels )
{
return;
}
if( r_showViewEntitys.GetInteger() >= 2 )
{
common->Printf( "view entities: " );
@ -978,7 +1006,7 @@ static void RB_ShowViewEntitys( viewEntity_t* vModels )
{
idBounds b;
glLoadMatrixf( vModel->modelViewMatrix );
//glLoadMatrixf( vModel->modelViewMatrix );
const idRenderEntityLocal* edef = vModel->entityDef;
if( !edef )
@ -986,8 +1014,6 @@ static void RB_ShowViewEntitys( viewEntity_t* vModels )
continue;
}
// draw the model bounds in white if directly visible,
// or, blue if it is only-for-sahdow
idVec4 color;
@ -1062,7 +1088,7 @@ static void RB_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs )
{
drawSurf = drawSurfs[i];
tri = drawSurf->frontEndGeo;
if( !tri->verts )
if( tri == NULL || tri->verts == NULL )
{
continue;
}
@ -1149,6 +1175,11 @@ static void RB_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int numDrawSurfs
RB_SimpleSurfaceSetup( drawSurf );
tri = drawSurf->frontEndGeo;
if( tri == NULL || tri->verts == NULL )
{
continue;
}
glBegin( GL_TRIANGLES );
for( j = 0; j < tri->numIndexes; j += 3 )
{
@ -1199,10 +1230,11 @@ static void RB_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs )
RB_SimpleSurfaceSetup( drawSurf );
tri = drawSurf->frontEndGeo;
if( !tri->verts )
if( tri == NULL || tri->verts == NULL )
{
continue;
}
glBegin( GL_TRIANGLES );
for( j = 0; j < tri->numIndexes; j++ )
{
@ -1255,6 +1287,9 @@ static void RB_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs )
}
globalImages->BindNull();
// RB begin
renderProgManager.BindShader_VertexColor();
GL_State( GLS_DEPTHFUNC_LESS );
for( i = 0; i < numDrawSurfs; i++ )
@ -1264,10 +1299,13 @@ static void RB_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs )
RB_SimpleSurfaceSetup( drawSurf );
tri = drawSurf->frontEndGeo;
if( !tri->verts )
if( tri == NULL || tri->verts == NULL )
{
continue;
}
renderProgManager.CommitUniforms();
glBegin( GL_TRIANGLES );
for( j = 0; j < tri->numIndexes; j++ )
{
@ -1280,6 +1318,8 @@ static void RB_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs )
glEnd();
}
// RB end
GL_State( GLS_DEFAULT );
}
@ -1334,33 +1374,39 @@ static void RB_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs )
RB_SimpleSurfaceSetup( drawSurf );
tri = drawSurf->frontEndGeo;
if( !tri->verts )
if( tri == NULL || tri->verts == NULL )
{
continue;
}
// RB begin
renderProgManager.BindShader_VertexColor();
glBegin( GL_LINES );
for( j = 0; j < tri->numVerts; j++ )
{
const idVec3 normal = tri->verts[j].GetNormal();
const idVec3 tangent = tri->verts[j].GetTangent();
const idVec3 bitangent = tri->verts[j].GetBiTangent();
GL_Color( 0, 0, 1 );
glColor3f( 0, 0, 1 );
glVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
VectorMA( tri->verts[j].xyz, size, normal, end );
glVertex3fv( end.ToFloatPtr() );
GL_Color( 1, 0, 0 );
glColor3f( 1, 0, 0 );
glVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
VectorMA( tri->verts[j].xyz, size, tangent, end );
glVertex3fv( end.ToFloatPtr() );
GL_Color( 0, 1, 0 );
glColor3f( 0, 1, 0 );
glVertex3fv( tri->verts[j].xyz.ToFloatPtr() );
VectorMA( tri->verts[j].xyz, size, bitangent, end );
glVertex3fv( end.ToFloatPtr() );
}
glEnd();
// RB end
}
if( showNumbers )
@ -1370,7 +1416,7 @@ static void RB_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs )
{
drawSurf = drawSurfs[i];
tri = drawSurf->frontEndGeo;
if( !tri->verts )
if( tri == NULL || tri->verts == NULL )
{
continue;
}
@ -1491,7 +1537,7 @@ static void RB_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs )
const srfTriangles_t* tri = drawSurf->frontEndGeo;
if( tri->verts == NULL )
if( tri == NULL || tri->verts == NULL )
{
continue;
}
@ -1600,7 +1646,7 @@ static void RB_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs )
tri = drawSurf->frontEndGeo;
if( !tri->verts )
if( tri == NULL || tri->verts == NULL )
{
continue;
}
@ -1764,9 +1810,9 @@ static void RB_ShowLights()
GL_State( GLS_DEFAULT );
// we use the 'vLight->invProjectMVPMatrix'
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
// glMatrixMode( GL_PROJECTION );
// glLoadIdentity();
globalImages->BindNull();
renderProgManager.BindShader_Color();
@ -1784,7 +1830,22 @@ static void RB_ShowLights()
if( r_showLights.GetInteger() >= 2 )
{
GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK );
GL_Color( 0.0f, 0.0f, 1.0f, 0.25f );
// RB: show different light types
if( vLight->parallel )
{
GL_Color( 1.0f, 0.0f, 0.0f, 0.25f );
}
else if( vLight->pointLight )
{
GL_Color( 0.0f, 0.0f, 1.0f, 0.25f );
}
else
{
GL_Color( 0.0f, 1.0f, 0.0f, 0.25f );
}
// RB end
idRenderMatrix invProjectMVPMatrix;
idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix );
RB_SetMVP( invProjectMVPMatrix );
@ -1964,7 +2025,10 @@ static void RB_DrawText( const char* text, const idVec3& origin, float scale, co
{
renderProgManager.BindShader_Color();
// RB begin
GL_Color( color[0], color[1], color[2], 1 /*color[3]*/ );
renderProgManager.CommitUniforms();
// RB end
int i, j, len, num, index, charIndex, line;
float textLen = 1.0f, spacing = 1.0f;
@ -1973,7 +2037,6 @@ static void RB_DrawText( const char* text, const idVec3& origin, float scale, co
if( text && *text )
{
glBegin( GL_LINES );
glColor3fv( color.ToFloatPtr() );
if( text[0] == '\n' )
{
@ -2195,6 +2258,11 @@ void RB_ShowDebugLines()
// all lines are expressed in world coordinates
RB_SimpleWorldSetup();
// RB begin
renderProgManager.BindShader_VertexColor();
renderProgManager.CommitUniforms();
// RB end
globalImages->BindNull();
width = r_debugLineWidth.GetInteger();
@ -2331,9 +2399,12 @@ void RB_ShowDebugPolygons()
// all lines are expressed in world coordinates
RB_SimpleWorldSetup();
globalImages->BindNull();
// RB begin
renderProgManager.BindShader_VertexColor();
renderProgManager.CommitUniforms();
// RB end
glDisable( GL_TEXTURE_2D );
globalImages->BindNull();
if( r_debugPolygonFilled.GetBool() )
{
@ -2721,11 +2792,12 @@ void RB_TestImage()
float projMatrixTranspose[16];
R_MatrixTranspose( finalOrtho, projMatrixTranspose );
renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, projMatrixTranspose, 4 );
glMatrixMode( GL_PROJECTION );
glLoadMatrixf( finalOrtho );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// glMatrixMode( GL_PROJECTION );
// glLoadMatrixf( finalOrtho );
// glMatrixMode( GL_MODELVIEW );
// glLoadIdentity();
// Set Color
GL_Color( 1, 1, 1, 1 );
@ -2752,6 +2824,102 @@ void RB_TestImage()
RB_DrawElementsWithCounters( &backEnd.testImageSurface );
}
// RB begin
void RB_ShowShadowMaps()
{
idImage* image = NULL;
int max;
float w, h;
if( !r_showShadowMaps.GetBool() )
return;
image = globalImages->shadowImage;
if( !image )
{
return;
}
// Set State
GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
// Set Parms
float texS[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
float texT[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_S, texS );
renderProgManager.SetRenderParm( RENDERPARM_TEXTUREMATRIX_T, texT );
float texGenEnabled[4] = { 0, 0, 0, 0 };
renderProgManager.SetRenderParm( RENDERPARM_TEXGEN_0_ENABLED, texGenEnabled );
for( int i = 0; i < ( r_shadowMapSplits.GetInteger() + 1 ); i++ )
{
max = image->GetUploadWidth() > image->GetUploadHeight() ? image->GetUploadWidth() : image->GetUploadHeight();
w = 0.25 * image->GetUploadWidth() / max;
h = 0.25 * image->GetUploadHeight() / max;
w *= ( float )renderSystem->GetHeight() / renderSystem->GetWidth();
// not really necessary but just for clarity
const float screenWidth = 1.0f;
const float screenHeight = 1.0f;
const float halfScreenWidth = screenWidth * 0.5f;
const float halfScreenHeight = screenHeight * 0.5f;
float scale[16] = { 0 };
scale[0] = w; // scale
scale[5] = h; // scale
scale[12] = ( halfScreenWidth * w * 2.1f * i ); // translate
scale[13] = halfScreenHeight + ( halfScreenHeight * h ); // translate
scale[10] = 1.0f;
scale[15] = 1.0f;
float ortho[16] = { 0 };
ortho[0] = 2.0f / screenWidth;
ortho[5] = -2.0f / screenHeight;
ortho[10] = -2.0f;
ortho[12] = -1.0f;
ortho[13] = 1.0f;
ortho[14] = -1.0f;
ortho[15] = 1.0f;
float finalOrtho[16];
R_MatrixMultiply( scale, ortho, finalOrtho );
float projMatrixTranspose[16];
R_MatrixTranspose( finalOrtho, projMatrixTranspose );
renderProgManager.SetRenderParms( RENDERPARM_MVPMATRIX_X, projMatrixTranspose, 4 );
float screenCorrectionParm[4];
screenCorrectionParm[0] = i;
screenCorrectionParm[1] = 0.0f;
screenCorrectionParm[2] = 0.0f;
screenCorrectionParm[3] = 1.0f;
renderProgManager.SetRenderParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor
// glMatrixMode( GL_PROJECTION );
// glLoadMatrixf( finalOrtho );
// glMatrixMode( GL_MODELVIEW );
// glLoadIdentity();
// Set Color
GL_Color( 1, 1, 1, 1 );
GL_SelectTexture( 0 );
image->Bind();
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE );
renderProgManager.BindShader_DebugShadowMap();
RB_DrawElementsWithCounters( &backEnd.testImageSurface );
}
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
}
// RB end
/*
=================
RB_DrawExpandedTriangles
@ -2950,6 +3118,10 @@ void RB_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs )
RB_ShowNormals( drawSurfs, numDrawSurfs );
RB_ShowViewEntitys( backEnd.viewDef->viewEntitys );
RB_ShowLights();
// RB begin
RB_ShowShadowMaps();
// RB end
RB_ShowTextureVectors( drawSurfs, numDrawSurfs );
RB_ShowDominantTris( drawSurfs, numDrawSurfs );
if( r_testGamma.GetInteger() > 0 ) // test here so stack check isn't so damn slow on debug builds

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -174,6 +175,7 @@ static void R_AddSingleLight( viewLight_t* vLight )
break;
}
}
if( lightStageNum == lightShader->GetNumStages() )
{
// we went through all the stages and didn't find one that adds anything
@ -184,6 +186,7 @@ static void R_AddSingleLight( viewLight_t* vLight )
}
}
//--------------------------------------------
// copy data used by backend
//--------------------------------------------
@ -207,6 +210,13 @@ static void R_AddSingleLight( viewLight_t* vLight )
// copy the matrix for deforming the 'zeroOneCubeModel' to exactly cover the light volume in world space
vLight->inverseBaseLightProject = light->inverseBaseLightProject;
// RB begin
vLight->baseLightProject = light->baseLightProject;
vLight->pointLight = light->parms.pointLight;
vLight->parallel = light->parms.parallel;
vLight->lightCenter = light->parms.lightCenter;
// RB end
vLight->falloffImage = light->falloffImage;
vLight->lightShader = light->lightShader;
vLight->shaderRegisters = lightRegs;
@ -420,7 +430,7 @@ static void R_AddSingleLight( viewLight_t* vLight )
//--------------------------------------------
// add the prelight shadows for the static world geometry
//--------------------------------------------
if( light->parms.prelightModel != NULL )
if( light->parms.prelightModel != NULL && !r_useShadowMapping.GetBool() )
{
srfTriangles_t* tri = light->parms.prelightModel->Surface( 0 )->geometry;

View file

@ -685,6 +685,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
{
tri->indexCache = vertexCache.AllocIndex( tri->indexes, ALIGN( tri->numIndexes * sizeof( triIndex_t ), INDEX_CACHE_ALIGN ) );
}
if( !vertexCache.CacheIsCurrent( tri->ambientCache ) )
{
// we are going to use it for drawing, so make sure we have the tangents and normals
@ -925,7 +926,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
}
// if the static shadow does not have any shadows
if( surfInter != NULL && surfInter->numShadowIndexes == 0 )
if( surfInter != NULL && surfInter->numShadowIndexes == 0 && !r_useShadowMapping.GetBool() )
{
continue;
}
@ -942,6 +943,82 @@ void R_AddSingleModel( viewEntity_t* vEntity )
continue;
}
// RB begin
if( r_useShadowMapping.GetBool() )
{
//if( addInteractions && surfaceDirectlyVisible && shader->ReceivesLighting() )
{
// static interactions can commonly find that no triangles from a surface
// contact the light, even when the total model does
if( surfInter == NULL || surfInter->lightTrisIndexCache > 0 )
{
// create a drawSurf for this interaction
drawSurf_t* shadowDrawSurf = ( drawSurf_t* )R_FrameAlloc( sizeof( *shadowDrawSurf ), FRAME_ALLOC_DRAW_SURFACE );
if( surfInter != NULL )
{
// optimized static interaction
shadowDrawSurf->numIndexes = surfInter->numLightTrisIndexes;
shadowDrawSurf->indexCache = surfInter->lightTrisIndexCache;
}
else
{
// make sure we have an ambient cache and all necessary normals / tangents
if( !vertexCache.CacheIsCurrent( tri->indexCache ) )
{
tri->indexCache = vertexCache.AllocIndex( tri->indexes, ALIGN( tri->numIndexes * sizeof( triIndex_t ), INDEX_CACHE_ALIGN ) );
}
// throw the entire source surface at it without any per-triangle culling
shadowDrawSurf->numIndexes = tri->numIndexes;
shadowDrawSurf->indexCache = tri->indexCache;
}
if( !vertexCache.CacheIsCurrent( tri->ambientCache ) )
{
// we are going to use it for drawing, so make sure we have the tangents and normals
if( shader->ReceivesLighting() && !tri->tangentsCalculated )
{
assert( tri->staticModelWithJoints == NULL );
R_DeriveTangents( tri );
// RB: this was hit by parametric particle models ..
//assert( false ); // this should no longer be hit
// RB end
}
tri->ambientCache = vertexCache.AllocVertex( tri->verts, ALIGN( tri->numVerts * sizeof( idDrawVert ), VERTEX_CACHE_ALIGN ) );
}
shadowDrawSurf->ambientCache = tri->ambientCache;
shadowDrawSurf->shadowCache = 0;
shadowDrawSurf->frontEndGeo = tri;
shadowDrawSurf->space = vEntity;
shadowDrawSurf->material = shader;
shadowDrawSurf->extraGLState = 0;
shadowDrawSurf->scissorRect = vLight->scissorRect; // interactionScissor;
shadowDrawSurf->sort = 0.0f;
shadowDrawSurf->renderZFail = 0;
//shadowDrawSurf->shaderRegisters = baseDrawSurf->shaderRegisters;
R_SetupDrawSurfJoints( shadowDrawSurf, tri, shader );
// determine which linked list to add the shadow surface to
//shadowDrawSurf->linkChain = shader->TestMaterialFlag( MF_NOSELFSHADOW ) ? &vLight->localShadows : &vLight->globalShadows;
shadowDrawSurf->linkChain = &vLight->globalShadows;
shadowDrawSurf->nextOnLight = vEntity->drawSurfs;
vEntity->drawSurfs = shadowDrawSurf;
}
}
continue;
}
// RB end
if( lightDef->parms.prelightModel && lightDef->lightHasMoved == false &&
entityDef->parms.hModel->IsStaticWorldModel() && !r_skipPrelightShadows.GetBool() )
{

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -384,6 +385,69 @@ static void R_SortDrawSurfs( drawSurf_t** drawSurfs, const int numDrawSurfs )
#endif
}
// RB begin
static void R_SetupSplitFrustums( viewDef_t* viewDef )
{
idVec3 planeOrigin;
const float zNearStart = ( viewDef->renderView.cramZNear ) ? ( r_znear.GetFloat() * 0.25f ) : r_znear.GetFloat();
float zFarEnd = 10000;
float zNear = zNearStart;
float zFar = zFarEnd;
float lambda = r_shadowMapSplitWeight.GetFloat();
float ratio = zFarEnd / zNearStart;
for( int i = 0; i < 6; i++ )
{
tr.viewDef->frustumSplitDistances[i] = idMath::INFINITY;
}
for( int i = 1; i <= ( r_shadowMapSplits.GetInteger() + 1 ) && i < MAX_FRUSTUMS; i++ )
{
float si = i / ( float )( r_shadowMapSplits.GetInteger() + 1 );
if( i > FRUSTUM_CASCADE1 )
{
zNear = zFar - ( zFar * 0.005f );
}
zFar = 1.005f * lambda * ( zNearStart * powf( ratio, si ) ) + ( 1 - lambda ) * ( zNearStart + ( zFarEnd - zNearStart ) * si );
if( i <= r_shadowMapSplits.GetInteger() )
{
tr.viewDef->frustumSplitDistances[i - 1] = zFar;
}
float projectionMatrix[16];
R_SetupProjectionMatrix2( tr.viewDef, zNear, zFar, projectionMatrix );
// setup render matrices for faster culling
idRenderMatrix projectionRenderMatrix;
idRenderMatrix::Transpose( *( idRenderMatrix* )projectionMatrix, projectionRenderMatrix );
idRenderMatrix viewRenderMatrix;
idRenderMatrix::Transpose( *( idRenderMatrix* )tr.viewDef->worldSpace.modelViewMatrix, viewRenderMatrix );
idRenderMatrix::Multiply( projectionRenderMatrix, viewRenderMatrix, tr.viewDef->frustumMVPs[i] );
// the planes of the view frustum are needed for portal visibility culling
idRenderMatrix::GetFrustumPlanes( tr.viewDef->frustums[i], tr.viewDef->frustumMVPs[i], false, true );
// the DOOM 3 frustum planes point outside the frustum
for( int j = 0; j < 6; j++ )
{
tr.viewDef->frustums[i][j] = - tr.viewDef->frustums[i][j];
}
// remove the Z-near to avoid portals from being near clipped
if( i == FRUSTUM_CASCADE1 )
{
tr.viewDef->frustums[i][4][3] -= r_znear.GetFloat();
}
}
}
// RB end
/*
================
R_RenderView
@ -415,15 +479,19 @@ void R_RenderView( viewDef_t* parms )
idRenderMatrix::Multiply( tr.viewDef->projectionRenderMatrix, viewRenderMatrix, tr.viewDef->worldSpace.mvp );
// the planes of the view frustum are needed for portal visibility culling
idRenderMatrix::GetFrustumPlanes( tr.viewDef->frustum, tr.viewDef->worldSpace.mvp, false, true );
idRenderMatrix::GetFrustumPlanes( tr.viewDef->frustums[FRUSTUM_PRIMARY], tr.viewDef->worldSpace.mvp, false, true );
// the DOOM 3 frustum planes point outside the frustum
for( int i = 0; i < 6; i++ )
{
tr.viewDef->frustum[i] = - tr.viewDef->frustum[i];
tr.viewDef->frustums[FRUSTUM_PRIMARY][i] = - tr.viewDef->frustums[FRUSTUM_PRIMARY][i];
}
// remove the Z-near to avoid portals from being near clipped
tr.viewDef->frustum[4][3] -= r_znear.GetFloat();
tr.viewDef->frustums[FRUSTUM_PRIMARY][4][3] -= r_znear.GetFloat();
// RB begin
R_SetupSplitFrustums( tr.viewDef );
// RB end
// identify all the visible portal areas, and create view lights and view entities
// for all the the entityDefs and lightDefs that are in the visible portal areas

View file

@ -194,7 +194,7 @@ bool R_PreciseCullSurface( const drawSurf_t* drawSurf, idBounds& ndcBounds )
for( int j = 0; j < 4; j++ )
{
if( !w.ClipInPlace( -tr.viewDef->frustum[j], 0.1f ) )
if( !w.ClipInPlace( -tr.viewDef->frustums[FRUSTUM_PRIMARY][j], 0.1f ) )
{
break;
}

View file

@ -3,7 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2012 Robert Beckebans
Copyright (C) 2012-2014 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -36,8 +36,8 @@ If you have questions concerning this license or the applicable additional terms
#include "ScreenRect.h"
#include "ImageOpts.h"
#include "Image.h"
#include "RenderTexture.h"
#include "Font.h"
#include "Framebuffer.h"
// everything that is needed by the backend needs
// to be double buffered to allow it to run in
@ -318,6 +318,12 @@ struct viewLight_t
idVec3 globalLightOrigin; // global light origin used by backend
idPlane lightProject[4]; // light project used by backend
idPlane fogPlane; // fog plane for backend fog volume rendering
// RB: added for shadow mapping
idRenderMatrix baseLightProject; // global xyz1 to projected light strq
bool pointLight; // otherwise a projection light (should probably invert the sense of this, because points are way more common)
bool parallel; // lightCenter gives the direction to the light at infinity
idVec3 lightCenter; // offset the lighting direction for shading and
// RB end
idRenderMatrix inverseBaseLightProject; // the matrix for deforming the 'zeroOneCubeModel' to exactly cover the light volume in world space
const idMaterial* lightShader; // light shader used by backend
const float* shaderRegisters; // shader registers used by backend
@ -377,6 +383,33 @@ struct viewEntity_t
const int MAX_CLIP_PLANES = 1; // we may expand this to six for some subview issues
// RB: added multiple subfrustums for cascaded shadow mapping
enum frustumPlanes_t
{
FRUSTUM_PLANE_LEFT,
FRUSTUM_PLANE_RIGHT,
FRUSTUM_PLANE_BOTTOM,
FRUSTUM_PLANE_TOP,
FRUSTUM_PLANE_NEAR,
FRUSTUM_PLANE_FAR,
FRUSTUM_PLANES = 6,
FRUSTUM_CLIPALL = 1 | 2 | 4 | 8 | 16 | 32
};
enum
{
FRUSTUM_PRIMARY,
FRUSTUM_CASCADE1,
FRUSTUM_CASCADE2,
FRUSTUM_CASCADE3,
FRUSTUM_CASCADE4,
FRUSTUM_CASCADE5,
MAX_FRUSTUMS,
};
typedef idPlane frustum_t[FRUSTUM_PLANES];
// RB end
// viewDefs are allocated on the frame temporary stack memory
struct viewDef_t
{
@ -432,7 +465,11 @@ struct viewDef_t
// of 2D rendering, which we can optimize in certain ways. A 2D view will
// not have any viewEntities
idPlane frustum[6]; // positive sides face outward, [4] is the front clip plane
// RB begin
frustum_t frustums[MAX_FRUSTUMS]; // positive sides face outward, [4] is the front clip plane
float frustumSplitDistances[MAX_FRUSTUMS];
idRenderMatrix frustumMVPs[MAX_FRUSTUMS];
// RB end
int areaNum; // -1 = not in a valid area
@ -623,6 +660,7 @@ struct performanceCounters_t
struct tmu_t
{
unsigned int current2DMap;
unsigned int current2DArray;
unsigned int currentCubeMap;
};
@ -650,6 +688,8 @@ struct glstate_t
// RB: 64 bit fixes, changed unsigned int to uintptr_t
uintptr_t currentVertexBuffer;
uintptr_t currentIndexBuffer;
Framebuffer* currentFramebuffer;
// RB end
float polyOfsScale;
@ -692,6 +732,11 @@ struct backEndState_t
idRenderMatrix prevMVP[2]; // world MVP from previous frame for motion blur, per-eye
// RB begin
idRenderMatrix shadowV[6]; // shadow depth view matrix
idRenderMatrix shadowP[6]; // shadow depth projection matrix
// RB end
// surfaces used for code-based drawing
drawSurf_t unitSquareSurface;
drawSurf_t zeroOneCubeSurface;
@ -910,6 +955,9 @@ extern idCVar r_useEntityCallbacks; // if 0, issue the callback immediately at
extern idCVar r_lightAllBackFaces; // light all the back faces, even when they would be shadowed
extern idCVar r_useLightDepthBounds; // use depth bounds test on lights to reduce both shadow and interaction fill
extern idCVar r_useShadowDepthBounds; // use depth bounds test on individual shadows to reduce shadow fill
// RB begin
extern idCVar r_useShadowMapping; // use shadow mapping instead of stencil shadows
// RB end
extern idCVar r_skipStaticInteractions; // skip interactions created at level load
extern idCVar r_skipDynamicInteractions; // skip interactions created after level load
@ -972,6 +1020,9 @@ extern idCVar r_showPrimitives; // report vertex/index/draw counts
extern idCVar r_showPortals; // draw portal outlines in color based on passed / not passed
extern idCVar r_showSkel; // draw the skeleton when model animates
extern idCVar r_showOverDraw; // show overdraw
// RB begin
extern idCVar r_showShadowMaps;
// RB end
extern idCVar r_jointNameScale; // size of joint names when r_showskel is set to 1
extern idCVar r_jointNameOffset; // offset of joint names when r_showskel is set to 1
@ -1001,6 +1052,17 @@ extern idCVar stereoRender_deGhost; // subtract from opposite eye to reduce gh
extern idCVar r_useGPUSkinning;
// RB begin
extern idCVar r_shadowMapFrustumFOV;
extern idCVar r_shadowMapSingleSide;
extern idCVar r_shadowMapImageSize;
extern idCVar r_shadowMapJitterScale;
extern idCVar r_shadowMapBiasScale;
extern idCVar r_shadowMapSamples;
extern idCVar r_shadowMapSplits;
extern idCVar r_shadowMapSplitWeight;
// RB end
/*
====================================================================
@ -1109,6 +1171,14 @@ void R_FreeEntityDefDecals( idRenderEntityLocal* def );
void R_FreeEntityDefOverlay( idRenderEntityLocal* def );
void R_FreeEntityDefFadedDecals( idRenderEntityLocal* def, int time );
// RB: for dmap
void R_DeriveLightData( idRenderLightLocal* light );
// Called by the editor and dmap to operate on light volumes
void R_RenderLightFrustum( const renderLight_t& renderLight, idPlane lightFrustum[6] );
srfTriangles_t* R_PolytopeSurface( int numPlanes, const idPlane* planes, idWinding** windings );
// RB end
void R_CreateLightRefs( idRenderLightLocal* light );
void R_FreeLightDefDerivedData( idRenderLightLocal* light );
@ -1352,6 +1422,7 @@ TR_BACKEND_DRAW
============================================================
*/
void RB_SetMVP( const idRenderMatrix& mvp );
void RB_DrawElementsWithCounters( const drawSurf_t* surf );
void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye );
void RB_DrawView( const void* data, const int stereoEye );
@ -1387,8 +1458,8 @@ void RB_ShutdownDebugTools();
#include "ResolutionScale.h"
#include "RenderLog.h"
#include "AutoRender.h"
#include "AutoRenderBink.h"
//#include "AutoRender.h"
//#include "AutoRenderBink.h"
#include "jobs/ShadowShared.h"
#include "jobs/prelightshadowvolume/PreLightShadowVolume.h"
#include "jobs/staticshadowvolume/StaticShadowVolume.h"