From bd4a5ef7fc2d753177d9391ea501d55588af1975 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 03:19:55 +0300 Subject: [PATCH] optimize a bit --- src/graphics/render/BlocksRenderer.cpp | 4 +- src/graphics/render/ChunksRenderer.cpp | 89 +++++++++++++------------- src/graphics/render/ChunksRenderer.hpp | 4 +- 3 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 5570de4c..2202931b 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -12,8 +12,6 @@ #include -#include "util/timeutil.hpp" - const glm::vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); BlocksRenderer::BlocksRenderer( @@ -607,7 +605,7 @@ SortingMeshData BlocksRenderer::renderTranslucent( return sortingMesh; } -void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) {; +void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) { this->chunk = chunk; voxelsBuffer->setPosition( chunk->x * CHUNK_W - voxelBufferPadding, 0, diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 7176500b..edbf83f3 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -14,12 +14,9 @@ #include "util/listutil.hpp" #include "settings.hpp" -#include #include #include -#include "util/timeutil.hpp" - static debug::Logger logger("chunks-render"); size_t ChunksRenderer::visibleChunks = 0; @@ -79,9 +76,6 @@ ChunksRenderer::ChunksRenderer( *level->content, cache, settings ); logger.info() << "created " << threadPool.getWorkersCount() << " workers"; - - float buf[1]{}; - sortedMesh = std::make_unique(buf, 0, CHUNK_VATTRS); } ChunksRenderer::~ChunksRenderer() { @@ -137,12 +131,12 @@ void ChunksRenderer::update() { threadPool.update(); } -bool ChunksRenderer::drawChunk( +const Mesh* ChunksRenderer::retrieveChunk( size_t index, const Camera& camera, Shader& shader, bool culling ) { auto chunk = level.chunks->getChunks()[index]; if (chunk == nullptr || !chunk->flags.lighted) { - return false; + return nullptr; } float distance = glm::distance( camera.position, @@ -154,7 +148,7 @@ bool ChunksRenderer::drawChunk( ); auto mesh = getOrRender(chunk, distance < CHUNK_W * 1.5f); if (mesh == nullptr) { - return false; + return nullptr; } if (culling) { glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D); @@ -164,13 +158,9 @@ bool ChunksRenderer::drawChunk( chunk->z * CHUNK_D + CHUNK_D ); - if (!frustum.isBoxVisible(min, max)) return false; + if (!frustum.isBoxVisible(min, max)) return nullptr; } - glm::vec3 coord(chunk->x * CHUNK_W + 0.5f, 0.5f, chunk->z * CHUNK_D + 0.5f); - glm::mat4 model = glm::translate(glm::mat4(1.0f), coord); - shader.uniformMatrix("u_model", model); - mesh->draw(); - return true; + return mesh; } void ChunksRenderer::drawChunks( @@ -207,19 +197,38 @@ void ChunksRenderer::drawChunks( visibleChunks = 0; shader.uniform1i("u_alphaClip", true); - //if (GLEW_ARB_multi_draw_indirect && false) { - // TODO: implement Multi Draw Indirect chunks draw - //} else { - for (size_t i = 0; i < indices.size(); i++) { - visibleChunks += drawChunk(indices[i].index, camera, shader, culling); + + // TODO: minimize draw calls number + for (size_t i = 0; i < indices.size(); i++) { + auto chunk = chunks.getChunks()[indices[i].index]; + auto mesh = retrieveChunk(indices[i].index, camera, shader, culling); + + if (mesh) { + glm::vec3 coord(chunk->x * CHUNK_W + 0.5f, 0.5f, chunk->z * CHUNK_D + 0.5f); + glm::mat4 model = glm::translate(glm::mat4(1.0f), coord); + shader.uniformMatrix("u_model", model); + mesh->draw(); + visibleChunks++; } - //} + } +} + +static inline void write_sorting_mesh_entries( + float* buffer, const std::vector& chunkEntries +) { + for (const auto& entry : chunkEntries) { + const auto& vertexData = entry.vertexData; + std::memcpy( + buffer, + vertexData.data(), + vertexData.size() * sizeof(float) + ); + buffer += vertexData.size(); + } } void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { - timeutil::ScopeLogTimer log(444); - - const int sortInterval = 6; + const int sortInterval = 8; static int frameid = 0; frameid++; @@ -238,26 +247,22 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { continue; } const auto& found = meshes.find(glm::ivec2(chunk->x, chunk->z)); - if (found == meshes.end()) { + if (found == meshes.end() || found->second.sortingMeshData.entries.empty()) { continue; } - glm::vec3 min( - chunk->x * CHUNK_W - CHUNK_W, 0, chunk->z * CHUNK_D - CHUNK_D - ); + glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D); glm::vec3 max( - chunk->x * CHUNK_W + CHUNK_W*2, - CHUNK_H, - chunk->z * CHUNK_D + CHUNK_D*2 + chunk->x * CHUNK_W + CHUNK_W, + chunk->top, + chunk->z * CHUNK_D + CHUNK_D ); if (!frustum.isBoxVisible(min, max)) continue; auto& chunkEntries = found->second.sortingMeshData.entries; - if (chunkEntries.empty()) { - continue; - } else if (chunkEntries.size() == 1) { + if (chunkEntries.size() == 1) { auto& entry = chunkEntries.at(0); if (found->second.sortedMesh == nullptr) { found->second.sortedMesh = std::make_unique( @@ -270,8 +275,9 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { continue; } for (auto& entry : chunkEntries) { - entry.distance = - static_cast(glm::distance2(entry.position, cameraPos)); + entry.distance = static_cast( + glm::distance2(entry.position, cameraPos) + ); } if (found->second.sortedMesh == nullptr || (frameid + chunk->x) % sortInterval == 0) { @@ -280,19 +286,12 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { for (const auto& entry : chunkEntries) { size += entry.vertexData.size(); } + static util::Buffer buffer; if (buffer.size() < size) { buffer = util::Buffer(size); } - size_t offset = 0; - for (const auto& entry : chunkEntries) { - std::memcpy( - (buffer.data() + offset), - entry.vertexData.data(), - entry.vertexData.size() * sizeof(float) - ); - offset += entry.vertexData.size(); - } + write_sorting_mesh_entries(buffer.data(), chunkEntries); found->second.sortedMesh = std::make_unique( buffer.data(), size / CHUNK_VERTEX_SIZE, CHUNK_VATTRS ); diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index 55e3b90e..5317c544 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -50,11 +50,9 @@ class ChunksRenderer { std::unordered_map inwork; std::vector indices; util::ThreadPool, RendererResult> threadPool; - - bool drawChunk( + const Mesh* retrieveChunk( size_t index, const Camera& camera, Shader& shader, bool culling ); - std::unique_ptr sortedMesh; public: ChunksRenderer( const Level* level,