From fb78c88576d9fed90ee69dfa35a9fbd3179ff486 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 30 Mar 2026 13:04:36 +0100 Subject: Use a single buffer for the location/rotation data of all renderable objects Removes the BufferedLocation and BufferedLocationUpdater mess. Note: appears to break bogie rendering in asset factory test only, same symptom as broken network render test? (out of date buffer data) --- gfx/followCameraController.cpp | 3 +- gfx/gl/bufferedLocation.cpp | 70 ---------------------- gfx/gl/bufferedLocation.h | 48 --------------- gfx/gl/instanceVertices.h | 8 ++- gfx/gl/sceneRenderer.cpp | 4 ++ gfx/gl/shaders/billboard.vert | 10 +++- gfx/gl/shaders/commonLocationData.glsl | 20 +++++++ gfx/gl/shaders/dynamicPointInst.vert | 6 +- gfx/gl/shaders/pointLight.vert | 8 ++- gfx/gl/shaders/shadowDynamicPointInst.vert | 6 +- .../shadowDynamicPointInstWithTextures.vert | 6 +- gfx/gl/shaders/shadowDynamicPointStencil.vert | 10 ++-- gfx/gl/shaders/spotLight.vert | 8 ++- gfx/renderable.cpp | 35 +++++++++++ gfx/renderable.h | 27 ++++++++- 15 files changed, 130 insertions(+), 139 deletions(-) delete mode 100644 gfx/gl/bufferedLocation.cpp delete mode 100644 gfx/gl/bufferedLocation.h create mode 100644 gfx/gl/shaders/commonLocationData.glsl (limited to 'gfx') diff --git a/gfx/followCameraController.cpp b/gfx/followCameraController.cpp index d7bbc0b..c3a5d08 100644 --- a/gfx/followCameraController.cpp +++ b/gfx/followCameraController.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -15,7 +14,7 @@ FollowCameraController::updateCamera(Camera * camera) const { const auto [pos, rot] = [this]() { const auto t {target.lock()}; - return std::tie(t->getLocation().pos, t->getLocation().rot); + return std::make_pair(t->getLocation().pos, t->getLocation().rot); }(); switch (mode) { diff --git a/gfx/gl/bufferedLocation.cpp b/gfx/gl/bufferedLocation.cpp deleted file mode 100644 index f1bedfe..0000000 --- a/gfx/gl/bufferedLocation.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "bufferedLocation.h" -#include "location.h" -#include - -BufferedLocation::BufferedLocation(GlobalPosition3D p, Rotation3D r) : BufferedLocation {Location {p, r}} { } - -BufferedLocation::BufferedLocation(const Location & l) : loc {l} { } - -BufferedLocation::operator const Location &() const -{ - return loc; -} - -BufferedLocation & -BufferedLocation::operator=(const Location & l) -{ - loc = l; - updateBuffer(); - return *this; -} - -GlobalPosition3D -BufferedLocation::position() const -{ - return loc.pos; -} - -Rotation3D -BufferedLocation::rotation() const -{ - return loc.rot; -} - -void -BufferedLocation::setPosition(GlobalPosition3D p, bool update) -{ - loc.pos = p; - if (update) { - updateBuffer(); - } -} - -void -BufferedLocation::setRotation(Rotation3D r, bool update) -{ - loc.rot = r; - if (update) { - updateBuffer(); - } -} - -void -BufferedLocation::setLocation(GlobalPosition3D p, Rotation3D r) -{ - loc.pos = p; - loc.rot = r; - updateBuffer(); -} - -glm::mat4 -BufferedLocation::getRotationTransform() const -{ - return loc.getRotationTransform(); -} - -void -BufferedLocationUpdater::updateBuffer() const -{ - onUpdate(this); -} diff --git a/gfx/gl/bufferedLocation.h b/gfx/gl/bufferedLocation.h deleted file mode 100644 index 87b957f..0000000 --- a/gfx/gl/bufferedLocation.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "location.h" -#include -#include -#include -#include - -class BufferedLocation { -public: - BufferedLocation(GlobalPosition3D = {}, Rotation3D = {}); - BufferedLocation(const Location &); - virtual ~BufferedLocation() = default; - - BufferedLocation & operator=(const Location &); - - operator const Location &() const; - - [[nodiscard]] GlobalPosition3D position() const; - [[nodiscard]] Rotation3D rotation() const; - void setPosition(GlobalPosition3D, bool update = true); - void setRotation(Rotation3D, bool update = true); - void setLocation(GlobalPosition3D, Rotation3D); - - [[nodiscard]] glm::mat4 getRotationTransform() const; - -private: - virtual void updateBuffer() const = 0; - - Location loc; -}; - -class BufferedLocationUpdater : public BufferedLocation { -public: - template - BufferedLocationUpdater(std::function onUpdate, LocationArgs &&... t) : - BufferedLocation {std::forward(t)...}, onUpdate {std::move(onUpdate)} - { - updateBuffer(); - } - - using BufferedLocation::operator=; - -private: - void updateBuffer() const override; - - std::function onUpdate; -}; diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h index e31fa83..9963a96 100644 --- a/gfx/gl/instanceVertices.h +++ b/gfx/gl/instanceVertices.h @@ -128,6 +128,12 @@ public: return base::begin().base().bufferName(); } + [[nodiscard]] GLuint + indexBufferName() const + { + return index.begin().base().bufferName(); + } + using typename base::value_type; using base::at; @@ -232,7 +238,7 @@ protected: } // Index into buffer given to nth proxy - std::vector index; + glVector index; std::vector reverseIndex; // List of free spaces in index std::vector unused; diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index ea11bea..a809ed5 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -78,6 +78,10 @@ SceneRenderer::preFrame(const SceneProvider & scene, const LightDirection lightD renderable->preFrame(camera, lightView); renderable->updateBillboard(billboardPainter); }); + if (auto cld = Renderable::commonLocationData.lock()) { + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, cld->bufferName()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, cld->indexBufferName()); + } } void diff --git a/gfx/gl/shaders/billboard.vert b/gfx/gl/shaders/billboard.vert index faf8b19..d6d3869 100644 --- a/gfx/gl/shaders/billboard.vert +++ b/gfx/gl/shaders/billboard.vert @@ -1,12 +1,15 @@ #version 460 core +#extension GL_ARB_shading_language_include : enable + +#include "commonLocationData.glsl" uniform mat4 viewProjection; uniform ivec4 viewPort; uniform ivec3 viewPoint; uniform vec3 centre; uniform float size; -layout(location = 0) in ivec3 modelPos; -layout(location = 1) in float yaw; + +layout(location = 0) in uint index; flat out vec3 ModelPos; flat out float Yaw; @@ -15,8 +18,9 @@ flat out float Depth; void main() { + const ivec3 modelPos = locations[cldIndex[index]].position.xyz; ModelPos = modelPos - viewPoint; - Yaw = yaw; + Yaw = locations[cldIndex[index]].rotation.x; gl_Position = viewProjection * vec4(ModelPos + centre, 1); Depth = gl_Position.w; gl_PointSize = (viewPort.w * size * 2) / gl_Position.w; diff --git a/gfx/gl/shaders/commonLocationData.glsl b/gfx/gl/shaders/commonLocationData.glsl new file mode 100644 index 0000000..4939b9b --- /dev/null +++ b/gfx/gl/shaders/commonLocationData.glsl @@ -0,0 +1,20 @@ +#ifndef COMMON_LOCATION_DATA_INCLUDED +#define COMMON_LOCATION_DATA_INCLUDED + +struct CommonLocationData { + ivec4 position; + vec4 rotation; + mat3x4 rotationMatrix; +}; + +layout(binding = 0, std430) restrict readonly buffer commonLocationData +{ + CommonLocationData locations[]; +}; + +layout(binding = 1, std430) restrict readonly buffer commonLocationDataIndex +{ + uint cldIndex[]; +}; + +#endif diff --git a/gfx/gl/shaders/dynamicPointInst.vert b/gfx/gl/shaders/dynamicPointInst.vert index 7a00099..7c50706 100644 --- a/gfx/gl/shaders/dynamicPointInst.vert +++ b/gfx/gl/shaders/dynamicPointInst.vert @@ -3,12 +3,14 @@ layout(binding = 1) uniform usampler2DRect materialData; +#include "commonLocationData.glsl" #include "materialInterface.glsl" #include "meshIn.glsl" uniform mat4 viewProjection; uniform ivec3 viewPoint; -layout(location = 5) in mat3 model; -layout(location = 8) in ivec3 modelPos; +layout(location = 5) in uint index; +mat3 model = mat3(locations[cldIndex[index]].rotationMatrix); +ivec3 modelPos = locations[cldIndex[index]].position.xyz; #include "commonPoint.glsl" diff --git a/gfx/gl/shaders/pointLight.vert b/gfx/gl/shaders/pointLight.vert index b8ddecb..61953ad 100644 --- a/gfx/gl/shaders/pointLight.vert +++ b/gfx/gl/shaders/pointLight.vert @@ -1,10 +1,14 @@ #version 460 core +#extension GL_ARB_shading_language_include : enable + +#include "commonLocationData.glsl" layout(location = 0) in vec3 v_position; layout(location = 1) in vec3 v_colour; layout(location = 2) in float v_kq; -layout(location = 3) in mat3 model; -layout(location = 6) in ivec3 modelPos; +layout(location = 3) in uint index; +mat3 model = mat3(locations[cldIndex[index]].rotationMatrix); +ivec3 modelPos = locations[cldIndex[index]].position.xyz; uniform ivec3 viewPoint; diff --git a/gfx/gl/shaders/shadowDynamicPointInst.vert b/gfx/gl/shaders/shadowDynamicPointInst.vert index d020717..b978e4a 100644 --- a/gfx/gl/shaders/shadowDynamicPointInst.vert +++ b/gfx/gl/shaders/shadowDynamicPointInst.vert @@ -1,10 +1,12 @@ #version 460 core #extension GL_ARB_shading_language_include : enable +#include "commonLocationData.glsl" #include "meshIn.glsl" uniform ivec3 viewPoint; -layout(location = 5) in mat3 model; -layout(location = 8) in ivec3 modelPos; +layout(location = 5) in uint index; +mat3 model = mat3(locations[cldIndex[index]].rotationMatrix); +ivec3 modelPos = locations[cldIndex[index]].position.xyz; #include "commonShadowPoint.glsl" diff --git a/gfx/gl/shaders/shadowDynamicPointInstWithTextures.vert b/gfx/gl/shaders/shadowDynamicPointInstWithTextures.vert index 51b05c8..a5e8245 100644 --- a/gfx/gl/shaders/shadowDynamicPointInstWithTextures.vert +++ b/gfx/gl/shaders/shadowDynamicPointInstWithTextures.vert @@ -4,12 +4,14 @@ layout(binding = 4) uniform usampler2DRect materialData; +#include "commonLocationData.glsl" #include "getMaterialDetail.glsl" #include "materialInterface.glsl" #include "meshIn.glsl" uniform ivec3 viewPoint; -layout(location = 5) in mat3 model; -layout(location = 8) in ivec3 modelPos; +layout(location = 5) in uint index; +mat3 model = mat3(locations[cldIndex[index]].rotationMatrix); +ivec3 modelPos = locations[cldIndex[index]].position.xyz; #include "commonShadowPoint.glsl" diff --git a/gfx/gl/shaders/shadowDynamicPointStencil.vert b/gfx/gl/shaders/shadowDynamicPointStencil.vert index b750b3e..0a41143 100644 --- a/gfx/gl/shaders/shadowDynamicPointStencil.vert +++ b/gfx/gl/shaders/shadowDynamicPointStencil.vert @@ -1,7 +1,9 @@ #version 460 core +#extension GL_ARB_shading_language_include : enable -layout(location = 0) in ivec3 worldPos; -layout(location = 1) in float modelYaw; +#include "commonLocationData.glsl" + +layout(location = 0) in uint index; uniform ivec3 viewPoint; uniform vec3 centre; @@ -11,6 +13,6 @@ out ivec3 vworldPos; void main() { - vmodelYaw = modelYaw; - vworldPos = worldPos - viewPoint + ivec3(centre); + vmodelYaw = locations[cldIndex[index]].rotation.x; + vworldPos = locations[cldIndex[index]].position.xyz - viewPoint + ivec3(centre); } diff --git a/gfx/gl/shaders/spotLight.vert b/gfx/gl/shaders/spotLight.vert index 83f3859..6f72a63 100644 --- a/gfx/gl/shaders/spotLight.vert +++ b/gfx/gl/shaders/spotLight.vert @@ -1,12 +1,16 @@ #version 460 core +#extension GL_ARB_shading_language_include : enable + +#include "commonLocationData.glsl" layout(location = 0) in vec3 v_position; layout(location = 1) in vec3 v_direction; layout(location = 2) in vec3 v_colour; layout(location = 3) in float v_kq; layout(location = 4) in float v_arc; -layout(location = 5) in mat3 model; -layout(location = 8) in ivec3 modelPos; +layout(location = 5) in uint index; +mat3 model = mat3(locations[cldIndex[index]].rotationMatrix); +ivec3 modelPos = locations[cldIndex[index]].position.xyz; uniform ivec3 viewPoint; diff --git a/gfx/renderable.cpp b/gfx/renderable.cpp index 8caab93..4597597 100644 --- a/gfx/renderable.cpp +++ b/gfx/renderable.cpp @@ -1,4 +1,39 @@ #include "renderable.h" +#include "gl_traits.h" +#include "location.h" +#include "maths.h" + +std::weak_ptr Renderable::commonLocationData; + +Renderable::CommonLocation::CommonLocation(Location const & location) : + position {location.pos, 0}, rotation {location.rot, 0}, rotationMatrix {location.getRotationTransform()} +{ +} + +Renderable::CommonLocation & +Renderable::CommonLocation ::operator=(Location const & location) +{ + position = location.pos || 0; + rotation = location.rot || 0.F; + rotationMatrix = location.getRotationTransform(); + return *this; +} + +Renderable::Renderable() +{ + if (!(locationData = commonLocationData.lock())) { + commonLocationData = locationData = std::make_shared(); + } +} + +GLuint +gl_traits::InstanceProxy>::vertexArrayAttribFormat( + GLuint vao, GLuint index, GLuint offset) +{ + return gl_traits< + decltype(InstanceVertices::InstanceProxy::index)>::vertexArrayAttribFormat(vao, + index, offset + offsetof(InstanceVertices::InstanceProxy, index)); +}; void Renderable::preFrame(const Frustum &, const Frustum &) diff --git a/gfx/renderable.h b/gfx/renderable.h index d0870ad..b0a42f2 100644 --- a/gfx/renderable.h +++ b/gfx/renderable.h @@ -1,5 +1,8 @@ #pragma once +#include "gfx/gl/instanceVertices.h" +#include "gl_traits.h" +#include #include class SceneShader; @@ -7,10 +10,11 @@ class Frustum; class ShadowMapper; class ShadowStenciller; class BillboardPainter; +class Location; class Renderable { public: - Renderable() = default; + Renderable(); virtual ~Renderable() = default; DEFAULT_MOVE_COPY(Renderable); @@ -21,4 +25,25 @@ public: virtual void updateStencil(const ShadowStenciller & lightDir) const; virtual void updateBillboard(const BillboardPainter &) const; + + struct CommonLocation { + CommonLocation(const Location &); + CommonLocation & operator=(const Location &); + + glm::ivec4 position; + glm::vec4 rotation; + glm::mat3x4 rotationMatrix; + }; + + using CommonLocationData = InstanceVertices; + using CommonLocationInstance = CommonLocationData::InstanceProxy; + + std::shared_ptr locationData; + + static std::weak_ptr commonLocationData; +}; + +template<> struct gl_traits::InstanceProxy> { + static GLuint vertexArrayAttribFormat(GLuint vao, GLuint index, GLuint offset); }; + -- cgit v1.3