mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-03 01:13:22 +00:00
- removed the remaining dependencies of the shadowmap code on game data.
Everything is handled with callbacks now.
This commit is contained in:
parent
ba0b42465d
commit
c30165db0d
5 changed files with 71 additions and 76 deletions
|
@ -20,8 +20,7 @@
|
|||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "r_state.h"
|
||||
#include "g_levellocals.h"
|
||||
#include <algorithm>
|
||||
#include "hw_aabbtree.h"
|
||||
|
||||
namespace hwrenderer
|
||||
|
@ -82,7 +81,7 @@ double LevelAABBTree::RayTest(const DVector3 &ray_start, const DVector3 &ray_end
|
|||
else if (nodes[node_index].line_index != -1) // isLeaf(node_index)
|
||||
{
|
||||
// We reached a leaf node. Do a ray/line intersection test to see if we hit the line.
|
||||
hit_fraction = MIN(IntersectRayLine(ray_start, ray_end, nodes[node_index].line_index, raydelta, rayd, raydist2), hit_fraction);
|
||||
hit_fraction = std::min(IntersectRayLine(ray_start, ray_end, nodes[node_index].line_index, raydelta, rayd, raydist2), hit_fraction);
|
||||
stack_pos--;
|
||||
}
|
||||
else if (stack_pos == 32)
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "actorinlines.h"
|
||||
#include "a_dynlight.h"
|
||||
#include "hw_dynlightdata.h"
|
||||
#include"hw_cvars.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
|
||||
// If we want to share the array to avoid constant allocations it needs to be thread local unless it'd be littered with expensive synchronization.
|
||||
|
@ -105,10 +106,15 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f
|
|||
i = 1;
|
||||
}
|
||||
|
||||
float shadowIndex = light->mShadowmapIndex + 1.0f;
|
||||
float shadowIndex;
|
||||
if (gl_light_shadowmap)
|
||||
{
|
||||
shadowIndex = light->mShadowmapIndex + 1.0f;
|
||||
|
||||
// Store attenuate flag in the sign bit of the float.
|
||||
if (light->IsAttenuated() || forceAttenuate) shadowIndex = -shadowIndex;
|
||||
// Store attenuate flag in the sign bit of the float.
|
||||
if (light->IsAttenuated() || forceAttenuate) shadowIndex = -shadowIndex;
|
||||
}
|
||||
else shadowIndex = 1025.f;
|
||||
|
||||
float lightType = 0.0f;
|
||||
float spotInnerAngle = 0.0f;
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
#include "hw_dynlightdata.h"
|
||||
#include "hwrenderer/data/buffers.h"
|
||||
#include "hwrenderer/data/shaderuniforms.h"
|
||||
#include "stats.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "v_video.h"
|
||||
#include "a_dynlight.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
|
||||
/*
|
||||
|
@ -63,6 +59,8 @@ cycle_t IShadowMap::UpdateCycles;
|
|||
int IShadowMap::LightsProcessed;
|
||||
int IShadowMap::LightsShadowmapped;
|
||||
|
||||
CVAR(Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
ADD_STAT(shadowmap)
|
||||
{
|
||||
FString out;
|
||||
|
@ -85,68 +83,14 @@ CUSTOM_CVAR(Int, gl_shadowmap_quality, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (!self) for (auto Level : AllLevels())
|
||||
{
|
||||
auto light = Level->lights;
|
||||
while (light)
|
||||
{
|
||||
light->mShadowmapIndex = 1024;
|
||||
light = light->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IShadowMap::ShadowTest(const DVector3 &lpos, const DVector3 &pos)
|
||||
{
|
||||
if (mAABBTree)
|
||||
if (mAABBTree && gl_light_shadowmap)
|
||||
return mAABBTree->RayTest(lpos, pos) >= 1.0f;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IShadowMap::IsEnabled() const
|
||||
{
|
||||
return gl_light_shadowmap && (screen->hwcaps & RFL_SHADER_STORAGE_BUFFER);
|
||||
}
|
||||
|
||||
void IShadowMap::CollectLights()
|
||||
{
|
||||
if (mLights.Size() != 1024 * 4) mLights.Resize(1024 * 4);
|
||||
int lightindex = 0;
|
||||
auto Level = &level;
|
||||
|
||||
// Todo: this should go through the blockmap in a spiral pattern around the player so that closer lights are preferred.
|
||||
for (auto light = Level->lights; light; light = light->next)
|
||||
{
|
||||
LightsProcessed++;
|
||||
if (light->shadowmapped && light->IsActive() && lightindex < 1024 * 4)
|
||||
{
|
||||
LightsShadowmapped++;
|
||||
|
||||
light->mShadowmapIndex = lightindex >> 2;
|
||||
|
||||
mLights[lightindex] = (float)light->X();
|
||||
mLights[lightindex+1] = (float)light->Y();
|
||||
mLights[lightindex+2] = (float)light->Z();
|
||||
mLights[lightindex+3] = light->GetRadius();
|
||||
lightindex += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
light->mShadowmapIndex = 1024;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (; lightindex < 1024 * 4; lightindex++)
|
||||
{
|
||||
mLights[lightindex] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IShadowMap::PerformUpdate()
|
||||
{
|
||||
UpdateCycles.Reset();
|
||||
|
@ -154,7 +98,7 @@ bool IShadowMap::PerformUpdate()
|
|||
LightsProcessed = 0;
|
||||
LightsShadowmapped = 0;
|
||||
|
||||
if (IsEnabled())
|
||||
if (gl_light_shadowmap && (screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && CollectLights != nullptr)
|
||||
{
|
||||
UpdateCycles.Clock();
|
||||
UploadAABBTree();
|
||||
|
@ -166,6 +110,7 @@ bool IShadowMap::PerformUpdate()
|
|||
|
||||
void IShadowMap::UploadLights()
|
||||
{
|
||||
mLights.Resize(1024 * 4);
|
||||
CollectLights();
|
||||
|
||||
if (mLightList == nullptr)
|
||||
|
@ -207,3 +152,4 @@ IShadowMap::~IShadowMap()
|
|||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,7 @@
|
|||
#include "stats.h"
|
||||
#include <memory>
|
||||
|
||||
struct FDynamicLight;
|
||||
struct level_info_t;
|
||||
class IDataBuffer;
|
||||
struct FLevelLocals;
|
||||
|
||||
class IShadowMap
|
||||
{
|
||||
|
@ -21,9 +18,6 @@ public:
|
|||
// Test if a world position is in shadow relative to the specified light and returns false if it is
|
||||
bool ShadowTest(const DVector3 &lpos, const DVector3 &pos);
|
||||
|
||||
// Returns true if gl_light_shadowmap is enabled and supported by the hardware
|
||||
bool IsEnabled() const;
|
||||
|
||||
static cycle_t UpdateCycles;
|
||||
static int LightsProcessed;
|
||||
static int LightsShadowmapped;
|
||||
|
@ -46,13 +40,23 @@ public:
|
|||
mNewTree = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void CollectLights();
|
||||
void SetCollectLights(std::function<void()> func)
|
||||
{
|
||||
CollectLights = std::move(func);
|
||||
}
|
||||
|
||||
void SetLight(int index, float x, float y, float z, float r)
|
||||
{
|
||||
index *= 4;
|
||||
mLights[index] = x;
|
||||
mLights[index + 1] = y;
|
||||
mLights[index + 2] = z;
|
||||
mLights[index + 3] = r;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Upload the AABB-tree to the GPU
|
||||
void UploadAABBTree();
|
||||
|
||||
// Upload light list to the GPU
|
||||
void UploadLights();
|
||||
|
||||
// Working buffer for creating the list of lights. Stored here to avoid allocating memory each frame
|
||||
|
@ -74,4 +78,6 @@ public:
|
|||
IDataBuffer *mNodesBuffer = nullptr;
|
||||
IDataBuffer *mLinesBuffer = nullptr;
|
||||
|
||||
std::function<void()> CollectLights = nullptr;
|
||||
|
||||
};
|
||||
|
|
|
@ -59,6 +59,41 @@ void CleanSWDrawer()
|
|||
swdrawer = nullptr;
|
||||
}
|
||||
|
||||
#include "g_levellocals.h"
|
||||
#include "a_dynlight.h"
|
||||
|
||||
|
||||
void CollectLights(FLevelLocals* Level)
|
||||
{
|
||||
IShadowMap* sm = &screen->mShadowMap;
|
||||
int lightindex = 0;
|
||||
|
||||
// Todo: this should go through the blockmap in a spiral pattern around the player so that closer lights are preferred.
|
||||
for (auto light = Level->lights; light; light = light->next)
|
||||
{
|
||||
IShadowMap::LightsProcessed++;
|
||||
if (light->shadowmapped && light->IsActive() && lightindex < 1024 * 4)
|
||||
{
|
||||
IShadowMap::LightsShadowmapped++;
|
||||
|
||||
light->mShadowmapIndex = lightindex;
|
||||
sm->SetLight(lightindex, (float)light->X(), (float)light->Y(), (float)light->Z(), light->GetRadius());
|
||||
lightindex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
light->mShadowmapIndex = 1024;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (; lightindex < 1024; lightindex++)
|
||||
{
|
||||
sm->SetLight(lightindex, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Renders one viewpoint in a scene
|
||||
|
@ -75,6 +110,9 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou
|
|||
{
|
||||
screen->SetAABBTree(camera->Level->aabbTree);
|
||||
screen->UpdateShadowMap();
|
||||
screen->mShadowMap.SetCollectLights([=] {
|
||||
CollectLights(camera->Level);
|
||||
});
|
||||
}
|
||||
|
||||
// Update the attenuation flag of all light defaults for each viewpoint.
|
||||
|
|
Loading…
Reference in a new issue