diff options
Diffstat (limited to 'gfx/gl')
34 files changed, 230 insertions, 153 deletions
diff --git a/gfx/gl/bufferedLocation.cpp b/gfx/gl/bufferedLocation.cpp index eb3dac3..d6a63b9 100644 --- a/gfx/gl/bufferedLocation.cpp +++ b/gfx/gl/bufferedLocation.cpp @@ -1,9 +1,8 @@ #include "bufferedLocation.h" #include "location.h" -#include "maths.h" #include <glm/gtx/transform.hpp> -BufferedLocation::BufferedLocation(glm::vec3 p, glm::vec3 r) : BufferedLocation {Location {p, r}} { } +BufferedLocation::BufferedLocation(GlobalPosition3D p, Rotation3D r) : BufferedLocation {Location {p, r}} { } BufferedLocation::BufferedLocation(const Location & l) : loc {l} { } @@ -20,20 +19,20 @@ BufferedLocation::operator=(const Location & l) return *this; } -glm::vec3 +GlobalPosition3D BufferedLocation::position() const { return loc.pos; } -glm::vec3 +Position3D BufferedLocation::rotation() const { return loc.rot; } void -BufferedLocation::setPosition(glm::vec3 p, bool update) +BufferedLocation::setPosition(GlobalPosition3D p, bool update) { loc.pos = p; if (update) { @@ -42,7 +41,7 @@ BufferedLocation::setPosition(glm::vec3 p, bool update) } void -BufferedLocation::setRotation(glm::vec3 r, bool update) +BufferedLocation::setRotation(Position3D r, bool update) { loc.rot = r; if (update) { @@ -51,7 +50,7 @@ BufferedLocation::setRotation(glm::vec3 r, bool update) } void -BufferedLocation::setLocation(glm::vec3 p, glm::vec3 r) +BufferedLocation::setLocation(GlobalPosition3D p, Rotation3D r) { loc.pos = p; loc.rot = r; @@ -59,7 +58,13 @@ BufferedLocation::setLocation(glm::vec3 p, glm::vec3 r) } glm::mat4 -BufferedLocation::getTransform() const +BufferedLocation::getRotationTransform() const { - return loc.getTransform(); + return loc.getRotationTransform(); +} + +void +BufferedLocationUpdater::updateBuffer() const +{ + onUpdate(this); } diff --git a/gfx/gl/bufferedLocation.h b/gfx/gl/bufferedLocation.h index 8096489..87b957f 100644 --- a/gfx/gl/bufferedLocation.h +++ b/gfx/gl/bufferedLocation.h @@ -4,11 +4,11 @@ #include <functional> #include <glm/mat4x4.hpp> #include <glm/vec3.hpp> -#include <tuple> +#include <utility> class BufferedLocation { public: - BufferedLocation(glm::vec3 = {}, glm::vec3 = {}); + BufferedLocation(GlobalPosition3D = {}, Rotation3D = {}); BufferedLocation(const Location &); virtual ~BufferedLocation() = default; @@ -16,25 +16,25 @@ public: operator const Location &() const; - glm::vec3 position() const; - glm::vec3 rotation() const; - void setPosition(glm::vec3, bool update = true); - void setRotation(glm::vec3, bool update = true); - void setLocation(glm::vec3, glm::vec3); + [[nodiscard]] GlobalPosition3D position() const; + [[nodiscard]] Rotation3D rotation() const; + void setPosition(GlobalPosition3D, bool update = true); + void setRotation(Rotation3D, bool update = true); + void setLocation(GlobalPosition3D, Rotation3D); - glm::mat4 getTransform() const; + [[nodiscard]] glm::mat4 getRotationTransform() const; private: - virtual void updateBuffer() = 0; + virtual void updateBuffer() const = 0; Location loc; }; -template<typename... Target> class BufferedLocationT : public BufferedLocation { +class BufferedLocationUpdater : public BufferedLocation { public: template<typename... LocationArgs> - BufferedLocationT(Target &&... target, LocationArgs &&... t) : - BufferedLocation {std::forward<LocationArgs>(t)...}, target {std::forward<Target>(target)...} + BufferedLocationUpdater(std::function<void(const BufferedLocation *)> onUpdate, LocationArgs &&... t) : + BufferedLocation {std::forward<LocationArgs>(t)...}, onUpdate {std::move(onUpdate)} { updateBuffer(); } @@ -42,11 +42,7 @@ public: using BufferedLocation::operator=; private: - void - updateBuffer() override - { - std::apply(std::invoke<const Target &...>, target) = getTransform(); - } + void updateBuffer() const override; - std::tuple<Target...> target; + std::function<void(const BufferedLocation *)> onUpdate; }; diff --git a/gfx/gl/camera.cpp b/gfx/gl/camera.cpp index c4c9544..15f76c4 100644 --- a/gfx/gl/camera.cpp +++ b/gfx/gl/camera.cpp @@ -2,19 +2,19 @@ #include <collections.h> #include <glm/gtx/intersect.hpp> // IWYU pragma: keep #include <glm/gtx/transform.hpp> // IWYU pragma: keep +#include <math.h> #include <maths.h> #include <ray.h> -Camera::Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar) : +Camera::Camera(Position3D pos, Angle fov, Angle aspect, Distance zNear, Distance zFar) : position {pos}, forward {::north}, up {::up}, near {zNear}, far {zFar}, - projection {glm::perspective(fov, aspect, zNear, zFar)}, - viewProjection {projection * glm::lookAt(position, position + forward, up)}, - inverseViewProjection {glm::inverse(viewProjection)} + projection {glm::perspective(fov, aspect, zNear, zFar)}, viewProjection {}, inverseViewProjection {} { + updateView(); } Ray -Camera::unProject(const glm::vec2 & mouse) const +Camera::unProject(const ScreenRelCoord & mouse) const { static constexpr const glm::vec4 screen {0, 0, 1, 1}; const auto mouseProjection = glm::lookAt(::origin, forward, up); @@ -24,12 +24,12 @@ Camera::unProject(const glm::vec2 & mouse) const void Camera::updateView() { - viewProjection = projection * glm::lookAt(position, position + forward, up); - inverseViewProjection = glm::inverse(viewProjection); + viewProjection = projection * glm::lookAt(origin, forward, up); + inverseViewProjection = glm::inverse(projection * glm::lookAt(position, position + forward, up)); } -glm::vec3 -Camera::upFromForward(const glm::vec3 & forward) +Direction3D +Camera::upFromForward(const Direction3D & forward) { const auto right = glm::cross(forward, ::down); return glm::cross(forward, right); @@ -38,11 +38,11 @@ Camera::upFromForward(const glm::vec3 & forward) std::array<glm::vec4, 4> Camera::extentsAtDist(const float dist) const { - const auto clampToSeaFloor = [this, dist](const glm::vec3 & target) { + const auto clampToSeaFloor = [this, dist](const Position3D & target) { if (target.z < -1.5F) { const auto vec = glm::normalize(target - position); - constexpr glm::vec3 seafloor {0, 0, -1.5F}; - float outdist; + constexpr Position3D seafloor {0, 0, -1.5F}; + float outdist {}; if (glm::intersectRayPlane(position, vec, seafloor, ::up, outdist)) { return (vec * outdist + position) ^ outdist; } diff --git a/gfx/gl/camera.h b/gfx/gl/camera.h index 3f1c3a7..469df0d 100644 --- a/gfx/gl/camera.h +++ b/gfx/gl/camera.h @@ -1,60 +1,69 @@ #pragma once +#include "config/types.h" #include <glm/glm.hpp> #include <maths.h> #include <ray.h> class Camera { public: - Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar); + Camera(Position3D, Angle fov, Angle aspect, Distance zNear, Distance zFar); [[nodiscard]] glm::mat4 getViewProjection() const { return viewProjection; } - [[nodiscard]] Ray unProject(const glm::vec2 &) const; + + [[nodiscard]] Ray unProject(const ScreenRelCoord &) const; void - setPosition(const glm::vec3 & p) + setPosition(const Position3D & p) { position = p; updateView(); } + void - setForward(const glm::vec3 & f) + setForward(const Direction3D & f) { setForward(f, upFromForward(f)); } + void - setForward(const glm::vec3 & f, const glm::vec3 & u) + setForward(const Direction3D & f, const Direction3D & u) { forward = f; up = u; updateView(); } + void - setView(const glm::vec3 & p, const glm::vec3 & f) + setView(const Position3D & p, const Direction3D & f) { position = p; setForward(f); } + void - setView(const glm::vec3 & p, const glm::vec3 & f, const glm::vec3 & u) + setView(const Position3D & p, const Direction3D & f, const Direction3D & u) { position = p; setView(f, u); } + void - lookAt(const glm::vec3 & target) + lookAt(const Position3D & target) { setForward(glm::normalize(target - position)); } + [[nodiscard]] auto getForward() const { return forward; } + [[nodiscard]] auto getPosition() const { @@ -63,14 +72,14 @@ public: [[nodiscard]] std::array<glm::vec4, 4> extentsAtDist(float) const; - [[nodiscard]] static glm::vec3 upFromForward(const glm::vec3 & forward); + [[nodiscard]] static Direction3D upFromForward(const Direction3D & forward); private: void updateView(); - glm::vec3 position; - glm::vec3 forward; - glm::vec3 up; + Position3D position; + Direction3D forward; + Direction3D up; float near, far; glm::mat4 projection; diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h index 7b0341b..a89aa78 100644 --- a/gfx/gl/instanceVertices.h +++ b/gfx/gl/instanceVertices.h @@ -13,9 +13,11 @@ public: class [[nodiscard]] InstanceProxy { public: InstanceProxy(InstanceVertices * iv, std::size_t idx) : instances {iv}, index {idx} { } + InstanceProxy(InstanceProxy && other) : instances {std::exchange(other.instances, nullptr)}, index {other.index} { } + NO_COPY(InstanceProxy); ~InstanceProxy() @@ -35,6 +37,7 @@ public: index = other.index; return *this; } + template<typename U> T & operator=(U && v) @@ -42,40 +45,46 @@ public: return instances->lookup(index) = std::forward<U>(v); } - [[nodiscard]] - operator T &() + [[nodiscard]] operator T &() { return instances->lookup(index); } + [[nodiscard]] operator const T &() const { return instances->lookup(index); } + [[nodiscard]] T * get() { return &instances->lookup(index); } + [[nodiscard]] const T * get() const { return &instances->lookup(index); } + [[nodiscard]] T * operator->() { return get(); } + [[nodiscard]] const T * operator->() const { return get(); } + [[nodiscard]] T & operator*() { return instances->lookup(index); } + [[nodiscard]] const T & operator*() const { diff --git a/gfx/gl/program.h b/gfx/gl/program.h index 76b6742..1a1c306 100644 --- a/gfx/gl/program.h +++ b/gfx/gl/program.h @@ -9,6 +9,7 @@ class Location; using ProgramRef = glRef<GLuint, &glCreateProgram, &glDeleteProgram>; + class Program { public: template<typename... S> explicit Program(const S &... srcs) @@ -16,12 +17,14 @@ public: (glAttachShader(m_program, srcs.compile()), ...); linkAndValidate(); } + virtual ~Program() = default; DEFAULT_MOVE_NO_COPY(Program); class UniformLocation { public: UniformLocation(GLuint prog, const char * name); + // NOLINTNEXTLINE(hicpp-explicit-conversions) operator auto() const { diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp index 0163b36..2e8604c 100644 --- a/gfx/gl/sceneProvider.cpp +++ b/gfx/gl/sceneProvider.cpp @@ -7,6 +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, 1, -1}, *this); } + void SceneProvider::shadows(const ShadowMapper &) const { diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index aa9453a..53178e5 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -13,8 +13,9 @@ static constexpr const std::array<const glm::i8vec4, 4> displayVAOdata {{ {1, 1, 1, 1}, {1, -1, 1, 0}, }}; -SceneRenderer::SceneRenderer(glm::ivec2 s, GLuint o) : - camera {{-1250.0F, -1250.0F, 35.0F}, quarter_pi, ratio(s), 0.1F, 10000.0F}, size {s}, output {o}, + +SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o) : + camera {{-1250000.0F, -1250000.0F, 35.0F}, quarter_pi, ratio(s), 100.F, 10000000.0F}, size {s}, output {o}, lighting {lighting_vs, lighting_fs}, shadowMapper {{2048, 2048}} { shader.setViewPort({0, 0, size.x, size.y}); @@ -51,7 +52,7 @@ SceneRenderer::SceneRenderer(glm::ivec2 s, GLuint o) : void SceneRenderer::render(const SceneProvider & scene) const { - shader.setViewProjection(camera.getViewProjection()); + shader.setViewProjection(camera.getPosition(), camera.getViewProjection()); glViewport(0, 0, size.x, size.y); // Geometry pass @@ -96,7 +97,7 @@ SceneRenderer::render(const SceneProvider & scene) const } void -SceneRenderer::setAmbientLight(const glm::vec3 & colour) const +SceneRenderer::setAmbientLight(const RGB & colour) const { glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); glClearColor(colour.r, colour.g, colour.b, 1.0F); @@ -104,8 +105,7 @@ SceneRenderer::setAmbientLight(const glm::vec3 & colour) const } void -SceneRenderer::setDirectionalLight( - const glm::vec3 & colour, const glm::vec3 & direction, const SceneProvider & scene) const +SceneRenderer::setDirectionalLight(const RGB & colour, const Direction3D & direction, const SceneProvider & scene) const { if (colour.r > 0 || colour.g > 0 || colour.b > 0) { const auto lvp = shadowMapper.update(scene, direction, camera); @@ -134,8 +134,8 @@ SceneRenderer::DirectionalLightProgram::DirectionalLightProgram() : } void -SceneRenderer::DirectionalLightProgram::setDirectionalLight(const glm::vec3 & c, const glm::vec3 & d, - const std::span<const glm::mat4x4> lvp, const std::span<const glm::vec4> shadowMapRegions, +SceneRenderer::DirectionalLightProgram::setDirectionalLight(const RGB & c, const Direction3D & d, + const std::span<const glm::mat4x4> lvp, const std::span<const TextureRelRegion> shadowMapRegions, std::size_t maps) const { glUniform3fv(colourLoc, 1, glm::value_ptr(c)); diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h index d4af665..30fd8d3 100644 --- a/gfx/gl/sceneRenderer.h +++ b/gfx/gl/sceneRenderer.h @@ -11,34 +11,36 @@ class SceneRenderer { public: - explicit SceneRenderer(glm::ivec2 size, GLuint output); + explicit SceneRenderer(ScreenAbsCoord size, GLuint output); void render(const SceneProvider &) const; - void setAmbientLight(const glm::vec3 & colour) const; - void setDirectionalLight(const glm::vec3 & colour, const glm::vec3 & direction, const SceneProvider &) const; + void setAmbientLight(const RGB & colour) const; + void setDirectionalLight(const RGB & colour, const Direction3D & direction, const SceneProvider &) const; Camera camera; private: void renderQuad() const; - glm::ivec2 size; + ScreenAbsCoord size; GLuint output; glFrameBuffer gBuffer; glTexture gPosition, gNormal, gAlbedoSpec, gIllumination; glRenderBuffer depth; + class DeferredLightProgram : public Program { public: using Program::Program; using Program::use; }; + class DirectionalLightProgram : public Program { public: DirectionalLightProgram(); using Program::use; - void setDirectionalLight(const glm::vec3 &, const glm::vec3 &, const std::span<const glm::mat4x4>, - const std::span<const glm::vec4>, std::size_t maps) const; + void setDirectionalLight(const RGB &, const Direction3D &, const std::span<const glm::mat4x4>, + const std::span<const TextureRelRegion>, std::size_t maps) const; private: RequiredUniformLocation directionLoc, colourLoc, lightViewProjectionLoc, lightViewProjectionCountLoc, diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp index 1354611..59a9748 100644 --- a/gfx/gl/sceneShader.cpp +++ b/gfx/gl/sceneShader.cpp @@ -26,16 +26,16 @@ SceneShader::SceneShader() : } void -SceneShader::setViewProjection(const glm::mat4 & viewProjection) const +SceneShader::setViewProjection(const Position3D & viewPoint, const glm::mat4 & viewProjection) const { for (const auto & prog : std::array<const SceneProgram *, 7> { &basic, &basicInst, &water, &landmass, &absolute, &pointLight, &spotLight}) { - prog->setViewProjection(viewProjection); + prog->setViewProjection(viewPoint, viewProjection); } } void -SceneShader::setViewPort(const glm::ivec4 & viewPort) const +SceneShader::setViewPort(const ViewPort & viewPort) const { for (const auto & prog : std::array<const SceneProgram *, 7> { &basic, &basicInst, &water, &landmass, &absolute, &pointLight, &spotLight}) { @@ -44,14 +44,15 @@ SceneShader::setViewPort(const glm::ivec4 & viewPort) const } void -SceneShader::SceneProgram::setViewProjection(const glm::mat4 & viewProjection) const +SceneShader::SceneProgram::setViewProjection(const Position3D & viewPoint, const glm::mat4 & viewProjection) const { glUseProgram(*this); glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection)); + glUniform3fv(viewPointLoc, 1, glm::value_ptr(viewPoint)); } void -SceneShader::SceneProgram::setViewPort(const glm::ivec4 & viewPort) const +SceneShader::SceneProgram::setViewPort(const ViewPort & viewPort) const { if (viewPortLoc >= 0) { glUseProgram(*this); @@ -59,13 +60,16 @@ SceneShader::SceneProgram::setViewPort(const glm::ivec4 & viewPort) const } } -SceneShader::BasicProgram::BasicProgram() : SceneProgram {dynamicPoint_vs, material_fs}, modelLoc {*this, "model"} { } +SceneShader::BasicProgram::BasicProgram() : + SceneProgram {dynamicPoint_vs, material_fs}, modelLoc {*this, "model"}, modelPosLoc {*this, "modelPos"} +{ +} void SceneShader::BasicProgram::setModel(Location const & location) const { - const auto model {glm::translate(location.pos) * rotate_ypr(location.rot)}; - glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); + glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(rotate_ypr(location.rot))); + glUniform3iv(modelPosLoc, 1, glm::value_ptr(location.pos)); } void @@ -81,38 +85,40 @@ void SceneShader::WaterProgram::use(float waveCycle) const { Program::use(); - glm::vec3 waves {waveCycle, 0.F, 0.F}; + Position3D waves {waveCycle, 0.F, 0.F}; glUniform3fv(waveLoc, 1, glm::value_ptr(waves)); } SceneShader::PointLightShader::PointLightShader() : - SceneProgram {pointLight_vs, pointLight_gs, pointLight_fs}, colourLoc {*this, "colour"}, kqLoc {*this, "kq"} + SceneProgram {pointLight_vs, pointLight_gs, pointLight_fs}, colourLoc {*this, "colour"}, kqLoc {*this, "kq"}, + viewPointLoc {*this, "viewPoint"} { - VertexArrayObject {va}.addAttribs<glm::vec3>(b); + VertexArrayObject {va}.addAttribs<Position3D>(b); } void -SceneShader::PointLightShader::add(const glm::vec3 & position, const glm::vec3 & colour, const float kq) const +SceneShader::PointLightShader::add(const Position3D & position, const RGB & colour, const float kq) const { Program::use(); glBindVertexArray(va); glBindBuffer(GL_ARRAY_BUFFER, b); glUniform3fv(colourLoc, 1, glm::value_ptr(colour)); glUniform1f(kqLoc, kq); - glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3), glm::value_ptr(position), GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(Position3D), glm::value_ptr(position), GL_DYNAMIC_DRAW); glDrawArrays(GL_POINTS, 0, 1); } SceneShader::SpotLightShader::SpotLightShader() : SceneProgram {spotLight_vs, spotLight_gs, spotLight_fs}, directionLoc {*this, "v_direction"}, - colourLoc {*this, "colour"}, kqLoc {*this, "kq"}, arcLoc {*this, "arc"} + colourLoc {*this, "colour"}, kqLoc {*this, "kq"}, arcLoc {*this, "arc"}, viewPointLoc {*this, "viewPoint"} + { - using v3pair = std::pair<glm::vec3, glm::vec3>; + using v3pair = std::pair<Position3D, Direction3D>; VertexArrayObject {va}.addAttribs<v3pair, &v3pair::first, &v3pair::second>(b); } void -SceneShader::SpotLightShader::add(const glm::vec3 & position, const glm::vec3 & direction, const glm::vec3 & colour, +SceneShader::SpotLightShader::add(const Position3D & position, const Direction3D & direction, const RGB & colour, const float kq, const float arc) const { Program::use(); @@ -122,6 +128,6 @@ SceneShader::SpotLightShader::add(const glm::vec3 & position, const glm::vec3 & glUniform3fv(directionLoc, 1, glm::value_ptr(direction)); glUniform1f(kqLoc, kq); glUniform1f(arcLoc, arc); - glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3), glm::value_ptr(position), GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(Position3D), glm::value_ptr(position), GL_DYNAMIC_DRAW); glDrawArrays(GL_POINTS, 0, 1); } diff --git a/gfx/gl/sceneShader.h b/gfx/gl/sceneShader.h index ead184e..83c234c 100644 --- a/gfx/gl/sceneShader.h +++ b/gfx/gl/sceneShader.h @@ -1,5 +1,6 @@ #pragma once +#include "config/types.h" #include "program.h" #include <glArrays.h> @@ -10,15 +11,16 @@ class SceneShader { public: template<typename... S> inline explicit SceneProgram(const S &... srcs) : - Program {srcs...}, viewProjectionLoc {*this, "viewProjection"}, viewPortLoc {*this, "viewPort"} + Program {srcs...}, viewProjectionLoc {*this, "viewProjection"}, viewPointLoc {*this, "viewPoint"}, + viewPortLoc {*this, "viewPort"} { } - void setViewProjection(const glm::mat4 &) const; - void setViewPort(const glm::ivec4 &) const; + void setViewProjection(const Position3D &, const glm::mat4 &) const; + void setViewPort(const ViewPort &) const; private: - RequiredUniformLocation viewProjectionLoc; + RequiredUniformLocation viewProjectionLoc, viewPointLoc; UniformLocation viewPortLoc; }; @@ -30,6 +32,7 @@ class SceneShader { private: RequiredUniformLocation modelLoc; + RequiredUniformLocation modelPosLoc; }; class AbsolutePosProgram : public SceneProgram { @@ -52,11 +55,12 @@ class SceneShader { public: PointLightShader(); - void add(const glm::vec3 & position, const glm::vec3 & colour, const float kq) const; + void add(const Position3D & position, const RGB & colour, const float kq) const; private: UniformLocation colourLoc; UniformLocation kqLoc; + UniformLocation viewPointLoc; glVertexArray va; glBuffer b; }; @@ -65,7 +69,7 @@ class SceneShader { public: SpotLightShader(); - void add(const glm::vec3 & position, const glm::vec3 & direction, const glm::vec3 & colour, const float kq, + void add(const Position3D & position, const Direction3D & direction, const RGB & colour, const float kq, const float arc) const; private: @@ -73,6 +77,7 @@ class SceneShader { UniformLocation colourLoc; UniformLocation kqLoc; UniformLocation arcLoc; + UniformLocation viewPointLoc; glVertexArray va; glBuffer b; }; @@ -86,6 +91,6 @@ public: PointLightShader pointLight; SpotLightShader spotLight; - void setViewProjection(const glm::mat4 & viewProjection) const; - void setViewPort(const glm::ivec4 & viewPort) const; + void setViewProjection(const Position3D & viewPoint, const glm::mat4 & viewProjection) const; + void setViewPort(const ViewPort & viewPort) const; }; diff --git a/gfx/gl/shader.h b/gfx/gl/shader.h index 0810e6b..cff2281 100644 --- a/gfx/gl/shader.h +++ b/gfx/gl/shader.h @@ -8,6 +8,7 @@ class Shader { public: using ShaderRef = glRef<GLuint, &glCreateShader, &glDeleteShader>; + constexpr Shader(const GLchar * text, GLint len, GLuint type) : text {text}, len {len}, type {type} { } [[nodiscard]] ShaderRef compile() const; diff --git a/gfx/gl/shaders/commonPoint.glsl b/gfx/gl/shaders/commonPoint.glsl index 35510e1..046da27 100644 --- a/gfx/gl/shaders/commonPoint.glsl +++ b/gfx/gl/shaders/commonPoint.glsl @@ -24,5 +24,5 @@ main() Colour = colour; Material = getMaterialDetail(material); - gl_Position = viewProjection * worldPos; + gl_Position = viewProjection * vec4(FragPos - viewPoint + modelPos, 1); } diff --git a/gfx/gl/shaders/commonShadowPoint.glsl b/gfx/gl/shaders/commonShadowPoint.glsl index c7cbd3e..216642e 100644 --- a/gfx/gl/shaders/commonShadowPoint.glsl +++ b/gfx/gl/shaders/commonShadowPoint.glsl @@ -1,6 +1,7 @@ void main() { - gl_Position = viewProjection * model * vec4(position, 1.0); + vec4 worldPos = model * vec4(position, 1.0); + gl_Position = viewProjection * vec4(worldPos.xyz - viewPoint + modelPos, 1); gl_Position.z = max(gl_Position.z, -1); } diff --git a/gfx/gl/shaders/dynamicPoint.vs b/gfx/gl/shaders/dynamicPoint.vs index 961535c..667f247 100644 --- a/gfx/gl/shaders/dynamicPoint.vs +++ b/gfx/gl/shaders/dynamicPoint.vs @@ -5,6 +5,8 @@ include(`meshIn.glsl') include(`materialInterface.glsl') uniform mat4 viewProjection; +uniform vec3 viewPoint; uniform mat4 model; +uniform ivec3 modelPos; include(`commonPoint.glsl') diff --git a/gfx/gl/shaders/dynamicPointInst.vs b/gfx/gl/shaders/dynamicPointInst.vs index 2d6cee5..adf39bd 100644 --- a/gfx/gl/shaders/dynamicPointInst.vs +++ b/gfx/gl/shaders/dynamicPointInst.vs @@ -5,6 +5,8 @@ include(`meshIn.glsl') include(`materialInterface.glsl') uniform mat4 viewProjection; +uniform vec3 viewPoint; layout(location = 5) in mat4 model; +layout(location = 9) in ivec3 modelPos; include(`commonPoint.glsl') diff --git a/gfx/gl/shaders/fixedPoint.vs b/gfx/gl/shaders/fixedPoint.vs index ed78c96..6e1ab49 100644 --- a/gfx/gl/shaders/fixedPoint.vs +++ b/gfx/gl/shaders/fixedPoint.vs @@ -5,6 +5,8 @@ include(`meshIn.glsl') include(`materialInterface.glsl') uniform mat4 viewProjection; +uniform vec3 viewPoint; const mat4 model = mat4(1); +const vec3 modelPos = ivec3(0); include(`commonPoint.glsl') diff --git a/gfx/gl/shaders/landmass.fs b/gfx/gl/shaders/landmass.fs index 4dc92bb..9865d11 100644 --- a/gfx/gl/shaders/landmass.fs +++ b/gfx/gl/shaders/landmass.fs @@ -11,9 +11,9 @@ const vec3 rock = vec3(.2, .2, .1); const vec3 sand = vec3(.76, .7, .5); const vec3 snow = vec3(.97, .97, .99); -const float beachline = .5; -const float snowline_low = 28; -const float snowline_high = 30; +const float beachline = 500; +const float snowline_low = 28000; +const float snowline_high = 30000; const float slope_min = .99; const float slope_mid = .95; diff --git a/gfx/gl/shaders/pointLight.fs b/gfx/gl/shaders/pointLight.fs index bd32c05..1a68df8 100644 --- a/gfx/gl/shaders/pointLight.fs +++ b/gfx/gl/shaders/pointLight.fs @@ -26,5 +26,5 @@ main() if (normalDot < 0) { discard; } - FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist, 2))); + FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist / 1000.0, 2))); } diff --git a/gfx/gl/shaders/pointLight.gs b/gfx/gl/shaders/pointLight.gs index 03d131d..ec089f5 100644 --- a/gfx/gl/shaders/pointLight.gs +++ b/gfx/gl/shaders/pointLight.gs @@ -19,6 +19,7 @@ const vec3[] cube = vec3[]( // http://www.cs.umd.edu/gvil/papers/av_ts.pdf vec3(1, 1, -1) // Back-top-right ); uniform mat4 viewProjection; +uniform vec3 viewPoint; in vec3 centre[]; in float size[]; diff --git a/gfx/gl/shaders/pointLight.vs b/gfx/gl/shaders/pointLight.vs index 35682fa..7694a25 100644 --- a/gfx/gl/shaders/pointLight.vs +++ b/gfx/gl/shaders/pointLight.vs @@ -4,6 +4,7 @@ layout(location = 0) in vec3 position; uniform vec3 colour; uniform float kq; +uniform vec3 viewPoint; out vec3 centre; out float size; @@ -12,6 +13,6 @@ void main() { centre = position; - size = (8 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq); - gl_Position = vec4(centre, 0); + size = (8000 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq); + gl_Position = vec4(centre - viewPoint, 0); } diff --git a/gfx/gl/shaders/shadowDynamicPoint.vs b/gfx/gl/shaders/shadowDynamicPoint.vs index f3ed533..e20d31a 100644 --- a/gfx/gl/shaders/shadowDynamicPoint.vs +++ b/gfx/gl/shaders/shadowDynamicPoint.vs @@ -3,6 +3,8 @@ include(`meshIn.glsl') uniform mat4 viewProjection; +uniform vec3 viewPoint; uniform mat4 model; +uniform ivec3 modelPos; include(`commonShadowPoint.glsl') diff --git a/gfx/gl/shaders/shadowDynamicPointInst.vs b/gfx/gl/shaders/shadowDynamicPointInst.vs index 1bf74ef..ab3e976 100644 --- a/gfx/gl/shaders/shadowDynamicPointInst.vs +++ b/gfx/gl/shaders/shadowDynamicPointInst.vs @@ -3,6 +3,8 @@ include(`meshIn.glsl') uniform mat4 viewProjection; +uniform vec3 viewPoint; layout(location = 5) in mat4 model; +layout(location = 9) in ivec3 modelPos; include(`commonShadowPoint.glsl') diff --git a/gfx/gl/shaders/shadowFixedPoint.vs b/gfx/gl/shaders/shadowFixedPoint.vs index 8921707..a9fb4a3 100644 --- a/gfx/gl/shaders/shadowFixedPoint.vs +++ b/gfx/gl/shaders/shadowFixedPoint.vs @@ -3,6 +3,8 @@ include(`meshIn.glsl') uniform mat4 viewProjection; +uniform vec3 viewPoint; const mat4 model = mat4(1); +const ivec3 modelPos = ivec3(0); include(`commonShadowPoint.glsl') diff --git a/gfx/gl/shaders/spotLight.fs b/gfx/gl/shaders/spotLight.fs index add86fd..78b8f72 100644 --- a/gfx/gl/shaders/spotLight.fs +++ b/gfx/gl/shaders/spotLight.fs @@ -30,5 +30,5 @@ main() if (normalDot < 0) { discard; } - FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist, 2))); + FragColor = (colour * normalDot) / (1 + (kq * pow(lightDist / 1000.0, 2))); } diff --git a/gfx/gl/shaders/spotLight.gs b/gfx/gl/shaders/spotLight.gs index ad65675..0529614 100644 --- a/gfx/gl/shaders/spotLight.gs +++ b/gfx/gl/shaders/spotLight.gs @@ -10,6 +10,7 @@ const vec3[] pyramid = vec3[]( // four-sided vec3(1, -1, 1) // Front-right ); uniform mat4 viewProjection; +uniform vec3 viewPoint; uniform float arc; in vec3 position[]; diff --git a/gfx/gl/shaders/spotLight.vs b/gfx/gl/shaders/spotLight.vs index dca0854..08197a4 100644 --- a/gfx/gl/shaders/spotLight.vs +++ b/gfx/gl/shaders/spotLight.vs @@ -6,6 +6,7 @@ uniform vec3 v_direction; uniform vec3 colour; uniform float kq; uniform float arc; +uniform vec3 viewPoint; out vec3 position; out vec3 direction; @@ -17,7 +18,7 @@ main() { position = v_position; direction = normalize(v_direction); - size = (8 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq); + size = (8000 * sqrt(max(max(colour.r, colour.g), colour.b))) / sqrt(kq); cosarc = cos(arc / 2); - gl_Position = vec4(position, 0); + gl_Position = vec4(position - viewPoint, 0); } diff --git a/gfx/gl/shaders/water.fs b/gfx/gl/shaders/water.fs index 04aa94c..2ccc924 100644 --- a/gfx/gl/shaders/water.fs +++ b/gfx/gl/shaders/water.fs @@ -13,5 +13,5 @@ main() gPosition = vec4(FragPos, 1); gNormal = vec4(Normal, 1); gAlbedoSpec = texture(texture0, TexCoords); - gAlbedoSpec.a *= clamp(-FragPos.z * .7, .1, 1.0); + gAlbedoSpec.a *= clamp(-FragPos.z * .0007, .1, 1.0); } diff --git a/gfx/gl/shaders/water.vs b/gfx/gl/shaders/water.vs index a21b49f..03eabb2 100644 --- a/gfx/gl/shaders/water.vs +++ b/gfx/gl/shaders/water.vs @@ -4,17 +4,18 @@ include(`meshIn.glsl') include(`materialInterface.glsl') uniform mat4 viewProjection; +uniform vec3 viewPoint; uniform vec3 waves; void main() { - vec4 wpos = vec4(position.x + cos(waves.x), position.y + cos(waves.x * waves.y / 2), - cos(waves.x + position.x + (position.y / 8)) * .3, 1.0); + vec3 wpos = vec3(position.x + (cos(waves.x) * 1000.0), position.y + (cos(waves.x * waves.y / 2) * 1000.0), + cos(waves.x + (position.x / 1000.0) + (position.y * 125.0)) * 300.0); FragPos = vec3(wpos.xy, position.z); TexCoords = texCoord; Normal = normal; - gl_Position = viewProjection * wpos; + gl_Position = viewProjection * vec4(wpos - viewPoint, 1.0); } diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 55d986c..07db6a1 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -15,7 +15,7 @@ #include <tuple> #include <vector> -ShadowMapper::ShadowMapper(const glm::ivec2 & s) : +ShadowMapper::ShadowMapper(const TextureAbsCoord & s) : fixedPoint {shadowFixedPoint_vs}, dynamicPointInst {shadowDynamicPointInst_vs}, size {s} { glBindTexture(GL_TEXTURE_2D, depthMap); @@ -24,7 +24,7 @@ ShadowMapper::ShadowMapper(const glm::ivec2 & s) : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 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::vec4 border {std::numeric_limits<float>::infinity()}; + static constexpr RGBA border {std::numeric_limits<RGBA::value_type>::infinity()}; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(border)); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); @@ -37,7 +37,7 @@ ShadowMapper::ShadowMapper(const glm::ivec2 & s) : glBindFramebuffer(GL_FRAMEBUFFER, 0); } -constexpr std::array<std::array<glm::ivec4, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> viewports {{ +constexpr std::array<std::array<TextureAbsRegion, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> viewports {{ {{ {31, 31, 0, 0}, // full }}, @@ -57,33 +57,34 @@ constexpr std::array<std::array<glm::ivec4, ShadowMapper::SHADOW_BANDS>, ShadowM {1, 1, 1, 1}, // upper right }}, }}; -constexpr std::array<std::array<glm::vec4, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> shadowMapRegions {{ - {{ - {0.5F, 0.5F, 0.5F, 0.5F}, // full - }}, - {{ - {0.5F, 0.25F, 0.5F, 0.25F}, // lower half - {0.5F, 0.25F, 0.5F, 0.75F}, // upper half - }}, - {{ - {0.5F, 0.25F, 0.5F, 0.25F}, // lower half - {0.25F, 0.25F, 0.25F, 0.75F}, // upper left - {0.25F, 0.25F, 0.75F, 0.75F}, // upper right - }}, - - {{ - {0.25F, 0.25F, 0.25F, 0.25F}, // lower left - {0.25F, 0.25F, 0.75F, 0.25F}, // lower right - {0.25F, 0.25F, 0.25F, 0.75F}, // upper left - {0.25F, 0.25F, 0.75F, 0.75F}, // upper right - }}, -}}; +constexpr std::array<std::array<TextureRelRegion, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> + shadowMapRegions {{ + {{ + {0.5F, 0.5F, 0.5F, 0.5F}, // full + }}, + {{ + {0.5F, 0.25F, 0.5F, 0.25F}, // lower half + {0.5F, 0.25F, 0.5F, 0.75F}, // upper half + }}, + {{ + {0.5F, 0.25F, 0.5F, 0.25F}, // lower half + {0.25F, 0.25F, 0.25F, 0.75F}, // upper left + {0.25F, 0.25F, 0.75F, 0.75F}, // upper right + }}, + + {{ + {0.25F, 0.25F, 0.25F, 0.25F}, // lower left + {0.25F, 0.25F, 0.75F, 0.25F}, // lower right + {0.25F, 0.25F, 0.25F, 0.75F}, // upper left + {0.25F, 0.25F, 0.75F, 0.75F}, // upper right + }}, + }}; constexpr std::array<float, ShadowMapper::SHADOW_BANDS + 1> shadowBands { - 1.F, - 250.F, - 750.F, - 2500.F, - 10000.F, + 1000.F, + 250000.F, + 750000.F, + 2500000.F, + 10000000.F, }; static_assert(viewports.size() == shadowMapRegions.size()); static_assert(shadowBands.size() == shadowMapRegions.size() + 1); @@ -94,22 +95,24 @@ struct DefinitionsInserter { { return out.maps++; }; + auto operator*() { return std::tie(out.projections[out.maps], out.regions[out.maps]); } + ShadowMapper::Definitions & out; }; -std::vector<std::array<glm::vec3, 4>> +std::vector<std::array<Position3D, 4>> ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightView) { - std::vector<std::array<glm::vec3, 4>> bandViewExtents; + std::vector<std::array<Position3D, 4>> bandViewExtents; for (const auto dist : shadowBands) { const auto extents = camera.extentsAtDist(dist); - bandViewExtents.emplace_back(extents * [&lightView](const auto & e) -> glm::vec3 { - return lightView * glm::vec4(glm::vec3 {e}, 1); + bandViewExtents.emplace_back(extents * [&lightView](const auto & e) -> Position3D { + return lightView * glm::vec4(Position3D {e}, 1); }); if (std::none_of(extents.begin(), extents.end(), [targetDist = dist * 0.99F](const glm::vec4 & e) { return e.w > targetDist; @@ -121,7 +124,7 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV } ShadowMapper::Definitions -ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const Camera & camera) const +ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const Camera & camera) const { glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); @@ -161,12 +164,14 @@ ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const C } ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) : Program {vs}, 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 { @@ -174,26 +179,28 @@ ShadowMapper::FixedPoint::use() const } ShadowMapper::DynamicPoint::DynamicPoint() : - Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, modelLoc {*this, "model"} + Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, modelLoc {*this, "model"}, + modelPosLoc {*this, "modelPos"} { } + 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); setModel(location); - const auto model = glm::translate(location.pos) * rotate_ypr(location.rot); - glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); } + void ShadowMapper::DynamicPoint::setModel(const Location & location) const { - const auto model = glm::translate(location.pos) * rotate_ypr(location.rot); - glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); + glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(rotate_ypr(location.rot))); + glUniform3iv(modelPosLoc, 1, glm::value_ptr(location.pos)); } diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h index 36371eb..b53a7f1 100644 --- a/gfx/gl/shadowMapper.h +++ b/gfx/gl/shadowMapper.h @@ -1,5 +1,6 @@ #pragma once +#include "config/types.h" #include "lib/glArrays.h" #include "program.h" #include <glm/vec2.hpp> @@ -8,17 +9,20 @@ class SceneProvider; class Camera; #include <gfx/models/texture.h> + class ShadowMapper { public: - explicit ShadowMapper(const glm::ivec2 & size); + explicit ShadowMapper(const TextureAbsCoord & size); static constexpr std::size_t SHADOW_BANDS {4}; + struct Definitions { std::array<glm::mat4x4, SHADOW_BANDS> projections {}; - std::array<glm::vec4, SHADOW_BANDS> regions {}; + std::array<TextureRelRegion, SHADOW_BANDS> regions {}; size_t maps {}; }; - [[nodiscard]] Definitions update(const SceneProvider &, const glm::vec3 & direction, const Camera &) const; + + [[nodiscard]] Definitions update(const SceneProvider &, const Direction3D & direction, const Camera &) const; class FixedPoint : public Program { public: @@ -29,6 +33,7 @@ public: private: RequiredUniformLocation viewProjectionLoc; }; + class DynamicPoint : public Program { public: DynamicPoint(); @@ -39,7 +44,9 @@ public: private: RequiredUniformLocation viewProjectionLoc; RequiredUniformLocation modelLoc; + RequiredUniformLocation modelPosLoc; }; + FixedPoint fixedPoint, dynamicPointInst; DynamicPoint dynamicPoint; @@ -50,9 +57,9 @@ public: } private: - [[nodiscard]] static std::vector<std::array<glm::vec3, 4>> getBandViewExtents( + [[nodiscard]] static std::vector<std::array<Position3D, 4>> getBandViewExtents( const Camera &, const glm::mat4 & lightView); glFrameBuffer depthMapFBO; glTexture depthMap; - glm::ivec2 size; + TextureAbsCoord size; }; diff --git a/gfx/gl/uiShader.cpp b/gfx/gl/uiShader.cpp index 78e0064..dc4f4dc 100644 --- a/gfx/gl/uiShader.cpp +++ b/gfx/gl/uiShader.cpp @@ -9,6 +9,7 @@ #include <initializer_list> UIShader::IconProgram::IconProgram(const glm::mat4 & vp) : UIProgram {vp, uiShader_vs, uiShader_fs} { } + UIShader::TextProgram::TextProgram(const glm::mat4 & vp) : UIProgram {vp, uiShader_vs, uiShaderFont_fs}, colorLoc {*this, "colour"} { @@ -18,10 +19,11 @@ UIShader::UIShader(size_t width, size_t height) : UIShader {glm::ortho<float>(0, static_cast<float>(width), 0, static_cast<float>(height))} { } + UIShader::UIShader(const glm::mat4 & viewProjection) : icon {viewProjection}, text {viewProjection} { } void -UIShader::TextProgram::use(const glm::vec3 & colour) const +UIShader::TextProgram::use(const RGB & colour) const { Program::use(); glUniform3fv(colorLoc, 1, glm::value_ptr(colour)); diff --git a/gfx/gl/uiShader.h b/gfx/gl/uiShader.h index 2766af8..362e90c 100644 --- a/gfx/gl/uiShader.h +++ b/gfx/gl/uiShader.h @@ -1,5 +1,6 @@ #pragma once +#include "config/types.h" #include "program.h" #include <cstddef> #include <glad/gl.h> @@ -33,7 +34,7 @@ private: class TextProgram : public UIProgram { public: explicit TextProgram(const glm::mat4 & vp); - void use(const glm::vec3 & colour) const; + void use(const RGB & colour) const; private: RequiredUniformLocation colorLoc; diff --git a/gfx/gl/vertexArrayObject.h b/gfx/gl/vertexArrayObject.h index fa6baa3..57daaf3 100644 --- a/gfx/gl/vertexArrayObject.h +++ b/gfx/gl/vertexArrayObject.h @@ -11,22 +11,27 @@ public: { glBindVertexArray(arrayObject); } + ~VertexArrayObject() { glBindVertexArray(0); } + NO_MOVE(VertexArrayObject); NO_COPY(VertexArrayObject); template<typename m, typename T> struct MP { constexpr MP(m T::*p) : P {p} { } + operator void *() const { return &(static_cast<T *>(nullptr)->*P); } + m T::*P; using value_type = m; }; + template<typename m, typename T> MP(m T::*) -> MP<m, T>; template<typename VertexT, MP... attribs> |