summaryrefslogtreecommitdiff
path: root/gfx/gl
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/gl')
-rw-r--r--gfx/gl/sceneRenderer.cpp6
-rw-r--r--gfx/gl/sceneRenderer.h1
-rw-r--r--gfx/gl/shadowMapper.cpp60
-rw-r--r--gfx/gl/shadowMapper.h7
4 files changed, 48 insertions, 26 deletions
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index 5e8241f..d005dfa 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -77,6 +77,12 @@ SceneRenderer::resize(ScreenAbsCoord newSize)
shader.setViewPort({0, 0, size.x, size.y});
}
+std::pair<const Frustum &, const Frustum &>
+SceneRenderer::preFrame(const LightDirection & lightDirection)
+{
+ return {camera, shadowMapper.preFrame(lightDirection, camera)};
+}
+
void
SceneRenderer::render(const SceneProvider & scene) const
{
diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h
index 05921a1..2ec8057 100644
--- a/gfx/gl/sceneRenderer.h
+++ b/gfx/gl/sceneRenderer.h
@@ -18,6 +18,7 @@ public:
void resize(ScreenAbsCoord size);
void render(const SceneProvider &) const;
+ std::pair<const Frustum &, const Frustum &> preFrame(const LightDirection &);
void setAmbientLight(const RGB & colour) const;
void setDirectionalLight(const RGB & colour, const LightDirection & direction, const SceneProvider &) const;
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index 7035162..a73caa0 100644
--- a/gfx/gl/shadowMapper.cpp
+++ b/gfx/gl/shadowMapper.cpp
@@ -31,7 +31,7 @@ ShadowMapper::ShadowMapper(const TextureAbsCoord & s) :
landmess {shadowLandmass_vert}, dynamicPointInst {shadowDynamicPointInst_vert},
dynamicPointInstWithTextures {shadowDynamicPointInstWithTextures_vert, shadowDynamicPointInstWithTextures_geom,
shadowDynamicPointInstWithTextures_frag},
- size {s}
+ size {s}, frustum {{}, {}, {}}
{
glDebugScope _ {depthMap};
glBindTexture(GL_TEXTURE_2D_ARRAY, depthMap);
@@ -82,6 +82,37 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV
return bandViewExtents;
}
+const Frustum &
+ShadowMapper::preFrame(const LightDirection & dir, const Camera & camera)
+{
+ const auto lightViewDir = glm::lookAt({}, dir.vector(), up);
+ const auto lightViewPoint = camera.getPosition();
+ const auto bandViewExtents = getBandViewExtents(camera, lightViewDir);
+ using ExtentsBoundingBox = AxisAlignedBoundingBox<RelativeDistance>;
+ definitions.clear();
+ sizes.clear();
+ std::ranges::transform(bandViewExtents | std::views::pairwise, std::back_inserter(definitions),
+ [&lightViewDir, this](const auto & band) mutable {
+ const auto & [near, far] = band;
+ auto extents = ExtentsBoundingBox::fromPoints(std::span {near.begin(), far.end()});
+ extents.min.z -= 10'000.F;
+ extents.max.z += 10'000.F;
+ const auto lightProjection = glm::ortho(
+ extents.min.x, extents.max.x, extents.min.y, extents.max.y, -extents.max.z, -extents.min.z);
+ sizes.emplace_back(extents.max - extents.min);
+ return lightProjection * lightViewDir;
+ });
+
+ ExtentsBoundingBox extents {lightViewPoint, lightViewPoint};
+ for (const auto & point : bandViewExtents.back()) {
+ extents += point;
+ }
+ const auto lightProjection
+ = glm::ortho(extents.min.x, extents.max.x, extents.min.y, extents.max.y, -extents.max.z, -extents.min.z);
+ frustum = {lightViewPoint, lightViewDir, lightProjection};
+ return frustum;
+}
+
ShadowMapper::Definitions
ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, const Camera & camera) const
{
@@ -100,39 +131,16 @@ ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, co
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, size.x, size.y);
- const auto lightViewDir = glm::lookAt({}, dir.vector(), up);
const auto lightViewPoint = camera.getPosition();
- const auto bandViewExtents = getBandViewExtents(camera, lightViewDir);
- Definitions out;
- Sizes sizes;
- using ExtentsBoundingBox = AxisAlignedBoundingBox<RelativeDistance>;
- std::ranges::transform(bandViewExtents | std::views::pairwise, std::back_inserter(out),
- [&lightViewDir, &sizes](const auto & band) mutable {
- const auto & [near, far] = band;
- auto extents = ExtentsBoundingBox::fromPoints(std::span {near.begin(), far.end()});
- extents.min.z -= 10'000.F;
- extents.max.z += 10'000.F;
- const auto lightProjection = glm::ortho(
- extents.min.x, extents.max.x, extents.min.y, extents.max.y, -extents.max.z, -extents.min.z);
- sizes.emplace_back(extents.max - extents.min);
- return lightProjection * lightViewDir;
- });
for (const auto p : std::initializer_list<const ShadowProgram *> {
&landmess, &dynamicPoint, &dynamicPointInst, &dynamicPointInstWithTextures, &stencilShadowProgram}) {
- p->setView(out, sizes, lightViewPoint);
- }
- ExtentsBoundingBox extents {lightViewPoint, lightViewPoint};
- for (const auto & point : bandViewExtents.back()) {
- extents += point;
+ p->setView(definitions, sizes, lightViewPoint);
}
- const auto lightProjection
- = glm::ortho(extents.min.x, extents.max.x, extents.min.y, extents.max.y, -extents.max.z, -extents.min.z);
- Frustum frustum {lightViewPoint, lightViewDir, lightProjection};
scene.shadows(*this, frustum);
glCullFace(GL_BACK);
- return out;
+ return definitions;
}
ShadowMapper::ShadowProgram::ShadowProgram(const Shader & vs) : Program {vs, commonShadowPoint_geom} { }
diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h
index 951e29c..82374cb 100644
--- a/gfx/gl/shadowMapper.h
+++ b/gfx/gl/shadowMapper.h
@@ -1,6 +1,7 @@
#pragma once
#include "config/types.h"
+#include "gfx/frustum.h"
#include "gfx/gl/shadowStenciller.h"
#include "lib/glArrays.h"
#include "program.h"
@@ -22,6 +23,7 @@ public:
using Definitions = std::vector<glm::mat4x4>;
using Sizes = std::vector<RelativePosition3D>;
+ const Frustum & preFrame(const LightDirection & direction, const Camera &);
[[nodiscard]] Definitions update(const SceneProvider &, const LightDirection & direction, const Camera &) const;
class ShadowProgram : public Program {
@@ -77,5 +79,10 @@ private:
glFrameBuffer depthMapFBO;
glTexture depthMap;
TextureAbsCoord size;
+
+ Definitions definitions;
+ Sizes sizes;
+ Frustum frustum;
+
mutable ShadowStenciller shadowStenciller;
};