summaryrefslogtreecommitdiff
path: root/gfx/gl
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/gl')
-rw-r--r--gfx/gl/camera.cpp62
-rw-r--r--gfx/gl/camera.h87
-rw-r--r--gfx/gl/sceneProvider.cpp2
-rw-r--r--gfx/gl/sceneProvider.h5
-rw-r--r--gfx/gl/sceneRenderer.cpp2
-rw-r--r--gfx/gl/sceneRenderer.h2
-rw-r--r--gfx/gl/shadowMapper.cpp42
7 files changed, 27 insertions, 175 deletions
diff --git a/gfx/gl/camera.cpp b/gfx/gl/camera.cpp
deleted file mode 100644
index f03e85b..0000000
--- a/gfx/gl/camera.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "camera.h"
-#include <collections.h>
-#include <glm/gtx/transform.hpp>
-#include <maths.h>
-#include <ray.h>
-
-Camera::Camera(GlobalPosition3D pos, Angle fov, Angle aspect, GlobalDistance zNear, GlobalDistance zFar) :
- position {pos}, forward {::north}, up {::up}, near {zNear}, far {zFar}, view {},
- projection {
- glm::perspective(fov, aspect, static_cast<RelativeDistance>(zNear), static_cast<RelativeDistance>(zFar))},
- viewProjection {}, inverseViewProjection {}
-{
- updateView();
-}
-
-Ray<GlobalPosition3D>
-Camera::unProject(const ScreenRelCoord & mouse) const
-{
- static constexpr const glm::vec4 SCREEN {0, 0, 1, 1};
- return {
- .start = position,
- .direction = glm::normalize(glm::unProject(mouse || 1.F, view, projection, SCREEN)),
- };
-}
-
-void
-Camera::updateView()
-{
- view = glm::lookAt({}, forward, up);
- viewProjection = projection * view;
- inverseViewProjection = glm::inverse(viewProjection);
-}
-
-Direction3D
-Camera::upFromForward(const Direction3D & forward)
-{
- const auto right = crossProduct(forward, ::down);
- return crossProduct(forward, right);
-}
-
-std::array<GlobalPosition4D, 4>
-Camera::extentsAtDist(const GlobalDistance dist) const
-{
- const auto clampToSeaFloor = [this, dist](GlobalPosition3D target) -> GlobalPosition4D {
- target += position;
- if (target.z < -1500) {
- const CalcPosition3D diff = target - position;
- const CalcDistance limit = -1500 - position.z;
- return {position + ((limit * diff) / diff.z), (limit * dist) / diff.z};
- }
- return {target, dist};
- };
- const auto depth = -(2.F * (static_cast<float>(dist - near)) * static_cast<float>(far))
- / (static_cast<float>(dist) * (static_cast<float>(near - far)))
- - 1.F;
- static constexpr const std::array extents {-1.F, 1.F};
- static constexpr const auto cartesianExtents = extents * extents;
- return cartesianExtents * [&depth, this, &clampToSeaFloor](const auto & extent) {
- const glm::vec4 in {extent.first, extent.second, depth, 1.F};
- return clampToSeaFloor(perspective_divide(inverseViewProjection * in));
- };
-}
diff --git a/gfx/gl/camera.h b/gfx/gl/camera.h
deleted file mode 100644
index 5c37744..0000000
--- a/gfx/gl/camera.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#pragma once
-
-#include "config/types.h"
-#include <glm/glm.hpp>
-#include <maths.h>
-#include <ray.h>
-
-class Camera {
-public:
- Camera(GlobalPosition3D, Angle fov, Angle aspect, GlobalDistance zNear, GlobalDistance zFar);
-
- [[nodiscard]] glm::mat4
- getViewProjection() const
- {
- return viewProjection;
- }
-
- [[nodiscard]] Ray<GlobalPosition3D> unProject(const ScreenRelCoord &) const;
-
- void
- setPosition(const GlobalPosition3D & p)
- {
- position = p;
- updateView();
- }
-
- void
- setForward(const Direction3D & f)
- {
- setForward(f, upFromForward(f));
- }
-
- void
- setForward(const Direction3D & f, const Direction3D & u)
- {
- forward = f;
- up = u;
- updateView();
- }
-
- void
- setView(const GlobalPosition3D & p, const Direction3D & f)
- {
- position = p;
- setForward(f);
- }
-
- void
- setView(const GlobalPosition3D & p, const Direction3D & f, const Direction3D & u)
- {
- position = p;
- setView(f, u);
- }
-
- void
- lookAt(const GlobalPosition3D & target)
- {
- setForward(glm::normalize(RelativePosition3D(target - position)));
- }
-
- [[nodiscard]] auto
- getForward() const
- {
- return forward;
- }
-
- [[nodiscard]] auto
- getPosition() const
- {
- return position;
- }
-
- [[nodiscard]] std::array<GlobalPosition4D, 4> extentsAtDist(GlobalDistance) const;
-
- [[nodiscard]] static Direction3D upFromForward(const Direction3D & forward);
-
-private:
- void updateView();
-
- GlobalPosition3D position;
- Direction3D forward;
- Direction3D up;
-
- GlobalDistance near, far;
- glm::mat4 view, projection;
- glm::mat4 viewProjection, inverseViewProjection;
-};
diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp
index 4e271db..e01532e 100644
--- a/gfx/gl/sceneProvider.cpp
+++ b/gfx/gl/sceneProvider.cpp
@@ -9,6 +9,6 @@ SceneProvider::environment(const SceneShader &, const SceneRenderer & renderer)
}
void
-SceneProvider::shadows(const ShadowMapper &) const
+SceneProvider::shadows(const ShadowMapper &, const Frustum &) const
{
}
diff --git a/gfx/gl/sceneProvider.h b/gfx/gl/sceneProvider.h
index f5e8e99..f6b7009 100644
--- a/gfx/gl/sceneProvider.h
+++ b/gfx/gl/sceneProvider.h
@@ -5,6 +5,7 @@
class SceneRenderer;
class ShadowMapper;
class SceneShader;
+class Frustum;
class SceneProvider {
public:
@@ -12,8 +13,8 @@ public:
virtual ~SceneProvider() = default;
DEFAULT_MOVE_COPY(SceneProvider);
- virtual void content(const SceneShader &) const = 0;
+ virtual void content(const SceneShader &, const Frustum &) const = 0;
virtual void environment(const SceneShader &, const SceneRenderer &) const;
virtual void lights(const SceneShader &) const = 0;
- virtual void shadows(const ShadowMapper &) const;
+ virtual void shadows(const ShadowMapper &, const Frustum &) const;
};
diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp
index b2a7d78..188c4fd 100644
--- a/gfx/gl/sceneRenderer.cpp
+++ b/gfx/gl/sceneRenderer.cpp
@@ -71,7 +71,7 @@ SceneRenderer::render(const SceneProvider & scene) const
glEnable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- scene.content(shader);
+ scene.content(shader, camera);
// Environment pass -
// * ambient - clears illumination texture - see setAmbientLight
diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h
index 93470f5..4649a68 100644
--- a/gfx/gl/sceneRenderer.h
+++ b/gfx/gl/sceneRenderer.h
@@ -1,12 +1,12 @@
#pragma once
-#include "camera.h"
#include "gfx/lightDirection.h"
#include "glArrays.h"
#include "program.h"
#include "sceneProvider.h"
#include "sceneShader.h"
#include "shadowMapper.h"
+#include <gfx/camera.h>
#include <glm/fwd.hpp>
class SceneRenderer {
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index 1b95aa3..6525f76 100644
--- a/gfx/gl/shadowMapper.cpp
+++ b/gfx/gl/shadowMapper.cpp
@@ -1,7 +1,7 @@
#include "shadowMapper.h"
-#include "camera.h"
#include "collections.h"
#include "game/gamestate.h"
+#include "gfx/aabb.h"
#include "gfx/gl/shaders/fs-shadowDynamicPointInstWithTextures.h"
#include "gfx/gl/shaders/fs-shadowDynamicPointStencil.h"
#include "gfx/gl/shaders/gs-commonShadowPoint.h"
@@ -20,7 +20,7 @@
#include "maths.h"
#include "sceneProvider.h"
#include "sceneShader.h"
-#include "sorting.h"
+#include <gfx/camera.h>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/matrix.hpp>
@@ -56,7 +56,7 @@ constexpr auto shadowBands
= []<GlobalDistance... ints>(const float scaleFactor, std::integer_sequence<GlobalDistance, ints...>) {
const auto base = 10'000'000 / pow(scaleFactor, sizeof...(ints) - 1);
return std::array {1, static_cast<GlobalDistance>((base * pow(scaleFactor, ints)))...};
- }(6.6F, std::make_integer_sequence<GlobalDistance, ShadowMapper::SHADOW_BANDS>());
+ }(4.6F, std::make_integer_sequence<GlobalDistance, ShadowMapper::SHADOW_BANDS>());
static_assert(shadowBands.front() == 1);
static_assert(shadowBands.back() == 10'000'000);
@@ -102,30 +102,30 @@ ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, co
const auto bandViewExtents = getBandViewExtents(camera, lightViewDir);
Definitions out;
Sizes sizes;
- std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()),
- std::back_inserter(out),
- [bands = bandViewExtents.size() - 2, &lightViewDir, &sizes](const auto & near, const auto & far) mutable {
- const auto extents_minmax
- = [extents = std::span {near.begin(), far.end()}](auto && comp, RelativeDistance extra) {
- const auto mm = std::minmax_element(extents.begin(), extents.end(), comp);
- return std::make_pair(comp.get(*mm.first) - extra, comp.get(*mm.second) + extra);
- };
- const std::array extents = {extents_minmax(CompareBy {0}, 0), extents_minmax(CompareBy {1}, 0),
- extents_minmax(CompareBy {2}, 10'000)};
-
- const auto lightProjection = [](const auto & x, const auto & y, const auto & z) {
- return glm::ortho(x.first, x.second, y.first, y.second, -z.second, -z.first);
- }(extents[0], extents[1], extents[2]);
-
- sizes.emplace_back(extents[0].second - extents[0].first, extents[1].second - extents[1].first,
- extents[2].second - extents[2].first);
+ 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);
}
- scene.shadows(*this);
+ 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 frustum {lightViewPoint, lightViewDir, lightProjection};
+ scene.shadows(*this, frustum);
glCullFace(GL_BACK);