summaryrefslogtreecommitdiff
path: root/gfx/gl
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/gl')
-rw-r--r--gfx/gl/sceneProvider.cpp4
-rw-r--r--gfx/gl/sceneProvider.h2
-rw-r--r--gfx/gl/shaders/shadowCast.fs6
-rw-r--r--gfx/gl/shaders/shadowDynamicPoint.vs12
-rw-r--r--gfx/gl/shaders/shadowFixedPoint.vs13
-rw-r--r--gfx/gl/shadowMapper.cpp92
-rw-r--r--gfx/gl/shadowMapper.h46
7 files changed, 175 insertions, 0 deletions
diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp
index d73ac3c..9152bfa 100644
--- a/gfx/gl/sceneProvider.cpp
+++ b/gfx/gl/sceneProvider.cpp
@@ -7,3 +7,7 @@ SceneProvider::environment(const SceneShader &, const SceneRenderer & renderer)
renderer.setAmbientLight({0.5F, 0.5F, 0.5F});
renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {1, 0, -1});
}
+void
+SceneProvider::shadows(const ShadowMapper &) const
+{
+}
diff --git a/gfx/gl/sceneProvider.h b/gfx/gl/sceneProvider.h
index a966f9c..ef269b3 100644
--- a/gfx/gl/sceneProvider.h
+++ b/gfx/gl/sceneProvider.h
@@ -1,6 +1,7 @@
#pragma once
class SceneRenderer;
+class ShadowMapper;
class SceneShader;
class SceneProvider {
@@ -9,4 +10,5 @@ public:
virtual void content(const SceneShader &) const = 0;
virtual void environment(const SceneShader &, const SceneRenderer &) const;
virtual void lights(const SceneShader &) const = 0;
+ virtual void shadows(const ShadowMapper &) const;
};
diff --git a/gfx/gl/shaders/shadowCast.fs b/gfx/gl/shaders/shadowCast.fs
new file mode 100644
index 0000000..d427da2
--- /dev/null
+++ b/gfx/gl/shaders/shadowCast.fs
@@ -0,0 +1,6 @@
+#version 330 core
+
+void
+main()
+{
+}
diff --git a/gfx/gl/shaders/shadowDynamicPoint.vs b/gfx/gl/shaders/shadowDynamicPoint.vs
new file mode 100644
index 0000000..91d8bf7
--- /dev/null
+++ b/gfx/gl/shaders/shadowDynamicPoint.vs
@@ -0,0 +1,12 @@
+#version 330 core
+
+in vec3 position;
+
+uniform mat4 viewProjection;
+uniform mat4 model;
+
+void
+main()
+{
+ gl_Position = viewProjection * model * vec4(position, 1.0);
+}
diff --git a/gfx/gl/shaders/shadowFixedPoint.vs b/gfx/gl/shaders/shadowFixedPoint.vs
new file mode 100644
index 0000000..9e1cc62
--- /dev/null
+++ b/gfx/gl/shaders/shadowFixedPoint.vs
@@ -0,0 +1,13 @@
+#version 330 core
+
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec3 normal;
+layout(location = 2) in vec2 tex;
+
+uniform mat4 viewProjection;
+
+void
+main()
+{
+ gl_Position = viewProjection * vec4(position, 1.0);
+}
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
new file mode 100644
index 0000000..4cc2e24
--- /dev/null
+++ b/gfx/gl/shadowMapper.cpp
@@ -0,0 +1,92 @@
+#include "shadowMapper.h"
+#include "gfx/gl/shaders/fs-shadowCast.h"
+#include "gfx/gl/shaders/vs-shadowDynamicPoint.h"
+#include "gfx/gl/shaders/vs-shadowFixedPoint.h"
+#include "gfx/models/texture.h"
+#include "location.hpp"
+#include "maths.h"
+#include "sceneProvider.h"
+#include "sceneShader.h"
+#include <glm/gtc/type_ptr.hpp>
+#include <glm/gtx/transform.hpp>
+#include <glm/matrix.hpp>
+
+ShadowMapper::ShadowMapper(const glm::ivec2 & s) : size {s}
+{
+ glBindTexture(GL_TEXTURE_2D, depthMap);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ static constexpr glm::vec3 border {std::numeric_limits<float>::infinity()};
+ // static constexpr glm::vec3 border {1};
+ glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(border));
+
+ glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ throw std::runtime_error("Framebuffer not complete!");
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+glm::mat4x4
+ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir) const
+{
+ const glm::vec3 centre {1200.F, 1200.F, 0.F};
+ const glm::vec3 range = glm::normalize(dir) * 1800.F;
+ const auto lightProjection = glm::ortho(-1200.F, 1200.F, -1200.F, 1200.F, 0.F, 3600.F);
+ const auto lightView = glm::lookAt(centre - range, centre, north);
+ const auto lightViewProjection = lightProjection * lightView;
+ fixedPoint.setViewProjection(lightViewProjection);
+ dynamicPoint.setViewProjection(lightViewProjection);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
+ glViewport(0, 0, size.x, size.y);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_DEPTH_TEST);
+ glCullFace(GL_FRONT);
+ scene.shadows(*this);
+ glCullFace(GL_BACK);
+
+ // Texture::saveDepth(depthMap, size, "/tmp/depth.tga");
+ return lightViewProjection;
+}
+
+ShadowMapper::FixedPoint::FixedPoint() :
+ Program {shadowFixedPoint_vs, shadowCast_fs}, viewProjectionLoc {*this, "viewProjection"}
+{
+}
+void
+ShadowMapper::FixedPoint::setViewProjection(const glm::mat4 & viewProjection) const
+{
+ use();
+ glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection));
+}
+void
+ShadowMapper::FixedPoint::use() const
+{
+ glUseProgram(*this);
+}
+
+ShadowMapper::DynamicPoint::DynamicPoint() :
+ Program {shadowDynamicPoint_vs, shadowCast_fs}, viewProjectionLoc {*this, "viewProjection"}, modelLoc {
+ *this, "model"}
+{
+}
+void
+ShadowMapper::DynamicPoint::setViewProjection(const glm::mat4 & viewProjection) const
+{
+ glUseProgram(*this);
+ glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection));
+}
+void
+ShadowMapper::DynamicPoint::use(const Location & location) const
+{
+ glUseProgram(*this);
+ const auto model = glm::translate(location.pos) * rotate_ypr(location.rot);
+ glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
+}
diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h
new file mode 100644
index 0000000..dcd0a02
--- /dev/null
+++ b/gfx/gl/shadowMapper.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "lib/glArrays.h"
+#include "program.h"
+#include <glm/vec2.hpp>
+
+class SceneProvider;
+
+class ShadowMapper {
+public:
+ ShadowMapper(const glm::ivec2 & size = {1024, 1024});
+
+ glm::mat4x4 update(const SceneProvider &, const glm::vec3 & direction) const;
+
+ class FixedPoint : public Program {
+ public:
+ FixedPoint();
+ void setViewProjection(const glm::mat4 &) const;
+ void use() const;
+
+ private:
+ RequiredUniformLocation viewProjectionLoc;
+ };
+ class DynamicPoint : public Program {
+ public:
+ DynamicPoint();
+ void setViewProjection(const glm::mat4 &) const;
+ void use(const Location &) const;
+
+ private:
+ RequiredUniformLocation viewProjectionLoc;
+ RequiredUniformLocation modelLoc;
+ };
+ FixedPoint fixedPoint;
+ DynamicPoint dynamicPoint;
+
+ operator GLuint() const
+ {
+ return depthMap;
+ }
+
+private:
+ glFrameBuffer depthMapFBO;
+ glTexture depthMap;
+ glm::ivec2 size;
+};