From b28bcf052b3bf33cd6bfe46cc09811fd8f397e97 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 09:18:14 +0300 Subject: [PATCH] optimize (part 1) --- src/graphics/core/Mesh.cpp | 7 ++--- src/graphics/render/BlocksRenderer.cpp | 39 ++++++++++++++++++++++++-- src/graphics/render/ChunksRenderer.cpp | 30 +++++++++++++------- src/graphics/render/ChunksRenderer.hpp | 1 + src/graphics/render/commons.hpp | 2 +- 5 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/graphics/core/Mesh.cpp b/src/graphics/core/Mesh.cpp index 78380ae1..c8c114c2 100644 --- a/src/graphics/core/Mesh.cpp +++ b/src/graphics/core/Mesh.cpp @@ -58,10 +58,9 @@ void Mesh::reload(const float* vertexBuffer, size_t vertices, const int* indexBu glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); if (vertexBuffer != nullptr && vertices != 0) { - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, vertexBuffer, GL_STATIC_DRAW); - } - else { - glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, vertexBuffer, GL_STREAM_DRAW); + } else { + glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STREAM_DRAW); } if (indexBuffer != nullptr && indices != 0) { if (ibo == 0) glGenBuffers(1, &ibo); diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index fcba92c3..6a8c8176 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -498,6 +498,9 @@ SortingMeshData BlocksRenderer::renderTranslucent( ) { SortingMeshData sortingMesh {{}}; + AABB aabb {}; + bool aabbInit = false; + size_t totalSize = 0; for (const auto drawGroup : *content.drawGroups) { int begin = beginEnds[drawGroup][0]; if (begin == 0) { @@ -557,21 +560,51 @@ SortingMeshData BlocksRenderer::renderTranslucent( ), util::Buffer(indexSize * VERTEX_SIZE)}; + totalSize += entry.vertexData.size(); + for (int j = 0; j < indexSize; j++) { std::memcpy( entry.vertexData.data() + j * VERTEX_SIZE, vertexBuffer.get() + indexBuffer[j] * VERTEX_SIZE, sizeof(float) * VERTEX_SIZE ); - entry.vertexData[j * VERTEX_SIZE + 0] += chunk->x * CHUNK_W + 0.5f; - entry.vertexData[j * VERTEX_SIZE + 1] += 0.5f; - entry.vertexData[j * VERTEX_SIZE + 2] += chunk->z * CHUNK_D + 0.5f; + float& vx = entry.vertexData[j * VERTEX_SIZE + 0]; + float& vy = entry.vertexData[j * VERTEX_SIZE + 1]; + float& vz = entry.vertexData[j * VERTEX_SIZE + 2]; + + if (!aabbInit) { + aabbInit = true; + aabb.a = aabb.b = {vx, vy, vz}; + } else { + aabb.addPoint(glm::vec3(vx, vy, vz)); + } + vx += chunk->x * CHUNK_W + 0.5f; + vy += 0.5f; + vz += chunk->z * CHUNK_D + 0.5f; } sortingMesh.entries.push_back(std::move(entry)); vertexOffset = 0; indexOffset = indexSize = 0; } } + + // additional powerful optimization + auto size = aabb.size(); + if (glm::abs(size.y) < 0.01f && sortingMesh.entries.size() > 1 && false) { + SortingMeshEntry newEntry { + sortingMesh.entries[0].position, + util::Buffer(totalSize) + }; + size_t offset = 0; + for (const auto& entry : sortingMesh.entries) { + std::memcpy( + newEntry.vertexData.data() + offset, + entry.vertexData.data(), entry.vertexData.size() * sizeof(float) + ); + offset += entry.vertexData.size(); + } + return SortingMeshData {{std::move(newEntry)}}; + } return sortingMesh; } diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index ed313e08..9a508831 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -79,6 +79,10 @@ ChunksRenderer::ChunksRenderer( *level->content, cache, settings ); logger.info() << "created " << threadPool.getWorkersCount() << " workers"; + + const vattr attrs[]{ {3}, {2}, {1}, {0} }; + float buf[]{}; + sortedMesh = std::make_unique(buf, 0, attrs); } ChunksRenderer::~ChunksRenderer() { @@ -210,16 +214,19 @@ void ChunksRenderer::drawChunks( } void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { - const vattr attrs[]{ {3}, {2}, {1}, {0} }; + timeutil::ScopeLogTimer log(444); std::vector entries; + const auto& chunks = level.chunks->getChunks(); + auto pposition = camera.position; size_t size = 0; bool culling = settings.graphics.frustumCulling.get(); - for (size_t i = 0; i < indices.size(); i++) { - auto chunk = level.chunks->getChunks()[indices[i].index]; + + for (const auto& index : indices) { + const auto& chunk = chunks[index.index]; if (chunk == nullptr || !chunk->flags.lighted) { continue; } @@ -238,19 +245,22 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { if (!frustum.isBoxVisible(min, max)) continue; auto& chunkEntries = found->second.sortingMesh.entries; + for (auto& entry : chunkEntries) { - entry.distance = glm::distance2(entry.position, pposition); + entry.distance = static_cast(glm::distance2(entry.position, pposition)); } + std::sort(chunkEntries.begin(), chunkEntries.end()); for (const auto& entry : chunkEntries) { size += entry.vertexData.size(); entries.push_back(&entry); } } - std::sort(entries.begin(), entries.end(), [=](const auto& a, const auto& b) { - return *a < *b; - }); - util::Buffer buffer(size); + static util::Buffer buffer; + + if (buffer.size() < size) { + buffer = util::Buffer(size); + } size_t offset = 0; for (const auto& entry : entries) { std::memcpy( @@ -260,8 +270,8 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { ); offset += entry->vertexData.size(); } - Mesh mesh(buffer.data(), size / 6, attrs); + sortedMesh->reload(buffer.data(), size / 6); shader.uniformMatrix("u_model", glm::mat4(1.0f)); - mesh.draw(); + sortedMesh->draw(); } diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index cd1df2fb..a631ae8a 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -54,6 +54,7 @@ class ChunksRenderer { bool drawChunk( size_t index, const Camera& camera, Shader& shader, bool culling ); + std::unique_ptr sortedMesh; public: ChunksRenderer( const Level* level, diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 3ef8fa26..c4c850e1 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -12,7 +12,7 @@ class Mesh; struct SortingMeshEntry { glm::vec3 position; util::Buffer vertexData; - float distance; + long long distance; inline bool operator<(const SortingMeshEntry& o) const noexcept { return distance > o.distance;