summaryrefslogtreecommitdiff
path: root/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'gfx')
-rw-r--r--gfx/followCameraController.cpp3
-rw-r--r--gfx/gl/bufferedLocation.cpp70
-rw-r--r--gfx/gl/bufferedLocation.h48
-rw-r--r--gfx/gl/glVertexArray.h19
-rw-r--r--gfx/gl/instanceVertices.h35
-rw-r--r--gfx/gl/sceneRenderer.cpp4
-rw-r--r--gfx/gl/shaders/billboard.vert10
-rw-r--r--gfx/gl/shaders/commonLocationData.glsl20
-rw-r--r--gfx/gl/shaders/dynamicPointInst.vert6
-rw-r--r--gfx/gl/shaders/pointLight.vert8
-rw-r--r--gfx/gl/shaders/shadowDynamicPointInst.vert6
-rw-r--r--gfx/gl/shaders/shadowDynamicPointInstWithTextures.vert6
-rw-r--r--gfx/gl/shaders/shadowDynamicPointStencil.vert10
-rw-r--r--gfx/gl/shaders/spotLight.vert8
-rw-r--r--gfx/models/lights.cpp11
-rw-r--r--gfx/models/lights.h29
-rw-r--r--gfx/renderable.cpp76
-rw-r--r--gfx/renderable.h38
18 files changed, 243 insertions, 164 deletions
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 <glm/glm.hpp>
#include <location.h>
#include <maths.h>
-#include <memory>
#include <tuple>
#include <utility>
@@ -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 <glm/gtx/transform.hpp>
-
-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 <functional>
-#include <glm/mat4x4.hpp>
-#include <glm/vec3.hpp>
-#include <utility>
-
-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<typename... LocationArgs>
- BufferedLocationUpdater(std::function<void(const BufferedLocation *)> onUpdate, LocationArgs &&... t) :
- BufferedLocation {std::forward<LocationArgs>(t)...}, onUpdate {std::move(onUpdate)}
- {
- updateBuffer();
- }
-
- using BufferedLocation::operator=;
-
-private:
- void updateBuffer() const override;
-
- std::function<void(const BufferedLocation *)> onUpdate;
-};
diff --git a/gfx/gl/glVertexArray.h b/gfx/gl/glVertexArray.h
index 323303c..4e8113f 100644
--- a/gfx/gl/glVertexArray.h
+++ b/gfx/gl/glVertexArray.h
@@ -4,6 +4,7 @@
#include "glArrays.h"
#include "glBuffer.h"
#include "gl_traits.h"
+#include "util.h"
namespace Impl {
class VertexArrayConfigurator {
@@ -20,11 +21,8 @@ namespace Impl {
}
M T::* ptr;
- using ValueType = M;
};
- template<typename M, typename T> MP(M T::*) -> MP<M, T>;
-
explicit VertexArrayConfigurator(GLuint name) : name {name} { }
VertexArrayConfigurator &
@@ -52,7 +50,7 @@ namespace Impl {
return addAttribsFor<VertexT>(divisor);
}
- template<typename VertexT, MP... Attribs>
+ template<typename VertexT, auto... Attribs>
VertexArrayConfigurator &
addAttribs(const GLuint divisor)
{
@@ -60,7 +58,7 @@ namespace Impl {
return *this;
}
- template<typename VertexT, MP... Attribs>
+ template<typename VertexT, auto... Attribs>
VertexArrayConfigurator &
addAttribs(const GLuint divisor, const glBuffer & buffer)
{
@@ -68,7 +66,7 @@ namespace Impl {
return addAttribs<VertexT, Attribs...>(divisor);
}
- template<typename VertexT, MP... Attribs>
+ template<typename VertexT, auto... Attribs>
VertexArrayConfigurator &
addAttribs(const GLuint divisor, glBuffer & buffer, const SequentialCollection<VertexT> auto & data)
{
@@ -93,14 +91,15 @@ namespace Impl {
setPointerMeta(attrib + gl_traits<T>::vertexArrayAttribFormat(name, attrib, offset));
}
- template<MP Attrib>
+ template<typename VertexT, auto Attrib>
void
setPointer()
{
- setPointer<typename decltype(Attrib)::ValueType>(Attrib);
+ using Mbr = MemberValueType<Attrib>;
+ setPointer<Mbr>(MP<Mbr, VertexT> {Attrib});
}
- template<typename VertexT, MP... Attribs>
+ template<typename VertexT, auto... Attribs>
void
configureAttribs(const GLuint divisor)
{
@@ -108,7 +107,7 @@ namespace Impl {
setPointer<VertexT>(0);
}
else {
- ((setPointer<Attribs>()), ...);
+ ((setPointer<VertexT, Attribs>()), ...);
}
glVertexArrayBindingDivisor(name, binding++, divisor);
}
diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h
index d984938..9963a96 100644
--- a/gfx/gl/instanceVertices.h
+++ b/gfx/gl/instanceVertices.h
@@ -9,11 +9,12 @@
template<typename T> class InstanceVertices : protected glVector<T> {
using base = glVector<T>;
+ using IndexT = uint32_t;
public:
class [[nodiscard]] InstanceProxy {
public:
- InstanceProxy(InstanceVertices * iv, std::size_t idx) : instances {iv}, index {idx} { }
+ InstanceProxy(InstanceVertices * iv, IndexT idx) : instances {iv}, index {idx} { }
InstanceProxy(InstanceProxy && other) noexcept :
instances {std::exchange(other.instances, nullptr)}, index {other.index}
@@ -98,9 +99,9 @@ public:
return instances->lookup(index);
}
- private:
+ // private:
InstanceVertices<T> * instances;
- std::size_t index;
+ IndexT index;
};
template<typename... Params>
@@ -110,15 +111,15 @@ public:
if (!unused.empty()) {
auto idx = unused.back();
unused.pop_back();
- index[idx] = base::size();
+ index[idx] = static_cast<IndexT>(base::size());
reverseIndex.emplace_back(idx);
base::emplace_back(std::forward<Params>(params)...);
return InstanceProxy {this, idx};
}
- index.emplace_back(base::size());
- reverseIndex.push_back(base::size());
+ index.emplace_back(static_cast<IndexT>(base::size()));
+ reverseIndex.push_back(static_cast<IndexT>(base::size()));
base::emplace_back(std::forward<Params>(params)...);
- return InstanceProxy {this, index.size() - 1};
+ return InstanceProxy {this, static_cast<IndexT>(index.size() - 1)};
}
[[nodiscard]] GLuint
@@ -127,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;
@@ -176,7 +183,7 @@ public:
}
protected:
- static constexpr auto npos = static_cast<size_t>(-1);
+ static constexpr auto npos = static_cast<IndexT>(-1);
friend InstanceProxy;
base::size_type
@@ -186,9 +193,9 @@ protected:
}
void
- release(const size_t pidx)
+ release(const IndexT pidx)
{
- if (const size_t last = base::size() - 1; last != index[pidx]) {
+ if (const auto last = static_cast<IndexT>(base::size() - 1); last != index[pidx]) {
lookup(pidx) = std::move(base::back());
const auto movedKey = reverseIndex[last];
index[movedKey] = std::exchange(index[pidx], npos);
@@ -207,7 +214,7 @@ protected:
}
[[nodiscard]] T &
- lookup(size_t pindex)
+ lookup(IndexT pindex)
{
return base::data()[index[pindex]];
}
@@ -231,8 +238,8 @@ protected:
}
// Index into buffer given to nth proxy
- std::vector<size_t> index;
- std::vector<size_t> reverseIndex;
+ glVector<IndexT> index;
+ std::vector<IndexT> reverseIndex;
// List of free spaces in index
- std::vector<size_t> unused;
+ std::vector<IndexT> 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/models/lights.cpp b/gfx/models/lights.cpp
new file mode 100644
index 0000000..8c0e9e6
--- /dev/null
+++ b/gfx/models/lights.cpp
@@ -0,0 +1,11 @@
+#include "lights.h"
+
+SpotLightVertex::SpotLightVertex(const SpotLightDef & light, uint32_t parentObjectIdx) :
+ SpotLightDef {light}, LightCommonVertex {parentObjectIdx}
+{
+}
+
+PointLightVertex::PointLightVertex(const PointLightDef & light, uint32_t parentObjectIdx) :
+ PointLightDef {light}, LightCommonVertex {parentObjectIdx}
+{
+}
diff --git a/gfx/models/lights.h b/gfx/models/lights.h
new file mode 100644
index 0000000..586b3ef
--- /dev/null
+++ b/gfx/models/lights.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "config/types.h"
+
+struct LightCommon {
+ RelativePosition3D position;
+ RGB colour;
+ RelativeDistance kq;
+};
+
+struct LightCommonVertex {
+ uint32_t parentObject;
+};
+
+struct SpotLightDef : LightCommon {
+ Direction3D direction;
+ Angle arc;
+};
+
+struct PointLightDef : LightCommon { };
+
+struct SpotLightVertex : SpotLightDef, LightCommonVertex {
+ SpotLightVertex(const SpotLightDef &, uint32_t);
+};
+
+struct PointLightVertex : PointLightDef, LightCommonVertex {
+ PointLightVertex(const PointLightDef &, uint32_t);
+};
+
diff --git a/gfx/renderable.cpp b/gfx/renderable.cpp
index 8caab93..8523118 100644
--- a/gfx/renderable.cpp
+++ b/gfx/renderable.cpp
@@ -1,4 +1,55 @@
#include "renderable.h"
+#include "gfx/gl/sceneShader.h"
+#include "gl_traits.h"
+#include "location.h"
+#include "maths.h"
+#include "util.h"
+
+std::weak_ptr<Renderable::CommonLocationData> Renderable::commonLocationData;
+std::weak_ptr<Renderable::CommonSpotLights> Renderable::commonSpotLights;
+std::weak_ptr<Renderable::CommonPointLights> Renderable::commonPointLights;
+std::weak_ptr<glVertexArray> Renderable::commonInstancesSpotLightVAO, Renderable::commonInstancesPointLightVAO;
+
+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()
+{
+ createIfRequired(locationData, commonLocationData);
+ createIfRequired(spotLights, commonSpotLights);
+ createIfRequired(pointLights, commonPointLights);
+ if (createIfRequired(instancesSpotLightVAO, commonInstancesSpotLightVAO)) {
+ instancesSpotLightVAO->configure()
+ .addAttribs<SpotLightVertex, &SpotLightVertex::position, &SpotLightVertex::direction,
+ &SpotLightVertex::colour, &SpotLightVertex::kq, &SpotLightVertex::arc,
+ &SpotLightVertex::parentObject>(0);
+ }
+ if (createIfRequired(instancesPointLightVAO, commonInstancesPointLightVAO)) {
+ instancesPointLightVAO->configure()
+ .addAttribs<PointLightVertex, &PointLightVertex::position, &PointLightVertex::colour,
+ &PointLightVertex::kq, &PointLightVertex::parentObject>(0);
+ }
+}
+
+GLuint
+gl_traits<InstanceVertices<Renderable::CommonLocation>::InstanceProxy>::vertexArrayAttribFormat(
+ GLuint vao, GLuint index, GLuint offset)
+{
+ return gl_traits<
+ decltype(InstanceVertices<Renderable::CommonLocation>::InstanceProxy::index)>::vertexArrayAttribFormat(vao,
+ index, offset + offsetof(InstanceVertices<Renderable::CommonLocation>::InstanceProxy, index));
+};
void
Renderable::preFrame(const Frustum &, const Frustum &)
@@ -6,8 +57,31 @@ Renderable::preFrame(const Frustum &, const Frustum &)
}
void
-Renderable::lights(const SceneShader &) const
+Renderable::lights(const SceneShader & shader)
{
+ glDebugScope _ {0};
+ if (const auto instancesSpotLight = commonSpotLights.lock()) {
+ if (const auto scount = instancesSpotLight->size()) {
+ if (const auto instancesSpotLightVAO = commonInstancesSpotLightVAO.lock()) {
+ glDebugScope _ {*instancesSpotLightVAO, "Spot lights"};
+ shader.spotLightInst.use();
+ glBindVertexArray(*instancesSpotLightVAO);
+ instancesSpotLightVAO->useBuffer(0, *instancesSpotLight);
+ glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(scount));
+ }
+ }
+ }
+ if (const auto instancesPointLight = commonPointLights.lock()) {
+ if (const auto pcount = instancesPointLight->size()) {
+ if (const auto instancesPointLightVAO = commonInstancesPointLightVAO.lock()) {
+ glDebugScope _ {*instancesPointLightVAO, "Point lights"};
+ shader.pointLightInst.use();
+ glBindVertexArray(*instancesPointLightVAO);
+ instancesPointLightVAO->useBuffer(0, *instancesPointLight);
+ glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(pcount));
+ }
+ }
+ }
}
void
diff --git a/gfx/renderable.h b/gfx/renderable.h
index d0870ad..7f4f52e 100644
--- a/gfx/renderable.h
+++ b/gfx/renderable.h
@@ -1,5 +1,10 @@
#pragma once
+#include "gfx/gl/glVertexArray.h"
+#include "gfx/gl/instanceVertices.h"
+#include "gfx/models/lights.h"
+#include "gl_traits.h"
+#include <glm/mat3x3.hpp>
#include <special_members.h>
class SceneShader;
@@ -7,18 +12,47 @@ class Frustum;
class ShadowMapper;
class ShadowStenciller;
class BillboardPainter;
+class Location;
class Renderable {
public:
- Renderable() = default;
+ Renderable();
virtual ~Renderable() = default;
DEFAULT_MOVE_COPY(Renderable);
virtual void preFrame(const Frustum &, const Frustum &);
virtual void render(const SceneShader & shader, const Frustum &) const = 0;
- virtual void lights(const SceneShader & shader) const;
+ static void lights(const SceneShader & shader);
virtual void shadows(const ShadowMapper & shadowMapper, const Frustum &) const;
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<CommonLocation>;
+ using CommonLocationInstance = CommonLocationData::InstanceProxy;
+ std::shared_ptr<CommonLocationData> locationData;
+ static std::weak_ptr<CommonLocationData> commonLocationData;
+
+ using CommonSpotLights = InstanceVertices<SpotLightVertex>;
+ std::shared_ptr<CommonSpotLights> spotLights;
+ static std::weak_ptr<CommonSpotLights> commonSpotLights;
+ using CommonPointLights = InstanceVertices<PointLightVertex>;
+ std::shared_ptr<CommonPointLights> pointLights;
+ static std::weak_ptr<CommonPointLights> commonPointLights;
+ std::shared_ptr<glVertexArray> instancesSpotLightVAO, instancesPointLightVAO;
+ static std::weak_ptr<glVertexArray> commonInstancesSpotLightVAO, commonInstancesPointLightVAO;
};
+
+template<> struct gl_traits<InstanceVertices<Renderable::CommonLocation>::InstanceProxy> {
+ static GLuint vertexArrayAttribFormat(GLuint vao, GLuint index, GLuint offset);
+};
+