summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assetFactory/assetFactory.cpp4
-rw-r--r--game/network/rail.cpp4
-rw-r--r--game/scenary/foliage.cpp35
-rw-r--r--game/scenary/foliage.h4
-rw-r--r--game/scenary/illuminator.cpp42
-rw-r--r--game/scenary/illuminator.h5
-rw-r--r--game/terrain.cpp33
-rw-r--r--game/terrain.h6
-rw-r--r--game/water.cpp2
-rw-r--r--gfx/models/mesh.cpp11
-rw-r--r--gfx/models/mesh.h26
11 files changed, 106 insertions, 66 deletions
diff --git a/assetFactory/assetFactory.cpp b/assetFactory/assetFactory.cpp
index b96e527..a8d6036 100644
--- a/assetFactory/assetFactory.cpp
+++ b/assetFactory/assetFactory.cpp
@@ -3,6 +3,7 @@
#include "cuboid.h"
#include "cylinder.h"
#include "filesystem.h"
+#include "gfx/gl/gldebug.h"
#include "gfx/image.h"
#include "gfx/models/texture.h"
#include "gfx/renderable.h"
@@ -26,6 +27,7 @@ AssetFactory::AssetFactory() :
std::shared_ptr<AssetFactory>
AssetFactory::loadXML(const std::filesystem::path & filename)
{
+ glDebugScope _ {0, filename.native()};
filesystem::FileStar file {filename.c_str(), "r"};
return Persistence::SAXParsePersistence {}.loadState<std::shared_ptr<AssetFactory>>(file);
}
@@ -33,6 +35,7 @@ AssetFactory::loadXML(const std::filesystem::path & filename)
AssetFactory::Assets
AssetFactory::loadAll(const std::filesystem::path & root)
{
+ glDebugScope _ {0};
return std::accumulate(std::filesystem::recursive_directory_iterator {root},
std::filesystem::recursive_directory_iterator {}, Assets {}, [](auto out, const auto & path) {
if (path.path().extension() == ".xml") {
@@ -115,6 +118,7 @@ void
AssetFactory::createTexutre() const
{
if (!textureFragments.empty() && !texture) {
+ glDebugScope _ {0};
// * layout images
std::map<const TextureFragment *, std::unique_ptr<const Image>> images;
std::transform(
diff --git a/game/network/rail.cpp b/game/network/rail.cpp
index 13d5ef5..e8cc1b6 100644
--- a/game/network/rail.cpp
+++ b/game/network/rail.cpp
@@ -138,6 +138,7 @@ RailLink::vehiclePositionOffset() const
template<> NetworkLinkHolder<RailLinkStraight>::NetworkLinkHolder()
{
+ glDebugScope _ {0};
vao.configure()
.addAttribs<RailLinkStraight::Vertex, &RailLinkStraight::Vertex::a, &RailLinkStraight::Vertex::b,
&RailLinkStraight::Vertex::rotation, &RailLinkStraight::Vertex::textureRepeats>(0);
@@ -145,6 +146,7 @@ template<> NetworkLinkHolder<RailLinkStraight>::NetworkLinkHolder()
template<> NetworkLinkHolder<RailLinkCurve>::NetworkLinkHolder()
{
+ glDebugScope _ {0};
vao.configure()
.addAttribs<RailLinkCurve::Vertex, &RailLinkCurve::Vertex::a, &RailLinkCurve::Vertex::b,
&RailLinkCurve::Vertex::c, &RailLinkCurve::Vertex::textureRepeats, &RailLinkCurve::Vertex::aangle,
@@ -170,7 +172,7 @@ void
RailLinks::render(const SceneShader & shader, const Frustum &) const
{
if (!links.empty()) {
- auto _ = glDebugScope(0);
+ glDebugScope _ {0};
texture->bind(0);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1, 0);
diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp
index b5b409e..ff00af4 100644
--- a/game/scenary/foliage.cpp
+++ b/game/scenary/foliage.cpp
@@ -20,6 +20,8 @@ namespace {
}
}
+std::weak_ptr<glVertexArray> Foliage::commonInstanceVAO, Foliage::commonInstancePointVAO;
+
std::any
Foliage::createAt(const Location & position) const
{
@@ -38,10 +40,15 @@ Foliage::postLoad()
{
texture = getTexture();
glDebugScope _ {0};
- bodyMesh->configureVAO(instanceVAO, 0)
- .addAttribs<LocationVertex, &LocationVertex::rotation, &LocationVertex::position>(1);
- instancePointVAO.configure().addAttribs<LocationVertex, &LocationVertex::position, &LocationVertex::yaw>(0);
-
+ if (!(instanceVAO = commonInstanceVAO.lock())) {
+ commonInstanceVAO = instanceVAO = std::make_shared<glVertexArray>();
+ bodyMesh->configureVAO(*instanceVAO, 0)
+ .addAttribs<LocationVertex, &LocationVertex::rotation, &LocationVertex::position>(1);
+ }
+ if (!(instancePointVAO = commonInstancePointVAO.lock())) {
+ commonInstancePointVAO = instancePointVAO = std::make_shared<glVertexArray>();
+ instancePointVAO->configure().addAttribs<LocationVertex, &LocationVertex::position, &LocationVertex::yaw>(0);
+ }
const auto & size = bodyMesh->getDimensions().size;
billboardSize = billboardTextureSizeForObject(size);
ShadowStenciller::configureStencilTexture(shadowStencil, {billboardSize, billboardSize});
@@ -93,7 +100,7 @@ void
Foliage::render(const SceneShader & shader, const Frustum &) const
{
if (instancePartitions.first) {
- glDebugScope _ {instanceVAO};
+ glDebugScope _ {*instanceVAO};
std::ignore = instances.size();
if (const auto count = instancePartitions.first - instancePartitions.second.first) {
glDebugScope _ {0, "Billboard"};
@@ -102,8 +109,8 @@ Foliage::render(const SceneShader & shader, const Frustum &) const
billboard[0].bind(0);
billboard[1].bind(1);
billboard[2].bind(2);
- glBindVertexArray(instancePointVAO);
- instancePointVAO.useBuffer(0, instances);
+ glBindVertexArray(*instancePointVAO);
+ instancePointVAO->useBuffer(0, instances);
glDrawArrays(GL_POINTS, static_cast<GLint>(instancePartitions.second.first), static_cast<GLsizei>(count));
glBindVertexArray(0);
}
@@ -113,8 +120,8 @@ Foliage::render(const SceneShader & shader, const Frustum &) const
if (texture) {
texture->bind(0);
}
- instanceVAO.useBuffer(1, instances);
- bodyMesh->drawInstanced(instanceVAO, static_cast<GLsizei>(count));
+ instanceVAO->useBuffer(1, instances);
+ bodyMesh->drawInstanced(*instanceVAO, static_cast<GLsizei>(count));
}
}
}
@@ -123,15 +130,15 @@ void
Foliage::shadows(const ShadowMapper & mapper, const Frustum &) const
{
if (instancePartitions.second.second) {
- glDebugScope _ {instanceVAO};
+ glDebugScope _ {*instanceVAO};
std::ignore = instances.size();
if (const auto count = instancePartitions.second.second - instancePartitions.second.first) {
glDebugScope _ {0, "Billboard"};
const auto dimensions = bodyMesh->getDimensions();
mapper.stencilShadowProgram.use(dimensions.centre, dimensions.size);
shadowStencil.bind(0);
- glBindVertexArray(instancePointVAO);
- instancePointVAO.useBuffer(0, instances);
+ glBindVertexArray(*instancePointVAO);
+ instancePointVAO->useBuffer(0, instances);
glDrawArrays(GL_POINTS, static_cast<GLint>(instancePartitions.second.first), static_cast<GLsizei>(count));
glBindVertexArray(0);
}
@@ -144,8 +151,8 @@ Foliage::shadows(const ShadowMapper & mapper, const Frustum &) const
else {
mapper.dynamicPointInst.use();
}
- instanceVAO.useBuffer(1, instances);
- bodyMesh->drawInstanced(instanceVAO, static_cast<GLsizei>(count));
+ instanceVAO->useBuffer(1, instances);
+ bodyMesh->drawInstanced(*instanceVAO, static_cast<GLsizei>(count));
}
}
}
diff --git a/game/scenary/foliage.h b/game/scenary/foliage.h
index bf98d55..c599649 100644
--- a/game/scenary/foliage.h
+++ b/game/scenary/foliage.h
@@ -12,8 +12,8 @@ class Location;
class Foliage : public Asset, public Renderable, public StdTypeDefs<Foliage> {
Mesh::Ptr bodyMesh;
Texture::Ptr texture;
- glVertexArray instanceVAO;
- glVertexArray instancePointVAO;
+ std::shared_ptr<glVertexArray> instanceVAO, instancePointVAO;
+ static std::weak_ptr<glVertexArray> commonInstanceVAO, commonInstancePointVAO;
public:
[[nodiscard]] std::any createAt(const Location &) const override;
diff --git a/game/scenary/illuminator.cpp b/game/scenary/illuminator.cpp
index a0ea5be..4398853 100644
--- a/game/scenary/illuminator.cpp
+++ b/game/scenary/illuminator.cpp
@@ -5,6 +5,9 @@
static_assert(std::is_constructible_v<Illuminator>);
+std::weak_ptr<glVertexArray> Illuminator::commonInstanceVAO, Illuminator::commonInstancesSpotLightVAO,
+ Illuminator::commonInstancesPointLightVAO;
+
std::any
Illuminator::createAt(const Location & position) const
{
@@ -41,25 +44,32 @@ Illuminator::postLoad()
}
texture = getTexture();
glDebugScope _ {0};
- bodyMesh->configureVAO(instanceVAO, 0)
- .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1);
- if (!spotLight.empty()) {
- instancesSpotLightVAO.emplace();
- instancesSpotLightVAO->configure()
- .addAttribs<SpotLightVertex, &SpotLightVertex::position, &SpotLightVertex::direction,
- &SpotLightVertex::colour, &SpotLightVertex::kq, &SpotLightVertex::arc>(0)
+ if (!(instanceVAO = commonInstanceVAO.lock())) {
+ commonInstanceVAO = instanceVAO = std::make_shared<glVertexArray>();
+ bodyMesh->configureVAO(*instanceVAO, 0)
.addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1);
+ }
+ if (!spotLight.empty()) {
+ if (!(instancesSpotLightVAO = commonInstancesSpotLightVAO.lock())) {
+ commonInstancesSpotLightVAO = instancesSpotLightVAO = std::make_shared<glVertexArray>();
+ instancesSpotLightVAO->configure()
+ .addAttribs<SpotLightVertex, &SpotLightVertex::position, &SpotLightVertex::direction,
+ &SpotLightVertex::colour, &SpotLightVertex::kq, &SpotLightVertex::arc>(0)
+ .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1);
+ }
std::transform(
spotLight.begin(), spotLight.end(), std::back_inserter(spotLightInstances), [this](const auto & s) {
return instancesSpotLight.acquire(*s);
});
}
if (!pointLight.empty()) {
- instancesPointLightVAO.emplace();
- instancesPointLightVAO->configure()
- .addAttribs<PointLightVertex, &PointLightVertex::position, &PointLightVertex::colour,
- &PointLightVertex::kq>(0)
- .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1);
+ if (!(instancesPointLightVAO = commonInstancesPointLightVAO.lock())) {
+ commonInstancesPointLightVAO = instancesPointLightVAO = std::make_shared<glVertexArray>();
+ instancesPointLightVAO->configure()
+ .addAttribs<PointLightVertex, &PointLightVertex::position, &PointLightVertex::colour,
+ &PointLightVertex::kq>(0)
+ .addAttribs<LocationVertex, &LocationVertex::first, &LocationVertex::second>(1);
+ }
std::transform(
pointLight.begin(), pointLight.end(), std::back_inserter(pointLightInstances), [this](const auto & s) {
return instancesPointLight.acquire(*s);
@@ -71,13 +81,13 @@ void
Illuminator::render(const SceneShader & shader, const Frustum &) const
{
if (const auto count = instances.size()) {
- glDebugScope _ {instanceVAO};
+ glDebugScope _ {*instanceVAO};
shader.basicInst.use();
if (texture) {
texture->bind(0);
}
- instanceVAO.useBuffer(1, instances);
- bodyMesh->drawInstanced(instanceVAO, static_cast<GLsizei>(count));
+ instanceVAO->useBuffer(1, instances);
+ bodyMesh->drawInstanced(*instanceVAO, static_cast<GLsizei>(count));
}
}
@@ -85,7 +95,7 @@ void
Illuminator::lights(const SceneShader & shader) const
{
if (const auto count = instances.size()) {
- glDebugScope _ {instanceVAO};
+ glDebugScope _ {*instanceVAO};
if (const auto scount = instancesSpotLight.size()) {
glDebugScope _ {*instancesSpotLightVAO, "Spot lights"};
shader.spotLightInst.use();
diff --git a/game/scenary/illuminator.h b/game/scenary/illuminator.h
index 200ba40..7b6e7ad 100644
--- a/game/scenary/illuminator.h
+++ b/game/scenary/illuminator.h
@@ -11,8 +11,8 @@ class Location;
class Illuminator : public Asset, public Renderable, public StdTypeDefs<Illuminator> {
Mesh::Ptr bodyMesh;
Texture::Ptr texture;
- glVertexArray instanceVAO;
- std::optional<glVertexArray> instancesSpotLightVAO, instancesPointLightVAO;
+ std::shared_ptr<glVertexArray> instanceVAO, instancesSpotLightVAO, instancesPointLightVAO;
+ static std::weak_ptr<glVertexArray> commonInstanceVAO, commonInstancesSpotLightVAO, commonInstancesPointLightVAO;
public:
[[nodiscard]] std::any createAt(const Location &) const override;
@@ -42,7 +42,6 @@ public:
bool persist(Persistence::PersistenceStore & store) override;
};
-public:
using LocationVertex = std::pair<glm::mat3, GlobalPosition3D>;
mutable InstanceVertices<LocationVertex> instances;
mutable InstanceVertices<SpotLightVertex> instancesSpotLight;
diff --git a/game/terrain.cpp b/game/terrain.cpp
index 43b1152..f3d7a7d 100644
--- a/game/terrain.cpp
+++ b/game/terrain.cpp
@@ -16,11 +16,13 @@
static constexpr RGB OPEN_SURFACE {-1};
static constexpr GlobalDistance TILE_SIZE = 1024 * 1024; // ~1km, power of 2, fast divide
-template<>
-Impl::VertexArrayConfigurator &
-Impl::VertexArrayConfigurator::addAttribsFor<Terrain::Vertex>(const GLuint divisor)
+void
+Terrain::initialise()
{
- return addAttribs<Terrain::Vertex, &Terrain::Vertex::pos, &Terrain::Vertex::normal>(divisor);
+ glDebugScope _ {0};
+ vertexArray.configure().addAttribs<Terrain::Vertex, &Terrain::Vertex::pos, &Terrain::Vertex::normal>(
+ 0, verticesBuffer);
+ generateMeshes();
}
bool
@@ -76,19 +78,10 @@ void
Terrain::copyIndicesToBuffers(const SurfaceIndices & surfaceIndices)
{
for (const auto & [surfaceKey, indices] : surfaceIndices) {
- auto meshItr = meshes.find(surfaceKey);
- if (meshItr == meshes.end()) {
- meshItr = meshes.emplace(surfaceKey, SurfaceArrayBuffer {}).first;
- meshItr->second.vertexArray.configure()
- .addAttribsFor<Vertex>(0, verticesBuffer)
- .addIndices(meshItr->second.indicesBuffer);
- }
- else {
- meshItr->second.vertexArray.configure().addIndices(meshItr->second.indicesBuffer);
- }
- meshItr->second.indicesBuffer.data(indices, GL_DYNAMIC_DRAW);
- meshItr->second.count = static_cast<GLsizei>(indices.size());
- meshItr->second.aabb = AxisAlignedBoundingBox<GlobalDistance>::fromPoints(
+ auto & mesh = meshes[surfaceKey];
+ mesh.indicesBuffer.data(indices, GL_DYNAMIC_DRAW);
+ mesh.count = static_cast<GLsizei>(indices.size());
+ mesh.aabb = AxisAlignedBoundingBox<GlobalDistance>::fromPoints(
indices | std::views::transform([this](const auto vertex) {
return this->point(VertexHandle {static_cast<int>(vertex)});
}));
@@ -130,6 +123,7 @@ void
Terrain::render(const SceneShader & shader, const Frustum & frustum) const
{
glDebugScope _ {0};
+ glBindVertexArray(vertexArray);
grass->bind(0);
const auto chunkBySurface = std::views::chunk_by([](const auto & itr1, const auto & itr2) {
@@ -140,7 +134,7 @@ Terrain::render(const SceneShader & shader, const Frustum & frustum) const
shader.landmass.use(surface ? surface->colorBias : OPEN_SURFACE);
for (const auto & sab : surfaceRange) {
if (frustum.contains(sab.second.aabb)) {
- glBindVertexArray(sab.second.vertexArray);
+ glVertexArrayElementBuffer(vertexArray, sab.second.indicesBuffer);
glDrawElements(GL_TRIANGLES, sab.second.count, GL_UNSIGNED_INT, nullptr);
}
}
@@ -152,10 +146,11 @@ void
Terrain::shadows(const ShadowMapper & shadowMapper, const Frustum & frustum) const
{
glDebugScope _ {0};
+ glBindVertexArray(vertexArray);
shadowMapper.landmess.use();
for (const auto & [surface, sab] : meshes) {
if (frustum.contains(sab.aabb)) {
- glBindVertexArray(sab.vertexArray);
+ glVertexArrayElementBuffer(vertexArray, sab.indicesBuffer);
glDrawElements(GL_TRIANGLES, sab.count, GL_UNSIGNED_INT, nullptr);
}
}
diff --git a/game/terrain.h b/game/terrain.h
index 1a63296..f1170f2 100644
--- a/game/terrain.h
+++ b/game/terrain.h
@@ -13,7 +13,7 @@ class Terrain : public GeoData, public WorldObject, public Renderable {
public:
template<typename... P> explicit Terrain(P &&... params) : GeoData {std::forward<P>(params)...}
{
- generateMeshes();
+ initialise();
}
void render(const SceneShader & shader, const Frustum &) const override;
@@ -29,15 +29,17 @@ public:
void generateMeshes();
private:
+ void initialise();
void afterChange() override;
struct SurfaceArrayBuffer {
- glVertexArray vertexArray;
glBuffer indicesBuffer;
GLsizei count;
AxisAlignedBoundingBox<GlobalDistance> aabb;
};
+ glVertexArray vertexArray;
+
struct SurfaceKey {
const Surface * surface;
GlobalPosition2D basePosition;
diff --git a/game/water.cpp b/game/water.cpp
index a3c1452..96f35cf 100644
--- a/game/water.cpp
+++ b/game/water.cpp
@@ -1,5 +1,6 @@
#include "water.h"
#include "game/geoData.h"
+#include "gfx/gl/gldebug.h"
#include "gfx/models/texture.h"
#include <algorithm>
#include <cstddef>
@@ -42,6 +43,7 @@ static constexpr GlobalDistance BORDER = TILE_SIZE / 2;
void
Water::generateMeshes()
{
+ glDebugScope _ {0};
// Map out where a water square needs to exist to cover all terrain faces with a low vertex
std::set<GlobalPosition2D> waterPositions;
std::for_each(geoData->vertices_sbegin(), geoData->vertices_end(), [this, &waterPositions](const auto vh) {
diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp
index 88314ae..6a53f52 100644
--- a/gfx/models/mesh.cpp
+++ b/gfx/models/mesh.cpp
@@ -1,7 +1,8 @@
#include "mesh.h"
-MeshBase::MeshBase(GLsizei m_numIndices, GLenum mode, const std::vector<RelativePosition3D> & positions) :
- numIndices {m_numIndices}, mode {mode}, dimensions {positions}
+MeshBase::MeshBase(
+ GLsizei m_numIndices, GLenum mode, const std::vector<RelativePosition3D> & positions, GLsizei vertexStride) :
+ vertexStride {vertexStride}, numIndices {m_numIndices}, mode {mode}, dimensions {positions}
{
}
@@ -31,7 +32,9 @@ MeshBase::Dimensions::extents(const std::span<const RelativePosition3D> position
void
MeshBase::draw() const
{
- glBindVertexArray(vertexArrayObject);
+ glBindVertexArray(*vertexArrayObject);
+ glVertexArrayVertexBuffer(*vertexArrayObject, 0, vertexArrayBuffers[0], 0, vertexStride);
+ glVertexArrayElementBuffer(*vertexArrayObject, vertexArrayBuffers[1]);
glDrawElements(mode, numIndices, GL_UNSIGNED_INT, nullptr);
@@ -42,6 +45,8 @@ void
MeshBase::drawInstanced(GLuint vao, GLsizei count, GLuint base) const
{
glBindVertexArray(vao);
+ glVertexArrayVertexBuffer(vao, 0, vertexArrayBuffers[0], 0, vertexStride);
+ glVertexArrayElementBuffer(vao, vertexArrayBuffers[1]);
glDrawElementsInstancedBaseInstance(mode, numIndices, GL_UNSIGNED_INT, nullptr, count, base);
diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h
index d4dbd68..fa12ae8 100644
--- a/gfx/models/mesh.h
+++ b/gfx/models/mesh.h
@@ -2,13 +2,15 @@
#include "config/types.h"
#include "gfx/gl/glBuffer.h"
-#include "gfx/models/vertex.h"
+#include "gfx/gl/gldebug.h"
#include <gfx/gl/glVertexArray.h>
#include <glad/gl.h>
#include <ranges>
#include <span>
#include <stdTypeDefs.h>
+class Vertex;
+
class MeshBase {
public:
class Dimensions {
@@ -35,10 +37,11 @@ public:
}
protected:
- MeshBase(GLsizei numIndices, GLenum mode, const std::vector<RelativePosition3D> &);
+ MeshBase(GLsizei numIndices, GLenum mode, const std::vector<RelativePosition3D> &, GLsizei vertexStride);
- glVertexArray vertexArrayObject;
+ std::shared_ptr<glVertexArray> vertexArrayObject;
glBuffers<2> vertexArrayBuffers;
+ GLsizei vertexStride;
GLsizei numIndices;
GLenum mode;
Dimensions dimensions;
@@ -50,18 +53,29 @@ public:
MeshBase {static_cast<GLsizei>(indices.size()), mode,
materializeRange(vertices | std::views::transform([](const auto & vertex) {
return static_cast<RelativePosition3D>(vertex.pos);
- }))}
+ })),
+ sizeof(V)}
{
+ glDebugScope _ {0};
vertexArrayBuffers[0].storage(vertices, 0);
vertexArrayBuffers[1].storage(indices, 0);
- configureVAO(vertexArrayObject, 0);
+ if (!(vertexArrayObject = commonVertexArrayObject.lock())) {
+ commonVertexArrayObject = vertexArrayObject = std::make_shared<glVertexArray>();
+ configureVAO(*vertexArrayObject, 0);
+ }
}
auto
configureVAO(glVertexArray & vao, GLuint divisor) const
{
- return vao.configure().addAttribsFor<V>(divisor, vertexArrayBuffers[0]).addIndices(vertexArrayBuffers[1]);
+ glDebugScope _ {0};
+ return vao.configure().addAttribsFor<V>(divisor);
}
+
+protected:
+ static std::weak_ptr<glVertexArray> commonVertexArrayObject;
};
+template<typename T> std::weak_ptr<glVertexArray> MeshT<T>::commonVertexArrayObject;
+
using Mesh = MeshT<Vertex>;