mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-05-30 16:31:10 +00:00
Merge branch 'IBL-environment-probes2' into vulkan
This commit is contained in:
commit
d4576f7cc5
36 changed files with 2666 additions and 46 deletions
|
@ -78,7 +78,6 @@ _______________________________
|
|||
|
||||
- Enhanced Subpixel Morphological Antialiasing
|
||||
For more information see "Anti-Aliasing Methods in CryENGINE 3" and the docs at http://www.iryoku.com/smaa/
|
||||
|
||||
- Filmic post process effects like Technicolor color grading and film grain
|
||||
|
||||
- Fixed issues with Mesa drivers and allowed them to use shadow mapping
|
||||
|
|
|
@ -60,6 +60,11 @@ half3 Fresnel_Schlick( half3 specularColor, half vdotH )
|
|||
return specularColor + ( 1.0 - specularColor ) * pow( 1.0 - vdotH, 5.0 );
|
||||
}
|
||||
|
||||
half3 Fresnel_Glossy( half3 specularColor, half roughness, half vdotH )
|
||||
{
|
||||
return specularColor + ( max( half3( 1.0 - roughness ), specularColor ) - specularColor ) * pow( 1.0 - vdotH, 5.0 );
|
||||
}
|
||||
|
||||
// Visibility term G( l, v, h )
|
||||
// Very similar to Marmoset Toolbag 2 and gives almost the same results as Smith GGX
|
||||
float Visibility_Schlick( half vdotN, half ldotN, float alpha )
|
||||
|
|
|
@ -9,6 +9,8 @@ return
|
|||
-- shaders
|
||||
"ambient_lighting.ps.hlsl",
|
||||
"ambient_lighting.vs.hlsl",
|
||||
"ambient_lighting_IBL.ps.hlsl",
|
||||
"ambient_lighting_IBL.vs.hlsl",
|
||||
"AmbientOcclusion_AO.ps.hlsl",
|
||||
"AmbientOcclusion_AO.vs.hlsl",
|
||||
"AmbientOcclusion_blur.ps.hlsl",
|
||||
|
|
179
base/renderprogs/ambient_lighting_IBL.ps.hlsl
Normal file
179
base/renderprogs/ambient_lighting_IBL.ps.hlsl
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013-2019 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 "global.inc.hlsl"
|
||||
#include "BRDF.inc.hlsl"
|
||||
|
||||
uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map
|
||||
uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map
|
||||
uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map
|
||||
uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture
|
||||
uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture
|
||||
|
||||
uniform samplerCUBE samp7 : register(s7); // texture 0 is the cube map
|
||||
uniform samplerCUBE samp8 : register(s8); // texture 0 is the cube 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.texcoord0.xy );
|
||||
// half4 lightFalloff = idtex2Dproj( samp1, fragment.texcoord2 );
|
||||
// half4 lightProj = idtex2Dproj( samp2, fragment.texcoord3 );
|
||||
half4 YCoCG = tex2D( samp2, fragment.texcoord1.xy );
|
||||
half4 specMap = tex2D( samp1, fragment.texcoord2.xy );
|
||||
|
||||
//half3 lightVector = normalize( fragment.texcoord0.xyz );
|
||||
half3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );
|
||||
|
||||
half3 localNormal;
|
||||
#if defined(USE_NORMAL_FMT_RGB8)
|
||||
localNormal.xy = bumpMap.rg - 0.5;
|
||||
#else
|
||||
localNormal.xy = bumpMap.wy - 0.5;
|
||||
#endif
|
||||
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 );
|
||||
// RB: added abs
|
||||
//half3 specularContribution = _half3( pow( abs( hDotN ), specularPower ) );
|
||||
|
||||
//half3 diffuseColor = diffuseMap * ( rpDiffuseModifier.xyz ) * 1.5f;
|
||||
//half3 specularColor = specMap.xyz * specularContribution * ( rpSpecularModifier.xyz );
|
||||
|
||||
// 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 );
|
||||
|
||||
float3 globalNormal;
|
||||
globalNormal.x = dot3( localNormal, fragment.texcoord4 );
|
||||
globalNormal.y = dot3( localNormal, fragment.texcoord5 );
|
||||
globalNormal.z = dot3( localNormal, fragment.texcoord6 );
|
||||
|
||||
float3 globalEye = normalize( fragment.texcoord3.xyz );
|
||||
|
||||
float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );
|
||||
reflectionVector = ( reflectionVector * 2.0f ) - globalEye;
|
||||
|
||||
#if defined(USE_PBR)
|
||||
|
||||
const half metallic = specMap.g;
|
||||
const half roughness = specMap.r;
|
||||
const half glossiness = 1.0 - roughness;
|
||||
|
||||
// the vast majority of real-world materials (anything not metal or gems) have F(0°)
|
||||
// values in a very narrow range (~0.02 - 0.08)
|
||||
|
||||
// approximate non-metals with linear RGB 0.04 which is 0.08 * 0.5 (default in UE4)
|
||||
const half3 dielectricColor = half3( 0.04 );
|
||||
|
||||
// derive diffuse and specular from albedo(m) base color
|
||||
const half3 baseColor = diffuseMap;
|
||||
|
||||
half3 diffuseColor = baseColor * ( 1.0 - metallic );
|
||||
half3 specularColor = lerp( dielectricColor, baseColor, metallic );
|
||||
|
||||
//diffuseColor = half3( 1.0 );
|
||||
float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseColor * ( rpDiffuseModifier.xyz ) * 1.5f;
|
||||
|
||||
//specularColor = half3( 0.0 );
|
||||
|
||||
float mip = clamp( ( roughness * 7.0 ) + 3.0, 0.0, 10.0 );
|
||||
float3 envColor = ( textureLod( samp8, reflectionVector, mip ).rgb ) * ( rpSpecularModifier.xyz ) * 1.0f;
|
||||
|
||||
float3 specularLight = envColor * specularColor;
|
||||
|
||||
#else
|
||||
|
||||
half4 specMapSRGB = specMap;
|
||||
specMap = sRGBAToLinearRGBA( specMap );
|
||||
|
||||
//float3 diffuseLight = sRGBToLinearRGB( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;
|
||||
float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;
|
||||
//float3 diffuseLight = diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 1.5f;
|
||||
|
||||
// HACK calculate roughness from D3 gloss maps
|
||||
float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );
|
||||
|
||||
//const float glossiness = clamp( 1.0 - specMapSRGB.r, 0.0, 0.98 );
|
||||
const float glossiness = clamp( pow( Y, 1.0 / 2.0 ), 0.0, 0.98 );
|
||||
|
||||
const float roughness = 1.0 - glossiness;
|
||||
|
||||
float mip = clamp( ( roughness * 7.0 ) + 0.0, 0.0, 10.0 );
|
||||
float3 envColor = ( textureLod( samp8, reflectionVector, mip ).rgb ) * ( rpSpecularModifier.xyz ) * 0.5f;
|
||||
|
||||
float3 specularLight = envColor * specMap.rgb;
|
||||
|
||||
#endif
|
||||
|
||||
// add glossy fresnel
|
||||
half hDotN = saturate( dot3( globalEye, globalNormal ) );
|
||||
|
||||
half3 specularColor2 = half3( 0.0 );
|
||||
float3 glossyFresnel = Fresnel_Glossy( specularColor2, roughness, hDotN );
|
||||
|
||||
// horizon fade
|
||||
const half horizonFade = 1.3;
|
||||
half horiz = saturate( 1.0 + horizonFade * saturate( dot3( reflectionVector, globalNormal ) ) );
|
||||
horiz *= horiz;
|
||||
//horiz = clamp( horiz, 0.0, 1.0 );
|
||||
|
||||
//specularLight = glossyFresnel * envColor;
|
||||
specularLight += glossyFresnel * envColor * ( rpSpecularModifier.xyz ) * 0.9 * horiz;
|
||||
|
||||
half3 lightColor = sRGBToLinearRGB( rpAmbientColor.rgb );
|
||||
|
||||
//result.color.rgb = diffuseLight;
|
||||
//result.color.rgb = diffuseLight * lightColor;
|
||||
//result.color.rgb = specularLight;
|
||||
result.color.rgb = ( diffuseLight + specularLight ) * lightColor * fragment.color.rgb;
|
||||
//result.color.rgb = localNormal.xyz * 0.5 + 0.5;
|
||||
//result.color.xyz = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor ) * fragment.color.rgb;
|
||||
//result.color = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor + rimColor ) * fragment.color.rgba;
|
||||
result.color.w = fragment.color.a;
|
||||
}
|
186
base/renderprogs/ambient_lighting_IBL.vs.hlsl
Normal file
186
base/renderprogs/ambient_lighting_IBL.vs.hlsl
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013-2015 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 "global.inc.hlsl"
|
||||
|
||||
#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;
|
||||
float4 texcoord0 : TEXCOORD0;
|
||||
float4 texcoord1 : TEXCOORD1;
|
||||
float4 texcoord2 : TEXCOORD2;
|
||||
float4 texcoord3 : TEXCOORD3;
|
||||
float4 texcoord4 : TEXCOORD4;
|
||||
float4 texcoord5 : TEXCOORD5;
|
||||
float4 texcoord6 : TEXCOORD6;
|
||||
float4 color : COLOR0;
|
||||
};
|
||||
|
||||
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 vBitangent = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;
|
||||
|
||||
#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
|
||||
int joint = int(vertex.color.x * 255.1 * 3.0);
|
||||
matX = matrices[int(joint+0)] * w0;
|
||||
matY = matrices[int(joint+1)] * w0;
|
||||
matZ = matrices[int(joint+2)] * w0;
|
||||
|
||||
joint = int(vertex.color.y * 255.1 * 3.0);
|
||||
matX += matrices[int(joint+0)] * w1;
|
||||
matY += matrices[int(joint+1)] * w1;
|
||||
matZ += matrices[int(joint+2)] * w1;
|
||||
|
||||
joint = int(vertex.color.z * 255.1 * 3.0);
|
||||
matX += matrices[int(joint+0)] * w2;
|
||||
matY += matrices[int(joint+1)] * w2;
|
||||
matZ += matrices[int(joint+2)] * w2;
|
||||
|
||||
joint = int(vertex.color.w * 255.1 * 3.0);
|
||||
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
|
||||
//float4 toLight = rpLocalLightOrigin;
|
||||
float4 toLight = normalize( float4( 0.0f, 0.5f, 1.0f, 1.0f ) );
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
|
||||
//# textures 0 takes the base coordinates by the texture matrix
|
||||
result.texcoord0 = defaultTexCoord;
|
||||
result.texcoord0.x = dot4( vertex.texcoord.xy, rpBumpMatrixS );
|
||||
result.texcoord0.y = dot4( vertex.texcoord.xy, rpBumpMatrixT );
|
||||
|
||||
//# textures 1 takes the base coordinates by the texture matrix
|
||||
result.texcoord1 = defaultTexCoord;
|
||||
result.texcoord1.x = dot4( vertex.texcoord.xy, rpDiffuseMatrixS );
|
||||
result.texcoord1.y = dot4( vertex.texcoord.xy, rpDiffuseMatrixT );
|
||||
|
||||
//# textures 2 takes the base coordinates by the texture matrix
|
||||
result.texcoord2 = defaultTexCoord;
|
||||
result.texcoord2.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );
|
||||
result.texcoord2.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );
|
||||
|
||||
//# calculate normalized vector to viewer in R1
|
||||
float4 toEye = normalize( rpLocalViewOrigin - modelPosition );
|
||||
|
||||
result.texcoord3.x = dot3( toEye, rpModelMatrixX );
|
||||
result.texcoord3.y = dot3( toEye, rpModelMatrixY );
|
||||
result.texcoord3.z = dot3( toEye, rpModelMatrixZ );
|
||||
|
||||
result.texcoord4.x = dot3( tangent, rpModelMatrixX );
|
||||
result.texcoord5.x = dot3( tangent, rpModelMatrixY );
|
||||
result.texcoord6.x = dot3( tangent, rpModelMatrixZ );
|
||||
|
||||
result.texcoord4.y = dot3( bitangent, rpModelMatrixX );
|
||||
result.texcoord5.y = dot3( bitangent, rpModelMatrixY );
|
||||
result.texcoord6.y = dot3( bitangent, rpModelMatrixZ );
|
||||
|
||||
result.texcoord4.z = dot3( normal, rpModelMatrixX );
|
||||
result.texcoord5.z = dot3( normal, rpModelMatrixY );
|
||||
result.texcoord6.z = dot3( normal, rpModelMatrixZ );
|
||||
|
||||
#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
|
||||
}
|
|
@ -115,7 +115,11 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
|
||||
#if OPERATOR == 0
|
||||
// advanced Reinhard operator, artistically desirable to burn out bright areas
|
||||
float L = Yr * ( 1.0 + Yr / ( Ymax * Ymax ) ) / ( 1.0 + Yr );
|
||||
//float L = Yr * ( 1.0 + Yr / ( Ymax * Ymax ) ) / ( 1.0 + Yr );
|
||||
|
||||
// exponential tone mapper that is very similar to the Uncharted one
|
||||
// very good in keeping the colors natural
|
||||
float L = 1.0 - exp( -Yr );
|
||||
color.rgb *= L;
|
||||
|
||||
#elif OPERATOR == 1
|
||||
|
|
|
@ -637,6 +637,7 @@ set(GAMED3XP_INCLUDES
|
|||
d3xp/Camera.h
|
||||
#d3xp/EndLevel.h
|
||||
d3xp/Entity.h
|
||||
d3xp/EnvironmentProbe.h
|
||||
d3xp/Fx.h
|
||||
d3xp/Game.h
|
||||
d3xp/GameEdit.h
|
||||
|
@ -674,6 +675,7 @@ set(GAMED3XP_SOURCES
|
|||
d3xp/Camera.cpp
|
||||
#d3xp/EndLevel.cpp
|
||||
d3xp/Entity.cpp
|
||||
d3xp/EnvironmentProbe.cpp
|
||||
d3xp/Fx.cpp
|
||||
d3xp/GameEdit.cpp
|
||||
d3xp/Game_local.cpp
|
||||
|
|
940
neo/d3xp/EnvironmentProbe.cpp
Normal file
940
neo/d3xp/EnvironmentProbe.cpp
Normal file
|
@ -0,0 +1,940 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2015 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 "Game_local.h"
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
idLight
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
const idEventDef EV_Envprobe_GetEnvprobeParm( "getEnvprobeParm", "d", 'f' );
|
||||
const idEventDef EV_Envprobe_SetEnvprobeParm( "setEnvprobeParm", "df" );
|
||||
const idEventDef EV_Envprobe_SetEnvprobeParms( "setEnvprobeParms", "ffff" );
|
||||
//const idEventDef EV_Envprobe_SetRadiusXYZ( "setRadiusXYZ", "fff" );
|
||||
//const idEventDef EV_Envprobe_SetRadius( "setRadius", "f" );
|
||||
const idEventDef EV_Envprobe_On( "On", NULL );
|
||||
const idEventDef EV_Envprobe_Off( "Off", NULL );
|
||||
const idEventDef EV_Envprobe_FadeOut( "fadeOutEnvprobe", "f" );
|
||||
const idEventDef EV_Envprobe_FadeIn( "fadeInEnvprobe", "f" );
|
||||
|
||||
CLASS_DECLARATION( idEntity, EnvironmentProbe )
|
||||
EVENT( EV_Envprobe_GetEnvprobeParm, EnvironmentProbe::Event_GetEnvprobeParm )
|
||||
EVENT( EV_Envprobe_SetEnvprobeParm, EnvironmentProbe::Event_SetEnvprobeParm )
|
||||
EVENT( EV_Envprobe_SetEnvprobeParms, EnvironmentProbe::Event_SetEnvprobeParms )
|
||||
//EVENT( EV_Envprobe_SetRadiusXYZ, EnvironmentProbe::Event_SetRadiusXYZ )
|
||||
//EVENT( EV_Envprobe_SetRadius, EnvironmentProbe::Event_SetRadius )
|
||||
EVENT( EV_Hide, EnvironmentProbe::Event_Hide )
|
||||
EVENT( EV_Show, EnvironmentProbe::Event_Show )
|
||||
EVENT( EV_Envprobe_On, EnvironmentProbe::Event_On )
|
||||
EVENT( EV_Envprobe_Off, EnvironmentProbe::Event_Off )
|
||||
EVENT( EV_Activate, EnvironmentProbe::Event_ToggleOnOff )
|
||||
//EVENT( EV_PostSpawn, EnvironmentProbe::Event_SetSoundHandles )
|
||||
EVENT( EV_Envprobe_FadeOut, EnvironmentProbe::Event_FadeOut )
|
||||
EVENT( EV_Envprobe_FadeIn, EnvironmentProbe::Event_FadeIn )
|
||||
END_CLASS
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
idGameEdit::ParseSpawnArgsToRenderLight
|
||||
|
||||
parse the light parameters
|
||||
this is the canonical renderLight parm parsing,
|
||||
which should be used by dmap and the editor
|
||||
================
|
||||
*/
|
||||
void idGameEdit::ParseSpawnArgsToRenderEnvprobe( const idDict* args, renderEnvironmentProbe_t* renderEnvprobe )
|
||||
{
|
||||
idVec3 color;
|
||||
|
||||
memset( renderEnvprobe, 0, sizeof( *renderEnvprobe ) );
|
||||
|
||||
if( !args->GetVector( "light_origin", "", renderEnvprobe->origin ) )
|
||||
{
|
||||
args->GetVector( "origin", "", renderEnvprobe->origin );
|
||||
}
|
||||
|
||||
// check for other attributes
|
||||
args->GetVector( "_color", "1 1 1", color );
|
||||
renderEnvprobe->shaderParms[ SHADERPARM_RED ] = color[0];
|
||||
renderEnvprobe->shaderParms[ SHADERPARM_GREEN ] = color[1];
|
||||
renderEnvprobe->shaderParms[ SHADERPARM_BLUE ] = color[2];
|
||||
args->GetFloat( "shaderParm3", "1", renderEnvprobe->shaderParms[ SHADERPARM_TIMESCALE ] );
|
||||
if( !args->GetFloat( "shaderParm4", "0", renderEnvprobe->shaderParms[ SHADERPARM_TIMEOFFSET ] ) )
|
||||
{
|
||||
// offset the start time of the shader to sync it to the game time
|
||||
renderEnvprobe->shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time );
|
||||
}
|
||||
|
||||
args->GetFloat( "shaderParm5", "0", renderEnvprobe->shaderParms[5] );
|
||||
args->GetFloat( "shaderParm6", "0", renderEnvprobe->shaderParms[6] );
|
||||
args->GetFloat( "shaderParm7", "0", renderEnvprobe->shaderParms[ SHADERPARM_MODE ] );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::UpdateChangeableSpawnArgs
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::UpdateChangeableSpawnArgs( const idDict* source )
|
||||
{
|
||||
idEntity::UpdateChangeableSpawnArgs( source );
|
||||
|
||||
if( source )
|
||||
{
|
||||
source->Print();
|
||||
}
|
||||
|
||||
gameEdit->ParseSpawnArgsToRenderEnvprobe( source ? source : &spawnArgs, &renderEnvprobe );
|
||||
|
||||
UpdateVisuals();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::EnvironmentProbe
|
||||
================
|
||||
*/
|
||||
EnvironmentProbe::EnvironmentProbe():
|
||||
previousBaseColor( vec3_zero ) ,
|
||||
nextBaseColor( vec3_zero )
|
||||
{
|
||||
memset( &renderEnvprobe, 0, sizeof( renderEnvprobe ) );
|
||||
localEnvprobeOrigin = vec3_zero;
|
||||
localEnvprobeAxis = mat3_identity;
|
||||
envprobeDefHandle = -1;
|
||||
levels = 0;
|
||||
currentLevel = 0;
|
||||
baseColor = vec3_zero;
|
||||
count = 0;
|
||||
triggercount = 0;
|
||||
lightParent = NULL;
|
||||
fadeFrom.Set( 1, 1, 1, 1 );
|
||||
fadeTo.Set( 1, 1, 1, 1 );
|
||||
fadeStart = 0;
|
||||
fadeEnd = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::~idLight
|
||||
================
|
||||
*/
|
||||
EnvironmentProbe::~EnvironmentProbe()
|
||||
{
|
||||
if( envprobeDefHandle != -1 )
|
||||
{
|
||||
gameRenderWorld->FreeEnvprobeDef( envprobeDefHandle );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Save
|
||||
|
||||
archives object for save game file
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Save( idSaveGame* savefile ) const
|
||||
{
|
||||
savefile->WriteRenderEnvprobe( renderEnvprobe );
|
||||
|
||||
savefile->WriteVec3( localEnvprobeOrigin );
|
||||
savefile->WriteMat3( localEnvprobeAxis );
|
||||
|
||||
savefile->WriteInt( levels );
|
||||
savefile->WriteInt( currentLevel );
|
||||
|
||||
savefile->WriteVec3( baseColor );
|
||||
savefile->WriteInt( count );
|
||||
savefile->WriteInt( triggercount );
|
||||
savefile->WriteObject( lightParent );
|
||||
|
||||
savefile->WriteVec4( fadeFrom );
|
||||
savefile->WriteVec4( fadeTo );
|
||||
savefile->WriteInt( fadeStart );
|
||||
savefile->WriteInt( fadeEnd );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Restore
|
||||
|
||||
unarchives object from save game file
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Restore( idRestoreGame* savefile )
|
||||
{
|
||||
savefile->ReadRenderEnvprobe( renderEnvprobe );
|
||||
|
||||
savefile->ReadVec3( localEnvprobeOrigin );
|
||||
savefile->ReadMat3( localEnvprobeAxis );
|
||||
|
||||
savefile->ReadInt( levels );
|
||||
savefile->ReadInt( currentLevel );
|
||||
|
||||
savefile->ReadVec3( baseColor );
|
||||
savefile->ReadInt( count );
|
||||
savefile->ReadInt( triggercount );
|
||||
savefile->ReadObject( reinterpret_cast<idClass*&>( lightParent ) );
|
||||
|
||||
savefile->ReadVec4( fadeFrom );
|
||||
savefile->ReadVec4( fadeTo );
|
||||
savefile->ReadInt( fadeStart );
|
||||
savefile->ReadInt( fadeEnd );
|
||||
|
||||
envprobeDefHandle = -1;
|
||||
|
||||
SetLightLevel();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Spawn
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Spawn()
|
||||
{
|
||||
bool start_off;
|
||||
|
||||
// do the parsing the same way dmap and the editor do
|
||||
gameEdit->ParseSpawnArgsToRenderEnvprobe( &spawnArgs, &renderEnvprobe );
|
||||
|
||||
// we need the origin and axis relative to the physics origin/axis
|
||||
localEnvprobeOrigin = ( renderEnvprobe.origin - GetPhysics()->GetOrigin() ) * GetPhysics()->GetAxis().Transpose();
|
||||
localEnvprobeAxis = /*renderEnvprobe.axis * */ GetPhysics()->GetAxis().Transpose();
|
||||
|
||||
// set the base color from the shader parms
|
||||
baseColor.Set( renderEnvprobe.shaderParms[ SHADERPARM_RED ], renderEnvprobe.shaderParms[ SHADERPARM_GREEN ], renderEnvprobe.shaderParms[ SHADERPARM_BLUE ] );
|
||||
previousBaseColor.Set( renderEnvprobe.shaderParms[ SHADERPARM_RED ], renderEnvprobe.shaderParms[ SHADERPARM_GREEN ], renderEnvprobe.shaderParms[ SHADERPARM_BLUE ] );
|
||||
nextBaseColor.Set( renderEnvprobe.shaderParms[ SHADERPARM_RED ], renderEnvprobe.shaderParms[ SHADERPARM_GREEN ], renderEnvprobe.shaderParms[ SHADERPARM_BLUE ] );
|
||||
|
||||
// set the number of light levels
|
||||
spawnArgs.GetInt( "levels", "1", levels );
|
||||
currentLevel = levels;
|
||||
if( levels <= 0 )
|
||||
{
|
||||
gameLocal.Error( "Invalid light level set on entity #%d(%s)", entityNumber, name.c_str() );
|
||||
}
|
||||
|
||||
// game specific functionality, not mirrored in
|
||||
// editor or dmap light parsing
|
||||
|
||||
envprobeDefHandle = -1; // no static version yet
|
||||
|
||||
spawnArgs.GetBool( "start_off", "0", start_off );
|
||||
if( start_off )
|
||||
{
|
||||
Off();
|
||||
}
|
||||
|
||||
// Midnight CTF
|
||||
if( gameLocal.mpGame.IsGametypeFlagBased() && gameLocal.serverInfo.GetBool( "si_midnight" ) && !spawnArgs.GetBool( "midnight_override" ) )
|
||||
{
|
||||
Off();
|
||||
}
|
||||
|
||||
health = spawnArgs.GetInt( "health", "0" );
|
||||
spawnArgs.GetInt( "count", "1", count );
|
||||
|
||||
triggercount = 0;
|
||||
|
||||
fadeFrom.Set( 1, 1, 1, 1 );
|
||||
fadeTo.Set( 1, 1, 1, 1 );
|
||||
fadeStart = 0;
|
||||
fadeEnd = 0;
|
||||
|
||||
PostEventMS( &EV_PostSpawn, 0 );
|
||||
|
||||
UpdateVisuals();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::SetLightLevel
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::SetLightLevel()
|
||||
{
|
||||
idVec3 color;
|
||||
float intensity;
|
||||
|
||||
intensity = ( float )currentLevel / ( float )levels;
|
||||
color = baseColor * intensity;
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_RED ] = color[ 0 ];
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_GREEN ] = color[ 1 ];
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_BLUE ] = color[ 2 ];
|
||||
|
||||
PresentEnvprobeDefChange();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::GetColor
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::GetColor( idVec3& out ) const
|
||||
{
|
||||
out[ 0 ] = renderEnvprobe.shaderParms[ SHADERPARM_RED ];
|
||||
out[ 1 ] = renderEnvprobe.shaderParms[ SHADERPARM_GREEN ];
|
||||
out[ 2 ] = renderEnvprobe.shaderParms[ SHADERPARM_BLUE ];
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::GetColor
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::GetColor( idVec4& out ) const
|
||||
{
|
||||
out[ 0 ] = renderEnvprobe.shaderParms[ SHADERPARM_RED ];
|
||||
out[ 1 ] = renderEnvprobe.shaderParms[ SHADERPARM_GREEN ];
|
||||
out[ 2 ] = renderEnvprobe.shaderParms[ SHADERPARM_BLUE ];
|
||||
out[ 3 ] = renderEnvprobe.shaderParms[ SHADERPARM_ALPHA ];
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::SetColor
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::SetColor( float red, float green, float blue )
|
||||
{
|
||||
baseColor.Set( red, green, blue );
|
||||
SetLightLevel();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::SetColor
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::SetColor( const idVec4& color )
|
||||
{
|
||||
baseColor = color.ToVec3();
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_ALPHA ] = color[ 3 ];
|
||||
SetLightLevel();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::SetColor
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::SetColor( const idVec3& color )
|
||||
{
|
||||
baseColor = color;
|
||||
SetLightLevel();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::SetEnvprobeParm
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::SetEnvprobeParm( int parmnum, float value )
|
||||
{
|
||||
if( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) )
|
||||
{
|
||||
gameLocal.Error( "shader parm index (%d) out of range", parmnum );
|
||||
return;
|
||||
}
|
||||
|
||||
renderEnvprobe.shaderParms[ parmnum ] = value;
|
||||
PresentEnvprobeDefChange();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::SetEnvprobeParms
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::SetEnvprobeParms( float parm0, float parm1, float parm2, float parm3 )
|
||||
{
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_RED ] = parm0;
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_GREEN ] = parm1;
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_BLUE ] = parm2;
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_ALPHA ] = parm3;
|
||||
PresentEnvprobeDefChange();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::On
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::On()
|
||||
{
|
||||
currentLevel = levels;
|
||||
// offset the start time of the shader to sync it to the game time
|
||||
renderEnvprobe.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time );
|
||||
|
||||
SetLightLevel();
|
||||
BecomeActive( TH_UPDATEVISUALS );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Off
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Off()
|
||||
{
|
||||
currentLevel = 0;
|
||||
|
||||
SetLightLevel();
|
||||
BecomeActive( TH_UPDATEVISUALS );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Fade
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Fade( const idVec4& to, float fadeTime )
|
||||
{
|
||||
GetColor( fadeFrom );
|
||||
fadeTo = to;
|
||||
fadeStart = gameLocal.time;
|
||||
fadeEnd = gameLocal.time + SEC2MS( fadeTime );
|
||||
BecomeActive( TH_THINK );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::FadeOut
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::FadeOut( float time )
|
||||
{
|
||||
Fade( colorBlack, time );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::FadeIn
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::FadeIn( float time )
|
||||
{
|
||||
idVec3 color;
|
||||
idVec4 color4;
|
||||
|
||||
currentLevel = levels;
|
||||
spawnArgs.GetVector( "_color", "1 1 1", color );
|
||||
color4.Set( color.x, color.y, color.z, 1.0f );
|
||||
Fade( color4, time );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::PresentEnvprobeDefChange
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::PresentEnvprobeDefChange()
|
||||
{
|
||||
// let the renderer apply it to the world
|
||||
if( ( envprobeDefHandle != -1 ) )
|
||||
{
|
||||
gameRenderWorld->UpdateEnvprobeDef( envprobeDefHandle, &renderEnvprobe );
|
||||
}
|
||||
else
|
||||
{
|
||||
envprobeDefHandle = gameRenderWorld->AddEnvprobeDef( &renderEnvprobe );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Present
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Present()
|
||||
{
|
||||
// don't present to the renderer if the entity hasn't changed
|
||||
if( !( thinkFlags & TH_UPDATEVISUALS ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// add the model
|
||||
idEntity::Present();
|
||||
|
||||
// current transformation
|
||||
// renderEnvprobe.axis = localEnvprobeAxis * GetPhysics()->GetAxis();
|
||||
renderEnvprobe.origin = GetPhysics()->GetOrigin() + GetPhysics()->GetAxis() * localEnvprobeOrigin;
|
||||
|
||||
// reference the sound for shader synced effects
|
||||
// FIXME TODO?
|
||||
/*
|
||||
if( lightParent )
|
||||
{
|
||||
renderLight.referenceSound = lightParent->GetSoundEmitter();
|
||||
renderEntity.referenceSound = lightParent->GetSoundEmitter();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderLight.referenceSound = refSound.referenceSound;
|
||||
renderEntity.referenceSound = refSound.referenceSound;
|
||||
}
|
||||
*/
|
||||
|
||||
// update the renderLight and renderEntity to render the light and flare
|
||||
PresentEnvprobeDefChange();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Think
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Think()
|
||||
{
|
||||
idVec4 color;
|
||||
|
||||
if( thinkFlags & TH_THINK )
|
||||
{
|
||||
if( fadeEnd > 0 )
|
||||
{
|
||||
if( gameLocal.time < fadeEnd )
|
||||
{
|
||||
color.Lerp( fadeFrom, fadeTo, ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
color = fadeTo;
|
||||
fadeEnd = 0;
|
||||
BecomeInactive( TH_THINK );
|
||||
}
|
||||
SetColor( color );
|
||||
}
|
||||
}
|
||||
|
||||
RunPhysics();
|
||||
Present();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::ClientThink
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::ClientThink( const int curTime, const float fraction, const bool predict )
|
||||
{
|
||||
|
||||
InterpolatePhysics( fraction );
|
||||
|
||||
if( baseColor != nextBaseColor )
|
||||
{
|
||||
baseColor = Lerp( previousBaseColor, nextBaseColor, fraction );
|
||||
SetColor( baseColor );
|
||||
BecomeActive( TH_UPDATEVISUALS );
|
||||
}
|
||||
|
||||
Present();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::GetPhysicsToSoundTransform
|
||||
================
|
||||
*/
|
||||
bool EnvironmentProbe::GetPhysicsToSoundTransform( idVec3& origin, idMat3& axis )
|
||||
{
|
||||
//origin = localEnvprobeOrigin + renderEnvprobe.lightCenter;
|
||||
//axis = localLightAxis * GetPhysics()->GetAxis();
|
||||
//return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::FreeEnvprobeDef
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::FreeEnvprobeDef()
|
||||
{
|
||||
if( envprobeDefHandle != -1 )
|
||||
{
|
||||
gameRenderWorld->FreeEnvprobeDef( envprobeDefHandle );
|
||||
envprobeDefHandle = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::SaveState
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::SaveState( idDict* args )
|
||||
{
|
||||
int i, c = spawnArgs.GetNumKeyVals();
|
||||
for( i = 0; i < c; i++ )
|
||||
{
|
||||
const idKeyValue* pv = spawnArgs.GetKeyVal( i );
|
||||
if( pv->GetKey().Find( "editor_", false ) >= 0 || pv->GetKey().Find( "parse_", false ) >= 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
args->Set( pv->GetKey(), pv->GetValue() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
EnvironmentProbe::ShowEditingDialog
|
||||
===============
|
||||
*/
|
||||
void EnvironmentProbe::ShowEditingDialog()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_GetEnvprobeParm
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_GetEnvprobeParm( int parmnum )
|
||||
{
|
||||
if( ( parmnum < 0 ) || ( parmnum >= MAX_ENTITY_SHADER_PARMS ) )
|
||||
{
|
||||
gameLocal.Error( "shader parm index (%d) out of range", parmnum );
|
||||
return;
|
||||
}
|
||||
|
||||
idThread::ReturnFloat( renderEnvprobe.shaderParms[ parmnum ] );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_SetEnvprobeParm
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_SetEnvprobeParm( int parmnum, float value )
|
||||
{
|
||||
SetEnvprobeParm( parmnum, value );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_SetEnvprobetParms
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_SetEnvprobeParms( float parm0, float parm1, float parm2, float parm3 )
|
||||
{
|
||||
SetEnvprobeParms( parm0, parm1, parm2, parm3 );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_Hide
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_Hide()
|
||||
{
|
||||
Hide();
|
||||
Off();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_Show
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_Show()
|
||||
{
|
||||
Show();
|
||||
On();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_On
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_On()
|
||||
{
|
||||
On();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_Off
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_Off()
|
||||
{
|
||||
Off();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_ToggleOnOff
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_ToggleOnOff( idEntity* activator )
|
||||
{
|
||||
triggercount++;
|
||||
if( triggercount < count )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// reset trigger count
|
||||
triggercount = 0;
|
||||
|
||||
if( !currentLevel )
|
||||
{
|
||||
On();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentLevel--;
|
||||
if( !currentLevel )
|
||||
{
|
||||
Off();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLightLevel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_SetSoundHandles
|
||||
|
||||
set the same sound def handle on all targeted lights
|
||||
================
|
||||
*/
|
||||
/*
|
||||
void EnvironmentProbe::Event_SetSoundHandles()
|
||||
{
|
||||
int i;
|
||||
idEntity* targetEnt;
|
||||
|
||||
if( !refSound.referenceSound )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( i = 0; i < targets.Num(); i++ )
|
||||
{
|
||||
targetEnt = targets[ i ].GetEntity();
|
||||
if( targetEnt != NULL && targetEnt->IsType( EnvironmentProbe::Type ) )
|
||||
{
|
||||
idLight* light = static_cast<idLight*>( targetEnt );
|
||||
light->lightParent = this;
|
||||
|
||||
// explicitly delete any sounds on the entity
|
||||
light->FreeSoundEmitter( true );
|
||||
|
||||
// manually set the refSound to this light's refSound
|
||||
light->renderEntity.referenceSound = renderEntity.referenceSound;
|
||||
|
||||
// update the renderEntity to the renderer
|
||||
light->UpdateVisuals();
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_FadeOut
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_FadeOut( float time )
|
||||
{
|
||||
FadeOut( time );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::Event_FadeIn
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::Event_FadeIn( float time )
|
||||
{
|
||||
FadeIn( time );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::ClientPredictionThink
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::ClientPredictionThink()
|
||||
{
|
||||
Think();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::WriteToSnapshot
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::WriteToSnapshot( idBitMsg& msg ) const
|
||||
{
|
||||
GetPhysics()->WriteToSnapshot( msg );
|
||||
WriteBindToSnapshot( msg );
|
||||
|
||||
msg.WriteByte( currentLevel );
|
||||
msg.WriteLong( PackColor( baseColor ) );
|
||||
// msg.WriteBits( lightParent.GetEntityNum(), GENTITYNUM_BITS );
|
||||
|
||||
/* // only helps prediction
|
||||
msg.WriteLong( PackColor( fadeFrom ) );
|
||||
msg.WriteLong( PackColor( fadeTo ) );
|
||||
msg.WriteLong( fadeStart );
|
||||
msg.WriteLong( fadeEnd );
|
||||
*/
|
||||
|
||||
// FIXME: send renderLight.shader
|
||||
//msg.WriteFloat( renderEnvprobe.lightRadius[0], 5, 10 );
|
||||
//msg.WriteFloat( renderEnvprobe.lightRadius[1], 5, 10 );
|
||||
//msg.WriteFloat( renderEnvprobe.lightRadius[2], 5, 10 );
|
||||
|
||||
msg.WriteLong( PackColor( idVec4( renderEnvprobe.shaderParms[SHADERPARM_RED],
|
||||
renderEnvprobe.shaderParms[SHADERPARM_GREEN],
|
||||
renderEnvprobe.shaderParms[SHADERPARM_BLUE],
|
||||
renderEnvprobe.shaderParms[SHADERPARM_ALPHA] ) ) );
|
||||
|
||||
msg.WriteFloat( renderEnvprobe.shaderParms[SHADERPARM_TIMESCALE], 5, 10 );
|
||||
msg.WriteLong( renderEnvprobe.shaderParms[SHADERPARM_TIMEOFFSET] );
|
||||
msg.WriteShort( renderEnvprobe.shaderParms[SHADERPARM_MODE] );
|
||||
|
||||
WriteColorToSnapshot( msg );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::ReadFromSnapshot
|
||||
================
|
||||
*/
|
||||
void EnvironmentProbe::ReadFromSnapshot( const idBitMsg& msg )
|
||||
{
|
||||
idVec4 shaderColor;
|
||||
int oldCurrentLevel = currentLevel;
|
||||
idVec3 oldBaseColor = baseColor;
|
||||
|
||||
previousBaseColor = nextBaseColor;
|
||||
|
||||
GetPhysics()->ReadFromSnapshot( msg );
|
||||
ReadBindFromSnapshot( msg );
|
||||
|
||||
currentLevel = msg.ReadByte();
|
||||
if( currentLevel != oldCurrentLevel )
|
||||
{
|
||||
// need to call On/Off for flickering lights to start/stop the sound
|
||||
// while doing it this way rather than through events, the flickering is out of sync between clients
|
||||
// but at least there is no question about saving the event and having them happening globally in the world
|
||||
if( currentLevel )
|
||||
{
|
||||
On();
|
||||
}
|
||||
else
|
||||
{
|
||||
Off();
|
||||
}
|
||||
}
|
||||
|
||||
UnpackColor( msg.ReadLong(), nextBaseColor );
|
||||
|
||||
// lightParentEntityNum = msg.ReadBits( GENTITYNUM_BITS );
|
||||
|
||||
/* // only helps prediction
|
||||
UnpackColor( msg.ReadLong(), fadeFrom );
|
||||
UnpackColor( msg.ReadLong(), fadeTo );
|
||||
fadeStart = msg.ReadLong();
|
||||
fadeEnd = msg.ReadLong();
|
||||
*/
|
||||
|
||||
// FIXME: read renderLight.shader
|
||||
//renderLight.lightRadius[0] = msg.ReadFloat( 5, 10 );
|
||||
//renderLight.lightRadius[1] = msg.ReadFloat( 5, 10 );
|
||||
//renderLight.lightRadius[2] = msg.ReadFloat( 5, 10 );
|
||||
|
||||
UnpackColor( msg.ReadLong(), shaderColor );
|
||||
renderEnvprobe.shaderParms[SHADERPARM_RED] = shaderColor[0];
|
||||
renderEnvprobe.shaderParms[SHADERPARM_GREEN] = shaderColor[1];
|
||||
renderEnvprobe.shaderParms[SHADERPARM_BLUE] = shaderColor[2];
|
||||
renderEnvprobe.shaderParms[SHADERPARM_ALPHA] = shaderColor[3];
|
||||
|
||||
renderEnvprobe.shaderParms[SHADERPARM_TIMESCALE] = msg.ReadFloat( 5, 10 );
|
||||
renderEnvprobe.shaderParms[SHADERPARM_TIMEOFFSET] = msg.ReadLong();
|
||||
renderEnvprobe.shaderParms[SHADERPARM_MODE] = msg.ReadShort();
|
||||
|
||||
ReadColorFromSnapshot( msg );
|
||||
|
||||
if( msg.HasChanged() )
|
||||
{
|
||||
if( ( currentLevel != oldCurrentLevel ) || ( previousBaseColor != nextBaseColor ) )
|
||||
{
|
||||
SetLightLevel();
|
||||
}
|
||||
else
|
||||
{
|
||||
PresentEnvprobeDefChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EnvironmentProbe::ClientReceiveEvent
|
||||
================
|
||||
*/
|
||||
/*
|
||||
bool EnvironmentProbe::ClientReceiveEvent( int event, int time, const idBitMsg& msg )
|
||||
{
|
||||
|
||||
switch( event )
|
||||
{
|
||||
case EVENT_BECOMEBROKEN:
|
||||
{
|
||||
BecomeBroken( NULL );
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return idEntity::ClientReceiveEvent( event, time, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
143
neo/d3xp/EnvironmentProbe.h
Normal file
143
neo/d3xp/EnvironmentProbe.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2015 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.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __GAME_ENVIRONMENTPROBE_H__
|
||||
#define __GAME_ENVIRONMENTPROBE_H__
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
Environment probe for Image Based Lighting (part of PBR).
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
class EnvironmentProbe : public idEntity
|
||||
{
|
||||
public:
|
||||
CLASS_PROTOTYPE( EnvironmentProbe );
|
||||
|
||||
EnvironmentProbe();
|
||||
~EnvironmentProbe();
|
||||
|
||||
void Spawn();
|
||||
|
||||
void Save( idSaveGame* savefile ) const; // archives object for save game file
|
||||
void Restore( idRestoreGame* savefile ); // unarchives object from save game file
|
||||
|
||||
virtual void UpdateChangeableSpawnArgs( const idDict* source );
|
||||
virtual void Think();
|
||||
virtual void ClientThink( const int curTime, const float fraction, const bool predict );
|
||||
virtual void FreeEnvprobeDef();
|
||||
virtual bool GetPhysicsToSoundTransform( idVec3& origin, idMat3& axis );
|
||||
void Present();
|
||||
|
||||
void SaveState( idDict* args );
|
||||
virtual void SetColor( float red, float green, float blue );
|
||||
virtual void SetColor( const idVec4& color );
|
||||
void SetColor( const idVec3& color );
|
||||
virtual void GetColor( idVec3& out ) const;
|
||||
virtual void GetColor( idVec4& out ) const;
|
||||
const idVec3& GetBaseColor() const
|
||||
{
|
||||
return baseColor;
|
||||
}
|
||||
void SetEnvprobeParm( int parmnum, float value );
|
||||
void SetEnvprobeParms( float parm0, float parm1, float parm2, float parm3 );
|
||||
void On();
|
||||
void Off();
|
||||
void Fade( const idVec4& to, float fadeTime );
|
||||
void FadeOut( float time );
|
||||
void FadeIn( float time );
|
||||
|
||||
qhandle_t GetEnvprobeDefHandle() const
|
||||
{
|
||||
return envprobeDefHandle;
|
||||
}
|
||||
|
||||
void SetEnvprobeParent( idEntity* lparent )
|
||||
{
|
||||
lightParent = lparent;
|
||||
}
|
||||
|
||||
void SetLightLevel();
|
||||
|
||||
virtual void ShowEditingDialog();
|
||||
|
||||
enum
|
||||
{
|
||||
EVENT_BECOMEBROKEN = idEntity::EVENT_MAXEVENTS,
|
||||
EVENT_MAXEVENTS
|
||||
};
|
||||
|
||||
virtual void ClientPredictionThink();
|
||||
virtual void WriteToSnapshot( idBitMsg& msg ) const;
|
||||
virtual void ReadFromSnapshot( const idBitMsg& msg );
|
||||
// virtual bool ClientReceiveEvent( int event, int time, const idBitMsg& msg );
|
||||
|
||||
private:
|
||||
renderEnvironmentProbe_t renderEnvprobe; // envprobe presented to the renderer
|
||||
idVec3 localEnvprobeOrigin; // light origin relative to the physics origin
|
||||
idMat3 localEnvprobeAxis; // light axis relative to physics axis
|
||||
qhandle_t envprobeDefHandle; // handle to renderer light def
|
||||
int levels;
|
||||
int currentLevel;
|
||||
idVec3 baseColor;
|
||||
|
||||
// Colors used for client-side interpolation.
|
||||
idVec3 previousBaseColor;
|
||||
idVec3 nextBaseColor;
|
||||
|
||||
int count;
|
||||
int triggercount;
|
||||
idEntity* lightParent;
|
||||
idVec4 fadeFrom;
|
||||
idVec4 fadeTo;
|
||||
int fadeStart;
|
||||
int fadeEnd;
|
||||
|
||||
private:
|
||||
void PresentEnvprobeDefChange();
|
||||
|
||||
void Event_GetEnvprobeParm( int parmnum );
|
||||
void Event_SetEnvprobeParm( int parmnum, float value );
|
||||
void Event_SetEnvprobeParms( float parm0, float parm1, float parm2, float parm3 );
|
||||
void Event_SetRadiusXYZ( float x, float y, float z );
|
||||
void Event_SetRadius( float radius );
|
||||
void Event_Hide();
|
||||
void Event_Show();
|
||||
void Event_On();
|
||||
void Event_Off();
|
||||
void Event_ToggleOnOff( idEntity* activator );
|
||||
void Event_SetSoundHandles();
|
||||
void Event_FadeOut( float time );
|
||||
void Event_FadeIn( float time );
|
||||
};
|
||||
|
||||
#endif /* !__GAME_ENVIRONMENTPROBE_H__ */
|
|
@ -240,6 +240,7 @@ public:
|
|||
// These are the canonical idDict to parameter parsing routines used by both the game and tools.
|
||||
virtual void ParseSpawnArgsToRenderLight( const idDict* args, renderLight_t* renderLight );
|
||||
virtual void ParseSpawnArgsToRenderEntity( const idDict* args, renderEntity_t* renderEntity );
|
||||
virtual void ParseSpawnArgsToRenderEnvprobe( const idDict* args, renderEnvironmentProbe_t* renderEnvprobe ); // RB
|
||||
virtual void ParseSpawnArgsToRefSound( const idDict* args, refSound_t* refSound );
|
||||
|
||||
// Animation system calls for non-game based skeletal rendering.
|
||||
|
|
|
@ -904,6 +904,7 @@ const int CINEMATIC_SKIP_DELAY = SEC2MS( 2.0f );
|
|||
#include "Projectile.h"
|
||||
#include "Weapon.h"
|
||||
#include "Light.h"
|
||||
#include "EnvironmentProbe.h"
|
||||
#include "WorldSpawn.h"
|
||||
#include "Item.h"
|
||||
#include "PlayerView.h"
|
||||
|
|
|
@ -731,6 +731,21 @@ void idSaveGame::WriteRenderLight( const renderLight_t& renderLight )
|
|||
}
|
||||
}
|
||||
|
||||
// RB begin
|
||||
void idSaveGame::WriteRenderEnvprobe( const renderEnvironmentProbe_t& renderEnvprobe )
|
||||
{
|
||||
WriteVec3( renderEnvprobe.origin );
|
||||
|
||||
WriteInt( renderEnvprobe.suppressEnvprobeInViewID );
|
||||
WriteInt( renderEnvprobe.allowEnvprobeInViewID );
|
||||
|
||||
for( int i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ )
|
||||
{
|
||||
WriteFloat( renderEnvprobe.shaderParms[ i ] );
|
||||
}
|
||||
}
|
||||
// Rb end
|
||||
|
||||
/*
|
||||
================
|
||||
idSaveGame::WriteRefSound
|
||||
|
@ -1629,6 +1644,21 @@ void idRestoreGame::ReadRenderLight( renderLight_t& renderLight )
|
|||
renderLight.referenceSound = gameSoundWorld->EmitterForIndex( index );
|
||||
}
|
||||
|
||||
// RB begin
|
||||
void idRestoreGame::ReadRenderEnvprobe( renderEnvironmentProbe_t& renderEnvprobe )
|
||||
{
|
||||
ReadVec3( renderEnvprobe.origin );
|
||||
|
||||
ReadInt( renderEnvprobe.suppressEnvprobeInViewID );
|
||||
ReadInt( renderEnvprobe.allowEnvprobeInViewID );
|
||||
|
||||
for( int i = 0; i < MAX_ENTITY_SHADER_PARMS; i++ )
|
||||
{
|
||||
ReadFloat( renderEnvprobe.shaderParms[ i ] );
|
||||
}
|
||||
}
|
||||
// RB end
|
||||
|
||||
/*
|
||||
================
|
||||
idRestoreGame::ReadRefSound
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2015 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -82,6 +83,7 @@ public:
|
|||
void WriteUserInterface( const idUserInterface* ui, bool unique );
|
||||
void WriteRenderEntity( const renderEntity_t& renderEntity );
|
||||
void WriteRenderLight( const renderLight_t& renderLight );
|
||||
void WriteRenderEnvprobe( const renderEnvironmentProbe_t& renderEnvprobe ); // RB
|
||||
void WriteRefSound( const refSound_t& refSound );
|
||||
void WriteRenderView( const renderView_t& view );
|
||||
void WriteUsercmd( const usercmd_t& usercmd );
|
||||
|
@ -169,6 +171,7 @@ public:
|
|||
void ReadUserInterface( idUserInterface*& ui );
|
||||
void ReadRenderEntity( renderEntity_t& renderEntity );
|
||||
void ReadRenderLight( renderLight_t& renderLight );
|
||||
void ReadRenderEnvprobe( renderEnvironmentProbe_t& renderEnvprobe ); // RB
|
||||
void ReadRefSound( refSound_t& refSound );
|
||||
void ReadRenderView( renderView_t& view );
|
||||
void ReadUsercmd( usercmd_t& usercmd );
|
||||
|
|
|
@ -194,7 +194,8 @@ gameReturn_t idGameThread::RunGameAndDraw( int numGameFrames_, idUserCmdMgr& use
|
|||
numGameFrames = numGameFrames_;
|
||||
|
||||
// start the thread going
|
||||
if( com_smp.GetInteger() <= 0 )
|
||||
// foresthale 2014-05-12: also check com_editors as many of them are not particularly thread-safe (editLights for example)
|
||||
if( com_smp.GetBool() == false || com_editors != 0 )
|
||||
{
|
||||
// run it in the main thread so PIX profiling catches everything
|
||||
Run();
|
||||
|
@ -249,8 +250,49 @@ void idCommonLocal::Draw()
|
|||
Sys_Sleep( com_sleepDraw.GetInteger() );
|
||||
}
|
||||
|
||||
if( loadGUI != NULL )
|
||||
if( loadPacifierBinarizeActive )
|
||||
{
|
||||
// foresthale 2014-05-30: when binarizing an asset we show a special
|
||||
// overlay indicating progress
|
||||
renderSystem->SetColor( colorBlack );
|
||||
renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, whiteMaterial );
|
||||
|
||||
// render the loading gui (idSWF actually) if it is loaded
|
||||
// (we want to see progress of the loading gui binarize too)
|
||||
if( loadGUI != NULL )
|
||||
loadGUI->Render( renderSystem, Sys_Milliseconds() );
|
||||
|
||||
// update our progress estimates
|
||||
int time = Sys_Milliseconds();
|
||||
if( loadPacifierBinarizeProgress > 0.0f )
|
||||
loadPacifierBinarizeTimeLeft = ( 1.0 - loadPacifierBinarizeProgress ) * ( time - loadPacifierBinarizeStartTime ) * 0.001f / loadPacifierBinarizeProgress;
|
||||
else
|
||||
loadPacifierBinarizeTimeLeft = -1.0f;
|
||||
|
||||
// prepare our strings
|
||||
const char* text;
|
||||
if( loadPacifierBinarizeTimeLeft >= 99.5f )
|
||||
text = va( "Binarizing %3.0f%% ETA %2.0f minutes", loadPacifierBinarizeProgress * 100.0f, loadPacifierBinarizeTimeLeft / 60.0f );
|
||||
else if( loadPacifierBinarizeTimeLeft )
|
||||
text = va( "Binarizing %3.0f%% ETA %2.0f seconds", loadPacifierBinarizeProgress * 100.0f, loadPacifierBinarizeTimeLeft );
|
||||
else
|
||||
text = va( "Binarizing %3.0f%%", loadPacifierBinarizeProgress * 100.0f );
|
||||
|
||||
// draw our basic overlay
|
||||
renderSystem->SetColor( idVec4( 0.0f, 0.0f, 0.5f, 1.0f ) );
|
||||
renderSystem->DrawStretchPic( 0, SCREEN_HEIGHT - 48, SCREEN_WIDTH, 48, 0, 0, 1, 1, whiteMaterial );
|
||||
renderSystem->SetColor( idVec4( 0.0f, 0.5f, 0.8f, 1.0f ) );
|
||||
renderSystem->DrawStretchPic( 0, SCREEN_HEIGHT - 48, loadPacifierBinarizeProgress * SCREEN_WIDTH, 32, 0, 0, 1, 1, whiteMaterial );
|
||||
renderSystem->DrawSmallStringExt( 0, SCREEN_HEIGHT - 48, loadPacifierBinarizeFilename.c_str(), idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
|
||||
renderSystem->DrawSmallStringExt( 0, SCREEN_HEIGHT - 32, va( "%s %d/%d lvls", loadPacifierBinarizeInfo.c_str(), loadPacifierBinarizeMiplevel, loadPacifierBinarizeMiplevelTotal ), idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
|
||||
renderSystem->DrawSmallStringExt( 0, SCREEN_HEIGHT - 16, text, idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
|
||||
}
|
||||
else if( loadGUI != NULL )
|
||||
{
|
||||
// foresthale 2014-05-30: showing a black background looks better than flickering in widescreen
|
||||
renderSystem->SetColor( colorBlack );
|
||||
renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, whiteMaterial );
|
||||
|
||||
loadGUI->Render( renderSystem, Sys_Milliseconds() );
|
||||
}
|
||||
// RB begin
|
||||
|
@ -371,6 +413,7 @@ void idCommonLocal::UpdateScreen( bool captureToImage, bool releaseMouse )
|
|||
// build all the draw commands without running a new game tic
|
||||
Draw();
|
||||
|
||||
// foresthale 2014-03-01: note: the only place that has captureToImage=true is idAutoRender::StartBackgroundAutoSwaps
|
||||
if( captureToImage )
|
||||
{
|
||||
renderSystem->CaptureRenderToImage( "_currentRender", false );
|
||||
|
@ -479,6 +522,8 @@ void idCommonLocal::Frame()
|
|||
|
||||
eventLoop->RunEventLoop();
|
||||
|
||||
renderSystem->OnFrame();
|
||||
|
||||
// DG: prepare new ImGui frame - I guess this is a good place, as all new events should be available?
|
||||
ImGuiHook::NewFrame();
|
||||
|
||||
|
@ -557,7 +602,9 @@ void idCommonLocal::Frame()
|
|||
// This may block if the GPU isn't finished renderng the previous frame.
|
||||
frameTiming.startSyncTime = Sys_Microseconds();
|
||||
const emptyCommand_t* renderCommands = NULL;
|
||||
if( com_smp.GetInteger() > 0 )
|
||||
|
||||
// foresthale 2014-05-12: also check com_editors as many of them are not particularly thread-safe (editLights for example)
|
||||
if( com_smp.GetInteger() > 0 && com_editors == 0 )
|
||||
{
|
||||
renderCommands = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu );
|
||||
}
|
||||
|
@ -786,12 +833,13 @@ void idCommonLocal::Frame()
|
|||
// start the game / draw command generation thread going in the background
|
||||
gameReturn_t ret = gameThread.RunGameAndDraw( numGameFrames, userCmdMgr, IsClient(), gameFrame - numGameFrames );
|
||||
|
||||
if( com_smp.GetInteger() < 0 )
|
||||
// foresthale 2014-05-12: also check com_editors as many of them are not particularly thread-safe (editLights for example)
|
||||
if( !com_smp.GetInteger() < 0 )
|
||||
{
|
||||
// RB: this is the same as Doom 3 renderSystem->EndFrame()
|
||||
renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu );
|
||||
}
|
||||
else if( com_smp.GetInteger() == 0 )
|
||||
else if( com_smp.GetInteger() == 0 || com_editors != 0 )
|
||||
{
|
||||
// in non-smp mode, run the commands we just generated, instead of
|
||||
// frame-delayed ones from a background thread
|
||||
|
|
|
@ -102,9 +102,11 @@ MEM_TAG( RENDER_WINDING )
|
|||
MEM_TAG( RENDER_STATIC )
|
||||
MEM_TAG( RENDER_ENTITY )
|
||||
MEM_TAG( RENDER_LIGHT )
|
||||
MEM_TAG( RENDER_ENVPROBE ) // RB
|
||||
MEM_TAG( RENDER_INTERACTION )
|
||||
MEM_TAG( SURFACE )
|
||||
MEM_TAG( LIGHT )
|
||||
MEM_TAG( ENVPROBE ) // RB
|
||||
MEM_TAG( AI )
|
||||
MEM_TAG( SCRIPT )
|
||||
MEM_TAG( EVENTS )
|
||||
|
|
|
@ -44,7 +44,7 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#include "Color/ColorSpace.h"
|
||||
|
||||
idCVar image_highQualityCompression( "image_highQualityCompression", "0", CVAR_BOOL, "Use high quality (slow) compression" );
|
||||
idCVar r_useHighQualitySky( "r_useHighQualitySky", "0", CVAR_BOOL | CVAR_ARCHIVE, "Use high quality skyboxes" );
|
||||
idCVar r_useHighQualitySky( "r_useHighQualitySky", "1", CVAR_BOOL | CVAR_ARCHIVE, "Use high quality skyboxes" );
|
||||
|
||||
/*
|
||||
========================
|
||||
|
@ -360,13 +360,37 @@ void idBinaryImage::LoadCubeFromMemory( int width, const byte* pics[6], int numL
|
|||
{
|
||||
img.Alloc( padSize * padSize / 2 );
|
||||
idDxtEncoder dxt;
|
||||
dxt.CompressImageDXT1Fast( padSrc, img.data, padSize, padSize );
|
||||
|
||||
if( image_highQualityCompression.GetBool() )
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - DXT1HQ", width, width ) );
|
||||
|
||||
dxt.CompressImageDXT1HQ( padSrc, img.data, padSize, padSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - DXT1Fast", width, width ) );
|
||||
|
||||
dxt.CompressImageDXT1Fast( padSrc, img.data, padSize, padSize );
|
||||
}
|
||||
}
|
||||
else if( textureFormat == FMT_DXT5 )
|
||||
{
|
||||
img.Alloc( padSize * padSize );
|
||||
idDxtEncoder dxt;
|
||||
dxt.CompressImageDXT5Fast( padSrc, img.data, padSize, padSize );
|
||||
|
||||
if( image_highQualityCompression.GetBool() )
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - DXT5HQ", width, width ) );
|
||||
|
||||
dxt.CompressImageDXT5HQ( padSrc, img.data, padSize, padSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeInfo( va( "(%d x %d) - DXT5Fast", width, width ) );
|
||||
|
||||
dxt.CompressImageDXT5Fast( padSrc, img.data, padSize, padSize );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -216,6 +216,10 @@ typedef enum
|
|||
TD_COVERAGE, // coverage map for fill depth pass when YCoCG is used
|
||||
TD_DEPTH, // depth buffer copy for motion blur
|
||||
// RB begin
|
||||
TD_SPECULAR_PBR_RMAO, // may be compressed, and always zeros the alpha channel, linear RGB R = roughness, G = metal, B = ambient occlusion
|
||||
TD_SPECULAR_PBR_RMAOD, // may be compressed, alpha channel contains displacement map
|
||||
TD_HIGHQUALITY_CUBE, // motorsep - Uncompressed cubemap texture (RGB colorspace)
|
||||
TD_LOWQUALITY_CUBE, // motorsep - Compressed cubemap texture (RGB colorspace DXT5)
|
||||
TD_SHADOW_ARRAY, // 2D depth buffer array for shadow mapping
|
||||
TD_RGBA16F,
|
||||
TD_RGBA32F,
|
||||
|
@ -365,6 +369,11 @@ public:
|
|||
return ( opts.format == FMT_DXT1 || opts.format == FMT_DXT5 );
|
||||
}
|
||||
|
||||
textureUsage_t GetUsage() const
|
||||
{
|
||||
return usage;
|
||||
}
|
||||
|
||||
bool IsLoaded() const;
|
||||
|
||||
static void GetGeneratedName( idStr& _name, const textureUsage_t& _usage, const cubeFiles_t& _cube );
|
||||
|
@ -564,6 +573,9 @@ public:
|
|||
idImage* ambientOcclusionImage[2]; // contain AO and bilateral filtering keys
|
||||
idImage* hierarchicalZbufferImage; // zbuffer with mip maps to accelerate screen space ray tracing
|
||||
idImage* imguiFontImage;
|
||||
|
||||
idImage* defaultUACIrradianceCube;
|
||||
idImage* defaultUACRadianceCube;
|
||||
// RB end
|
||||
idImage* scratchImage;
|
||||
idImage* scratchImage2;
|
||||
|
@ -572,7 +584,7 @@ public:
|
|||
idImage* currentDepthImage; // for motion blur
|
||||
idImage* originalCurrentRenderImage; // currentRenderImage before any changes for stereo rendering
|
||||
idImage* loadingIconImage; // loading icon must exist always
|
||||
idImage* hellLoadingIconImage; // loading icon must exist always
|
||||
idImage* hellLoadingIconImage; // loading icon must exist always
|
||||
|
||||
//--------------------------------------------------------
|
||||
|
||||
|
|
|
@ -920,6 +920,9 @@ void idImageManager::CreateIntrinsicImages()
|
|||
loadingIconImage = ImageFromFile( "textures/loadingicon2", TF_DEFAULT, TR_CLAMP, TD_DEFAULT, CF_2D );
|
||||
hellLoadingIconImage = ImageFromFile( "textures/loadingicon3", TF_DEFAULT, TR_CLAMP, TD_DEFAULT, CF_2D );
|
||||
|
||||
defaultUACIrradianceCube = ImageFromFile( "env/testmap_1_amb", TF_DEFAULT, TR_CLAMP, TD_HIGHQUALITY_CUBE, CF_NATIVE );
|
||||
defaultUACRadianceCube = ImageFromFile( "env/testmap_1_spec", TF_DEFAULT, TR_CLAMP, TD_HIGHQUALITY_CUBE, CF_NATIVE );
|
||||
|
||||
release_assert( loadingIconImage->referencedOutsideLevelLoad );
|
||||
release_assert( hellLoadingIconImage->referencedOutsideLevelLoad );
|
||||
}
|
||||
|
|
|
@ -137,6 +137,19 @@ ID_INLINE void idImage::DeriveOpts()
|
|||
opts.format = FMT_DXT1;
|
||||
opts.colorFormat = CFM_DEFAULT;
|
||||
break;
|
||||
|
||||
case TD_SPECULAR_PBR_RMAO:
|
||||
opts.gammaMips = false;
|
||||
opts.format = FMT_DXT1;
|
||||
opts.colorFormat = CFM_DEFAULT;
|
||||
break;
|
||||
|
||||
case TD_SPECULAR_PBR_RMAOD:
|
||||
opts.gammaMips = false;
|
||||
opts.format = FMT_DXT5;
|
||||
opts.colorFormat = CFM_DEFAULT;
|
||||
break;
|
||||
|
||||
case TD_DEFAULT:
|
||||
opts.gammaMips = true;
|
||||
opts.format = FMT_DXT5;
|
||||
|
@ -169,6 +182,17 @@ ID_INLINE void idImage::DeriveOpts()
|
|||
case TD_LOOKUP_TABLE_RGBA:
|
||||
opts.format = FMT_RGBA8;
|
||||
break;
|
||||
// motorsep 05-17-2015; added this for uncompressed cubemap/skybox textures
|
||||
case TD_HIGHQUALITY_CUBE:
|
||||
opts.colorFormat = CFM_DEFAULT;
|
||||
opts.format = FMT_RGBA8;
|
||||
opts.gammaMips = true;
|
||||
break;
|
||||
case TD_LOWQUALITY_CUBE:
|
||||
opts.colorFormat = CFM_DEFAULT; // CFM_YCOCG_DXT5;
|
||||
opts.format = FMT_DXT5;
|
||||
opts.gammaMips = true;
|
||||
break;
|
||||
default:
|
||||
assert( false );
|
||||
opts.format = FMT_RGBA8;
|
||||
|
@ -217,6 +241,35 @@ void idImage::AllocImage( const idImageOpts& imgOpts, textureFilter_t tf, textur
|
|||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
// foresthale 2014-05-30: give a nice progress display when binarizing
|
||||
commonLocal.LoadPacifierBinarizeFilename( GetName() , "generated image" );
|
||||
if( opts.numLevels > 1 )
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height * 4 / 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height );
|
||||
}
|
||||
|
||||
commonLocal.LoadPacifierBinarizeEnd();
|
||||
|
||||
|
||||
// foresthale 2014-05-30: give a nice progress display when binarizing
|
||||
commonLocal.LoadPacifierBinarizeFilename( GetName(), "generated cube image" );
|
||||
if( opts.numLevels > 1 )
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
|
||||
}
|
||||
|
||||
commonLocal.LoadPacifierBinarizeEnd();
|
||||
|
||||
===============
|
||||
GetGeneratedName
|
||||
|
||||
|
@ -474,6 +527,19 @@ void idImage::ActuallyLoadImage( bool fromBackEnd )
|
|||
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
|
||||
}
|
||||
|
||||
commonLocal.LoadPacifierBinarizeEnd();
|
||||
|
||||
// foresthale 2014-05-30: give a nice progress display when binarizing
|
||||
commonLocal.LoadPacifierBinarizeFilename( generatedName.c_str(), binarizeReason.c_str() );
|
||||
if( opts.numLevels > 1 )
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
|
||||
}
|
||||
|
||||
im.Load2DFromMemory( opts.width, opts.height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
|
||||
commonLocal.LoadPacifierBinarizeEnd();
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ struct surfaceInteraction_t
|
|||
|
||||
class idRenderEntityLocal;
|
||||
class idRenderLightLocal;
|
||||
class RenderEnvprobeLocal;
|
||||
|
||||
class idInteraction
|
||||
{
|
||||
|
|
|
@ -72,6 +72,8 @@ typedef struct mtrParsingData_s
|
|||
bool forceOverlays;
|
||||
} mtrParsingData_t;
|
||||
|
||||
extern idCVar r_useHighQualitySky;
|
||||
|
||||
idCVar r_forceSoundOpAmplitude( "r_forceSoundOpAmplitude", "0", CVAR_FLOAT, "Don't call into the sound system for amplitudes" );
|
||||
|
||||
/*
|
||||
|
@ -1045,17 +1047,17 @@ void idMaterial::ParseBlend( idLexer& src, shaderStage_t* stage )
|
|||
stage->drawStateBits = GLS_SRCBLEND_ZERO | GLS_DSTBLEND_ONE;
|
||||
return;
|
||||
}
|
||||
if( !token.Icmp( "bumpmap" ) )
|
||||
if( !token.Icmp( "bumpmap" ) || !token.Icmp( "normalmap" ) )
|
||||
{
|
||||
stage->lighting = SL_BUMP;
|
||||
return;
|
||||
}
|
||||
if( !token.Icmp( "diffusemap" ) )
|
||||
if( !token.Icmp( "diffusemap" ) || !token.Icmp( "basecolormap" ) )
|
||||
{
|
||||
stage->lighting = SL_DIFFUSE;
|
||||
return;
|
||||
}
|
||||
if( !token.Icmp( "specularmap" ) )
|
||||
if( !token.Icmp( "specularmap" ) || !token.Icmp( "rmaomap" ) )
|
||||
{
|
||||
stage->lighting = SL_SPECULAR;
|
||||
return;
|
||||
|
@ -1555,8 +1557,16 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
{
|
||||
continue;
|
||||
}
|
||||
if( !token.Icmp( "uncompressed" ) )
|
||||
if( !token.Icmp( "uncompressedCubeMap" ) )
|
||||
{
|
||||
if( r_useHighQualitySky.GetBool() )
|
||||
{
|
||||
td = TD_HIGHQUALITY_CUBE; // motorsep 05-17-2015; token to mark cubemap/skybox to be uncompressed texture
|
||||
}
|
||||
else
|
||||
{
|
||||
td = TD_LOWQUALITY_CUBE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( !token.Icmp( "nopicmip" ) )
|
||||
|
@ -1897,7 +1907,18 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
td = TD_DIFFUSE;
|
||||
break;
|
||||
case SL_SPECULAR:
|
||||
td = TD_SPECULAR;
|
||||
if( idStr::FindText( imageName, "_rmaod", false ) != -1 )
|
||||
{
|
||||
td = TD_SPECULAR_PBR_RMAOD;
|
||||
}
|
||||
else if( idStr::FindText( imageName, "_rmao", false ) != -1 )
|
||||
{
|
||||
td = TD_SPECULAR_PBR_RMAO;
|
||||
}
|
||||
else
|
||||
{
|
||||
td = TD_SPECULAR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1910,10 +1931,13 @@ void idMaterial::ParseStage( idLexer& src, const textureRepeat_t trpDefault )
|
|||
// create new coverage stage
|
||||
shaderStage_t* newCoverageStage = &pd->parseStages[numStages];
|
||||
numStages++;
|
||||
|
||||
// copy it
|
||||
*newCoverageStage = *ss;
|
||||
|
||||
// toggle alphatest off for the current stage so it doesn't get called during the depth fill pass
|
||||
ss->hasAlphaTest = false;
|
||||
|
||||
// toggle alpha test on for the coverage stage
|
||||
newCoverageStage->hasAlphaTest = true;
|
||||
newCoverageStage->lighting = SL_COVERAGE;
|
||||
|
@ -2465,7 +2489,7 @@ void idMaterial::ParseMaterial( idLexer& src )
|
|||
continue;
|
||||
}
|
||||
// diffusemap for stage shortcut
|
||||
else if( !token.Icmp( "diffusemap" ) )
|
||||
else if( !token.Icmp( "diffusemap" ) || !token.Icmp( "basecolormap" ) )
|
||||
{
|
||||
str = R_ParsePastImageProgram( src );
|
||||
idStr::snPrintf( buffer, sizeof( buffer ), "blend diffusemap\nmap %s\n}\n", str );
|
||||
|
@ -2487,7 +2511,7 @@ void idMaterial::ParseMaterial( idLexer& src )
|
|||
continue;
|
||||
}
|
||||
// normalmap for stage shortcut
|
||||
else if( !token.Icmp( "bumpmap" ) )
|
||||
else if( !token.Icmp( "bumpmap" ) || !token.Icmp( "normalmap" ) )
|
||||
{
|
||||
str = R_ParsePastImageProgram( src );
|
||||
idStr::snPrintf( buffer, sizeof( buffer ), "blend bumpmap\nmap %s\n}\n", str );
|
||||
|
|
|
@ -690,9 +690,7 @@ void idRenderBackend::PrepareStageTexturing( const shaderStage_t* pStage, const
|
|||
}
|
||||
else if( pStage->texture.texgen == TG_SKYBOX_CUBE )
|
||||
{
|
||||
|
||||
renderProgManager.BindShader_SkyBox();
|
||||
|
||||
}
|
||||
else if( pStage->texture.texgen == TG_WOBBLESKY_CUBE )
|
||||
{
|
||||
|
@ -1205,6 +1203,9 @@ const int INTERACTION_TEXUNIT_PROJECTION = 4;
|
|||
const int INTERACTION_TEXUNIT_SHADOWMAPS = 5;
|
||||
const int INTERACTION_TEXUNIT_JITTER = 6;
|
||||
|
||||
const int INTERACTION_TEXUNIT_AMBIENT_CUBE1 = 7;
|
||||
const int INTERACTION_TEXUNIT_SPECULAR_CUBE1 = 8;
|
||||
|
||||
/*
|
||||
==================
|
||||
idRenderBackend::SetupInteractionStage
|
||||
|
@ -1267,7 +1268,7 @@ void idRenderBackend::SetupInteractionStage( const shaderStage_t* surfaceStage,
|
|||
idRenderBackend::DrawSingleInteraction
|
||||
=================
|
||||
*/
|
||||
void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din )
|
||||
void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din, bool useIBL )
|
||||
{
|
||||
if( din->bumpImage == NULL )
|
||||
{
|
||||
|
@ -1300,6 +1301,35 @@ void idRenderBackend::DrawSingleInteraction( drawInteraction_t* din )
|
|||
return;
|
||||
}
|
||||
|
||||
if( useIBL )
|
||||
{
|
||||
const textureUsage_t specUsage = din->specularImage->GetUsage();
|
||||
|
||||
if( specUsage == TD_SPECULAR_PBR_RMAO || specUsage == TD_SPECULAR_PBR_RMAOD )
|
||||
{
|
||||
// PBR path with roughness, metal and AO
|
||||
if( din->surf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLightingSkinned_PBR();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLighting_PBR();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( din->surf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLightingSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLighting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bump matrix
|
||||
SetVertexParm( RENDERPARM_BUMPMATRIX_S, din->bumpMatrix[0].ToFloatPtr() );
|
||||
SetVertexParm( RENDERPARM_BUMPMATRIX_T, din->bumpMatrix[1].ToFloatPtr() );
|
||||
|
@ -1838,7 +1868,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
|
|||
// draw any previous interaction
|
||||
if( inter.bumpImage != NULL )
|
||||
{
|
||||
DrawSingleInteraction( &inter );
|
||||
DrawSingleInteraction( &inter, false );
|
||||
}
|
||||
inter.bumpImage = surfaceStage->texture.image;
|
||||
inter.diffuseImage = NULL;
|
||||
|
@ -1856,7 +1886,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
|
|||
// draw any previous interaction
|
||||
if( inter.diffuseImage != NULL )
|
||||
{
|
||||
DrawSingleInteraction( &inter );
|
||||
DrawSingleInteraction( &inter, false );
|
||||
}
|
||||
inter.diffuseImage = surfaceStage->texture.image;
|
||||
inter.vertexColor = surfaceStage->vertexColor;
|
||||
|
@ -1874,7 +1904,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
|
|||
// draw any previous interaction
|
||||
if( inter.specularImage != NULL )
|
||||
{
|
||||
DrawSingleInteraction( &inter );
|
||||
DrawSingleInteraction( &inter, false );
|
||||
}
|
||||
inter.specularImage = surfaceStage->texture.image;
|
||||
inter.vertexColor = surfaceStage->vertexColor;
|
||||
|
@ -1886,7 +1916,7 @@ void idRenderBackend::RenderInteractions( const drawSurf_t* surfList, const view
|
|||
}
|
||||
|
||||
// draw the final interaction
|
||||
DrawSingleInteraction( &inter );
|
||||
DrawSingleInteraction( &inter, false );
|
||||
|
||||
renderLog.CloseBlock();
|
||||
}
|
||||
|
@ -2054,6 +2084,23 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
else
|
||||
#endif
|
||||
{
|
||||
#if 1
|
||||
// draw Quake 4 style ambient
|
||||
if( drawSurf->jointCache )
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLightingSkinned();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderProgManager.BindShader_ImageBasedLighting();
|
||||
}
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_AMBIENT_CUBE1 );
|
||||
globalImages->defaultUACIrradianceCube->Bind();
|
||||
|
||||
GL_SelectTexture( INTERACTION_TEXUNIT_SPECULAR_CUBE1 );
|
||||
globalImages->defaultUACRadianceCube->Bind();
|
||||
#else
|
||||
// draw Quake 4 style ambient
|
||||
if( drawSurf->jointCache )
|
||||
{
|
||||
|
@ -2063,6 +2110,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
{
|
||||
renderProgManager.BindShader_AmbientLighting();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2118,6 +2166,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
renderProgManager.SetRenderParm( RENDERPARM_COLOR, directedColor.ToFloatPtr() );
|
||||
renderProgManager.SetRenderParm( RENDERPARM_AMBIENT_COLOR, ambientColor.ToFloatPtr() );
|
||||
}
|
||||
float ambientBoost = r_useHDR.GetBool() ? 1.5 : 1.0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -2226,7 +2275,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
// draw any previous interaction
|
||||
if( inter.bumpImage != NULL )
|
||||
{
|
||||
DrawSingleInteraction( &inter );
|
||||
DrawSingleInteraction( &inter, !fillGbuffer );
|
||||
}
|
||||
inter.bumpImage = surfaceStage->texture.image;
|
||||
inter.diffuseImage = NULL;
|
||||
|
@ -2247,7 +2296,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
// draw any previous interaction
|
||||
if( inter.diffuseImage != NULL )
|
||||
{
|
||||
DrawSingleInteraction( &inter );
|
||||
DrawSingleInteraction( &inter, !fillGbuffer );
|
||||
}
|
||||
|
||||
inter.diffuseImage = surfaceStage->texture.image;
|
||||
|
@ -2267,7 +2316,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
// draw any previous interaction
|
||||
if( inter.specularImage != NULL )
|
||||
{
|
||||
DrawSingleInteraction( &inter );
|
||||
DrawSingleInteraction( &inter, !fillGbuffer );
|
||||
}
|
||||
inter.specularImage = surfaceStage->texture.image;
|
||||
inter.vertexColor = surfaceStage->vertexColor;
|
||||
|
@ -2279,7 +2328,7 @@ void idRenderBackend::AmbientPass( const drawSurf_t* const* drawSurfs, int numDr
|
|||
}
|
||||
|
||||
// draw the final interaction
|
||||
DrawSingleInteraction( &inter );
|
||||
DrawSingleInteraction( &inter, !fillGbuffer );
|
||||
|
||||
renderLog.CloseBlock();
|
||||
}
|
||||
|
|
|
@ -242,12 +242,6 @@ all state modified by the back end is separated from the front end state
|
|||
|
||||
===========================================================================
|
||||
*/
|
||||
//namespace ImGui
|
||||
//{
|
||||
//
|
||||
//}
|
||||
|
||||
//#include "../libs/imgui/imgui.h"
|
||||
struct ImDrawData;
|
||||
|
||||
class idRenderBackend
|
||||
|
@ -304,7 +298,7 @@ private:
|
|||
idVec4 matrix[2], float color[4] );
|
||||
|
||||
void DrawInteractions( const viewDef_t* _viewDef );
|
||||
void DrawSingleInteraction( drawInteraction_t* din );
|
||||
void DrawSingleInteraction( drawInteraction_t* din, bool useIBL );
|
||||
int DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const int numDrawSurfs,
|
||||
const float guiStereoScreenOffset, const int stereoEye );
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ enum demoCommand_t
|
|||
DC_SET_PORTAL_STATE,
|
||||
DC_UPDATE_SOUNDOCCLUSION,
|
||||
DC_GUI_MODEL,
|
||||
DC_UPDATE_ENVPROBEDEF,
|
||||
DC_DELETE_ENVPROBEDEF,
|
||||
DC_UPDATE_DECAL,
|
||||
DC_DELETE_DECAL,
|
||||
DC_UPDATE_OVERLAY,
|
||||
|
@ -129,9 +131,12 @@ struct areaReference_t
|
|||
areaReference_t* areaNext; // chain in the area
|
||||
areaReference_t* areaPrev;
|
||||
areaReference_t* ownerNext; // chain on either the entityDef or lightDef
|
||||
idRenderEntityLocal* entity; // only one of entity / light will be non-NULL
|
||||
idRenderLightLocal* light; // only one of entity / light will be non-NULL
|
||||
struct portalArea_s* area; // so owners can find all the areas they are in
|
||||
|
||||
idRenderEntityLocal* entity; // only one of entity / light / envprobe will be non-NULL
|
||||
idRenderLightLocal* light; // only one of entity / light / envprobe will be non-NULL
|
||||
RenderEnvprobeLocal* envprobe; // only one of entity / light / envprobe will be non-NULL
|
||||
|
||||
struct portalArea_s* area; // so owners can find all the areas they are in
|
||||
};
|
||||
|
||||
|
||||
|
@ -148,6 +153,19 @@ public:
|
|||
virtual int GetIndex() = 0;
|
||||
};
|
||||
|
||||
// RB : RennderEnvprobe should become the new public interface replacing the qhandle_t to envprobe defs in the idRenderWorld interface
|
||||
class RenderEnvprobe
|
||||
{
|
||||
public:
|
||||
virtual ~RenderEnvprobe() {}
|
||||
|
||||
virtual void FreeRenderEnvprobe() = 0;
|
||||
virtual void UpdateRenderEnvprobe( const renderEnvironmentProbe_t* ep, bool forceUpdate = false ) = 0;
|
||||
virtual void GetRenderEnvprobe( renderEnvironmentProbe_t* ep ) = 0;
|
||||
virtual void ForceUpdate() = 0;
|
||||
virtual int GetIndex() = 0;
|
||||
};
|
||||
// RB end
|
||||
|
||||
// idRenderEntity should become the new public interface replacing the qhandle_t to entity defs in the idRenderWorld interface
|
||||
class idRenderEntity
|
||||
|
@ -221,6 +239,40 @@ public:
|
|||
};
|
||||
|
||||
|
||||
// RB begin
|
||||
class RenderEnvprobeLocal : public RenderEnvprobe
|
||||
{
|
||||
public:
|
||||
RenderEnvprobeLocal();
|
||||
|
||||
virtual void FreeRenderEnvprobe() override;
|
||||
virtual void UpdateRenderEnvprobe( const renderEnvironmentProbe_t* ep, bool forceUpdate = false ) override;
|
||||
virtual void GetRenderEnvprobe( renderEnvironmentProbe_t* ep ) override;
|
||||
virtual void ForceUpdate() override;
|
||||
virtual int GetIndex() override;
|
||||
|
||||
renderEnvironmentProbe_t parms; // specification
|
||||
|
||||
bool envprobeHasMoved; // the light has changed its position since it was
|
||||
// first added, so the prelight model is not valid
|
||||
idRenderWorldLocal* world;
|
||||
int index; // in world envprobeDefs
|
||||
|
||||
int areaNum; // if not -1, we may be able to cull all the envprobe's
|
||||
// interactions if !viewDef->connectedAreas[areaNum]
|
||||
|
||||
int lastModifiedFrameNum; // to determine if it is constantly changing,
|
||||
// and should go in the dynamic frame memory, or kept
|
||||
// in the cached memory
|
||||
bool archived; // for demo writing
|
||||
|
||||
// derived information
|
||||
areaReference_t* references; // each area the light is present in will have a lightRef
|
||||
//idInteraction* firstInteraction; // doubly linked list
|
||||
//idInteraction* lastInteraction;
|
||||
};
|
||||
// RB end
|
||||
|
||||
class idRenderEntityLocal : public idRenderEntity
|
||||
{
|
||||
public:
|
||||
|
@ -666,6 +718,7 @@ struct performanceCounters_t
|
|||
int c_tangentIndexes; // R_DeriveTangents()
|
||||
int c_entityUpdates;
|
||||
int c_lightUpdates;
|
||||
int c_envprobeUpdates;
|
||||
int c_entityReferences;
|
||||
int c_lightReferences;
|
||||
int c_guiSurfs;
|
||||
|
@ -1181,6 +1234,10 @@ void R_DeriveLightData( idRenderLightLocal* light );
|
|||
void R_RenderLightFrustum( const renderLight_t& renderLight, idPlane lightFrustum[6] );
|
||||
|
||||
srfTriangles_t* R_PolytopeSurface( int numPlanes, const idPlane* planes, idWinding** windings );
|
||||
|
||||
void R_CreateEnvprobeRefs( RenderEnvprobeLocal* probe );
|
||||
void R_FreeEnvprobeDefDerivedData( RenderEnvprobeLocal* probe );
|
||||
|
||||
// RB end
|
||||
void R_CreateLightRefs( idRenderLightLocal* light );
|
||||
void R_FreeLightDefDerivedData( idRenderLightLocal* light );
|
||||
|
|
|
@ -129,6 +129,38 @@ int idRenderLightLocal::GetIndex()
|
|||
return index;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
RenderEnvprobeLocal::RenderEnvprobeLocal()
|
||||
{
|
||||
memset( &parms, 0, sizeof( parms ) );
|
||||
|
||||
envprobeHasMoved = false;
|
||||
world = NULL;
|
||||
index = 0;
|
||||
areaNum = 0;
|
||||
lastModifiedFrameNum = 0;
|
||||
archived = false;
|
||||
references = NULL;
|
||||
}
|
||||
|
||||
void RenderEnvprobeLocal::FreeRenderEnvprobe()
|
||||
{
|
||||
}
|
||||
void RenderEnvprobeLocal::UpdateRenderEnvprobe( const renderEnvironmentProbe_t* ep, bool forceUpdate )
|
||||
{
|
||||
}
|
||||
void RenderEnvprobeLocal::GetRenderEnvprobe( renderEnvironmentProbe_t* ep )
|
||||
{
|
||||
}
|
||||
void RenderEnvprobeLocal::ForceUpdate()
|
||||
{
|
||||
}
|
||||
int RenderEnvprobeLocal::GetIndex()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
void idRenderEntityLocal::ReadFromDemoFile( class idDemoFile* f )
|
||||
{
|
||||
|
|
|
@ -109,6 +109,10 @@ void idRenderProgManager::Init()
|
|||
{ BUILTIN_VERTEX_COLOR, "vertex_color.vfp", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING, "ambient_lighting", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_SKINNED, "ambient_lighting", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_IBL, "ambient_lighting_IBL", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED, "ambient_lighting_IBL", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_IBL_PBR, "ambient_lighting_IBL", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED, "ambient_lighting_IBL", "_PBR_skinned", BIT( USE_GPU_SKINNING | USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_SMALL_GEOMETRY_BUFFER, "gbuffer", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
{ BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED, "gbuffer", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
|
||||
// RB end
|
||||
|
@ -242,6 +246,8 @@ void idRenderProgManager::Init()
|
|||
renderProgs[builtinShaders[BUILTIN_FOG_SKINNED]].usesJoints = true;
|
||||
// RB begin
|
||||
renderProgs[builtinShaders[BUILTIN_AMBIENT_LIGHTING_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED]].usesJoints = true;
|
||||
renderProgs[builtinShaders[BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED]].usesJoints = true;
|
||||
|
@ -661,4 +667,4 @@ void RpPrintState( uint64 stateBits, uint64* stencilBits )
|
|||
{
|
||||
printStencil( STENCIL_FACE_NUM, stateBits, mask, ref );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,6 +290,26 @@ public:
|
|||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTING_SKINNED );
|
||||
}
|
||||
|
||||
void BindShader_ImageBasedLighting()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTING_IBL );
|
||||
}
|
||||
|
||||
void BindShader_ImageBasedLightingSkinned()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED );
|
||||
}
|
||||
|
||||
void BindShader_ImageBasedLighting_PBR()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTING_IBL_PBR );
|
||||
}
|
||||
|
||||
void BindShader_ImageBasedLightingSkinned_PBR()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED );
|
||||
}
|
||||
|
||||
void BindShader_SmallGeometryBuffer()
|
||||
{
|
||||
BindShader_Builtin( BUILTIN_SMALL_GEOMETRY_BUFFER );
|
||||
|
@ -647,6 +667,10 @@ private:
|
|||
BUILTIN_VERTEX_COLOR,
|
||||
BUILTIN_AMBIENT_LIGHTING,
|
||||
BUILTIN_AMBIENT_LIGHTING_SKINNED,
|
||||
BUILTIN_AMBIENT_LIGHTING_IBL,
|
||||
BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED,
|
||||
BUILTIN_AMBIENT_LIGHTING_IBL_PBR,
|
||||
BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED,
|
||||
BUILTIN_SMALL_GEOMETRY_BUFFER,
|
||||
BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED,
|
||||
// RB end
|
||||
|
@ -732,6 +756,7 @@ private:
|
|||
BRIGHTPASS,
|
||||
HDR_DEBUG,
|
||||
USE_SRGB,
|
||||
USE_PBR,
|
||||
|
||||
MAX_SHADER_MACRO_NAMES,
|
||||
};
|
||||
|
|
|
@ -314,7 +314,8 @@ const char* idRenderProgManager::GLSLMacroNames[MAX_SHADER_MACRO_NAMES] =
|
|||
"LIGHT_PARALLEL",
|
||||
"BRIGHTPASS",
|
||||
"HDR_DEBUG",
|
||||
"USE_SRGB"
|
||||
"USE_SRGB",
|
||||
"USE_PBR"
|
||||
};
|
||||
// RB end
|
||||
|
||||
|
|
|
@ -1800,6 +1800,11 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" return specularColor + ( 1.0 - specularColor ) * pow( 1.0 - vdotH, 5.0 );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"half3 Fresnel_Glossy( half3 specularColor, half roughness, half vdotH )\n"
|
||||
"{\n"
|
||||
" return specularColor + ( max( half3( 1.0 - roughness ), specularColor ) - specularColor ) * pow( 1.0 - vdotH, 5.0 );\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"// Visibility term G( l, v, h )\n"
|
||||
"// Very similar to Marmoset Toolbag 2 and gives almost the same results as Smith GGX\n"
|
||||
"float Visibility_Schlick( half vdotN, half ldotN, float alpha )\n"
|
||||
|
@ -2185,6 +2190,382 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
|
||||
},
|
||||
|
||||
{
|
||||
"renderprogs/ambient_lighting_IBL.ps.hlsl",
|
||||
"/*\n"
|
||||
"===========================================================================\n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition GPL Source Code\n"
|
||||
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. \n"
|
||||
"Copyright (C) 2013-2019 Robert Beckebans\n"
|
||||
"\n"
|
||||
"This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\"). \n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation, either version 3 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU General Public License\n"
|
||||
"along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.\n"
|
||||
"\n"
|
||||
"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.\n"
|
||||
"\n"
|
||||
"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.\n"
|
||||
"\n"
|
||||
"===========================================================================\n"
|
||||
"*/\n"
|
||||
"\n"
|
||||
"#include \"global.inc.hlsl\"\n"
|
||||
"#include \"BRDF.inc.hlsl\"\n"
|
||||
"\n"
|
||||
"uniform sampler2D samp0 : register(s0); // texture 1 is the per-surface normal map\n"
|
||||
"uniform sampler2D samp1 : register(s1); // texture 3 is the per-surface specular or roughness/metallic/AO mixer map\n"
|
||||
"uniform sampler2D samp2 : register(s2); // texture 2 is the per-surface baseColor map \n"
|
||||
"uniform sampler2D samp3 : register(s3); // texture 4 is the light falloff texture\n"
|
||||
"uniform sampler2D samp4 : register(s4); // texture 5 is the light projection texture\n"
|
||||
"\n"
|
||||
"uniform samplerCUBE samp7 : register(s7); // texture 0 is the cube map\n"
|
||||
"uniform samplerCUBE samp8 : register(s8); // texture 0 is the cube map\n"
|
||||
"\n"
|
||||
"struct PS_IN {\n"
|
||||
" half4 position : VPOS;\n"
|
||||
" half4 texcoord0 : TEXCOORD0_centroid;\n"
|
||||
" half4 texcoord1 : TEXCOORD1_centroid;\n"
|
||||
" half4 texcoord2 : TEXCOORD2_centroid;\n"
|
||||
" half4 texcoord3 : TEXCOORD3_centroid;\n"
|
||||
" half4 texcoord4 : TEXCOORD4_centroid;\n"
|
||||
" half4 texcoord5 : TEXCOORD5_centroid;\n"
|
||||
" half4 texcoord6 : TEXCOORD6_centroid;\n"
|
||||
" half4 color : COLOR0;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct PS_OUT {\n"
|
||||
" half4 color : COLOR;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"void main( PS_IN fragment, out PS_OUT result ) {\n"
|
||||
" half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy );\n"
|
||||
"// half4 lightFalloff = idtex2Dproj( samp1, fragment.texcoord2 );\n"
|
||||
"// half4 lightProj = idtex2Dproj( samp2, fragment.texcoord3 );\n"
|
||||
" half4 YCoCG = tex2D( samp2, fragment.texcoord1.xy );\n"
|
||||
" half4 specMap = tex2D( samp1, fragment.texcoord2.xy );\n"
|
||||
"\n"
|
||||
" //half3 lightVector = normalize( fragment.texcoord0.xyz );\n"
|
||||
" half3 diffuseMap = sRGBToLinearRGB( ConvertYCoCgToRGB( YCoCG ) );\n"
|
||||
"\n"
|
||||
" half3 localNormal;\n"
|
||||
"#if defined(USE_NORMAL_FMT_RGB8)\n"
|
||||
" localNormal.xy = bumpMap.rg - 0.5;\n"
|
||||
"#else\n"
|
||||
" localNormal.xy = bumpMap.wy - 0.5;\n"
|
||||
"#endif\n"
|
||||
" localNormal.z = sqrt( abs( dot( localNormal.xy, localNormal.xy ) - 0.25 ) );\n"
|
||||
" localNormal = normalize( localNormal );\n"
|
||||
"\n"
|
||||
" //const half specularPower = 10.0f;\n"
|
||||
" //half hDotN = dot3( normalize( fragment.texcoord6.xyz ), localNormal );\n"
|
||||
" // RB: added abs\n"
|
||||
" //half3 specularContribution = _half3( pow( abs( hDotN ), specularPower ) );\n"
|
||||
"\n"
|
||||
" //half3 diffuseColor = diffuseMap * ( rpDiffuseModifier.xyz ) * 1.5f;\n"
|
||||
" //half3 specularColor = specMap.xyz * specularContribution * ( rpSpecularModifier.xyz ); \n"
|
||||
" \n"
|
||||
" // RB: http://developer.valvesoftware.com/wiki/Half_Lambert\n"
|
||||
" //float halfLdotN = dot3( localNormal, lightVector ) * 0.5 + 0.5;\n"
|
||||
" //halfLdotN *= halfLdotN;\n"
|
||||
" \n"
|
||||
" // traditional very dark Lambert light model used in Doom 3\n"
|
||||
" //float ldotN = dot3( localNormal, lightVector );\n"
|
||||
" \n"
|
||||
" float3 globalNormal;\n"
|
||||
" globalNormal.x = dot3( localNormal, fragment.texcoord4 );\n"
|
||||
" globalNormal.y = dot3( localNormal, fragment.texcoord5 );\n"
|
||||
" globalNormal.z = dot3( localNormal, fragment.texcoord6 );\n"
|
||||
"\n"
|
||||
" float3 globalEye = normalize( fragment.texcoord3.xyz );\n"
|
||||
"\n"
|
||||
" float3 reflectionVector = globalNormal * dot3( globalEye, globalNormal );\n"
|
||||
" reflectionVector = ( reflectionVector * 2.0f ) - globalEye;\n"
|
||||
" \n"
|
||||
"#if defined(USE_PBR)\n"
|
||||
" \n"
|
||||
" const half metallic = specMap.g;\n"
|
||||
" const half roughness = specMap.r;\n"
|
||||
" const half glossiness = 1.0 - roughness;\n"
|
||||
"\n"
|
||||
" // the vast majority of real-world materials (anything not metal or gems) have F(0°)\n"
|
||||
" // values in a very narrow range (~0.02 - 0.08)\n"
|
||||
" \n"
|
||||
" // approximate non-metals with linear RGB 0.04 which is 0.08 * 0.5 (default in UE4)\n"
|
||||
" const half3 dielectricColor = half3( 0.04 );\n"
|
||||
" \n"
|
||||
" // derive diffuse and specular from albedo(m) base color\n"
|
||||
" const half3 baseColor = diffuseMap;\n"
|
||||
" \n"
|
||||
" half3 diffuseColor = baseColor * ( 1.0 - metallic );\n"
|
||||
" half3 specularColor = lerp( dielectricColor, baseColor, metallic );\n"
|
||||
" \n"
|
||||
" //diffuseColor = half3( 1.0 );\n"
|
||||
" float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseColor * ( rpDiffuseModifier.xyz ) * 1.5f;\n"
|
||||
" \n"
|
||||
" //specularColor = half3( 0.0 );\n"
|
||||
" \n"
|
||||
" float mip = clamp( ( roughness * 7.0 ) + 3.0, 0.0, 10.0 );\n"
|
||||
" float3 envColor = ( textureLod( samp8, reflectionVector, mip ).rgb ) * ( rpSpecularModifier.xyz ) * 1.0f;\n"
|
||||
" \n"
|
||||
" float3 specularLight = envColor * specularColor;\n"
|
||||
" \n"
|
||||
"#else\n"
|
||||
" \n"
|
||||
" half4 specMapSRGB = specMap;\n"
|
||||
" specMap = sRGBAToLinearRGBA( specMap );\n"
|
||||
" \n"
|
||||
" //float3 diffuseLight = sRGBToLinearRGB( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;\n"
|
||||
" float3 diffuseLight = ( texCUBE( samp7, globalNormal ).rgb ) * diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 3.5f;\n"
|
||||
" //float3 diffuseLight = diffuseMap.rgb * ( rpDiffuseModifier.xyz ) * 1.5f;\n"
|
||||
"\n"
|
||||
" // HACK calculate roughness from D3 gloss maps\n"
|
||||
" float Y = dot( LUMINANCE_SRGB.rgb, specMapSRGB.rgb );\n"
|
||||
" \n"
|
||||
" //const float glossiness = clamp( 1.0 - specMapSRGB.r, 0.0, 0.98 );\n"
|
||||
" const float glossiness = clamp( pow( Y, 1.0 / 2.0 ), 0.0, 0.98 );\n"
|
||||
" \n"
|
||||
" const float roughness = 1.0 - glossiness;\n"
|
||||
" \n"
|
||||
" float mip = clamp( ( roughness * 7.0 ) + 0.0, 0.0, 10.0 );\n"
|
||||
" float3 envColor = ( textureLod( samp8, reflectionVector, mip ).rgb ) * ( rpSpecularModifier.xyz ) * 0.5f;\n"
|
||||
" \n"
|
||||
" float3 specularLight = envColor * specMap.rgb;\n"
|
||||
" \n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" // add glossy fresnel\n"
|
||||
" half hDotN = saturate( dot3( globalEye, globalNormal ) );\n"
|
||||
" \n"
|
||||
" half3 specularColor2 = half3( 0.0 );\n"
|
||||
" float3 glossyFresnel = Fresnel_Glossy( specularColor2, roughness, hDotN );\n"
|
||||
" \n"
|
||||
" // horizon fade\n"
|
||||
" const half horizonFade = 1.3;\n"
|
||||
" half horiz = saturate( 1.0 + horizonFade * saturate( dot3( reflectionVector, globalNormal ) ) );\n"
|
||||
" horiz *= horiz;\n"
|
||||
" //horiz = clamp( horiz, 0.0, 1.0 );\n"
|
||||
" \n"
|
||||
" //specularLight = glossyFresnel * envColor;\n"
|
||||
" specularLight += glossyFresnel * envColor * ( rpSpecularModifier.xyz ) * 0.9 * horiz;\n"
|
||||
"\n"
|
||||
" half3 lightColor = sRGBToLinearRGB( rpAmbientColor.rgb );\n"
|
||||
" \n"
|
||||
" //result.color.rgb = diffuseLight;\n"
|
||||
" //result.color.rgb = diffuseLight * lightColor;\n"
|
||||
" //result.color.rgb = specularLight;\n"
|
||||
" result.color.rgb = ( diffuseLight + specularLight ) * lightColor * fragment.color.rgb;\n"
|
||||
" //result.color.rgb = localNormal.xyz * 0.5 + 0.5;\n"
|
||||
" //result.color.xyz = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor ) * fragment.color.rgb;\n"
|
||||
" //result.color = ( ( diffuseColor + specularColor ) * halfLdotN * lightColor + rimColor ) * fragment.color.rgba;\n"
|
||||
" result.color.w = fragment.color.a;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
"renderprogs/ambient_lighting_IBL.vs.hlsl",
|
||||
"/*\n"
|
||||
"===========================================================================\n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition GPL Source Code\n"
|
||||
"Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. \n"
|
||||
"Copyright (C) 2013-2015 Robert Beckebans\n"
|
||||
"\n"
|
||||
"This file is part of the Doom 3 BFG Edition GPL Source Code (\"Doom 3 BFG Edition Source Code\"). \n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation, either version 3 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU General Public License\n"
|
||||
"along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.\n"
|
||||
"\n"
|
||||
"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.\n"
|
||||
"\n"
|
||||
"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.\n"
|
||||
"\n"
|
||||
"===========================================================================\n"
|
||||
"*/\n"
|
||||
"\n"
|
||||
"#include \"global.inc.hlsl\"\n"
|
||||
"\n"
|
||||
"#if defined( USE_GPU_SKINNING )\n"
|
||||
"uniform matrices_ubo { float4 matrices[408]; };\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"struct VS_IN {\n"
|
||||
" float4 position : POSITION;\n"
|
||||
" float2 texcoord : TEXCOORD0;\n"
|
||||
" float4 normal : NORMAL;\n"
|
||||
" float4 tangent : TANGENT;\n"
|
||||
" float4 color : COLOR0;\n"
|
||||
" float4 color2 : COLOR1;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VS_OUT {\n"
|
||||
" float4 position : POSITION;\n"
|
||||
" float4 texcoord0 : TEXCOORD0;\n"
|
||||
" float4 texcoord1 : TEXCOORD1;\n"
|
||||
" float4 texcoord2 : TEXCOORD2;\n"
|
||||
" float4 texcoord3 : TEXCOORD3;\n"
|
||||
" float4 texcoord4 : TEXCOORD4;\n"
|
||||
" float4 texcoord5 : TEXCOORD5;\n"
|
||||
" float4 texcoord6 : TEXCOORD6;\n"
|
||||
" float4 color : COLOR0;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"void main( VS_IN vertex, out VS_OUT result ) {\n"
|
||||
"\n"
|
||||
" float4 vNormal = vertex.normal * 2.0 - 1.0;\n"
|
||||
" float4 vTangent = vertex.tangent * 2.0 - 1.0;\n"
|
||||
" float3 vBitangent = cross( vNormal.xyz, vTangent.xyz ) * vTangent.w;\n"
|
||||
"\n"
|
||||
"#if defined( USE_GPU_SKINNING )\n"
|
||||
" //--------------------------------------------------------------\n"
|
||||
" // GPU transformation of the normal / tangent / bitangent\n"
|
||||
" //\n"
|
||||
" // multiplying with 255.1 give us the same result and is faster than floor( w * 255 + 0.5 )\n"
|
||||
" //--------------------------------------------------------------\n"
|
||||
" const float w0 = vertex.color2.x;\n"
|
||||
" const float w1 = vertex.color2.y;\n"
|
||||
" const float w2 = vertex.color2.z;\n"
|
||||
" const float w3 = vertex.color2.w;\n"
|
||||
"\n"
|
||||
" float4 matX, matY, matZ; // must be float4 for vec4\n"
|
||||
" int joint = int(vertex.color.x * 255.1 * 3.0);\n"
|
||||
" matX = matrices[int(joint+0)] * w0;\n"
|
||||
" matY = matrices[int(joint+1)] * w0;\n"
|
||||
" matZ = matrices[int(joint+2)] * w0;\n"
|
||||
"\n"
|
||||
" joint = int(vertex.color.y * 255.1 * 3.0);\n"
|
||||
" matX += matrices[int(joint+0)] * w1;\n"
|
||||
" matY += matrices[int(joint+1)] * w1;\n"
|
||||
" matZ += matrices[int(joint+2)] * w1;\n"
|
||||
"\n"
|
||||
" joint = int(vertex.color.z * 255.1 * 3.0);\n"
|
||||
" matX += matrices[int(joint+0)] * w2;\n"
|
||||
" matY += matrices[int(joint+1)] * w2;\n"
|
||||
" matZ += matrices[int(joint+2)] * w2;\n"
|
||||
"\n"
|
||||
" joint = int(vertex.color.w * 255.1 * 3.0);\n"
|
||||
" matX += matrices[int(joint+0)] * w3;\n"
|
||||
" matY += matrices[int(joint+1)] * w3;\n"
|
||||
" matZ += matrices[int(joint+2)] * w3;\n"
|
||||
"\n"
|
||||
" float3 normal;\n"
|
||||
" normal.x = dot3( matX, vNormal );\n"
|
||||
" normal.y = dot3( matY, vNormal );\n"
|
||||
" normal.z = dot3( matZ, vNormal );\n"
|
||||
" normal = normalize( normal );\n"
|
||||
"\n"
|
||||
" float3 tangent;\n"
|
||||
" tangent.x = dot3( matX, vTangent );\n"
|
||||
" tangent.y = dot3( matY, vTangent );\n"
|
||||
" tangent.z = dot3( matZ, vTangent );\n"
|
||||
" tangent = normalize( tangent );\n"
|
||||
"\n"
|
||||
" float3 bitangent;\n"
|
||||
" bitangent.x = dot3( matX, vBitangent );\n"
|
||||
" bitangent.y = dot3( matY, vBitangent );\n"
|
||||
" bitangent.z = dot3( matZ, vBitangent );\n"
|
||||
" bitangent = normalize( bitangent );\n"
|
||||
"\n"
|
||||
" float4 modelPosition;\n"
|
||||
" modelPosition.x = dot4( matX, vertex.position );\n"
|
||||
" modelPosition.y = dot4( matY, vertex.position );\n"
|
||||
" modelPosition.z = dot4( matZ, vertex.position );\n"
|
||||
" modelPosition.w = 1.0;\n"
|
||||
"\n"
|
||||
"#else\n"
|
||||
" float4 modelPosition = vertex.position;\n"
|
||||
" float3 normal = vNormal.xyz;\n"
|
||||
" float3 tangent = vTangent.xyz;\n"
|
||||
" float3 bitangent = vBitangent.xyz;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
" result.position.x = dot4( modelPosition, rpMVPmatrixX );\n"
|
||||
" result.position.y = dot4( modelPosition, rpMVPmatrixY );\n"
|
||||
" result.position.z = dot4( modelPosition, rpMVPmatrixZ );\n"
|
||||
" result.position.w = dot4( modelPosition, rpMVPmatrixW );\n"
|
||||
"\n"
|
||||
" float4 defaultTexCoord = float4( 0.0f, 0.5f, 0.0f, 1.0f );\n"
|
||||
"\n"
|
||||
" //calculate vector to light\n"
|
||||
" //float4 toLight = rpLocalLightOrigin;\n"
|
||||
" float4 toLight = normalize( float4( 0.0f, 0.5f, 1.0f, 1.0f ) );\n"
|
||||
"\n"
|
||||
" //--------------------------------------------------------------\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" //# textures 0 takes the base coordinates by the texture matrix\n"
|
||||
" result.texcoord0 = defaultTexCoord;\n"
|
||||
" result.texcoord0.x = dot4( vertex.texcoord.xy, rpBumpMatrixS );\n"
|
||||
" result.texcoord0.y = dot4( vertex.texcoord.xy, rpBumpMatrixT );\n"
|
||||
"\n"
|
||||
" //# textures 1 takes the base coordinates by the texture matrix\n"
|
||||
" result.texcoord1 = defaultTexCoord;\n"
|
||||
" result.texcoord1.x = dot4( vertex.texcoord.xy, rpDiffuseMatrixS );\n"
|
||||
" result.texcoord1.y = dot4( vertex.texcoord.xy, rpDiffuseMatrixT );\n"
|
||||
"\n"
|
||||
" //# textures 2 takes the base coordinates by the texture matrix\n"
|
||||
" result.texcoord2 = defaultTexCoord;\n"
|
||||
" result.texcoord2.x = dot4( vertex.texcoord.xy, rpSpecularMatrixS );\n"
|
||||
" result.texcoord2.y = dot4( vertex.texcoord.xy, rpSpecularMatrixT );\n"
|
||||
"\n"
|
||||
" //# calculate normalized vector to viewer in R1\n"
|
||||
" float4 toEye = normalize( rpLocalViewOrigin - modelPosition );\n"
|
||||
"\n"
|
||||
" result.texcoord3.x = dot3( toEye, rpModelMatrixX );\n"
|
||||
" result.texcoord3.y = dot3( toEye, rpModelMatrixY );\n"
|
||||
" result.texcoord3.z = dot3( toEye, rpModelMatrixZ );\n"
|
||||
" \n"
|
||||
" result.texcoord4.x = dot3( tangent, rpModelMatrixX );\n"
|
||||
" result.texcoord5.x = dot3( tangent, rpModelMatrixY );\n"
|
||||
" result.texcoord6.x = dot3( tangent, rpModelMatrixZ );\n"
|
||||
"\n"
|
||||
" result.texcoord4.y = dot3( bitangent, rpModelMatrixX );\n"
|
||||
" result.texcoord5.y = dot3( bitangent, rpModelMatrixY );\n"
|
||||
" result.texcoord6.y = dot3( bitangent, rpModelMatrixZ );\n"
|
||||
"\n"
|
||||
" result.texcoord4.z = dot3( normal, rpModelMatrixX );\n"
|
||||
" result.texcoord5.z = dot3( normal, rpModelMatrixY );\n"
|
||||
" result.texcoord6.z = dot3( normal, rpModelMatrixZ );\n"
|
||||
"\n"
|
||||
"#if defined( USE_GPU_SKINNING )\n"
|
||||
" // for joint transformation of the tangent space, we use color and\n"
|
||||
" // color2 for weighting information, so hopefully there aren't any\n"
|
||||
" // effects that need vertex color...\n"
|
||||
" result.color = float4( 1.0f, 1.0f, 1.0f, 1.0f );\n"
|
||||
"#else\n"
|
||||
" //# generate the vertex color, which can be 1.0, color, or 1.0 - color\n"
|
||||
" //# for 1.0 : env[16] = 0, env[17] = 1\n"
|
||||
" //# for color : env[16] = 1, env[17] = 0\n"
|
||||
" //# for 1.0-color : env[16] = -1, env[17] = 1 \n"
|
||||
" result.color = ( swizzleColor( vertex.color ) * rpVertexColorModulate ) + rpVertexColorAdd;\n"
|
||||
"#endif\n"
|
||||
"}\n"
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
"renderprogs/AmbientOcclusion_AO.ps.hlsl",
|
||||
"/**\n"
|
||||
|
@ -12313,7 +12694,11 @@ static const cgShaderDef_t cg_renderprogs[] =
|
|||
" \n"
|
||||
"#if OPERATOR == 0\n"
|
||||
" // advanced Reinhard operator, artistically desirable to burn out bright areas\n"
|
||||
" float L = Yr * ( 1.0 + Yr / ( Ymax * Ymax ) ) / ( 1.0 + Yr );\n"
|
||||
" //float L = Yr * ( 1.0 + Yr / ( Ymax * Ymax ) ) / ( 1.0 + Yr );\n"
|
||||
" \n"
|
||||
" // exponential tone mapper that is very similar to the Uncharted one\n"
|
||||
" // very good in keeping the colors natural\n"
|
||||
" float L = 1.0 - exp( -Yr );\n"
|
||||
" color.rgb *= L;\n"
|
||||
"\n"
|
||||
"#elif OPERATOR == 1\n"
|
||||
|
|
|
@ -267,7 +267,7 @@ idCVar r_ldrContrastThreshold( "r_ldrContrastThreshold", "1.1", CVAR_RENDERER |
|
|||
idCVar r_ldrContrastOffset( "r_ldrContrastOffset", "3", CVAR_RENDERER | CVAR_FLOAT, "" );
|
||||
|
||||
idCVar r_useFilmicPostProcessEffects( "r_useFilmicPostProcessEffects", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "apply several post process effects to mimic a filmic look" );
|
||||
idCVar r_forceAmbient( "r_forceAmbient", "0.2", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "render additional ambient pass to make the game less dark", 0.0f, 0.4f );
|
||||
idCVar r_forceAmbient( "r_forceAmbient", "0.3", CVAR_RENDERER | CVAR_FLOAT, "render additional ambient pass to make the game less dark", 0.0f, 0.4f );
|
||||
|
||||
idCVar r_useSSGI( "r_useSSGI", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use screen space global illumination and reflections" );
|
||||
idCVar r_ssgiDebug( "r_ssgiDebug", "0", CVAR_RENDERER | CVAR_INTEGER, "" );
|
||||
|
|
|
@ -611,6 +611,155 @@ const renderLight_t* idRenderWorldLocal::GetRenderLight( qhandle_t lightHandle )
|
|||
return &def->parms;
|
||||
}
|
||||
|
||||
|
||||
// RB begin
|
||||
qhandle_t idRenderWorldLocal::AddEnvprobeDef( const renderEnvironmentProbe_t* ep )
|
||||
{
|
||||
// try and reuse a free spot
|
||||
int envprobeHandle = envprobeDefs.FindNull();
|
||||
|
||||
if( envprobeHandle == -1 )
|
||||
{
|
||||
envprobeHandle = envprobeDefs.Append( NULL );
|
||||
|
||||
// TODO
|
||||
//if( interactionTable && envprobeDefs.Num() > interactionTableHeight )
|
||||
//{
|
||||
// ResizeEnvprobeInteractionTable();
|
||||
//}
|
||||
}
|
||||
|
||||
UpdateEnvprobeDef( envprobeHandle, ep );
|
||||
|
||||
return envprobeHandle;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
UpdateEnvprobeDef
|
||||
|
||||
The generation of all the derived interaction data will
|
||||
usually be deferred until it is visible in a scene
|
||||
|
||||
Does not write to the demo file, which will only be done for visible lights
|
||||
=================
|
||||
*/
|
||||
void idRenderWorldLocal::UpdateEnvprobeDef( qhandle_t envprobeHandle, const renderEnvironmentProbe_t* ep )
|
||||
{
|
||||
if( r_skipUpdates.GetBool() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
tr.pc.c_envprobeUpdates++;
|
||||
|
||||
// create new slots if needed
|
||||
if( envprobeHandle < 0 || envprobeHandle > LUDICROUS_INDEX )
|
||||
{
|
||||
common->Error( "idRenderWorld::UpdateEnvprobeDef: index = %i", envprobeHandle );
|
||||
}
|
||||
while( envprobeHandle >= envprobeDefs.Num() )
|
||||
{
|
||||
envprobeDefs.Append( NULL );
|
||||
}
|
||||
|
||||
bool justUpdate = false;
|
||||
RenderEnvprobeLocal* probe = envprobeDefs[envprobeHandle];
|
||||
if( probe )
|
||||
{
|
||||
// if the shape of the envprobe stays the same, we don't need to dump
|
||||
// any of our derived data, because shader parms are calculated every frame
|
||||
if( ep->origin == probe->parms.origin )
|
||||
{
|
||||
justUpdate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
probe->envprobeHasMoved = true;
|
||||
R_FreeEnvprobeDefDerivedData( probe );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// create a new one
|
||||
probe = new( TAG_RENDER_LIGHT ) RenderEnvprobeLocal;
|
||||
envprobeDefs[envprobeHandle] = probe;
|
||||
|
||||
probe->world = this;
|
||||
probe->index = envprobeHandle;
|
||||
}
|
||||
|
||||
probe->parms = *ep;
|
||||
probe->lastModifiedFrameNum = tr.frameCount;
|
||||
if( common->WriteDemo() && probe->archived )
|
||||
{
|
||||
WriteFreeEnvprobe( envprobeHandle );
|
||||
probe->archived = false;
|
||||
}
|
||||
|
||||
if( !justUpdate )
|
||||
{
|
||||
R_CreateEnvprobeRefs( probe );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
FreeEnvprobeDef
|
||||
|
||||
Frees all references and lit surfaces from the light, and
|
||||
NULL's out it's entry in the world list
|
||||
====================
|
||||
*/
|
||||
void idRenderWorldLocal::FreeEnvprobeDef( qhandle_t envprobeHandle )
|
||||
{
|
||||
RenderEnvprobeLocal* probe;
|
||||
|
||||
if( envprobeHandle < 0 || envprobeHandle >= envprobeDefs.Num() )
|
||||
{
|
||||
common->Printf( "idRenderWorld::FreeEnvprobeDef: invalid handle %i [0, %i]\n", envprobeHandle, envprobeDefs.Num() );
|
||||
return;
|
||||
}
|
||||
|
||||
probe = envprobeDefs[envprobeHandle];
|
||||
if( !probe )
|
||||
{
|
||||
common->Printf( "idRenderWorld::FreeEnvprobeDef: handle %i is NULL\n", envprobeHandle );
|
||||
return;
|
||||
}
|
||||
|
||||
R_FreeEnvprobeDefDerivedData( probe );
|
||||
|
||||
if( common->WriteDemo() && probe->archived )
|
||||
{
|
||||
WriteFreeEnvprobe( envprobeHandle );
|
||||
}
|
||||
|
||||
delete probe;
|
||||
envprobeDefs[envprobeHandle] = NULL;
|
||||
}
|
||||
|
||||
const renderEnvironmentProbe_t* idRenderWorldLocal::GetRenderEnvprobe( qhandle_t envprobeHandle ) const
|
||||
{
|
||||
RenderEnvprobeLocal* def;
|
||||
|
||||
if( envprobeHandle < 0 || envprobeHandle >= envprobeDefs.Num() )
|
||||
{
|
||||
common->Printf( "idRenderWorld::GetRenderEnvprobe: handle %i > %i\n", envprobeHandle, envprobeDefs.Num() );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
def = envprobeDefs[envprobeHandle];
|
||||
if( !def )
|
||||
{
|
||||
common->Printf( "idRenderWorld::GetRenderEnvprobe: handle %i is NULL\n", envprobeHandle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &def->parms;
|
||||
}
|
||||
// RB end
|
||||
|
||||
/*
|
||||
================
|
||||
idRenderWorldLocal::ProjectDecalOntoWorld
|
||||
|
@ -1739,6 +1888,35 @@ void idRenderWorldLocal::AddLightRefToArea( idRenderLightLocal* light, portalAre
|
|||
area->lightRefs.areaNext = lref;
|
||||
}
|
||||
|
||||
// RB begin
|
||||
void idRenderWorldLocal::AddEnvprobeRefToArea( RenderEnvprobeLocal* probe, portalArea_t* area )
|
||||
{
|
||||
areaReference_t* lref;
|
||||
|
||||
for( lref = probe->references; lref != NULL; lref = lref->ownerNext )
|
||||
{
|
||||
if( lref->area == area )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// add a envproberef to this area
|
||||
lref = areaReferenceAllocator.Alloc();
|
||||
lref->envprobe = probe;
|
||||
lref->area = area;
|
||||
lref->ownerNext = probe->references;
|
||||
probe->references = lref;
|
||||
tr.pc.c_lightReferences++;
|
||||
|
||||
// doubly linked list so we can free them easily later
|
||||
area->envprobeRefs.areaNext->areaPrev = lref;
|
||||
lref->areaNext = area->envprobeRefs.areaNext;
|
||||
lref->areaPrev = &area->envprobeRefs;
|
||||
area->envprobeRefs.areaNext = lref;
|
||||
}
|
||||
// RB end
|
||||
|
||||
/*
|
||||
===================
|
||||
idRenderWorldLocal::GenerateAllInteractions
|
||||
|
@ -1955,6 +2133,67 @@ void idRenderWorldLocal::PushFrustumIntoTree( idRenderEntityLocal* def, idRender
|
|||
PushFrustumIntoTree_r( def, light, corners, 0 );
|
||||
}
|
||||
|
||||
|
||||
// RB begin
|
||||
void idRenderWorldLocal::PushEnvprobeIntoTree_r( RenderEnvprobeLocal* probe, int nodeNum )
|
||||
{
|
||||
if( nodeNum < 0 )
|
||||
{
|
||||
int areaNum = -1 - nodeNum;
|
||||
portalArea_t* area = &portalAreas[ areaNum ];
|
||||
if( area->viewCount == tr.viewCount )
|
||||
{
|
||||
return; // already added a reference here
|
||||
}
|
||||
area->viewCount = tr.viewCount;
|
||||
|
||||
if( probe != NULL )
|
||||
{
|
||||
AddEnvprobeRefToArea( probe, area );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
areaNode_t* node = areaNodes + nodeNum;
|
||||
|
||||
// if we know that all possible children nodes only touch an area
|
||||
// we have already marked, we can early out
|
||||
if( node->commonChildrenArea != CHILDREN_HAVE_MULTIPLE_AREAS && r_useNodeCommonChildren.GetBool() )
|
||||
{
|
||||
// note that we do NOT try to set a reference in this area
|
||||
// yet, because the test volume may yet wind up being in the
|
||||
// solid part, which would cause bounds slightly poked into
|
||||
// a wall to show up in the next room
|
||||
if( portalAreas[ node->commonChildrenArea ].viewCount == tr.viewCount )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int cull = node->plane.Side( probe->parms.origin );
|
||||
|
||||
if( cull != PLANESIDE_BACK )
|
||||
{
|
||||
nodeNum = node->children[0];
|
||||
if( nodeNum != 0 ) // 0 = solid
|
||||
{
|
||||
PushEnvprobeIntoTree_r( probe, nodeNum );
|
||||
}
|
||||
}
|
||||
|
||||
if( cull != PLANESIDE_FRONT )
|
||||
{
|
||||
nodeNum = node->children[1];
|
||||
if( nodeNum != 0 ) // 0 = solid
|
||||
{
|
||||
PushEnvprobeIntoTree_r( probe, nodeNum );
|
||||
}
|
||||
}
|
||||
}
|
||||
// RB end
|
||||
|
||||
//===================================================================
|
||||
|
||||
/*
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2015 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -216,6 +217,24 @@ typedef struct renderLight_s
|
|||
} renderLight_t;
|
||||
|
||||
|
||||
// RB begin
|
||||
typedef struct
|
||||
{
|
||||
idVec3 origin;
|
||||
float shaderParms[MAX_ENTITY_SHADER_PARMS];
|
||||
|
||||
// if non-zero, the environment probe will not show up in the specific view,
|
||||
// which may be used if we want to have slightly different muzzle
|
||||
// flash lights for the player and other views
|
||||
int suppressEnvprobeInViewID;
|
||||
|
||||
// if non-zero, the environment probe will only show up in the specific view
|
||||
// which can allow player gun gui lights and such to not effect everyone
|
||||
int allowEnvprobeInViewID;
|
||||
|
||||
} renderEnvironmentProbe_t;
|
||||
// RB end
|
||||
|
||||
typedef struct renderView_s
|
||||
{
|
||||
// player views will set this to a non-zero integer for model suppress / allow
|
||||
|
@ -315,6 +334,13 @@ public:
|
|||
virtual void FreeLightDef( qhandle_t lightHandle ) = 0;
|
||||
virtual const renderLight_t* GetRenderLight( qhandle_t lightHandle ) const = 0;
|
||||
|
||||
// RB: environment probes for IBL
|
||||
virtual qhandle_t AddEnvprobeDef( const renderEnvironmentProbe_t* ep ) = 0;
|
||||
virtual void UpdateEnvprobeDef( qhandle_t envprobeHandle, const renderEnvironmentProbe_t* ep ) = 0;
|
||||
virtual void FreeEnvprobeDef( qhandle_t envprobeHandle ) = 0;
|
||||
virtual const renderEnvironmentProbe_t* GetRenderEnvprobe( qhandle_t envprobeHandle ) const = 0;
|
||||
// RB end
|
||||
|
||||
// Force the generation of all light / surface interactions at the start of a level
|
||||
// If this isn't called, they will all be dynamically generated
|
||||
virtual void GenerateAllInteractions() = 0;
|
||||
|
|
|
@ -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-2014 Robert Beckebans
|
||||
Copyright (C) 2013-2015 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -753,6 +753,55 @@ void R_CreateLightRefs( idRenderLightLocal* light )
|
|||
/*
|
||||
=================================================================================
|
||||
|
||||
ENVPROBE DEFS
|
||||
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void R_CreateEnvprobeRefs( RenderEnvprobeLocal* probe )
|
||||
{
|
||||
// TODO ? derive envprobe data
|
||||
//R_DeriveEnvprobeData( probe );
|
||||
|
||||
// determine the areaNum for the envprobe origin, which may let us
|
||||
// cull the envprobe if it is behind a closed door
|
||||
probe->areaNum = probe->world->PointInArea( probe->parms.origin );
|
||||
|
||||
// bump the view count so we can tell if an
|
||||
// area already has a reference
|
||||
tr.viewCount++;
|
||||
|
||||
// push the probe down the BSP tree into areas
|
||||
probe->world->PushEnvprobeIntoTree_r( probe, 0 );
|
||||
}
|
||||
|
||||
void R_FreeEnvprobeDefDerivedData( RenderEnvprobeLocal* probe )
|
||||
{
|
||||
// TODO free all the interactions
|
||||
//while( ldef->firstInteraction != NULL )
|
||||
//{
|
||||
// ldef->firstInteraction->UnlinkAndFree();
|
||||
//}
|
||||
|
||||
// free all the references to the envprobe
|
||||
areaReference_t* nextRef = NULL;
|
||||
for( areaReference_t* lref = probe->references; lref != NULL; lref = nextRef )
|
||||
{
|
||||
nextRef = lref->ownerNext;
|
||||
|
||||
// unlink from the area
|
||||
lref->areaNext->areaPrev = lref->areaPrev;
|
||||
lref->areaPrev->areaNext = lref->areaNext;
|
||||
|
||||
// put it back on the free list for reuse
|
||||
probe->world->areaReferenceAllocator.Free( lref );
|
||||
}
|
||||
probe->references = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================================================================================
|
||||
|
||||
WORLD MODEL & LIGHT DEFS
|
||||
|
||||
=================================================================================
|
||||
|
@ -790,6 +839,18 @@ void R_FreeDerivedData()
|
|||
}
|
||||
R_FreeLightDefDerivedData( light );
|
||||
}
|
||||
|
||||
// RB begin
|
||||
for( int i = 0; i < rw->envprobeDefs.Num(); i++ )
|
||||
{
|
||||
RenderEnvprobeLocal* probe = rw->envprobeDefs[i];
|
||||
if( probe == NULL )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
R_FreeEnvprobeDefDerivedData( probe );
|
||||
}
|
||||
// RB end
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -869,6 +930,21 @@ void R_ReCreateWorldReferences()
|
|||
light->world->FreeLightDef( i );
|
||||
rw->UpdateLightDef( i, &parms );
|
||||
}
|
||||
|
||||
// RB begin
|
||||
for( int i = 0; i < rw->envprobeDefs.Num(); i++ )
|
||||
{
|
||||
RenderEnvprobeLocal* probe = rw->envprobeDefs[i];
|
||||
if( probe == NULL )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
renderEnvironmentProbe_t parms = probe->parms;
|
||||
|
||||
probe->world->FreeLightDef( i );
|
||||
rw->UpdateEnvprobeDef( i, &parms );
|
||||
}
|
||||
// RB end
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -970,3 +970,26 @@ void idRenderWorldLocal::WriteFreeOverlay( idDemoFile* f, qhandle_t handle )
|
|||
common->Printf( "write DC_DELETE_OVERLAY: %i\n", handle );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// RB begin
|
||||
void idRenderWorldLocal::WriteFreeEnvprobe( qhandle_t handle )
|
||||
{
|
||||
|
||||
// only the main renderWorld writes stuff to demos, not the wipes or
|
||||
// menu renders
|
||||
if( this != common->RW() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
common->WriteDemo()->WriteInt( DS_RENDER );
|
||||
common->WriteDemo()->WriteInt( DC_DELETE_ENVPROBEDEF );
|
||||
common->WriteDemo()->WriteInt( handle );
|
||||
|
||||
if( r_showDemo.GetBool() )
|
||||
{
|
||||
common->Printf( "write DC_DELETE_ENVPROBEDEF: %i\n", handle );
|
||||
}
|
||||
}
|
||||
// RB end
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2015 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -417,10 +418,15 @@ void idRenderWorldLocal::SetupAreaRefs()
|
|||
for( int i = 0; i < numPortalAreas; i++ )
|
||||
{
|
||||
portalAreas[i].areaNum = i;
|
||||
|
||||
portalAreas[i].lightRefs.areaNext =
|
||||
portalAreas[i].lightRefs.areaPrev = &portalAreas[i].lightRefs;
|
||||
|
||||
portalAreas[i].entityRefs.areaNext =
|
||||
portalAreas[i].entityRefs.areaPrev = &portalAreas[i].entityRefs;
|
||||
|
||||
portalAreas[i].envprobeRefs.areaNext =
|
||||
portalAreas[i].envprobeRefs.areaPrev = &portalAreas[i].envprobeRefs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,6 +787,18 @@ void idRenderWorldLocal::FreeDefs()
|
|||
}
|
||||
}
|
||||
|
||||
// RB: free all envprobeDefs
|
||||
for( int i = 0; i < envprobeDefs.Num(); i++ )
|
||||
{
|
||||
RenderEnvprobeLocal* ep = envprobeDefs[i];
|
||||
if( ep != NULL && ep->world == this )
|
||||
{
|
||||
FreeEnvprobeDef( i );
|
||||
envprobeDefs[i] = NULL;
|
||||
}
|
||||
}
|
||||
// RB end
|
||||
|
||||
// Reset decals and overlays
|
||||
for( int i = 0; i < decals.Num(); i++ )
|
||||
{
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef struct portalArea_s
|
|||
portal_t* portals; // never changes after load
|
||||
areaReference_t entityRefs; // head/tail of doubly linked list, may change
|
||||
areaReference_t lightRefs; // head/tail of doubly linked list, may change
|
||||
areaReference_t envprobeRefs; // head/tail of doubly linked list, may change
|
||||
} portalArea_t;
|
||||
|
||||
|
||||
|
@ -117,6 +118,13 @@ public:
|
|||
virtual void FreeLightDef( qhandle_t lightHandle );
|
||||
virtual const renderLight_t* GetRenderLight( qhandle_t lightHandle ) const;
|
||||
|
||||
// RB: environment probes for IBL
|
||||
virtual qhandle_t AddEnvprobeDef( const renderEnvironmentProbe_t* ep );
|
||||
virtual void UpdateEnvprobeDef( qhandle_t envprobeHandle, const renderEnvironmentProbe_t* ep );
|
||||
virtual void FreeEnvprobeDef( qhandle_t envprobeHandle );
|
||||
virtual const renderEnvironmentProbe_t* GetRenderEnvprobe( qhandle_t envprobeHandle ) const;
|
||||
// RB end
|
||||
|
||||
virtual bool CheckAreaForPortalSky( int areaNum );
|
||||
|
||||
virtual void GenerateAllInteractions();
|
||||
|
@ -177,8 +185,9 @@ public:
|
|||
|
||||
idList<idRenderModel*, TAG_MODEL> localModels;
|
||||
|
||||
idList<idRenderEntityLocal*, TAG_ENTITY> entityDefs;
|
||||
idList<idRenderLightLocal*, TAG_LIGHT> lightDefs;
|
||||
idList<idRenderEntityLocal*, TAG_ENTITY> entityDefs;
|
||||
idList<idRenderLightLocal*, TAG_LIGHT> lightDefs;
|
||||
idList<RenderEnvprobeLocal*, TAG_ENVPROBE> envprobeDefs; // RB
|
||||
|
||||
idBlockAlloc<areaReference_t, 1024> areaReferenceAllocator;
|
||||
idBlockAlloc<idInteraction, 256> interactionAllocator;
|
||||
|
@ -266,12 +275,15 @@ public:
|
|||
void WriteFreeOverlay( idDemoFile* f, qhandle_t handle );
|
||||
void WriteFreeLight( qhandle_t handle );
|
||||
void WriteFreeEntity( qhandle_t handle );
|
||||
void WriteFreeEnvprobe( qhandle_t handle ); // RB
|
||||
void WriteRenderDecal( idDemoFile* f, qhandle_t handle );
|
||||
void WriteRenderOverlay( idDemoFile* f, qhandle_t handle );
|
||||
void WriteRenderLight( idDemoFile* f, qhandle_t handle, const renderLight_t* light );
|
||||
void WriteRenderEntity( idDemoFile* f, idRenderEntityLocal* entity );
|
||||
void WriteRenderEnvprobe( qhandle_t handle, const renderEnvironmentProbe_t* probe ); // RB
|
||||
void ReadRenderEntity();
|
||||
void ReadRenderLight();
|
||||
void ReadRenderEnvprobe(); // RB
|
||||
|
||||
|
||||
//--------------------------
|
||||
|
@ -281,6 +293,7 @@ public:
|
|||
|
||||
void AddEntityRefToArea( idRenderEntityLocal* def, portalArea_t* area );
|
||||
void AddLightRefToArea( idRenderLightLocal* light, portalArea_t* area );
|
||||
void AddEnvprobeRefToArea( RenderEnvprobeLocal* probe, portalArea_t* area ); // RB
|
||||
|
||||
void RecurseProcBSP_r( modelTrace_t* results, int parentNodeNum, int nodeNum, float p1f, float p2f, const idVec3& p1, const idVec3& p2 ) const;
|
||||
void BoundsInAreas_r( int nodeNum, const idBounds& bounds, int* areas, int* numAreas, int maxAreas ) const;
|
||||
|
@ -291,6 +304,7 @@ public:
|
|||
|
||||
void PushFrustumIntoTree_r( idRenderEntityLocal* def, idRenderLightLocal* light, const frustumCorners_t& corners, int nodeNum );
|
||||
void PushFrustumIntoTree( idRenderEntityLocal* def, idRenderLightLocal* light, const idRenderMatrix& frustumTransform, const idBounds& frustumBounds );
|
||||
void PushEnvprobeIntoTree_r( RenderEnvprobeLocal* probe, int nodeNum ); // RB
|
||||
|
||||
idRenderModelDecal* AllocDecal( qhandle_t newEntityHandle, int startTime );
|
||||
idRenderModelOverlay* AllocOverlay( qhandle_t newEntityHandle, int startTime );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue