From c403a71564def731f4d3b80d6ff63f08aa3c7ea3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 11 Mar 2026 20:45:05 +0000 Subject: Reuse vertex array objects for common structures with DSA Slashes the number of VAOs required and the amount of setup required. --- game/terrain.cpp | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) (limited to 'game/terrain.cpp') 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(const GLuint divisor) +void +Terrain::initialise() { - return addAttribs(divisor); + glDebugScope _ {0}; + vertexArray.configure().addAttribs( + 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(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(indices.size()); - meshItr->second.aabb = AxisAlignedBoundingBox::fromPoints( + auto & mesh = meshes[surfaceKey]; + mesh.indicesBuffer.data(indices, GL_DYNAMIC_DRAW); + mesh.count = static_cast(indices.size()); + mesh.aabb = AxisAlignedBoundingBox::fromPoints( indices | std::views::transform([this](const auto vertex) { return this->point(VertexHandle {static_cast(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); } } -- cgit v1.3