From 5793c52ac6aff52a9730ddcce938672bff8f5f71 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 15 Nov 2024 06:47:03 +0300 Subject: [PATCH 01/22] Revert "remove 'translucent' block property (will be reverted later)" This reverts commit 7aacadc926432da2583b95f6a02af08ee51c2c91. --- res/content/base/blocks/water.json | 3 ++- src/content/ContentLoader.cpp | 1 + src/voxels/Block.cpp | 1 + src/voxels/Block.hpp | 3 +++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/res/content/base/blocks/water.json b/res/content/base/blocks/water.json index 943640e84..f77850447 100644 --- a/res/content/base/blocks/water.json +++ b/res/content/base/blocks/water.json @@ -6,5 +6,6 @@ "sky-light-passing": false, "obstacle": false, "selectable": false, - "replaceable": true + "replaceable": true, + "translucent": true } diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index a801500e3..4414999dd 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -333,6 +333,7 @@ void ContentLoader::loadBlock( root.at("inventory-size").get(def.inventorySize); root.at("tick-interval").get(def.tickInterval); root.at("overlay-texture").get(def.overlayTexture); + root.at("translucent").get(def.translucent); if (root.has("fields")) { def.dataStruct = std::make_unique(); diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index 51d9662b5..6d4ff7613 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -140,6 +140,7 @@ void Block::cloneTo(Block& dst) { dst.inventorySize = inventorySize; dst.tickInterval = tickInterval; dst.overlayTexture = overlayTexture; + dst.translucent = translucent; if (particles) { dst.particles = std::make_unique(*particles); } diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 26b384691..84835534e 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -172,6 +172,9 @@ class Block { /// @brief Turns off block item generation bool hidden = false; + /// @brief Block has semi-transparent texture + bool translucent = false; + /// @brief Set of block physical hitboxes std::vector hitboxes; From 5b6256e0fa93183c1da9371d65877398ef5f6542 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 04:13:00 +0300 Subject: [PATCH 02/22] introduce ChunkMesh --- src/graphics/render/BlocksRenderer.cpp | 154 ++++++++++++++++++++----- src/graphics/render/BlocksRenderer.hpp | 12 +- src/graphics/render/ChunksRenderer.cpp | 14 ++- src/graphics/render/ChunksRenderer.hpp | 5 +- src/graphics/render/commons.hpp | 29 +++++ 5 files changed, 172 insertions(+), 42 deletions(-) create mode 100644 src/graphics/render/commons.hpp diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index bf55ef126..25e8997d5 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -12,6 +12,8 @@ #include +#include "util/timeutil.hpp" + const uint BlocksRenderer::VERTEX_SIZE = 6; const glm::vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); @@ -433,21 +435,9 @@ glm::vec4 BlocksRenderer::pickSoftLight( right, up); } -void BlocksRenderer::render(const voxel* voxels) { - int totalBegin = chunk->bottom * (CHUNK_W * CHUNK_D); - int totalEnd = chunk->top * (CHUNK_W * CHUNK_D); - - int beginEnds[256][2] {}; - for (int i = totalBegin; i < totalEnd; i++) { - const voxel& vox = voxels[i]; - blockid_t id = vox.id; - const auto& def = *blockDefsCache[id]; - - if (beginEnds[def.drawGroup][0] == 0) { - beginEnds[def.drawGroup][0] = i+1; - } - beginEnds[def.drawGroup][1] = i; - } +void BlocksRenderer::render( + const voxel* voxels, int beginEnds[256][2] +) { for (const auto drawGroup : *content.drawGroups) { int begin = beginEnds[drawGroup][0]; if (begin == 0) { @@ -462,13 +452,13 @@ void BlocksRenderer::render(const voxel* voxels) { if (id == 0 || def.drawGroup != drawGroup || state.segment) { continue; } + //if (def.translucent) { + // continue; + //} const UVRegion texfaces[6] { - cache.getRegion(id, 0), - cache.getRegion(id, 1), - cache.getRegion(id, 2), - cache.getRegion(id, 3), - cache.getRegion(id, 4), - cache.getRegion(id, 5) + cache.getRegion(id, 0), cache.getRegion(id, 1), + cache.getRegion(id, 2), cache.getRegion(id, 3), + cache.getRegion(id, 4), cache.getRegion(id, 5) }; int x = i % CHUNK_W; int y = i / (CHUNK_D * CHUNK_W); @@ -503,43 +493,143 @@ void BlocksRenderer::render(const voxel* voxels) { } } +SortingMeshData BlocksRenderer::renderTranslucent( + const voxel* voxels, int beginEnds[256][2] +) { + timeutil::ScopeLogTimer log(555); + SortingMeshData sortingMesh {{}}; + + for (const auto drawGroup : *content.drawGroups) { + int begin = beginEnds[drawGroup][0]; + if (begin == 0) { + continue; + } + int end = beginEnds[drawGroup][1]; + for (int i = begin-1; i <= end; i++) { + const voxel& vox = voxels[i]; + blockid_t id = vox.id; + blockstate state = vox.state; + const auto& def = *blockDefsCache[id]; + if (id == 0 || def.drawGroup != drawGroup || state.segment) { + continue; + } + if (!def.translucent) { + continue; + } + const UVRegion texfaces[6] { + cache.getRegion(id, 0), cache.getRegion(id, 1), + cache.getRegion(id, 2), cache.getRegion(id, 3), + cache.getRegion(id, 4), cache.getRegion(id, 5) + }; + int x = i % CHUNK_W; + int y = i / (CHUNK_D * CHUNK_W); + int z = (i / CHUNK_D) % CHUNK_W; + switch (def.model) { + case BlockModel::block: + blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless, + def.ambientOcclusion); + break; + case BlockModel::xsprite: { + blockXSprite(x, y, z, glm::vec3(1.0f), + texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); + break; + } + case BlockModel::aabb: { + blockAABB({x, y, z}, texfaces, &def, vox.state.rotation, + !def.shadeless, def.ambientOcclusion); + break; + } + case BlockModel::custom: { + blockCustomModel({x, y, z}, &def, vox.state.rotation, + !def.shadeless, def.ambientOcclusion); + break; + } + default: + break; + } + if (vertexOffset == 0) { + continue; + } + SortingMeshEntry entry {glm::vec3( + x + chunk->x * CHUNK_W, y, z + chunk->z * CHUNK_D + ), util::Buffer(indexSize * VERTEX_SIZE)}; + + for (int j = 0; j < indexSize; j++) { + std::memcpy( + entry.vertexData.data(), + vertexBuffer.get() + indexBuffer[j] * VERTEX_SIZE, + sizeof(float) * VERTEX_SIZE + ); + } + sortingMesh.entries.push_back(std::move(entry)); + vertexOffset = 0; + indexOffset = indexSize = 0; + } + } + return sortingMesh; +} + void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) { this->chunk = chunk; voxelsBuffer->setPosition( chunk->x * CHUNK_W - voxelBufferPadding, 0, chunk->z * CHUNK_D - voxelBufferPadding); chunks->getVoxels(voxelsBuffer.get(), settings.graphics.backlight.get()); - overflow = false; - vertexOffset = 0; - indexOffset = indexSize = 0; + if (voxelsBuffer->pickBlockId( chunk->x * CHUNK_W, 0, chunk->z * CHUNK_D ) == BLOCK_VOID) { cancelled = true; return; } - cancelled = false; const voxel* voxels = chunk->voxels; - render(voxels); + + int totalBegin = chunk->bottom * (CHUNK_W * CHUNK_D); + int totalEnd = chunk->top * (CHUNK_W * CHUNK_D); + + int beginEnds[256][2] {}; + for (int i = totalBegin; i < totalEnd; i++) { + const voxel& vox = voxels[i]; + blockid_t id = vox.id; + const auto& def = *blockDefsCache[id]; + + if (beginEnds[def.drawGroup][0] == 0) { + beginEnds[def.drawGroup][0] = i+1; + } + beginEnds[def.drawGroup][1] = i; + } + cancelled = false; + + overflow = false; + vertexOffset = 0; + indexOffset = indexSize = 0; + + sortingMesh = std::move(renderTranslucent(voxels, beginEnds)); + + overflow = false; + vertexOffset = 0; + indexOffset = indexSize = 0; + + render(voxels, beginEnds); } -MeshData BlocksRenderer::createMesh() { +ChunkMeshData BlocksRenderer::createMesh() { const vattr attrs[]{ {3}, {2}, {1}, {0} }; - return MeshData( + return ChunkMeshData{MeshData( util::Buffer(vertexBuffer.get(), vertexOffset), util::Buffer(indexBuffer.get(), indexSize), util::Buffer({{3}, {2}, {1}, {0}}) - ); + ), std::move(sortingMesh)}; } -std::shared_ptr BlocksRenderer::render(const Chunk* chunk, const Chunks* chunks) { +ChunkMesh BlocksRenderer::render(const Chunk* chunk, const Chunks* chunks) { build(chunk, chunks); const vattr attrs[]{ {3}, {2}, {1}, {0} }; size_t vcount = vertexOffset / BlocksRenderer::VERTEX_SIZE; - return std::make_shared( + return ChunkMesh{std::make_shared( vertexBuffer.get(), vcount, indexBuffer.get(), indexSize, attrs - ); + ), std::move(sortingMesh)}; } VoxelsVolume* BlocksRenderer::getVoxelsBuffer() const { diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index 828ddf7d2..cdb207491 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -12,6 +12,7 @@ #include "voxels/VoxelsVolume.hpp" #include "graphics/core/MeshData.hpp" #include "maths/util.hpp" +#include "commons.hpp" class Content; class Mesh; @@ -45,6 +46,8 @@ class BlocksRenderer { util::PseudoRandom randomizer; + SortingMeshData sortingMesh; + void vertex(const glm::vec3& coord, float u, float v, const glm::vec4& light); void index(int a, int b, int c, int d, int e, int f); @@ -115,7 +118,6 @@ class BlocksRenderer { bool isOpenForLight(int x, int y, int z) const; - // Does block allow to see other blocks sides (is it transparent) inline bool isOpen(const glm::ivec3& pos, ubyte group) const { auto id = voxelsBuffer->pickBlockId( @@ -135,7 +137,9 @@ class BlocksRenderer { glm::vec4 pickLight(const glm::ivec3& coord) const; glm::vec4 pickSoftLight(const glm::ivec3& coord, const glm::ivec3& right, const glm::ivec3& up) const; glm::vec4 pickSoftLight(float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up) const; - void render(const voxel* voxels); + + void render(const voxel* voxels, int beginEnds[256][2]); + SortingMeshData renderTranslucent(const voxel* voxels, int beginEnds[256][2]); public: BlocksRenderer( size_t capacity, @@ -146,8 +150,8 @@ class BlocksRenderer { virtual ~BlocksRenderer(); void build(const Chunk* chunk, const Chunks* chunks); - std::shared_ptr render(const Chunk* chunk, const Chunks* chunks); - MeshData createMesh(); + ChunkMesh render(const Chunk* chunk, const Chunks* chunks); + ChunkMeshData createMesh(); VoxelsVolume* getVoxelsBuffer() const; bool isCancelled() const { diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index d0ae56b4d..847163fcf 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -62,7 +62,11 @@ ChunksRenderer::ChunksRenderer( [&](){return std::make_shared(*level, cache, settings);}, [&](RendererResult& result){ if (!result.cancelled) { - meshes[result.key] = std::make_shared(result.meshData); + auto meshData = std::move(result.meshData); + meshes[result.key] = ChunkMesh { + std::make_shared(meshData.mesh), + std::move(meshData.sortingMesh) + }; } inwork.erase(result.key); }, settings.graphics.chunkMaxRenderers.get()) @@ -82,8 +86,10 @@ std::shared_ptr ChunksRenderer::render(const std::shared_ptr& chunk chunk->flags.modified = false; if (important) { auto mesh = renderer->render(chunk.get(), level.chunks.get()); - meshes[glm::ivec2(chunk->x, chunk->z)] = mesh; - return mesh; + meshes[glm::ivec2(chunk->x, chunk->z)] = ChunkMesh { + std::move(mesh.mesh), std::move(mesh.sortingMesh) + }; + return meshes[glm::ivec2(chunk->x, chunk->z)].mesh; } glm::ivec2 key(chunk->x, chunk->z); if (inwork.find(key) != inwork.end()) { @@ -115,7 +121,7 @@ std::shared_ptr ChunksRenderer::getOrRender(const std::shared_ptr& if (chunk->flags.modified) { render(chunk, important); } - return found->second; + return found->second.mesh; } void ChunksRenderer::update() { diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index c08266bb7..e44940eaa 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -10,6 +10,7 @@ #include "voxels/ChunksStorage.hpp" #include "util/ThreadPool.hpp" #include "graphics/core/MeshData.hpp" +#include "commons.hpp" class Mesh; class Chunk; @@ -35,7 +36,7 @@ struct ChunksSortEntry { struct RendererResult { glm::ivec2 key; bool cancelled; - MeshData meshData; + ChunkMeshData meshData; }; class ChunksRenderer { @@ -45,7 +46,7 @@ class ChunksRenderer { const EngineSettings& settings; std::unique_ptr renderer; - std::unordered_map> meshes; + std::unordered_map meshes; std::unordered_map inwork; std::vector indices; util::ThreadPool, RendererResult> threadPool; diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp new file mode 100644 index 000000000..4101f8a8e --- /dev/null +++ b/src/graphics/render/commons.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +#include "graphics/core/MeshData.hpp" +#include "util/Buffer.hpp" + +class Mesh; + +struct SortingMeshEntry { + glm::vec3 position; + util::Buffer vertexData; +}; + +struct SortingMeshData { + std::vector entries; +}; + +struct ChunkMeshData { + MeshData mesh; + SortingMeshData sortingMesh; +}; + +struct ChunkMesh { + std::shared_ptr mesh; + SortingMeshData sortingMesh; +}; From faadfca8c3ec490c196fdb3c15970cb3f4d69710 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 07:34:58 +0300 Subject: [PATCH 03/22] add base:ice block --- res/content/base/blocks/ice.json | 7 +++++++ res/content/base/content.json | 15 ++++++++------- res/content/base/textures/blocks/ice.png | Bin 0 -> 7220 bytes 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 res/content/base/blocks/ice.json create mode 100644 res/content/base/textures/blocks/ice.png diff --git a/res/content/base/blocks/ice.json b/res/content/base/blocks/ice.json new file mode 100644 index 000000000..19d9af12e --- /dev/null +++ b/res/content/base/blocks/ice.json @@ -0,0 +1,7 @@ +{ + "texture": "ice", + "material": "base:glass", + "draw-group": 4, + "light-passing": true, + "translucent": true +} diff --git a/res/content/base/content.json b/res/content/base/content.json index cec825a85..db13bae2b 100644 --- a/res/content/base/content.json +++ b/res/content/base/content.json @@ -1,6 +1,8 @@ { - "items": [ - "bazalt_breaker" + "entities": [ + "drop", + "player", + "falling_block" ], "blocks": [ "dirt", @@ -27,11 +29,10 @@ "lightbulb", "torch", "wooden_door", - "coal_ore" + "coal_ore", + "ice" ], - "entities": [ - "drop", - "player", - "falling_block" + "items": [ + "bazalt_breaker" ] } \ No newline at end of file diff --git a/res/content/base/textures/blocks/ice.png b/res/content/base/textures/blocks/ice.png new file mode 100644 index 0000000000000000000000000000000000000000..36592775c01375a6799eb81ee7ff0a40bc01bc03 GIT binary patch literal 7220 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 yJGo6U-?7Gwz^t=3wtUgfC Date: Sat, 16 Nov 2024 07:41:36 +0300 Subject: [PATCH 04/22] feat: actually working slow prototype --- src/graphics/render/BlocksRenderer.cpp | 26 ++++++----- src/graphics/render/ChunksRenderer.cpp | 60 ++++++++++++++++++++++++++ src/graphics/render/ChunksRenderer.hpp | 2 + src/graphics/render/commons.hpp | 5 +++ 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 25e8997d5..fcba92c3f 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -452,9 +452,9 @@ void BlocksRenderer::render( if (id == 0 || def.drawGroup != drawGroup || state.segment) { continue; } - //if (def.translucent) { - // continue; - //} + if (def.translucent) { + continue; + } const UVRegion texfaces[6] { cache.getRegion(id, 0), cache.getRegion(id, 1), cache.getRegion(id, 2), cache.getRegion(id, 3), @@ -496,7 +496,6 @@ void BlocksRenderer::render( SortingMeshData BlocksRenderer::renderTranslucent( const voxel* voxels, int beginEnds[256][2] ) { - timeutil::ScopeLogTimer log(555); SortingMeshData sortingMesh {{}}; for (const auto drawGroup : *content.drawGroups) { @@ -550,16 +549,23 @@ SortingMeshData BlocksRenderer::renderTranslucent( if (vertexOffset == 0) { continue; } - SortingMeshEntry entry {glm::vec3( - x + chunk->x * CHUNK_W, y, z + chunk->z * CHUNK_D - ), util::Buffer(indexSize * VERTEX_SIZE)}; - + SortingMeshEntry entry { + glm::vec3( + x + chunk->x * CHUNK_W + 0.5f, + y + 0.5f, + z + chunk->z * CHUNK_D + 0.5f + ), + util::Buffer(indexSize * VERTEX_SIZE)}; + for (int j = 0; j < indexSize; j++) { std::memcpy( - entry.vertexData.data(), + 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; } sortingMesh.entries.push_back(std::move(entry)); vertexOffset = 0; @@ -569,7 +575,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 847163fcf..ed313e089 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -18,6 +18,8 @@ #include #include +#include "util/timeutil.hpp" + static debug::Logger logger("chunks-render"); size_t ChunksRenderer::visibleChunks = 0; @@ -204,4 +206,62 @@ void ChunksRenderer::drawChunks( visibleChunks += drawChunk(indices[i].index, camera, shader, culling); } //} + drawSortedMeshes(camera, shader); +} + +void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { + const vattr attrs[]{ {3}, {2}, {1}, {0} }; + + std::vector entries; + + 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]; + if (chunk == nullptr || !chunk->flags.lighted) { + continue; + } + const auto& found = meshes.find(glm::ivec2(chunk->x, chunk->z)); + if (found == meshes.end()) { + continue; + } + + glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D); + glm::vec3 max( + chunk->x * CHUNK_W + CHUNK_W, + chunk->top, + chunk->z * CHUNK_D + CHUNK_D + ); + + if (!frustum.isBoxVisible(min, max)) continue; + + auto& chunkEntries = found->second.sortingMesh.entries; + for (auto& entry : chunkEntries) { + entry.distance = glm::distance2(entry.position, pposition); + } + 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); + size_t offset = 0; + for (const auto& entry : entries) { + std::memcpy( + (buffer.data() + offset), + entry->vertexData.data(), + entry->vertexData.size() * sizeof(float) + ); + offset += entry->vertexData.size(); + } + Mesh mesh(buffer.data(), size / 6, attrs); + + shader.uniformMatrix("u_model", glm::mat4(1.0f)); + mesh.draw(); } diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index e44940eaa..cd1df2fba 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -75,6 +75,8 @@ class ChunksRenderer { ); void drawChunks(const Camera& camera, Shader& shader); + void drawSortedMeshes(const Camera& camera, Shader& shader); + void update(); static size_t visibleChunks; diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 4101f8a8e..3ef8fa267 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -12,6 +12,11 @@ class Mesh; struct SortingMeshEntry { glm::vec3 position; util::Buffer vertexData; + float distance; + + inline bool operator<(const SortingMeshEntry& o) const noexcept { + return distance > o.distance; + } }; struct SortingMeshData { From b28bcf052b3bf33cd6bfe46cc09811fd8f397e97 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 09:18:14 +0300 Subject: [PATCH 05/22] 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 78380ae1b..c8c114c23 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 fcba92c3f..6a8c81765 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 ed313e089..9a5088319 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 cd1df2fba..a631ae8a0 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 3ef8fa267..c4c850e16 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; From 171cbb48d099032d7e78c51a46c374104f96f0d1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 09:30:02 +0300 Subject: [PATCH 06/22] fix blocks selection with semi-transparent blocks --- src/graphics/render/ChunksRenderer.cpp | 5 ++++- src/graphics/render/WorldRenderer.cpp | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 9a5088319..39dbb08db 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -210,11 +210,14 @@ void ChunksRenderer::drawChunks( visibleChunks += drawChunk(indices[i].index, camera, shader, culling); } //} - drawSortedMeshes(camera, shader); } void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { timeutil::ScopeLogTimer log(444); + + const auto& atlas = assets.require("blocks"); + + atlas.getTexture()->bind(); std::vector entries; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 1ad16a628..0593305de 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -164,10 +164,18 @@ void WorldRenderer::renderLevel( particles->render(camera, delta * !pause); auto& shader = assets.require("main"); + auto& linesShader = assets.require("lines"); + setupWorldShader(shader, camera, settings, fogFactor); chunks->drawChunks(camera, shader); + if (hudVisible) { + renderLines(camera, linesShader, ctx); + } + shader.use(); + chunks->drawSortedMeshes(camera, shader); + if (!pause) { scripting::on_frontend_render(); } @@ -326,7 +334,6 @@ void WorldRenderer::draw( ctx, camera, *lineBatch, linesShader, showChunkBorders ); } - renderLines(camera, linesShader, ctx); if (player->currentCamera == player->fpCamera) { renderHands(camera, delta * !pause); } From 2327f0ddf8b5cc0d668a274147a79a5fef63368d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 09:31:33 +0300 Subject: [PATCH 07/22] fix msvc error C2466: cannot allocate an array of constant size 0 --- src/graphics/render/ChunksRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 39dbb08db..1fddfd666 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -81,7 +81,7 @@ ChunksRenderer::ChunksRenderer( logger.info() << "created " << threadPool.getWorkersCount() << " workers"; const vattr attrs[]{ {3}, {2}, {1}, {0} }; - float buf[]{}; + float buf[1]{}; sortedMesh = std::make_unique(buf, 0, attrs); } From 99f159464511592f974b726be65a5eea30157497 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 15:08:25 +0300 Subject: [PATCH 08/22] fix Mesh --- src/graphics/core/Mesh.cpp | 8 ++++---- src/graphics/core/Mesh.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/graphics/core/Mesh.cpp b/src/graphics/core/Mesh.cpp index c8c114c23..e0cc5484a 100644 --- a/src/graphics/core/Mesh.cpp +++ b/src/graphics/core/Mesh.cpp @@ -21,8 +21,8 @@ Mesh::Mesh(const MeshData& data) Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs) : ibo(0), - vertices(vertices), - indices(indices) + vertices(0), + indices(0) { meshesCount++; vertexSize = 0; @@ -74,7 +74,7 @@ void Mesh::reload(const float* vertexBuffer, size_t vertices, const int* indexBu this->indices = indices; } -void Mesh::draw(unsigned int primitive){ +void Mesh::draw(unsigned int primitive) const { drawCalls++; glBindVertexArray(vao); if (ibo != 0) { @@ -86,6 +86,6 @@ void Mesh::draw(unsigned int primitive){ glBindVertexArray(0); } -void Mesh::draw() { +void Mesh::draw() const { draw(GL_TRIANGLES); } diff --git a/src/graphics/core/Mesh.hpp b/src/graphics/core/Mesh.hpp index 87c8e69b4..b36b044d2 100644 --- a/src/graphics/core/Mesh.hpp +++ b/src/graphics/core/Mesh.hpp @@ -28,10 +28,10 @@ class Mesh { /// @brief Draw mesh with specified primitives type /// @param primitive primitives type - void draw(unsigned int primitive); + void draw(unsigned int primitive) const; /// @brief Draw mesh as triangles - void draw(); + void draw() const; /// @brief Total numbers of alive mesh objects static int meshesCount; From 1ff89491e6f85ed04193d62a7878ecf64242e049 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 15:11:05 +0300 Subject: [PATCH 09/22] optimize (part 2) --- src/graphics/render/BlocksRenderer.cpp | 2 +- src/graphics/render/ChunksRenderer.cpp | 69 ++++++++++++++------------ src/graphics/render/commons.hpp | 3 +- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 6a8c81765..aa36ead69 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -590,7 +590,7 @@ SortingMeshData BlocksRenderer::renderTranslucent( // additional powerful optimization auto size = aabb.size(); - if (glm::abs(size.y) < 0.01f && sortingMesh.entries.size() > 1 && false) { + if (glm::abs(size.y) < 0.01f && sortingMesh.entries.size() > 1) { SortingMeshEntry newEntry { sortingMesh.entries[0].position, util::Buffer(totalSize) diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 1fddfd666..fc3b3eb6e 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -49,6 +49,8 @@ class RendererWorker : public util::Worker, RendererResul } }; +const vattr ATTRS[]{ {3}, {2}, {1}, {0} }; + ChunksRenderer::ChunksRenderer( const Level* level, const Assets& assets, @@ -80,9 +82,8 @@ ChunksRenderer::ChunksRenderer( ); logger.info() << "created " << threadPool.getWorkersCount() << " workers"; - const vattr attrs[]{ {3}, {2}, {1}, {0} }; float buf[1]{}; - sortedMesh = std::make_unique(buf, 0, attrs); + sortedMesh = std::make_unique(buf, 0, ATTRS); } ChunksRenderer::~ChunksRenderer() { @@ -93,7 +94,7 @@ std::shared_ptr ChunksRenderer::render(const std::shared_ptr& chunk if (important) { auto mesh = renderer->render(chunk.get(), level.chunks.get()); meshes[glm::ivec2(chunk->x, chunk->z)] = ChunkMesh { - std::move(mesh.mesh), std::move(mesh.sortingMesh) + std::move(mesh.mesh), std::move(mesh.sortingMeshData) }; return meshes[glm::ivec2(chunk->x, chunk->z)].mesh; } @@ -214,19 +215,18 @@ void ChunksRenderer::drawChunks( void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { timeutil::ScopeLogTimer log(444); - + const auto& atlas = assets.require("blocks"); atlas.getTexture()->bind(); - std::vector entries; - const auto& chunks = level.chunks->getChunks(); auto pposition = camera.position; size_t size = 0; bool culling = settings.graphics.frustumCulling.get(); + shader.uniformMatrix("u_model", glm::mat4(1.0f)); for (const auto& index : indices) { const auto& chunk = chunks[index.index]; @@ -238,43 +238,50 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { continue; } - glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D); + glm::vec3 min( + chunk->x * CHUNK_W - CHUNK_W, 0, chunk->z * CHUNK_D - CHUNK_D + ); glm::vec3 max( - chunk->x * CHUNK_W + CHUNK_W, - chunk->top, - chunk->z * CHUNK_D + CHUNK_D + chunk->x * CHUNK_W + CHUNK_W*2, + CHUNK_H, + chunk->z * CHUNK_D + CHUNK_D*2 ); if (!frustum.isBoxVisible(min, max)) continue; - auto& chunkEntries = found->second.sortingMesh.entries; + auto& chunkEntries = found->second.sortingMeshData.entries; for (auto& entry : chunkEntries) { entry.distance = static_cast(glm::distance2(entry.position, pposition)); } + + if (chunkEntries.size() == 1) { + auto& entry = chunkEntries.at(0); + if (found->second.planesMesh == nullptr) { + found->second.planesMesh = std::make_shared( + entry.vertexData.data(), entry.vertexData.size() / 6, ATTRS + ); + } + found->second.planesMesh->draw(); + continue; + } + std::sort(chunkEntries.begin(), chunkEntries.end()); + size_t size = 0; for (const auto& entry : chunkEntries) { size += entry.vertexData.size(); - entries.push_back(&entry); } + util::Buffer 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(); + } + sortedMesh->reload(buffer.data(), size / 6); + sortedMesh->draw(); } - - static util::Buffer buffer; - - if (buffer.size() < size) { - buffer = util::Buffer(size); - } - size_t offset = 0; - for (const auto& entry : entries) { - std::memcpy( - (buffer.data() + offset), - entry->vertexData.data(), - entry->vertexData.size() * sizeof(float) - ); - offset += entry->vertexData.size(); - } - sortedMesh->reload(buffer.data(), size / 6); - - shader.uniformMatrix("u_model", glm::mat4(1.0f)); - sortedMesh->draw(); } diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index c4c850e16..fe6330129 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -30,5 +30,6 @@ struct ChunkMeshData { struct ChunkMesh { std::shared_ptr mesh; - SortingMeshData sortingMesh; + SortingMeshData sortingMeshData; + std::shared_ptr planesMesh = nullptr; }; From 7bdeba982b29fc166873e1c1202ad80116806fbc Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 15:24:46 +0300 Subject: [PATCH 10/22] optimize (part 3) --- src/graphics/render/ChunksRenderer.cpp | 45 ++++++++++++++++---------- src/graphics/render/commons.hpp | 2 +- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index fc3b3eb6e..02929c256 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -257,31 +257,42 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { if (chunkEntries.size() == 1) { auto& entry = chunkEntries.at(0); - if (found->second.planesMesh == nullptr) { - found->second.planesMesh = std::make_shared( + if (found->second.sortedMesh == nullptr) { + found->second.sortedMesh = std::make_shared( entry.vertexData.data(), entry.vertexData.size() / 6, ATTRS ); } - found->second.planesMesh->draw(); + found->second.sortedMesh->draw(); continue; } - std::sort(chunkEntries.begin(), chunkEntries.end()); - size_t size = 0; - for (const auto& entry : chunkEntries) { - size += entry.vertexData.size(); + if (chunkEntries.empty()) { + continue; } - util::Buffer buffer(size); - size_t offset = 0; - for (const auto& entry : chunkEntries) { - std::memcpy( - (buffer.data() + offset), - entry.vertexData.data(), - entry.vertexData.size() * sizeof(float) + + if (found->second.sortedMesh == nullptr) { + std::sort(chunkEntries.begin(), chunkEntries.end()); + size_t size = 0; + 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(); + } + found->second.sortedMesh = std::make_shared( + buffer.data(), size / 6, ATTRS ); - offset += entry.vertexData.size(); } - sortedMesh->reload(buffer.data(), size / 6); - sortedMesh->draw(); + found->second.sortedMesh->draw(); } } diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index fe6330129..1bff70f54 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -31,5 +31,5 @@ struct ChunkMeshData { struct ChunkMesh { std::shared_ptr mesh; SortingMeshData sortingMeshData; - std::shared_ptr planesMesh = nullptr; + std::shared_ptr sortedMesh = nullptr; }; From 399943b253e5ae70a20c347d98c30e6d2acc24e9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 15:37:30 +0300 Subject: [PATCH 11/22] fix --- src/graphics/render/ChunksRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 02929c256..ba3405488 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -270,7 +270,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { continue; } - if (found->second.sortedMesh == nullptr) { + if (found->second.sortedMesh == nullptr || true) { std::sort(chunkEntries.begin(), chunkEntries.end()); size_t size = 0; for (const auto& entry : chunkEntries) { From ebc890bdd62a3ca1a66c66e79a303fc64ae6424a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 15:49:53 +0300 Subject: [PATCH 12/22] optimize (part 4) & format ChunkRenderer --- src/graphics/render/ChunksRenderer.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index ba3405488..2c1534b28 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -50,6 +50,7 @@ class RendererWorker : public util::Worker, RendererResul }; const vattr ATTRS[]{ {3}, {2}, {1}, {0} }; +inline constexpr int VERTEX_SIZE = 6; ChunksRenderer::ChunksRenderer( const Level* level, @@ -89,7 +90,9 @@ ChunksRenderer::ChunksRenderer( ChunksRenderer::~ChunksRenderer() { } -std::shared_ptr ChunksRenderer::render(const std::shared_ptr& chunk, bool important) { +std::shared_ptr ChunksRenderer::render( + const std::shared_ptr& chunk, bool important +) { chunk->flags.modified = false; if (important) { auto mesh = renderer->render(chunk.get(), level.chunks.get()); @@ -120,7 +123,9 @@ void ChunksRenderer::clear() { threadPool.clearQueue(); } -std::shared_ptr ChunksRenderer::getOrRender(const std::shared_ptr& chunk, bool important) { +std::shared_ptr ChunksRenderer::getOrRender( + const std::shared_ptr& chunk, bool important +) { auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); if (found == meshes.end()) { return render(chunk, important); @@ -216,6 +221,10 @@ void ChunksRenderer::drawChunks( void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { timeutil::ScopeLogTimer log(444); + const int sortInterval = 6; + static int frameid = 0; + frameid++; + const auto& atlas = assets.require("blocks"); atlas.getTexture()->bind(); @@ -252,14 +261,17 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { auto& chunkEntries = found->second.sortingMeshData.entries; for (auto& entry : chunkEntries) { - entry.distance = static_cast(glm::distance2(entry.position, pposition)); + entry.distance = + static_cast(glm::distance2(entry.position, pposition)); } if (chunkEntries.size() == 1) { auto& entry = chunkEntries.at(0); if (found->second.sortedMesh == nullptr) { found->second.sortedMesh = std::make_shared( - entry.vertexData.data(), entry.vertexData.size() / 6, ATTRS + entry.vertexData.data(), + entry.vertexData.size() / VERTEX_SIZE, + ATTRS ); } found->second.sortedMesh->draw(); @@ -270,7 +282,8 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { continue; } - if (found->second.sortedMesh == nullptr || true) { + if (found->second.sortedMesh == nullptr || + (frameid + chunk->x) % sortInterval == 0) { std::sort(chunkEntries.begin(), chunkEntries.end()); size_t size = 0; for (const auto& entry : chunkEntries) { @@ -290,7 +303,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { offset += entry.vertexData.size(); } found->second.sortedMesh = std::make_shared( - buffer.data(), size / 6, ATTRS + buffer.data(), size / VERTEX_SIZE, ATTRS ); } found->second.sortedMesh->draw(); From 71788e4eb9d35db01a30bb21c1532dd3be63cffc Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 16:04:00 +0300 Subject: [PATCH 13/22] remove unnecessary shared_ptrs from ChunksRenderer and ChunkMesh --- src/graphics/render/BlocksRenderer.cpp | 2 +- src/graphics/render/ChunksRenderer.cpp | 40 +++++++++++--------------- src/graphics/render/ChunksRenderer.hpp | 4 +-- src/graphics/render/commons.hpp | 4 +-- 4 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index aa36ead69..04622e46a 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -666,7 +666,7 @@ ChunkMesh BlocksRenderer::render(const Chunk* chunk, const Chunks* chunks) { const vattr attrs[]{ {3}, {2}, {1}, {0} }; size_t vcount = vertexOffset / BlocksRenderer::VERTEX_SIZE; - return ChunkMesh{std::make_shared( + return ChunkMesh{std::make_unique( vertexBuffer.get(), vcount, indexBuffer.get(), indexSize, attrs ), std::move(sortingMesh)}; } diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 2c1534b28..7ef3ea68c 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -69,7 +69,7 @@ ChunksRenderer::ChunksRenderer( if (!result.cancelled) { auto meshData = std::move(result.meshData); meshes[result.key] = ChunkMesh { - std::make_shared(meshData.mesh), + std::make_unique(meshData.mesh), std::move(meshData.sortingMesh) }; } @@ -90,7 +90,7 @@ ChunksRenderer::ChunksRenderer( ChunksRenderer::~ChunksRenderer() { } -std::shared_ptr ChunksRenderer::render( +const Mesh* ChunksRenderer::render( const std::shared_ptr& chunk, bool important ) { chunk->flags.modified = false; @@ -99,7 +99,7 @@ std::shared_ptr ChunksRenderer::render( meshes[glm::ivec2(chunk->x, chunk->z)] = ChunkMesh { std::move(mesh.mesh), std::move(mesh.sortingMeshData) }; - return meshes[glm::ivec2(chunk->x, chunk->z)].mesh; + return meshes[glm::ivec2(chunk->x, chunk->z)].mesh.get(); } glm::ivec2 key(chunk->x, chunk->z); if (inwork.find(key) != inwork.end()) { @@ -123,7 +123,7 @@ void ChunksRenderer::clear() { threadPool.clearQueue(); } -std::shared_ptr ChunksRenderer::getOrRender( +const Mesh* ChunksRenderer::getOrRender( const std::shared_ptr& chunk, bool important ) { auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); @@ -133,7 +133,7 @@ std::shared_ptr ChunksRenderer::getOrRender( if (chunk->flags.modified) { render(chunk, important); } - return found->second.mesh; + return found->second.mesh.get(); } void ChunksRenderer::update() { @@ -225,16 +225,12 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { static int frameid = 0; frameid++; + bool culling = settings.graphics.frustumCulling.get(); + const auto& chunks = level.chunks->getChunks(); + const auto& cameraPos = camera.position; const auto& atlas = assets.require("blocks"); atlas.getTexture()->bind(); - - const auto& chunks = level.chunks->getChunks(); - - auto pposition = camera.position; - - size_t size = 0; - bool culling = settings.graphics.frustumCulling.get(); shader.uniformMatrix("u_model", glm::mat4(1.0f)); for (const auto& index : indices) { @@ -259,16 +255,13 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { if (!frustum.isBoxVisible(min, max)) continue; auto& chunkEntries = found->second.sortingMeshData.entries; - - for (auto& entry : chunkEntries) { - entry.distance = - static_cast(glm::distance2(entry.position, pposition)); - } - if (chunkEntries.size() == 1) { + if (chunkEntries.empty()) { + continue; + } else if (chunkEntries.size() == 1) { auto& entry = chunkEntries.at(0); if (found->second.sortedMesh == nullptr) { - found->second.sortedMesh = std::make_shared( + found->second.sortedMesh = std::make_unique( entry.vertexData.data(), entry.vertexData.size() / VERTEX_SIZE, ATTRS @@ -277,11 +270,10 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { found->second.sortedMesh->draw(); continue; } - - if (chunkEntries.empty()) { - continue; + for (auto& entry : chunkEntries) { + entry.distance = + static_cast(glm::distance2(entry.position, cameraPos)); } - if (found->second.sortedMesh == nullptr || (frameid + chunk->x) % sortInterval == 0) { std::sort(chunkEntries.begin(), chunkEntries.end()); @@ -302,7 +294,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { ); offset += entry.vertexData.size(); } - found->second.sortedMesh = std::make_shared( + found->second.sortedMesh = std::make_unique( buffer.data(), size / VERTEX_SIZE, ATTRS ); } diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index a631ae8a0..55e3b90ee 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -65,13 +65,13 @@ class ChunksRenderer { ); virtual ~ChunksRenderer(); - std::shared_ptr render( + const Mesh* render( const std::shared_ptr& chunk, bool important ); void unload(const Chunk* chunk); void clear(); - std::shared_ptr getOrRender( + const Mesh* getOrRender( const std::shared_ptr& chunk, bool important ); void drawChunks(const Camera& camera, Shader& shader); diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 1bff70f54..5cd926314 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -29,7 +29,7 @@ struct ChunkMeshData { }; struct ChunkMesh { - std::shared_ptr mesh; + std::unique_ptr mesh; SortingMeshData sortingMeshData; - std::shared_ptr sortedMesh = nullptr; + std::unique_ptr sortedMesh = nullptr; }; From 608eb60514aa4345c8581cd124bb591c10fe9274 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 16 Nov 2024 16:13:18 +0300 Subject: [PATCH 14/22] add 'u_alphaClip' to the blocks shader --- res/shaders/main.glslf | 4 ++-- src/graphics/render/ChunksRenderer.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/res/shaders/main.glslf b/res/shaders/main.glslf index 4c1cb0141..7db1a544d 100644 --- a/res/shaders/main.glslf +++ b/res/shaders/main.glslf @@ -9,14 +9,14 @@ uniform samplerCube u_cubemap; uniform vec3 u_fogColor; uniform float u_fogFactor; uniform float u_fogCurve; +uniform bool u_alphaClip; void main() { vec3 fogColor = texture(u_cubemap, a_dir).rgb; vec4 tex_color = texture(u_texture0, a_texCoord); float depth = (a_distance/256.0); float alpha = a_color.a * tex_color.a; - // anyway it's any alpha-test alternative required - if (alpha < 0.3f) + if (u_alphaClip && alpha < 0.9f) discard; f_color = mix(a_color * tex_color, vec4(fogColor,1.0), min(1.0, pow(depth*u_fogFactor, u_fogCurve))); diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 7ef3ea68c..e52cd3eb8 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -209,6 +209,7 @@ void ChunksRenderer::drawChunks( bool culling = settings.graphics.frustumCulling.get(); visibleChunks = 0; + shader.uniform1i("u_alphaClip", true); //if (GLEW_ARB_multi_draw_indirect && false) { // TODO: implement Multi Draw Indirect chunks draw //} else { @@ -232,6 +233,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { atlas.getTexture()->bind(); shader.uniformMatrix("u_model", glm::mat4(1.0f)); + shader.uniform1i("u_alphaClip", false); for (const auto& index : indices) { const auto& chunk = chunks[index.index]; From 65287b327326709f0d48edbff2b244aefd68ab04 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 00:54:10 +0300 Subject: [PATCH 15/22] move chunk vertex attributes info to commons.hpp --- src/graphics/render/BlocksRenderer.cpp | 45 +++++++++++++------------- src/graphics/render/BlocksRenderer.hpp | 1 - src/graphics/render/ChunksRenderer.cpp | 11 +++---- src/graphics/render/commons.hpp | 5 +++ 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 04622e46a..8b041b581 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -14,7 +14,6 @@ #include "util/timeutil.hpp" -const uint BlocksRenderer::VERTEX_SIZE = 6; const glm::vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); BlocksRenderer::BlocksRenderer( @@ -23,7 +22,7 @@ BlocksRenderer::BlocksRenderer( const ContentGfxCache& cache, const EngineSettings& settings ) : content(content), - vertexBuffer(std::make_unique(capacity * VERTEX_SIZE)), + vertexBuffer(std::make_unique(capacity * CHUNK_VERTEX_SIZE)), indexBuffer(std::make_unique(capacity)), vertexOffset(0), indexOffset(0), @@ -87,7 +86,7 @@ void BlocksRenderer::face( const glm::vec4(&lights)[4], const glm::vec4& tint ) { - if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { + if (vertexOffset + CHUNK_VERTEX_SIZE * 4 > capacity) { overflow = true; return; } @@ -127,7 +126,7 @@ void BlocksRenderer::faceAO( const UVRegion& region, bool lights ) { - if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { + if (vertexOffset + CHUNK_VERTEX_SIZE * 4 > capacity) { overflow = true; return; } @@ -165,7 +164,7 @@ void BlocksRenderer::face( glm::vec4 tint, bool lights ) { - if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { + if (vertexOffset + CHUNK_VERTEX_SIZE * 4 > capacity) { overflow = true; return; } @@ -290,7 +289,7 @@ void BlocksRenderer::blockCustomModel( const auto& model = cache.getModel(block->rt.id); for (const auto& mesh : model.meshes) { - if (vertexOffset + BlocksRenderer::VERTEX_SIZE * mesh.vertices.size() > capacity) { + if (vertexOffset + CHUNK_VERTEX_SIZE * mesh.vertices.size() > capacity) { overflow = true; return; } @@ -558,19 +557,19 @@ SortingMeshData BlocksRenderer::renderTranslucent( y + 0.5f, z + chunk->z * CHUNK_D + 0.5f ), - util::Buffer(indexSize * VERTEX_SIZE)}; + util::Buffer(indexSize * CHUNK_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.data() + j * CHUNK_VERTEX_SIZE, + vertexBuffer.get() + indexBuffer[j] * CHUNK_VERTEX_SIZE, + sizeof(float) * CHUNK_VERTEX_SIZE ); - float& vx = entry.vertexData[j * VERTEX_SIZE + 0]; - float& vy = entry.vertexData[j * VERTEX_SIZE + 1]; - float& vz = entry.vertexData[j * VERTEX_SIZE + 2]; + float& vx = entry.vertexData[j * CHUNK_VERTEX_SIZE + 0]; + float& vy = entry.vertexData[j * CHUNK_VERTEX_SIZE + 1]; + float& vz = entry.vertexData[j * CHUNK_VERTEX_SIZE + 2]; if (!aabbInit) { aabbInit = true; @@ -653,21 +652,23 @@ void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) {; } ChunkMeshData BlocksRenderer::createMesh() { - const vattr attrs[]{ {3}, {2}, {1}, {0} }; - return ChunkMeshData{MeshData( - util::Buffer(vertexBuffer.get(), vertexOffset), - util::Buffer(indexBuffer.get(), indexSize), - util::Buffer({{3}, {2}, {1}, {0}}) - ), std::move(sortingMesh)}; + return ChunkMeshData { + MeshData( + util::Buffer(vertexBuffer.get(), vertexOffset), + util::Buffer(indexBuffer.get(), indexSize), + util::Buffer( + CHUNK_VATTRS, sizeof(CHUNK_VATTRS) / sizeof(vattr) + ) + ), + std::move(sortingMesh)}; } ChunkMesh BlocksRenderer::render(const Chunk* chunk, const Chunks* chunks) { build(chunk, chunks); - const vattr attrs[]{ {3}, {2}, {1}, {0} }; - size_t vcount = vertexOffset / BlocksRenderer::VERTEX_SIZE; + size_t vcount = vertexOffset / CHUNK_VERTEX_SIZE; return ChunkMesh{std::make_unique( - vertexBuffer.get(), vcount, indexBuffer.get(), indexSize, attrs + vertexBuffer.get(), vcount, indexBuffer.get(), indexSize, CHUNK_VATTRS ), std::move(sortingMesh)}; } diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index cdb207491..c0e0086e0 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -27,7 +27,6 @@ struct UVRegion; class BlocksRenderer { static const glm::vec3 SUN_VECTOR; - static const uint VERTEX_SIZE; const Content& content; std::unique_ptr vertexBuffer; std::unique_ptr indexBuffer; diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index e52cd3eb8..7176500b8 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -49,9 +49,6 @@ class RendererWorker : public util::Worker, RendererResul } }; -const vattr ATTRS[]{ {3}, {2}, {1}, {0} }; -inline constexpr int VERTEX_SIZE = 6; - ChunksRenderer::ChunksRenderer( const Level* level, const Assets& assets, @@ -84,7 +81,7 @@ ChunksRenderer::ChunksRenderer( logger.info() << "created " << threadPool.getWorkersCount() << " workers"; float buf[1]{}; - sortedMesh = std::make_unique(buf, 0, ATTRS); + sortedMesh = std::make_unique(buf, 0, CHUNK_VATTRS); } ChunksRenderer::~ChunksRenderer() { @@ -265,8 +262,8 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { if (found->second.sortedMesh == nullptr) { found->second.sortedMesh = std::make_unique( entry.vertexData.data(), - entry.vertexData.size() / VERTEX_SIZE, - ATTRS + entry.vertexData.size() / CHUNK_VERTEX_SIZE, + CHUNK_VATTRS ); } found->second.sortedMesh->draw(); @@ -297,7 +294,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { offset += entry.vertexData.size(); } found->second.sortedMesh = std::make_unique( - buffer.data(), size / VERTEX_SIZE, ATTRS + buffer.data(), size / CHUNK_VERTEX_SIZE, CHUNK_VATTRS ); } found->second.sortedMesh->draw(); diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 5cd926314..b6d180035 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -7,6 +7,11 @@ #include "graphics/core/MeshData.hpp" #include "util/Buffer.hpp" +/// @brief Chunk mesh vertex attributes +inline const vattr CHUNK_VATTRS[]{ {3}, {2}, {1}, {0} }; +/// @brief Chunk mesh vertex size divided by sizeof(float) +inline constexpr int CHUNK_VERTEX_SIZE = 6; + class Mesh; struct SortingMeshEntry { From 5240fe62263242fe5b0a154f9708a702848a6274 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 01:00:27 +0300 Subject: [PATCH 16/22] rename vattr to VertexAttribute --- src/graphics/core/Batch2D.cpp | 2 +- src/graphics/core/Batch3D.cpp | 2 +- src/graphics/core/LineBatch.cpp | 2 +- src/graphics/core/Mesh.cpp | 4 ++-- src/graphics/core/Mesh.hpp | 4 ++-- src/graphics/core/MeshData.hpp | 6 +++--- src/graphics/core/PostProcessing.cpp | 2 +- src/graphics/render/BlocksRenderer.cpp | 4 ++-- src/graphics/render/MainBatch.cpp | 2 +- src/graphics/render/Skybox.cpp | 2 +- src/graphics/render/commons.hpp | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/graphics/core/Batch2D.cpp b/src/graphics/core/Batch2D.cpp index 13b485862..c4c67db29 100644 --- a/src/graphics/core/Batch2D.cpp +++ b/src/graphics/core/Batch2D.cpp @@ -11,7 +11,7 @@ inline constexpr uint B2D_VERTEX_SIZE = 8; Batch2D::Batch2D(size_t capacity) : capacity(capacity), color(1.0f){ - const vattr attrs[] = { + const VertexAttribute attrs[] = { {2}, {2}, {4}, {0} }; diff --git a/src/graphics/core/Batch3D.cpp b/src/graphics/core/Batch3D.cpp index 1770fc21d..a81f4ffb8 100644 --- a/src/graphics/core/Batch3D.cpp +++ b/src/graphics/core/Batch3D.cpp @@ -12,7 +12,7 @@ inline constexpr uint B3D_VERTEX_SIZE = 9; Batch3D::Batch3D(size_t capacity) : capacity(capacity) { - const vattr attrs[] = { + const VertexAttribute attrs[] = { {3}, {2}, {4}, {0} }; diff --git a/src/graphics/core/LineBatch.cpp b/src/graphics/core/LineBatch.cpp index dd3f8067b..aed8a2496 100644 --- a/src/graphics/core/LineBatch.cpp +++ b/src/graphics/core/LineBatch.cpp @@ -6,7 +6,7 @@ inline constexpr uint LB_VERTEX_SIZE = (3+4); LineBatch::LineBatch(size_t capacity) : capacity(capacity) { - const vattr attrs[] = { {3},{4}, {0} }; + const VertexAttribute attrs[] = { {3},{4}, {0} }; buffer = std::make_unique(capacity * LB_VERTEX_SIZE * 2); mesh = std::make_unique(buffer.get(), 0, attrs); index = 0; diff --git a/src/graphics/core/Mesh.cpp b/src/graphics/core/Mesh.cpp index e0cc5484a..e8cffe6ff 100644 --- a/src/graphics/core/Mesh.cpp +++ b/src/graphics/core/Mesh.cpp @@ -4,7 +4,7 @@ int Mesh::meshesCount = 0; int Mesh::drawCalls = 0; -inline size_t calc_vertex_size(const vattr* attrs) { +inline size_t calc_vertex_size(const VertexAttribute* attrs) { size_t vertexSize = 0; for (int i = 0; attrs[i].size; i++) { vertexSize += attrs[i].size; @@ -19,7 +19,7 @@ Mesh::Mesh(const MeshData& data) data.indices.size(), data.attrs.data()) {} -Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs) : +Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const VertexAttribute* attrs) : ibo(0), vertices(0), indices(0) diff --git a/src/graphics/core/Mesh.hpp b/src/graphics/core/Mesh.hpp index b36b044d2..482c82bfc 100644 --- a/src/graphics/core/Mesh.hpp +++ b/src/graphics/core/Mesh.hpp @@ -14,8 +14,8 @@ class Mesh { size_t vertexSize; public: Mesh(const MeshData& data); - Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs); - Mesh(const float* vertexBuffer, size_t vertices, const vattr* attrs) : + Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const VertexAttribute* attrs); + Mesh(const float* vertexBuffer, size_t vertices, const VertexAttribute* attrs) : Mesh(vertexBuffer, vertices, nullptr, 0, attrs) {}; ~Mesh(); diff --git a/src/graphics/core/MeshData.hpp b/src/graphics/core/MeshData.hpp index 62b329037..392201197 100644 --- a/src/graphics/core/MeshData.hpp +++ b/src/graphics/core/MeshData.hpp @@ -6,7 +6,7 @@ #include "util/Buffer.hpp" /// @brief Vertex attribute info -struct vattr { +struct VertexAttribute { ubyte size; }; @@ -14,7 +14,7 @@ struct vattr { struct MeshData { util::Buffer vertices; util::Buffer indices; - util::Buffer attrs; + util::Buffer attrs; MeshData() = default; @@ -24,7 +24,7 @@ struct MeshData { MeshData( util::Buffer vertices, util::Buffer indices, - util::Buffer attrs + util::Buffer attrs ) : vertices(std::move(vertices)), indices(std::move(indices)), attrs(std::move(attrs)) {} diff --git a/src/graphics/core/PostProcessing.cpp b/src/graphics/core/PostProcessing.cpp index 7352c3b55..3478ca08f 100644 --- a/src/graphics/core/PostProcessing.cpp +++ b/src/graphics/core/PostProcessing.cpp @@ -14,7 +14,7 @@ PostProcessing::PostProcessing() { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f }; - vattr attrs[] {{2}, {0}}; + VertexAttribute attrs[] {{2}, {0}}; quadMesh = std::make_unique(vertices, 6, attrs); } diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 8b041b581..5570de4cc 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -656,8 +656,8 @@ ChunkMeshData BlocksRenderer::createMesh() { MeshData( util::Buffer(vertexBuffer.get(), vertexOffset), util::Buffer(indexBuffer.get(), indexSize), - util::Buffer( - CHUNK_VATTRS, sizeof(CHUNK_VATTRS) / sizeof(vattr) + util::Buffer( + CHUNK_VATTRS, sizeof(CHUNK_VATTRS) / sizeof(VertexAttribute) ) ), std::move(sortingMesh)}; diff --git a/src/graphics/render/MainBatch.cpp b/src/graphics/render/MainBatch.cpp index 1cbb6c420..e3a87db70 100644 --- a/src/graphics/render/MainBatch.cpp +++ b/src/graphics/render/MainBatch.cpp @@ -6,7 +6,7 @@ #include "voxels/Chunks.hpp" #include "voxels/Chunk.hpp" -static const vattr attrs[] = { +static const VertexAttribute attrs[] = { {3}, {2}, {3}, {1}, {0} }; diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index e96e894ac..af3a15870 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -39,7 +39,7 @@ Skybox::Skybox(uint size, Shader& shader) -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f }; - vattr attrs[] {{2}, {0}}; + VertexAttribute attrs[] {{2}, {0}}; mesh = std::make_unique(vertices, 6, attrs); sprites.push_back(skysprite { diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index b6d180035..79b773932 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -8,7 +8,7 @@ #include "util/Buffer.hpp" /// @brief Chunk mesh vertex attributes -inline const vattr CHUNK_VATTRS[]{ {3}, {2}, {1}, {0} }; +inline const VertexAttribute CHUNK_VATTRS[]{ {3}, {2}, {1}, {0} }; /// @brief Chunk mesh vertex size divided by sizeof(float) inline constexpr int CHUNK_VERTEX_SIZE = 6; From bd4a5ef7fc2d753177d9391ea501d55588af1975 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 03:19:55 +0300 Subject: [PATCH 17/22] 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 5570de4cc..2202931b0 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 7176500b8..edbf83f3c 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++; } - //} + } } -void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { - timeutil::ScopeLogTimer log(444); +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(); + } +} - const int sortInterval = 6; +void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { + 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 55e3b90ee..5317c5448 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, From 3c94061fd33bbaa50ee9d5ef3c2777c4ae7f3bff Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 04:01:02 +0300 Subject: [PATCH 18/22] update ice texture --- res/content/base/textures/blocks/ice.png | Bin 7220 -> 7429 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/res/content/base/textures/blocks/ice.png b/res/content/base/textures/blocks/ice.png index 36592775c01375a6799eb81ee7ff0a40bc01bc03..707ee89ae82e4f4c612a9cd504c28fd073aea062 100644 GIT binary patch delta 2554 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 From 5f71522653d3bbcf7ffcf638ad5c16bfc8280cd8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 04:31:07 +0300 Subject: [PATCH 19/22] extend that one optimization --- src/graphics/render/BlocksRenderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 2202931b0..cb590bcb4 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -587,7 +587,8 @@ SortingMeshData BlocksRenderer::renderTranslucent( // additional powerful optimization auto size = aabb.size(); - if (glm::abs(size.y) < 0.01f && sortingMesh.entries.size() > 1) { + if ((size.y < 0.01f || size.x < 0.01f || size.z < 0.01f) && + sortingMesh.entries.size() > 1) { SortingMeshEntry newEntry { sortingMesh.entries[0].position, util::Buffer(totalSize) From 71d18ae3a99140e5c2b76df3a8365e5ee9277aa8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 04:58:15 +0300 Subject: [PATCH 20/22] minor refactor --- src/constants.hpp | 8 +++++--- src/graphics/render/ChunksRenderer.cpp | 9 ++++----- src/graphics/render/ChunksRenderer.hpp | 5 +++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/constants.hpp b/src/constants.hpp index 12e12c758..84d8b22c1 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -35,9 +35,6 @@ inline constexpr int CHUNK_D = 16; inline constexpr uint VOXEL_USER_BITS = 8; inline constexpr uint VOXEL_USER_BITS_OFFSET = sizeof(blockstate_t)*8-VOXEL_USER_BITS; -/// @brief pixel size of an item inventory icon -inline constexpr int ITEM_ICON_SIZE = 48; - /// @brief chunk volume (count of voxels per Chunk) inline constexpr int CHUNK_VOL = (CHUNK_W * CHUNK_H * CHUNK_D); @@ -53,6 +50,11 @@ inline constexpr uint vox_index(uint x, uint y, uint z, uint w=CHUNK_W, uint d=C return (y * d + z) * w + x; } +/// @brief pixel size of an item inventory icon +inline constexpr int ITEM_ICON_SIZE = 48; + +inline constexpr int TRANSLUCENT_BLOCKS_SORT_INTERVAL = 8; + inline const std::string SHADERS_FOLDER = "shaders"; inline const std::string TEXTURES_FOLDER = "textures"; inline const std::string FONTS_FOLDER = "fonts"; diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index edbf83f3c..d3686a860 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -14,9 +14,6 @@ #include "util/listutil.hpp" #include "settings.hpp" -#include -#include - static debug::Logger logger("chunks-render"); size_t ChunksRenderer::visibleChunks = 0; @@ -204,7 +201,9 @@ void ChunksRenderer::drawChunks( 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::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(); @@ -228,7 +227,7 @@ static inline void write_sorting_mesh_entries( } void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { - const int sortInterval = 8; + const int sortInterval = TRANSLUCENT_BLOCKS_SORT_INTERVAL; static int frameid = 0; frameid++; diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index 5317c5448..859bca9eb 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -4,10 +4,12 @@ #include #include #include + #include +#define GLM_ENABLE_EXPERIMENTAL +#include #include "voxels/Block.hpp" -#include "voxels/ChunksStorage.hpp" #include "util/ThreadPool.hpp" #include "graphics/core/MeshData.hpp" #include "commons.hpp" @@ -17,7 +19,6 @@ class Chunk; class Level; class Camera; class Shader; -class Chunks; class Assets; class Frustum; class BlocksRenderer; From 0a33970a7ad4e3389dcc2a25a97edd4c7eef9550 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 05:19:39 +0300 Subject: [PATCH 21/22] fix base:glass visibility --- res/content/base/blocks/glass.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/content/base/blocks/glass.json b/res/content/base/blocks/glass.json index 902a2cf15..9bd4f0214 100644 --- a/res/content/base/blocks/glass.json +++ b/res/content/base/blocks/glass.json @@ -3,5 +3,6 @@ "material": "base:glass", "draw-group": 2, "light-passing": true, - "sky-light-passing": true + "sky-light-passing": true, + "translucent": true } From eaa5150d3edbb4dacb72afccc4c8d6396ff0cbd0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 17 Nov 2024 05:23:50 +0300 Subject: [PATCH 22/22] update doc/*/block-properties.md --- doc/en/block-properties.md | 6 ++++++ doc/ru/block-properties.md | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/doc/en/block-properties.md b/doc/en/block-properties.md index cef58a9ab..18c068caa 100644 --- a/doc/en/block-properties.md +++ b/doc/en/block-properties.md @@ -39,6 +39,12 @@ Block model type from list: Integer specifying number of block draw group (render order). Used for semi-transparent blocks. +### *translucent* + +Enables translucency support in block textures (examples: water, ice). +Should only be used when needed, as it impacts performance. +Not required for full transparency (grass, flowers). + ### *rotation* Rotation profile (set of available block rotations and behaviour of placing block rotation) from list: diff --git a/doc/ru/block-properties.md b/doc/ru/block-properties.md index 62ef8ec43..79b08da25 100644 --- a/doc/ru/block-properties.md +++ b/doc/ru/block-properties.md @@ -40,6 +40,12 @@ Целое число определяющее номер группы отрисовки данного блока. Актуально для полупрозрачных блоков - решает проблемы невидимых сторон блоков за этим блоком. +### Полупрозрачность - *translucent* + +Включает поддержку полупрозрачности в текстурах блока (примеры: вода, лёд). +Следует использовать только при надобности, так как влияет на производительность. +Не требуется для полной прозрачности (трава, цветы). + ### Вращение - *rotation* Профиль вращения (набор положений, в которые можно установить блок) из списка: