From 8f84e67b7b9dcd4f5993909aa9ee2e222a207836 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Apr 2023 20:56:49 +0100 Subject: Assert the buffer is actually mapped Will fail if the context is deleted. We shouldn't trigger that, but we do right now. --- gfx/gl/instanceVertices.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h index 228020d..8bb2f21 100644 --- a/gfx/gl/instanceVertices.h +++ b/gfx/gl/instanceVertices.h @@ -1,6 +1,7 @@ #pragma once #include "glArrays.h" +#include #include #include #include @@ -186,6 +187,7 @@ protected: { if (!data) { data = static_cast(glMapNamedBuffer(buffer, GL_READ_WRITE)); + assert(data); } } -- cgit v1.2.3 From af378e83ce0ea1c0c675d451c72e7ff20e42f35e Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Apr 2023 21:01:33 +0100 Subject: Clear world objects explicitly Otherwise the fail to remove themselves from the VBO after the GL context is destroyed. --- application/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/application/main.cpp b/application/main.cpp index 9feb80b..177c795 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -99,6 +99,7 @@ public: t_start = t_end; } + world.objects.clear(); return 0; } -- cgit v1.2.3 From 4dafa2b53578c8d82eec6c3363568b5bfd7ac183 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Apr 2023 21:08:41 +0100 Subject: Add getTransform to Location; wraps the standard mat4 calculations --- lib/location.cpp | 9 +++++++++ lib/location.hpp | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 lib/location.cpp diff --git a/lib/location.cpp b/lib/location.cpp new file mode 100644 index 0000000..bff27a2 --- /dev/null +++ b/lib/location.cpp @@ -0,0 +1,9 @@ +#include "location.hpp" +#include "maths.h" +#include + +glm::mat4 +Location::getTransform() const +{ + return glm::translate(pos) * rotate_ypr(rot); +} diff --git a/lib/location.hpp b/lib/location.hpp index 1360c47..078f5d3 100644 --- a/lib/location.hpp +++ b/lib/location.hpp @@ -1,11 +1,14 @@ #pragma once -#include +#include +#include class Location { public: explicit Location(glm::vec3 pos = {}, glm::vec3 rot = {}) : pos {pos}, rot {rot} { } + glm::mat4 getTransform() const; + glm::vec3 pos; glm::vec3 rot; }; -- cgit v1.2.3 From a2e87cf25f15ec8d6184a0aefc7ad949fb89b52b Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Apr 2023 21:10:46 +0100 Subject: Use Location::getTransform in Plant instead of duplicating --- game/scenary/plant.cpp | 6 +++--- game/scenary/plant.h | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/game/scenary/plant.cpp b/game/scenary/plant.cpp index 678d4a7..2a79807 100644 --- a/game/scenary/plant.cpp +++ b/game/scenary/plant.cpp @@ -1,7 +1,7 @@ #include "plant.h" +#include "location.hpp" -Plant::Plant(std::shared_ptr type, Location position) : - type {std::move(type)}, - location {this->type->instances.acquire(glm::translate(position.pos) * rotate_ypr(position.rot))} +Plant::Plant(std::shared_ptr type, const Location & position) : + type {std::move(type)}, location {this->type->instances.acquire(position.getTransform())} { } diff --git a/game/scenary/plant.h b/game/scenary/plant.h index 77c5979..82ab0e5 100644 --- a/game/scenary/plant.h +++ b/game/scenary/plant.h @@ -2,9 +2,8 @@ #include "foliage.h" #include "game/worldobject.h" -#include "location.hpp" -#include "maths.h" -#include + +class Location; class Plant : public WorldObject { std::shared_ptr type; @@ -16,5 +15,5 @@ class Plant : public WorldObject { } public: - Plant(std::shared_ptr type, Location position); + Plant(std::shared_ptr type, const Location & position); }; -- cgit v1.2.3 From 5e022ee1ea94812b3446cac76e4f9ff9f3856d8c Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Apr 2023 21:26:32 +0100 Subject: Add BufferedLocation Wraps Location, storing a pre-computed mat4 transformation of the position/rotation in a VBO handled by InstanceVertices. --- gfx/gl/bufferedLocation.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++ gfx/gl/bufferedLocation.h | 30 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 gfx/gl/bufferedLocation.cpp create mode 100644 gfx/gl/bufferedLocation.h diff --git a/gfx/gl/bufferedLocation.cpp b/gfx/gl/bufferedLocation.cpp new file mode 100644 index 0000000..4484053 --- /dev/null +++ b/gfx/gl/bufferedLocation.cpp @@ -0,0 +1,77 @@ +#include "bufferedLocation.h" +#include "location.hpp" +#include "maths.h" +#include + +BufferedLocation::BufferedLocation(InstanceVertices & i, glm::vec3 p, glm::vec3 r) : + BufferedLocation {i, Location {p, r}} +{ +} + +BufferedLocation::BufferedLocation(InstanceVertices & i, const Location & l) : + loc {l}, buffer {i.acquire(getTransform())} +{ +} + +BufferedLocation::operator const Location &() const +{ + return loc; +} + +BufferedLocation & +BufferedLocation::operator=(const Location & l) +{ + loc = l; + updateBuffer(); + return *this; +} + +glm::vec3 +BufferedLocation::position() const +{ + return loc.pos; +} + +glm::vec3 +BufferedLocation::rotation() const +{ + return loc.rot; +} + +void +BufferedLocation::setPosition(glm::vec3 p, bool update) +{ + loc.pos = p; + if (update) { + updateBuffer(); + } +} + +void +BufferedLocation::setRotation(glm::vec3 r, bool update) +{ + loc.rot = r; + if (update) { + updateBuffer(); + } +} + +void +BufferedLocation::setLocation(glm::vec3 p, glm::vec3 r) +{ + loc.pos = p; + loc.rot = r; + updateBuffer(); +} + +void +BufferedLocation::updateBuffer() +{ + buffer = getTransform(); +} + +glm::mat4 +BufferedLocation::getTransform() const +{ + return loc.getTransform(); +} diff --git a/gfx/gl/bufferedLocation.h b/gfx/gl/bufferedLocation.h new file mode 100644 index 0000000..cf7afed --- /dev/null +++ b/gfx/gl/bufferedLocation.h @@ -0,0 +1,30 @@ +#pragma once + +#include "instanceVertices.h" +#include "location.hpp" +#include +#include + +class BufferedLocation { +public: + BufferedLocation(InstanceVertices &, glm::vec3 = {}, glm::vec3 = {}); + BufferedLocation(InstanceVertices &, const Location &); + + BufferedLocation & operator=(const Location &); + + 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); + + glm::mat4 getTransform() const; + +private: + void updateBuffer(); + + Location loc; + InstanceVertices::InstanceProxy buffer; +}; -- cgit v1.2.3 From 687afb09ada73fb4aee932242a3b7ee492e63cb0 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Apr 2023 21:31:41 +0100 Subject: Handle rendering of RailVehicles through RailVehicleClass instancing Trains no longer need rendering as their parts are all RVC assets and that just works now. This commit creates some irritating duplication in RVC wrt body/2 bogies all of which are stored separately, but function in exactly the same way. This breaks RV shadows as we have no instancing shadow shaders yet. --- game/vehicles/railVehicle.cpp | 29 +++++++++---------------- game/vehicles/railVehicle.h | 12 ++++------- game/vehicles/railVehicleClass.cpp | 44 ++++++++++++++++++++++---------------- game/vehicles/railVehicleClass.h | 15 ++++++++++--- game/vehicles/train.cpp | 11 ---------- game/vehicles/train.h | 3 --- game/vehicles/vehicle.h | 2 +- test/test-assetFactory.cpp | 2 +- test/test-render.cpp | 14 ++++++------ 9 files changed, 60 insertions(+), 72 deletions(-) diff --git a/game/vehicles/railVehicle.cpp b/game/vehicles/railVehicle.cpp index 77907be..b77b93c 100644 --- a/game/vehicles/railVehicle.cpp +++ b/game/vehicles/railVehicle.cpp @@ -11,22 +11,14 @@ #include #include -RailVehicle::RailVehicle(RailVehicleClassPtr rvc) : rvClass {std::move(rvc)} +RailVehicle::RailVehicle(RailVehicleClassPtr rvc) : + rvClass {std::move(rvc)}, location {rvClass->instancesBody}, bogies { + rvClass->instancesBogies.front(), + rvClass->instancesBogies.back(), + } { - bogies.front().pos.y = rvClass->wheelBase / 2.F; - bogies.back().pos.y = -bogies.front().pos.y; -} - -void -RailVehicle::render(const SceneShader & shader) const -{ - rvClass->render(shader, location, bogies); -} - -void -RailVehicle::shadows(const ShadowMapper & shadowMapper) const -{ - rvClass->shadows(shadowMapper, location, bogies); + bogies.front().setPosition({0, rvClass->wheelBase / 2.F, 0}); + bogies.back().setPosition({0, -bogies.front().position().y, 0}); } void @@ -35,9 +27,8 @@ RailVehicle::move(const Train * t, float & trailBy) const auto overhang {(rvClass->length - rvClass->wheelBase) / 2}; const auto & b1Pos = bogies[0] = t->getBogiePosition(t->linkDist, trailBy += overhang); const auto & b2Pos = bogies[1] = t->getBogiePosition(t->linkDist, trailBy += rvClass->wheelBase); - const auto diff = glm::normalize(b2Pos.pos - b1Pos.pos); - location.pos = (b1Pos.pos + b2Pos.pos) / 2.F; - location.rot = {vector_pitch(diff), vector_yaw(diff), 0}; + const auto diff = glm::normalize(b2Pos.position() - b1Pos.position()); + location.setLocation((b1Pos.position() + b2Pos.position()) / 2.F, {vector_pitch(diff), vector_yaw(diff), 0}); trailBy += 0.6F + overhang; } @@ -47,7 +38,7 @@ RailVehicle::intersectRay(const Ray & ray, glm::vec2 * baryPos, float * distance constexpr const auto X = 1.35F; const auto Y = this->rvClass->length / 2.F; constexpr const auto Z = 3.9F; - const auto moveBy = glm::translate(location.pos) * rotate_ypr(location.rot); + const auto moveBy = location.getTransform(); const std::array cornerVertices {{ moveBy * glm::vec4 {-X, Y, 0, 1}, // LFB moveBy * glm::vec4 {X, Y, 0, 1}, // RFB diff --git a/game/vehicles/railVehicle.h b/game/vehicles/railVehicle.h index bbf4df9..247bf66 100644 --- a/game/vehicles/railVehicle.h +++ b/game/vehicles/railVehicle.h @@ -1,11 +1,10 @@ #pragma once -#include "gfx/renderable.h" +#include "gfx/gl/bufferedLocation.h" #include "railVehicleClass.h" #include #include #include -#include #include #include @@ -14,19 +13,16 @@ class ShadowMapper; class Ray; class Train; -class RailVehicle : public Renderable, Selectable { +class RailVehicle : Selectable { public: explicit RailVehicle(RailVehicleClassPtr rvc); void move(const Train *, float & trailBy); - void render(const SceneShader & shader) const override; - void shadows(const ShadowMapper & shadowMapper) const override; [[nodiscard]] bool intersectRay(const Ray &, glm::vec2 *, float *) const override; - Location location; - RailVehicleClassPtr rvClass; - std::array bogies; + BufferedLocation location; + std::array bogies; }; using RailVehiclePtr = std::unique_ptr; diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp index b7a3b1e..3e62bf1 100644 --- a/game/vehicles/railVehicleClass.cpp +++ b/game/vehicles/railVehicleClass.cpp @@ -1,6 +1,7 @@ #include "railVehicleClass.h" #include "gfx/gl/sceneShader.h" #include "gfx/gl/shadowMapper.h" +#include "gfx/gl/vertexArrayObject.hpp" #include "gfx/models/mesh.h" #include "gfx/models/texture.h" #include @@ -33,30 +34,37 @@ void RailVehicleClass::postLoad() { texture = getTexture(); + bodyMesh->configureVAO(instanceVAO).addAttribs(instancesBody.bufferName(), 1); + bogies.front() + ->configureVAO(instancesBogiesVAO.front()) + .addAttribs(instancesBogies.front().bufferName(), 1); + bogies.back() + ->configureVAO(instancesBogiesVAO.back()) + .addAttribs(instancesBogies.back().bufferName(), 1); } void -RailVehicleClass::render( - const SceneShader & shader, const Location & location, const std::array & bl) const +RailVehicleClass::render(const SceneShader & shader) const { - shader.basic.use(location); - if (texture) { - texture->bind(); - } - bodyMesh->Draw(); - for (auto b = 0U; b < bogies.size(); ++b) { - shader.basic.setModel(bl[b]); - bogies[b]->Draw(); + if (const auto count = instancesBody.count()) { + if (texture) { + texture->bind(); + } + shader.basicInst.use(); + glBindVertexArray(instanceVAO); + glDrawElementsInstanced( + bodyMesh->type(), bodyMesh->count(), GL_UNSIGNED_INT, nullptr, static_cast(count)); + glBindVertexArray(instancesBogiesVAO.front()); + glDrawElementsInstanced(bogies.front()->type(), bogies.front()->count(), GL_UNSIGNED_INT, nullptr, + static_cast(instancesBogies.front().count())); + glBindVertexArray(instancesBogiesVAO.back()); + glDrawElementsInstanced(bogies.back()->type(), bogies.back()->count(), GL_UNSIGNED_INT, nullptr, + static_cast(instancesBogies.back().count())); + glBindVertexArray(0); } } + void -RailVehicleClass::shadows( - const ShadowMapper & shadowMapper, const Location & location, const std::array & bl) const +RailVehicleClass::shadows(const ShadowMapper &) const { - shadowMapper.dynamicPoint.use(location); - bodyMesh->Draw(); - for (auto b = 0U; b < bogies.size(); ++b) { - shadowMapper.dynamicPoint.setModel(bl[b]); - bogies[b]->Draw(); - } } diff --git a/game/vehicles/railVehicleClass.h b/game/vehicles/railVehicleClass.h index 1a52e2b..2fda8f7 100644 --- a/game/vehicles/railVehicleClass.h +++ b/game/vehicles/railVehicleClass.h @@ -1,7 +1,9 @@ #pragma once #include "assetFactory/asset.h" +#include "gfx/gl/instanceVertices.h" #include "gfx/models/mesh.h" +#include "gfx/renderable.h" #include #include #include @@ -11,10 +13,10 @@ class ShadowMapper; class Texture; class Location; -class RailVehicleClass : public Asset { +class RailVehicleClass : public Renderable, public Asset { public: - void render(const SceneShader &, const Location &, const std::array &) const; - void shadows(const ShadowMapper &, const Location &, const std::array &) const; + void render(const SceneShader & shader) const override; + void shadows(const ShadowMapper & shadowMapper) const override; std::array bogies; Mesh::Ptr bodyMesh; @@ -23,9 +25,16 @@ public: float length; float maxSpeed; + mutable InstanceVertices instancesBody; + mutable std::array, 2> instancesBogies; + protected: friend Persistence::SelectionPtrBase>; bool persist(Persistence::PersistenceStore & store) override; void postLoad() override; + +private: + glVertexArray instanceVAO; + std::array instancesBogiesVAO; }; using RailVehicleClassPtr = std::shared_ptr; diff --git a/game/vehicles/train.cpp b/game/vehicles/train.cpp index 0332c04..fdfc3e1 100644 --- a/game/vehicles/train.cpp +++ b/game/vehicles/train.cpp @@ -11,17 +11,6 @@ class Ray; -void -Train::render(const SceneShader & shader) const -{ - apply(&Renderable::render, shader); -} -void -Train::shadows(const ShadowMapper & shadowMapper) const -{ - apply(&Renderable::shadows, shadowMapper); -} - Location Train::getBogiePosition(float linkDist, float dist) const { diff --git a/game/vehicles/train.h b/game/vehicles/train.h index 91f7ddb..15e2f6e 100644 --- a/game/vehicles/train.h +++ b/game/vehicles/train.h @@ -27,9 +27,6 @@ public: return objects.front()->location; } - void render(const SceneShader & shader) const override; - void shadows(const ShadowMapper & shadowMapper) const override; - [[nodiscard]] bool intersectRay(const Ray &, glm::vec2 *, float *) const override; void tick(TickDuration elapsed) override; diff --git a/game/vehicles/vehicle.h b/game/vehicles/vehicle.h index 3fa3092..369bd7a 100644 --- a/game/vehicles/vehicle.h +++ b/game/vehicles/vehicle.h @@ -12,7 +12,7 @@ class Location; -class Vehicle : public WorldObject, public Renderable, public Selectable { +class Vehicle : public WorldObject, public Selectable { public: explicit Vehicle(const Link::Ptr & link, float linkDist = 0); float linkDist; // distance along current link diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index 82a1825..c0edd66 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(brush47xml, *boost::unit_test::timeout(5)) BOOST_REQUIRE(brush47rvc->bogies.back()); auto railVehicle = std::make_shared(brush47rvc); - objects.objects.push_back(railVehicle); + objects.objects.push_back(brush47rvc); render(); } diff --git a/test/test-render.cpp b/test/test-render.cpp index 1643068..0fbeb2b 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -22,6 +22,8 @@ class TestScene : public SceneProvider { std::shared_ptr train1, train2; + const RailVehicleClassPtr brush47rvc = std::dynamic_pointer_cast( + AssetFactory::loadXML(RESDIR "/brush47.xml")->assets.at("brush-47")); Terrain terrain {[]() { auto gd = std::make_shared(GeoData::Limits {{0, 0}, {100, 100}}); @@ -32,19 +34,16 @@ class TestScene : public SceneProvider { public: TestScene() { - const auto assetFactory = AssetFactory::loadXML(RESDIR "/brush47.xml"); - const auto brush47rvc = std::dynamic_pointer_cast(assetFactory->assets.at("brush-47")); train1 = std::make_shared(brush47rvc); - train1->location.pos = {52, 50, 2}; + train1->location.setPosition({52, 50, 2}); train2 = std::make_shared(brush47rvc); - train2->location.pos = {52, 30, 2}; + train2->location.setPosition({52, 30, 2}); } void content(const SceneShader & shader) const override { terrain.render(shader); - train1->render(shader); - train2->render(shader); + brush47rvc->render(shader); } void lights(const SceneShader &) const override @@ -54,8 +53,7 @@ public: shadows(const ShadowMapper & shadowMapper) const override { terrain.shadows(shadowMapper); - train1->shadows(shadowMapper); - train2->shadows(shadowMapper); + brush47rvc->shadows(shadowMapper); } }; -- cgit v1.2.3 From e751ab465bbbf1365ec6e108c64dafd03ce42f1d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Apr 2023 21:46:21 +0100 Subject: Pop and complete instanced shadow support --- game/scenary/foliage.cpp | 9 ++++++++- game/vehicles/railVehicleClass.cpp | 15 ++++++++++++++- gfx/gl/shaders/shadowDynamicPointInst.vs | 13 +++++++++++++ gfx/gl/shadowMapper.cpp | 7 +++++-- gfx/gl/shadowMapper.h | 4 ++-- 5 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 gfx/gl/shaders/shadowDynamicPointInst.vs diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp index 35be051..e54dfbd 100644 --- a/game/scenary/foliage.cpp +++ b/game/scenary/foliage.cpp @@ -34,6 +34,13 @@ Foliage::render(const SceneShader & shader) const } void -Foliage::shadows(const ShadowMapper &) const +Foliage::shadows(const ShadowMapper & mapper) const { + if (const auto count = instances.count()) { + mapper.dynamicPointInst.use(); + glBindVertexArray(instanceVAO); + glDrawElementsInstanced( + bodyMesh->type(), bodyMesh->count(), GL_UNSIGNED_INT, nullptr, static_cast(count)); + glBindVertexArray(0); + } } diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp index 3e62bf1..66d7ba3 100644 --- a/game/vehicles/railVehicleClass.cpp +++ b/game/vehicles/railVehicleClass.cpp @@ -65,6 +65,19 @@ RailVehicleClass::render(const SceneShader & shader) const } void -RailVehicleClass::shadows(const ShadowMapper &) const +RailVehicleClass::shadows(const ShadowMapper & mapper) const { + if (const auto count = instancesBody.count()) { + mapper.dynamicPointInst.use(); + glBindVertexArray(instanceVAO); + glDrawElementsInstanced( + bodyMesh->type(), bodyMesh->count(), GL_UNSIGNED_INT, nullptr, static_cast(count)); + glBindVertexArray(instancesBogiesVAO.front()); + glDrawElementsInstanced(bogies.front()->type(), bogies.front()->count(), GL_UNSIGNED_INT, nullptr, + static_cast(instancesBogies.front().count())); + glBindVertexArray(instancesBogiesVAO.back()); + glDrawElementsInstanced(bogies.back()->type(), bogies.back()->count(), GL_UNSIGNED_INT, nullptr, + static_cast(instancesBogies.back().count())); + glBindVertexArray(0); + } } diff --git a/gfx/gl/shaders/shadowDynamicPointInst.vs b/gfx/gl/shaders/shadowDynamicPointInst.vs new file mode 100644 index 0000000..eb7313a --- /dev/null +++ b/gfx/gl/shaders/shadowDynamicPointInst.vs @@ -0,0 +1,13 @@ +#version 330 core + +include(`meshIn.glsl') +layout(location = 5) in mat4 model; + +uniform mat4 viewProjection; + +void +main() +{ + gl_Position = viewProjection * model * vec4(position, 1.0); + gl_Position.z = max(gl_Position.z, -1); +} diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 7649a54..9f1e420 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -2,6 +2,7 @@ #include "camera.h" #include "collections.hpp" #include "gfx/gl/shaders/vs-shadowDynamicPoint.h" +#include "gfx/gl/shaders/vs-shadowDynamicPointInst.h" #include "gfx/gl/shaders/vs-shadowFixedPoint.h" #include "location.hpp" #include "maths.h" @@ -14,7 +15,8 @@ #include #include -ShadowMapper::ShadowMapper(const glm::ivec2 & s) : size {s} +ShadowMapper::ShadowMapper(const glm::ivec2 & s) : + fixedPoint {shadowFixedPoint_vs}, dynamicPointInst {shadowDynamicPointInst_vs}, 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, nullptr); @@ -144,6 +146,7 @@ ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const C const auto lightViewProjection = lightProjection * lightView; fixedPoint.setViewProjection(lightViewProjection); dynamicPoint.setViewProjection(lightViewProjection); + dynamicPointInst.setViewProjection(lightViewProjection); const auto & viewport = viewports[bands][out.maps]; glViewport(size.x >> viewport.x, size.y >> viewport.y, size.x >> viewport.z, size.y >> viewport.w); @@ -157,7 +160,7 @@ ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const C return out; } -ShadowMapper::FixedPoint::FixedPoint() : Program {shadowFixedPoint_vs}, viewProjectionLoc {*this, "viewProjection"} { } +ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) : Program {vs}, viewProjectionLoc {*this, "viewProjection"} { } void ShadowMapper::FixedPoint::setViewProjection(const glm::mat4 & viewProjection) const { diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h index a5c2c7b..36371eb 100644 --- a/gfx/gl/shadowMapper.h +++ b/gfx/gl/shadowMapper.h @@ -22,7 +22,7 @@ public: class FixedPoint : public Program { public: - FixedPoint(); + FixedPoint(const Shader & vs); void setViewProjection(const glm::mat4 &) const; void use() const; @@ -40,7 +40,7 @@ public: RequiredUniformLocation viewProjectionLoc; RequiredUniformLocation modelLoc; }; - FixedPoint fixedPoint; + FixedPoint fixedPoint, dynamicPointInst; DynamicPoint dynamicPoint; // NOLINTNEXTLINE(hicpp-explicit-conversions) -- cgit v1.2.3 From 59cc4b8a7cb25a7ac003eb05794ee94e080ad302 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Apr 2023 21:53:20 +0100 Subject: Fudge RV bogey position the same as we do the body in test-render --- test/test-render.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/test-render.cpp b/test/test-render.cpp index 0fbeb2b..d5e2d87 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -36,8 +36,12 @@ public: { train1 = std::make_shared(brush47rvc); train1->location.setPosition({52, 50, 2}); + train1->bogies.front().setPosition(train1->bogies.front().position() + train1->location.position()); + train1->bogies.back().setPosition(train1->bogies.back().position() + train1->location.position()); train2 = std::make_shared(brush47rvc); train2->location.setPosition({52, 30, 2}); + train2->bogies.front().setPosition(train2->bogies.front().position() + train2->location.position()); + train2->bogies.back().setPosition(train2->bogies.back().position() + train2->location.position()); } void content(const SceneShader & shader) const override -- cgit v1.2.3 From ac0e30371f3cbddde990179711997acac507a09c Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 24 Apr 2023 19:56:07 +0100 Subject: Point shaders can all share the same implementation now in a single place They all just get `model` from a different place --- gfx/gl/shaders/commonPoint.glsl | 13 +++++++++++++ gfx/gl/shaders/dynamicPoint.vs | 14 +------------- gfx/gl/shaders/dynamicPointInst.vs | 16 ++-------------- gfx/gl/shaders/fixedPoint.vs | 13 ++----------- 4 files changed, 18 insertions(+), 38 deletions(-) create mode 100644 gfx/gl/shaders/commonPoint.glsl diff --git a/gfx/gl/shaders/commonPoint.glsl b/gfx/gl/shaders/commonPoint.glsl new file mode 100644 index 0000000..ecf5fc9 --- /dev/null +++ b/gfx/gl/shaders/commonPoint.glsl @@ -0,0 +1,13 @@ +void +main() +{ + vec4 worldPos = model * vec4(position, 1.0); + + FragPos = worldPos.xyz; + TexCoords = texCoord; + Normal = (model * vec4(normal, 0.0)).xyz; + Colour = colour; + Material = material; + + gl_Position = viewProjection * worldPos; +} diff --git a/gfx/gl/shaders/dynamicPoint.vs b/gfx/gl/shaders/dynamicPoint.vs index e1701ed..ffa8275 100644 --- a/gfx/gl/shaders/dynamicPoint.vs +++ b/gfx/gl/shaders/dynamicPoint.vs @@ -6,16 +6,4 @@ include(`materialInterface.glsl') uniform mat4 viewProjection; uniform mat4 model; -void -main() -{ - vec4 worldPos = model * vec4(position, 1.0); - - FragPos = worldPos.xyz; - TexCoords = texCoord; - Normal = (model * vec4(normal, 0.0)).xyz; - Colour = colour; - Material = material; - - gl_Position = viewProjection * worldPos; -} +include(`commonPoint.glsl') diff --git a/gfx/gl/shaders/dynamicPointInst.vs b/gfx/gl/shaders/dynamicPointInst.vs index 1c66979..e4c8526 100644 --- a/gfx/gl/shaders/dynamicPointInst.vs +++ b/gfx/gl/shaders/dynamicPointInst.vs @@ -1,21 +1,9 @@ #version 330 core include(`meshIn.glsl') -layout(location = 5) in mat4 model; include(`materialInterface.glsl') uniform mat4 viewProjection; +layout(location = 5) in mat4 model; -void -main() -{ - vec4 worldPos = model * vec4(position, 1.0); - - FragPos = worldPos.xyz; - TexCoords = texCoord; - Normal = (model * vec4(normal, 0.0)).xyz; - Colour = colour; - Material = material; - - gl_Position = viewProjection * worldPos; -} +include(`commonPoint.glsl') diff --git a/gfx/gl/shaders/fixedPoint.vs b/gfx/gl/shaders/fixedPoint.vs index 0cc8153..6f517ca 100644 --- a/gfx/gl/shaders/fixedPoint.vs +++ b/gfx/gl/shaders/fixedPoint.vs @@ -4,15 +4,6 @@ include(`meshIn.glsl') include(`materialInterface.glsl') uniform mat4 viewProjection; +const mat4 model = mat4(1); -void -main() -{ - FragPos = position; - TexCoords = texCoord; - Normal = normal; - Colour = colour; - Material = material; - - gl_Position = viewProjection * vec4(position, 1.0); -} +include(`commonPoint.glsl') -- cgit v1.2.3 From 553f738d55e1492f11ee7f150758963344ac79d4 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 24 Apr 2023 19:56:07 +0100 Subject: Point shaders (shadows) can all share the same implementation now in a single place They all just get `model` from a different place --- gfx/gl/shaders/commonShadowPoint.glsl | 6 ++++++ gfx/gl/shaders/shadowDynamicPoint.vs | 7 +------ gfx/gl/shaders/shadowDynamicPointInst.vs | 9 ++------- gfx/gl/shaders/shadowFixedPoint.vs | 8 ++------ 4 files changed, 11 insertions(+), 19 deletions(-) create mode 100644 gfx/gl/shaders/commonShadowPoint.glsl diff --git a/gfx/gl/shaders/commonShadowPoint.glsl b/gfx/gl/shaders/commonShadowPoint.glsl new file mode 100644 index 0000000..c7cbd3e --- /dev/null +++ b/gfx/gl/shaders/commonShadowPoint.glsl @@ -0,0 +1,6 @@ +void +main() +{ + gl_Position = viewProjection * model * vec4(position, 1.0); + gl_Position.z = max(gl_Position.z, -1); +} diff --git a/gfx/gl/shaders/shadowDynamicPoint.vs b/gfx/gl/shaders/shadowDynamicPoint.vs index 531d8de..f3ed533 100644 --- a/gfx/gl/shaders/shadowDynamicPoint.vs +++ b/gfx/gl/shaders/shadowDynamicPoint.vs @@ -5,9 +5,4 @@ include(`meshIn.glsl') uniform mat4 viewProjection; uniform mat4 model; -void -main() -{ - gl_Position = viewProjection * model * vec4(position, 1.0); - gl_Position.z = max(gl_Position.z, -1); -} +include(`commonShadowPoint.glsl') diff --git a/gfx/gl/shaders/shadowDynamicPointInst.vs b/gfx/gl/shaders/shadowDynamicPointInst.vs index eb7313a..1bf74ef 100644 --- a/gfx/gl/shaders/shadowDynamicPointInst.vs +++ b/gfx/gl/shaders/shadowDynamicPointInst.vs @@ -1,13 +1,8 @@ #version 330 core include(`meshIn.glsl') -layout(location = 5) in mat4 model; uniform mat4 viewProjection; +layout(location = 5) in mat4 model; -void -main() -{ - gl_Position = viewProjection * model * vec4(position, 1.0); - gl_Position.z = max(gl_Position.z, -1); -} +include(`commonShadowPoint.glsl') diff --git a/gfx/gl/shaders/shadowFixedPoint.vs b/gfx/gl/shaders/shadowFixedPoint.vs index c9fa19b..8921707 100644 --- a/gfx/gl/shaders/shadowFixedPoint.vs +++ b/gfx/gl/shaders/shadowFixedPoint.vs @@ -3,10 +3,6 @@ include(`meshIn.glsl') uniform mat4 viewProjection; +const mat4 model = mat4(1); -void -main() -{ - gl_Position = viewProjection * vec4(position, 1.0); - gl_Position.z = max(gl_Position.z, -1); -} +include(`commonShadowPoint.glsl') -- cgit v1.2.3 From 4b560f03201f1c2d7c632126cd1e512ed4027072 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 26 Apr 2023 01:16:06 +0100 Subject: Add Mesh helper for drawing instances Assumes the supplied VAO was created and configured for the mesh it's passed back to. --- gfx/models/mesh.cpp | 10 ++++++++++ gfx/models/mesh.h | 1 + 2 files changed, 11 insertions(+) diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp index 55759cb..3faf252 100644 --- a/gfx/models/mesh.cpp +++ b/gfx/models/mesh.cpp @@ -42,3 +42,13 @@ Mesh::Draw() const glBindVertexArray(0); } + +void +Mesh::DrawInstanced(GLuint vao, GLsizei count) const +{ + glBindVertexArray(vao); + + glDrawElementsInstanced(mode, m_numIndices, GL_UNSIGNED_INT, nullptr, count); + + glBindVertexArray(0); +} diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h index 472b7ed..a2205a1 100644 --- a/gfx/models/mesh.h +++ b/gfx/models/mesh.h @@ -14,6 +14,7 @@ public: Mesh(const std::span vertices, const std::span indices, GLenum = GL_TRIANGLES); void Draw() const; + void DrawInstanced(GLuint vao, GLsizei count) const; VertexArrayObject & configureVAO(VertexArrayObject &&) const; GLsizei count() const; GLenum type() const; -- cgit v1.2.3 From c96f4f89905f96492bdfc87bc3d45bf5cbd7b005 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 26 Apr 2023 01:42:45 +0100 Subject: Draw rail vehicle classes and foliage with new mesh instance helper --- game/scenary/foliage.cpp | 10 ++-------- game/vehicles/railVehicleClass.cpp | 28 ++++++++-------------------- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp index e54dfbd..0913c6e 100644 --- a/game/scenary/foliage.cpp +++ b/game/scenary/foliage.cpp @@ -26,10 +26,7 @@ Foliage::render(const SceneShader & shader) const if (texture) { texture->bind(); } - glBindVertexArray(instanceVAO); - glDrawElementsInstanced( - bodyMesh->type(), bodyMesh->count(), GL_UNSIGNED_INT, nullptr, static_cast(count)); - glBindVertexArray(0); + bodyMesh->DrawInstanced(instanceVAO, static_cast(count)); } } @@ -38,9 +35,6 @@ Foliage::shadows(const ShadowMapper & mapper) const { if (const auto count = instances.count()) { mapper.dynamicPointInst.use(); - glBindVertexArray(instanceVAO); - glDrawElementsInstanced( - bodyMesh->type(), bodyMesh->count(), GL_UNSIGNED_INT, nullptr, static_cast(count)); - glBindVertexArray(0); + bodyMesh->DrawInstanced(instanceVAO, static_cast(count)); } } diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp index 66d7ba3..82a442e 100644 --- a/game/vehicles/railVehicleClass.cpp +++ b/game/vehicles/railVehicleClass.cpp @@ -51,16 +51,10 @@ RailVehicleClass::render(const SceneShader & shader) const texture->bind(); } shader.basicInst.use(); - glBindVertexArray(instanceVAO); - glDrawElementsInstanced( - bodyMesh->type(), bodyMesh->count(), GL_UNSIGNED_INT, nullptr, static_cast(count)); - glBindVertexArray(instancesBogiesVAO.front()); - glDrawElementsInstanced(bogies.front()->type(), bogies.front()->count(), GL_UNSIGNED_INT, nullptr, - static_cast(instancesBogies.front().count())); - glBindVertexArray(instancesBogiesVAO.back()); - glDrawElementsInstanced(bogies.back()->type(), bogies.back()->count(), GL_UNSIGNED_INT, nullptr, - static_cast(instancesBogies.back().count())); - glBindVertexArray(0); + bodyMesh->DrawInstanced(instanceVAO, static_cast(count)); + bogies.front()->DrawInstanced( + instancesBogiesVAO.front(), static_cast(instancesBogies.front().count())); + bogies.back()->DrawInstanced(instancesBogiesVAO.back(), static_cast(instancesBogies.back().count())); } } @@ -69,15 +63,9 @@ RailVehicleClass::shadows(const ShadowMapper & mapper) const { if (const auto count = instancesBody.count()) { mapper.dynamicPointInst.use(); - glBindVertexArray(instanceVAO); - glDrawElementsInstanced( - bodyMesh->type(), bodyMesh->count(), GL_UNSIGNED_INT, nullptr, static_cast(count)); - glBindVertexArray(instancesBogiesVAO.front()); - glDrawElementsInstanced(bogies.front()->type(), bogies.front()->count(), GL_UNSIGNED_INT, nullptr, - static_cast(instancesBogies.front().count())); - glBindVertexArray(instancesBogiesVAO.back()); - glDrawElementsInstanced(bogies.back()->type(), bogies.back()->count(), GL_UNSIGNED_INT, nullptr, - static_cast(instancesBogies.back().count())); - glBindVertexArray(0); + bodyMesh->DrawInstanced(instanceVAO, static_cast(count)); + bogies.front()->DrawInstanced( + instancesBogiesVAO.front(), static_cast(instancesBogies.front().count())); + bogies.back()->DrawInstanced(instancesBogiesVAO.back(), static_cast(instancesBogies.back().count())); } } -- cgit v1.2.3 From c3af3f3ec6aff3e366acb8825413096581c736c1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 26 Apr 2023 02:04:17 +0100 Subject: Revert "Export mesh size and primitive type" This reverts commit f3343e1cc8a56f039888d4d375a6d5a088a68494. --- gfx/models/mesh.cpp | 12 ------------ gfx/models/mesh.h | 2 -- 2 files changed, 14 deletions(-) diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp index 3faf252..52c9275 100644 --- a/gfx/models/mesh.cpp +++ b/gfx/models/mesh.cpp @@ -21,18 +21,6 @@ Mesh::configureVAO(VertexArrayObject && vao) const .addIndices(m_vertexArrayBuffers[1]); } -GLsizei -Mesh::count() const -{ - return m_numIndices; -} - -GLenum -Mesh::type() const -{ - return mode; -} - void Mesh::Draw() const { diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h index a2205a1..538c57a 100644 --- a/gfx/models/mesh.h +++ b/gfx/models/mesh.h @@ -16,8 +16,6 @@ public: void Draw() const; void DrawInstanced(GLuint vao, GLsizei count) const; VertexArrayObject & configureVAO(VertexArrayObject &&) const; - GLsizei count() const; - GLenum type() const; private: glVertexArray m_vertexArrayObject; -- cgit v1.2.3