From 2498a171494404e01f049c334e61e5ecdfb8f0c3 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Mon, 30 Nov 2020 18:27:06 +0100 Subject: [PATCH] Autospawn env probes in the center of BSP areas --- base/renderprogs/ambient_lighting_IBL.ps.hlsl | 45 ------- base/renderprogs/global.inc.hlsl | 41 ++++++ base/renderprogs/octahedron.ps.hlsl | 63 ++++++++++ base/renderprogs/octahedron.vs.hlsl | 119 ++++++++++++++++++ neo/d3xp/Game_local.cpp | 70 ++++++++++- neo/d3xp/Game_local.h | 6 + neo/renderer/OpenGL/RenderDebug_GL.cpp | 2 +- neo/renderer/RenderProgs.cpp | 4 + neo/renderer/RenderProgs.h | 13 ++ neo/renderer/RenderWorld.cpp | 17 +++ neo/renderer/RenderWorld.h | 3 + neo/renderer/RenderWorld_defs.cpp | 8 +- neo/renderer/RenderWorld_envprobes.cpp | 4 +- neo/renderer/RenderWorld_load.cpp | 7 +- neo/renderer/RenderWorld_local.h | 4 + 15 files changed, 350 insertions(+), 56 deletions(-) create mode 100644 base/renderprogs/octahedron.ps.hlsl create mode 100644 base/renderprogs/octahedron.vs.hlsl diff --git a/base/renderprogs/ambient_lighting_IBL.ps.hlsl b/base/renderprogs/ambient_lighting_IBL.ps.hlsl index fa19e218..9760d29a 100644 --- a/base/renderprogs/ambient_lighting_IBL.ps.hlsl +++ b/base/renderprogs/ambient_lighting_IBL.ps.hlsl @@ -60,51 +60,6 @@ struct PS_OUT // *INDENT-ON* - -/** Efficient GPU implementation of the octahedral unit vector encoding from - - Cigolle, Donow, Evangelakos, Mara, McGuire, Meyer, - A Survey of Efficient Representations for Independent Unit Vectors, Journal of Computer Graphics Techniques (JCGT), vol. 3, no. 2, 1-30, 2014 - - Available online http://jcgt.org/published/0003/02/01/ -*/ - -float signNotZeroFloat( float k ) -{ - return ( k >= 0.0 ) ? 1.0 : -1.0; -} - - -float2 signNotZero( float2 v ) -{ - return float2( signNotZeroFloat( v.x ), signNotZeroFloat( v.y ) ); -} - -/** Assumes that v is a unit vector. The result is an octahedral vector on the [-1, +1] square. */ -float2 octEncode( float3 v ) -{ - float l1norm = abs( v.x ) + abs( v.y ) + abs( v.z ); - float2 oct = v.xy * ( 1.0 / l1norm ); - if( v.z < 0.0 ) - { - oct = ( 1.0 - abs( oct.yx ) ) * signNotZero( oct.xy ); - } - return oct; -} - - -/** Returns a unit vector. Argument o is an octahedral vector packed via octEncode, - on the [-1, +1] square*/ -float3 octDecode( float2 o ) -{ - float3 v = float3( o.x, o.y, 1.0 - abs( o.x ) - abs( o.y ) ); - if( v.z < 0.0 ) - { - v.xy = ( 1.0 - abs( v.yx ) ) * signNotZero( v.xy ); - } - return normalize( v ); -} - void main( PS_IN fragment, out PS_OUT result ) { half4 bumpMap = tex2D( samp0, fragment.texcoord0.xy ); diff --git a/base/renderprogs/global.inc.hlsl b/base/renderprogs/global.inc.hlsl index 3c10a87b..6177467d 100644 --- a/base/renderprogs/global.inc.hlsl +++ b/base/renderprogs/global.inc.hlsl @@ -205,8 +205,49 @@ float4 LinearRGBToSRGB( float4 c ) #endif } +/** Efficient GPU implementation of the octahedral unit vector encoding from + + Cigolle, Donow, Evangelakos, Mara, McGuire, Meyer, + A Survey of Efficient Representations for Independent Unit Vectors, Journal of Computer Graphics Techniques (JCGT), vol. 3, no. 2, 1-30, 2014 + + Available online http://jcgt.org/published/0003/02/01/ +*/ + +float signNotZeroFloat( float k ) +{ + return ( k >= 0.0 ) ? 1.0 : -1.0; +} +float2 signNotZero( float2 v ) +{ + return float2( signNotZeroFloat( v.x ), signNotZeroFloat( v.y ) ); +} + +/** Assumes that v is a unit vector. The result is an octahedral vector on the [-1, +1] square. */ +float2 octEncode( float3 v ) +{ + float l1norm = abs( v.x ) + abs( v.y ) + abs( v.z ); + float2 oct = v.xy * ( 1.0 / l1norm ); + if( v.z < 0.0 ) + { + oct = ( 1.0 - abs( oct.yx ) ) * signNotZero( oct.xy ); + } + return oct; +} + + +/** Returns a unit vector. Argument o is an octahedral vector packed via octEncode, + on the [-1, +1] square*/ +float3 octDecode( float2 o ) +{ + float3 v = float3( o.x, o.y, 1.0 - abs( o.x ) - abs( o.y ) ); + if( v.z < 0.0 ) + { + v.xy = ( 1.0 - abs( v.yx ) ) * signNotZero( v.xy ); + } + return normalize( v ); +} // RB end diff --git a/base/renderprogs/octahedron.ps.hlsl b/base/renderprogs/octahedron.ps.hlsl new file mode 100644 index 00000000..3b53cbdb --- /dev/null +++ b/base/renderprogs/octahedron.ps.hlsl @@ -0,0 +1,63 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2020 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 . + +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" + +// *INDENT-OFF* +uniform sampler2D samp0 : register(s0); // texture 0 is octahedron cube map + +struct PS_IN { + float4 position : VPOS; + float3 texcoord0 : TEXCOORD0_centroid; + float3 texcoord1 : TEXCOORD1_centroid; + float4 color : COLOR0; +}; + +struct PS_OUT { + float4 color : COLOR; +}; +// *INDENT-ON* + +void main( PS_IN fragment, out PS_OUT result ) +{ + + float3 globalNormal = normalize( fragment.texcoord1 ); + float3 globalEye = normalize( fragment.texcoord0 ); + + float3 reflectionVector = _float3( dot3( globalEye, globalNormal ) ); + reflectionVector *= globalNormal; + reflectionVector = ( reflectionVector * 2.0f ) - globalEye; + + float2 normalizedOctCoord = octEncode( reflectionVector ); + float2 normalizedOctCoordZeroOne = ( normalizedOctCoord + float2( 1.0 ) ) * 0.5; + + float4 envMap = tex2D( samp0, normalizedOctCoordZeroOne ); + + result.color = float4( sRGBToLinearRGB( envMap.xyz ), 1.0f ) * fragment.color; +} diff --git a/base/renderprogs/octahedron.vs.hlsl b/base/renderprogs/octahedron.vs.hlsl new file mode 100644 index 00000000..ffd3a629 --- /dev/null +++ b/base/renderprogs/octahedron.vs.hlsl @@ -0,0 +1,119 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2020 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 . + +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" + +uniform matrices_ubo { float4 matrices[408]; }; + +// *INDENT-OFF* +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; + float3 texcoord0 : TEXCOORD0; + float3 texcoord1 : TEXCOORD1; + float4 color : COLOR0; +}; +// *INDENT-ON* + +void main( VS_IN vertex, out VS_OUT result ) +{ + float4 vNormal = vertex.normal * 2.0 - 1.0; + +#if defined( USE_GPU_SKINNING ) + + //-------------------------------------------------------------- + // GPU transformation of the normal / binormal / 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 ); + + 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; + float4 normal = vNormal; + +#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 toEye = rpLocalViewOrigin - vertex.position; + + result.texcoord0 = toEye.xyz; + result.texcoord1 = normal.xyz; + + result.color = sRGBAToLinearRGBA( rpColor ); +} diff --git a/neo/d3xp/Game_local.cpp b/neo/d3xp/Game_local.cpp index 31c5a534..d9a1c00c 100644 --- a/neo/d3xp/Game_local.cpp +++ b/neo/d3xp/Game_local.cpp @@ -1257,6 +1257,71 @@ void idGameLocal::MapPopulate() SetScriptFPS( com_engineHz_latched ); } +/* +=================== +RB idGameLocal::PopulateEnvironmentProbes +=================== +*/ +void idGameLocal::PopulateEnvironmentProbes() +{ + idEntity* ent; + + // check if there are already environment probes defined by the artist + int numEnvprobes = 0; + + for( ent = spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) + { + if( !ent->IsType( EnvironmentProbe::Type ) ) + { + continue; + } + + numEnvprobes++; + } + + if( numEnvprobes > 0 ) + { + return; + } + + const idDict* envProbeDef = gameLocal.FindEntityDefDict( "env_probe", false ); + if( !envProbeDef ) + { + return; + } + + // naive approach: place an env probe into the center of each BSP area + + int numAreas = gameRenderWorld->NumAreas(); + + for( int i = 0 ; i < numAreas ; i++ ) + { + idBounds areaBounds = gameRenderWorld->AreaBounds( i ); + + idVec3 point = areaBounds.GetCenter(); + + int areaNum = gameRenderWorld->PointInArea( point ); + if( areaNum < 0 ) + { + Warning( "PopulateEnvironmentProbes: location '%i' is not in a valid area\n", i ); + continue; + } + + idDict args; + args.Set( "classname", "env_probe" ); + args.Set( "origin", point.ToString() ); + + gameLocal.SpawnEntityDef( args, &ent ); + if( !ent ) + { + gameLocal.Error( "Couldn't spawn 'env_probe'" ); + } + + //environmentProbes.Append( probe ); + } +} +// RB end + /* =================== idGameLocal::InitFromNewMap @@ -1294,6 +1359,9 @@ void idGameLocal::InitFromNewMap( const char* mapName, idRenderWorld* renderWorl MapPopulate(); + // RB + PopulateEnvironmentProbes(); + mpGame.Reset(); mpGame.Precache(); @@ -1564,7 +1632,6 @@ bool idGameLocal::InitFromSaveGame( const char* mapName, idRenderWorld* renderWo savegame.RestoreObjects(); mpGame.Reset(); - mpGame.Precache(); // free up any unused animations @@ -3990,7 +4057,6 @@ void idGameLocal::SpawnMapEntities() { common->UpdateLevelLoadPacifier(); - mapEnt = mapFile->GetEntity( i ); args = mapEnt->epairs; diff --git a/neo/d3xp/Game_local.h b/neo/d3xp/Game_local.h index 59c81f6f..4cd346f3 100644 --- a/neo/d3xp/Game_local.h +++ b/neo/d3xp/Game_local.h @@ -68,6 +68,7 @@ class idThread; class idEditEntities; class idLocationEntity; class idMenuHandler_Shell; +class EnvironmentProbe; // RB const int MAX_CLIENTS = MAX_PLAYERS; const int MAX_CLIENTS_IN_PVS = MAX_CLIENTS >> 3; @@ -638,6 +639,8 @@ private: idLocationEntity** locationEntities; // for location names, etc + idList environmentProbes; // RB + idCamera* camera; const idMaterial* globalMaterial; // for overriding everything @@ -704,6 +707,9 @@ private: void MapPopulate(); void MapClear( bool clearClients ); + // RB: spawn environment probes if there aren't any by default + void PopulateEnvironmentProbes(); + pvsHandle_t GetClientPVS( idPlayer* player, pvsType_t type ); void SetupPlayerPVS(); void FreePlayerPVS(); diff --git a/neo/renderer/OpenGL/RenderDebug_GL.cpp b/neo/renderer/OpenGL/RenderDebug_GL.cpp index 1ce1d701..3ea18f27 100644 --- a/neo/renderer/OpenGL/RenderDebug_GL.cpp +++ b/neo/renderer/OpenGL/RenderDebug_GL.cpp @@ -1714,7 +1714,7 @@ void idRenderBackend::DBG_ShowViewEnvprobes() GL_State( GLS_DEFAULT | GLS_CULL_TWOSIDED ); - renderProgManager.BindShader_Environment(); + renderProgManager.BindShader_Octahedron(); int count = 0; for( viewEnvprobe_t* vProbe = viewDef->viewEnvprobes; vProbe != NULL; vProbe = vProbe->next ) diff --git a/neo/renderer/RenderProgs.cpp b/neo/renderer/RenderProgs.cpp index b5e3619a..9eba9fcb 100644 --- a/neo/renderer/RenderProgs.cpp +++ b/neo/renderer/RenderProgs.cpp @@ -153,6 +153,9 @@ void idRenderProgManager::Init() { BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL, "interactionSM", "_parallel_PBR", BIT( LIGHT_PARALLEL ) | BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT }, { BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, "interactionSM", "_parallel_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_PARALLEL ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT }, + + { BUILTIN_OCTAHEDRON, "octahedron", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT }, + { BUILTIN_OCTAHEDRON_SKINNED, "octahedron", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT }, // RB end { BUILTIN_ENVIRONMENT, "environment", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT }, @@ -269,6 +272,7 @@ void idRenderProgManager::Init() renderProgs[builtinShaders[BUILTIN_SHADOW_DEBUG_SKINNED]].usesJoints = true; renderProgs[builtinShaders[BUILTIN_FOG_SKINNED]].usesJoints = true; // RB begin + renderProgs[builtinShaders[BUILTIN_OCTAHEDRON_SKINNED]].usesJoints = true; 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; diff --git a/neo/renderer/RenderProgs.h b/neo/renderer/RenderProgs.h index f027136b..f6bdc335 100644 --- a/neo/renderer/RenderProgs.h +++ b/neo/renderer/RenderProgs.h @@ -449,6 +449,16 @@ public: { BindShader_Builtin( BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED ); } + + void BindShader_Octahedron() + { + BindShader_Builtin( BUILTIN_OCTAHEDRON ); + } + + void BindShader_OctahedronSkinned() + { + BindShader_Builtin( BUILTIN_OCTAHEDRON_SKINNED ); + } // RB end void BindShader_Environment() @@ -755,6 +765,9 @@ private: BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT_SKINNED, BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL, BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, + + BUILTIN_OCTAHEDRON, + BUILTIN_OCTAHEDRON_SKINNED, // RB end BUILTIN_ENVIRONMENT, BUILTIN_ENVIRONMENT_SKINNED, diff --git a/neo/renderer/RenderWorld.cpp b/neo/renderer/RenderWorld.cpp index ecf46857..39094c97 100644 --- a/neo/renderer/RenderWorld.cpp +++ b/neo/renderer/RenderWorld.cpp @@ -1241,6 +1241,23 @@ exitPortal_t idRenderWorldLocal::GetPortal( int areaNum, int portalNum ) return ret; } +/* +=================== +RB: idRenderWorldLocal::AreaBounds +=================== +*/ +idBounds idRenderWorldLocal::AreaBounds( int areaNum ) const +{ + if( areaNum < 0 || areaNum > numPortalAreas ) + { + common->Error( "idRenderWorld::GetPortal: areaNum > numAreas" ); + } + + portalArea_t* area = &portalAreas[areaNum]; + + return area->globalBounds; +} + /* =============== idRenderWorldLocal::PointInAreaNum diff --git a/neo/renderer/RenderWorld.h b/neo/renderer/RenderWorld.h index 3949ed63..072e817a 100644 --- a/neo/renderer/RenderWorld.h +++ b/neo/renderer/RenderWorld.h @@ -415,6 +415,9 @@ public: // returns one portal from an area virtual exitPortal_t GetPortal( int areaNum, int portalNum ) = 0; + // RB: returns the AABB of a BSP area + virtual idBounds AreaBounds( int areaNum ) const = 0; + //-------------- Tracing ----------------- // Checks a ray trace against any gui surfaces in an entity, returning the diff --git a/neo/renderer/RenderWorld_defs.cpp b/neo/renderer/RenderWorld_defs.cpp index b7fe2bbb..e85cdbf7 100644 --- a/neo/renderer/RenderWorld_defs.cpp +++ b/neo/renderer/RenderWorld_defs.cpp @@ -760,19 +760,19 @@ ENVPROBE DEFS void R_DeriveEnvprobeData( RenderEnvprobeLocal* probe ) { - idStr basename = tr.primaryWorld->mapName; + idStr basename = probe->world->mapName; basename.StripFileExtension(); idStr fullname; - int probeIndex = tr.primaryWorld->envprobeDefs.Num() - 1; + int probeIndex = probe->world->envprobeDefs.Num() - 1; // TODO get preconvolved cubemaps fullname.Format( "env/%s/envprobe%i_amb", basename.c_str(), probeIndex ); - probe->irradianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_CLAMP, TD_HIGHQUALITY_CUBE, CF_NATIVE ); + probe->irradianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D ); fullname.Format( "env/%s/envprobe%i_spec", basename.c_str(), probeIndex ); - probe->radianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_CLAMP, TD_HIGHQUALITY_CUBE, CF_NATIVE ); + probe->radianceImage = globalImages->ImageFromFile( fullname, TF_DEFAULT, TR_CLAMP, TD_LOOKUP_TABLE_RGB1, CF_2D ); // ------------------------------------ // compute the light projection matrix diff --git a/neo/renderer/RenderWorld_envprobes.cpp b/neo/renderer/RenderWorld_envprobes.cpp index ace05fcd..ee9eef88 100644 --- a/neo/renderer/RenderWorld_envprobes.cpp +++ b/neo/renderer/RenderWorld_envprobes.cpp @@ -672,7 +672,7 @@ void R_MakeAmbientMap( const char* baseName, const char* suffix, int outSize, fl bool pacifier = true; // resample with hemispherical blending - int samples = 1000; + int samples = 1; byte* outBuffer = ( byte* )_alloca( outSize * outSize * 4 ); @@ -780,7 +780,7 @@ void R_MakeAmbientMap( const char* baseName, const char* suffix, int outSize, fl total[2] += result[2]; } -#if 0 +#if 1 outBuffer[( y * outSize + x ) * 4 + 0] = total[0] / samples; outBuffer[( y * outSize + x ) * 4 + 1] = total[1] / samples; outBuffer[( y * outSize + x ) * 4 + 2] = total[2] / samples; diff --git a/neo/renderer/RenderWorld_load.cpp b/neo/renderer/RenderWorld_load.cpp index 70e71c93..7aa03b94 100644 --- a/neo/renderer/RenderWorld_load.cpp +++ b/neo/renderer/RenderWorld_load.cpp @@ -1089,7 +1089,6 @@ void idRenderWorldLocal::AddWorldModelEntities() { common->UpdateLevelLoadPacifier(); - idRenderEntityLocal* def = new( TAG_RENDER_ENTITY ) idRenderEntityLocal; // try and reuse a free spot @@ -1141,7 +1140,11 @@ void idRenderWorldLocal::AddWorldModelEntities() R_DeriveEntityData( def ); - AddEntityRefToArea( def, &portalAreas[i] ); + portalArea_t* area = &portalAreas[i]; + AddEntityRefToArea( def, area ); + + // RB: remember BSP area AABB for quick lookup later + area->globalBounds = def->globalReferenceBounds; } } diff --git a/neo/renderer/RenderWorld_local.h b/neo/renderer/RenderWorld_local.h index 67ed1f32..7881eb8f 100644 --- a/neo/renderer/RenderWorld_local.h +++ b/neo/renderer/RenderWorld_local.h @@ -65,6 +65,9 @@ typedef struct portalArea_s int areaNum; int connectedAreaNum[NUM_PORTAL_ATTRIBUTES]; // if two areas have matching connectedAreaNum, they are // not separated by a portal with the apropriate PS_BLOCK_* blockingBits + + idBounds globalBounds; // RB: AABB of the BSP area used for light grid density + int viewCount; // set by R_FindViewLightsAndEntities portal_t* portals; // never changes after load areaReference_t entityRefs; // head/tail of doubly linked list, may change @@ -143,6 +146,7 @@ public: virtual int BoundsInAreas( const idBounds& bounds, int* areas, int maxAreas ) const; virtual int NumPortalsInArea( int areaNum ); virtual exitPortal_t GetPortal( int areaNum, int portalNum ); + virtual idBounds AreaBounds( int areaNum ) const; // RB virtual guiPoint_t GuiTrace( qhandle_t entityHandle, const idVec3 start, const idVec3 end ) const; virtual bool ModelTrace( modelTrace_t& trace, qhandle_t entityHandle, const idVec3& start, const idVec3& end, const float radius ) const;