From 88fead6cfcb5c83b86771af7b358dbf1cf689200 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sat, 31 May 2025 14:22:46 +0200 Subject: [PATCH] adding transparent water --- Application/Block.h | 2 +- Application/Chunk.cpp | 182 ++++++++++-------- Application/Chunk.h | 4 + Application/Noise.cpp | 10 +- Application/World.cpp | 2 + ScopEngine/Runtime/Includes/Graphics/Actor.h | 6 +- ScopEngine/Runtime/Includes/Graphics/Scene.h | 10 +- .../Renderer/RenderPasses/ForwardPass.cpp | 36 +++- 8 files changed, 152 insertions(+), 100 deletions(-) diff --git a/Application/Block.h b/Application/Block.h index 362b7af..bc37607 100644 --- a/Application/Block.h +++ b/Application/Block.h @@ -8,11 +8,11 @@ enum class BlockType : std::uint32_t { Air = 0, + Water, Dirt, Stone, Grass, Sand, - Water, Snow, SnowyGrass, Cactus, diff --git a/Application/Chunk.cpp b/Application/Chunk.cpp index 756dc6d..98c3389 100644 --- a/Application/Chunk.cpp +++ b/Application/Chunk.cpp @@ -10,11 +10,11 @@ constexpr Scop::Vec2f SPRITE_UNIT = Scop::Vec2f(SPRITE_SIZE) / Scop::Vec2f(ATLAS constexpr std::array, BlocksCount> BLOCKS_TO_ATLAS = { std::array{ Scop::Vec2ui{ 0, 0 }, Scop::Vec2ui{ 0, 0 }, Scop::Vec2ui{ 0, 0 } }, // Air + std::array{ Scop::Vec2ui{ 1, 1 }, Scop::Vec2ui{ 1, 1 }, Scop::Vec2ui{ 1, 1 } }, // Water std::array{ Scop::Vec2ui{ 0, 0 }, Scop::Vec2ui{ 0, 0 }, Scop::Vec2ui{ 0, 0 } }, // Dirt std::array{ Scop::Vec2ui{ 1, 0 }, Scop::Vec2ui{ 1, 0 }, Scop::Vec2ui{ 1, 0 } }, // Stone std::array{ Scop::Vec2ui{ 2, 0 }, Scop::Vec2ui{ 0, 0 }, Scop::Vec2ui{ 3, 0 } }, // Grass std::array{ Scop::Vec2ui{ 0, 1 }, Scop::Vec2ui{ 0, 1 }, Scop::Vec2ui{ 0, 1 } }, // Sand - std::array{ Scop::Vec2ui{ 1, 1 }, Scop::Vec2ui{ 1, 1 }, Scop::Vec2ui{ 1, 1 } }, // Water std::array{ Scop::Vec2ui{ 2, 1 }, Scop::Vec2ui{ 2, 1 }, Scop::Vec2ui{ 2, 1 } }, // Snow std::array{ Scop::Vec2ui{ 3, 1 }, Scop::Vec2ui{ 3, 1 }, Scop::Vec2ui{ 3, 1 } }, // SnowyGrass std::array{ Scop::Vec2ui{ 0, 2 }, Scop::Vec2ui{ 0, 2 }, Scop::Vec2ui{ 0, 2 } }, // Cactus @@ -56,9 +56,12 @@ void Chunk::GenerateMesh() if(!m_mesh_data.empty()) return; - std::size_t offset = 0; + std::uint32_t mesh_offset = 0; + std::uint32_t water_offset = 0; m_mesh_data.reserve(CHUNK_VOLUME); m_mesh_index_data.reserve(CHUNK_VOLUME * 4); + m_water_mesh_data.reserve(CHUNK_VOLUME); + m_water_mesh_index_data.reserve(CHUNK_VOLUME * 4); for(std::int32_t x = 0; x < CHUNK_SIZE.x; x++) { @@ -70,104 +73,113 @@ void Chunk::GenerateMesh() if(type == BlockType::Air) continue; - if(!GetBlock(Scop::Vec3i(x, y, z + 1))) - { - m_mesh_index_data.push_back(offset); - m_mesh_index_data.push_back(offset + 2); - m_mesh_index_data.push_back(offset + 3); - m_mesh_index_data.push_back(offset); - m_mesh_index_data.push_back(offset + 3); - m_mesh_index_data.push_back(offset + 1); + bool is_water = type == BlockType::Water; + std::vector& mesh_data = (is_water ? m_water_mesh_data : m_mesh_data); + std::vector& index_data = (is_water ? m_water_mesh_index_data : m_mesh_index_data); + std::uint32_t& offset = (is_water ? water_offset : mesh_offset); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[0].position + Scop::Vec3f(x, y, z), BLOCK_MESH[0].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[0].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[1].position + Scop::Vec3f(x, y, z), BLOCK_MESH[1].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[1].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[2].position + Scop::Vec3f(x, y, z), BLOCK_MESH[2].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[2].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[3].position + Scop::Vec3f(x, y, z), BLOCK_MESH[3].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[3].uv))); + Scop::Vec4f color = is_water ? Scop::Vec4f{ 1.0f, 1.0f, 1.0f, 0.8f } : Scop::Vec4f{ 1.0f }; + + std::uint32_t invalid_limit = is_water ? static_cast(BlockType::Air) : static_cast(BlockType::Water); + + if(GetBlock(Scop::Vec3i(x, y, z + 1)) <= invalid_limit) + { + index_data.push_back(offset); + index_data.push_back(offset + 2); + index_data.push_back(offset + 3); + index_data.push_back(offset); + index_data.push_back(offset + 3); + index_data.push_back(offset + 1); + + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[0].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[0].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[0].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[1].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[1].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[1].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[2].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[2].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[2].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[3].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[3].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[3].uv))); offset += 4; } - if(!GetBlock(Scop::Vec3i(x, y, z - 1))) + if(GetBlock(Scop::Vec3i(x, y, z - 1)) <= invalid_limit) { - m_mesh_index_data.push_back(offset + 2); - m_mesh_index_data.push_back(offset + 3); - m_mesh_index_data.push_back(offset + 1); - m_mesh_index_data.push_back(offset + 2); - m_mesh_index_data.push_back(offset + 1); - m_mesh_index_data.push_back(offset); + index_data.push_back(offset + 2); + index_data.push_back(offset + 3); + index_data.push_back(offset + 1); + index_data.push_back(offset + 2); + index_data.push_back(offset + 1); + index_data.push_back(offset); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[4].position + Scop::Vec3f(x, y, z), BLOCK_MESH[4].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[4].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[5].position + Scop::Vec3f(x, y, z), BLOCK_MESH[5].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[5].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[6].position + Scop::Vec3f(x, y, z), BLOCK_MESH[6].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[6].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[7].position + Scop::Vec3f(x, y, z), BLOCK_MESH[7].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[7].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[4].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[4].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[4].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[5].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[5].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[5].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[6].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[6].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[6].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[7].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[7].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[7].uv))); offset += 4; } - if(!GetBlock(Scop::Vec3i(x, y + 1, z))) + if(GetBlock(Scop::Vec3i(x, y + 1, z)) <= invalid_limit) { - m_mesh_index_data.push_back(offset + 1); - m_mesh_index_data.push_back(offset); - m_mesh_index_data.push_back(offset + 2); - m_mesh_index_data.push_back(offset + 1); - m_mesh_index_data.push_back(offset + 2); - m_mesh_index_data.push_back(offset + 3); + index_data.push_back(offset + 1); + index_data.push_back(offset); + index_data.push_back(offset + 2); + index_data.push_back(offset + 1); + index_data.push_back(offset + 2); + index_data.push_back(offset + 3); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[8].position + Scop::Vec3f(x, y, z), BLOCK_MESH[0].normal, GetAtlasOffset(type, Side::Top) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[8].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[9].position + Scop::Vec3f(x, y, z), BLOCK_MESH[9].normal, GetAtlasOffset(type, Side::Top) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[9].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[10].position + Scop::Vec3f(x, y, z), BLOCK_MESH[10].normal, GetAtlasOffset(type, Side::Top) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[10].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[11].position + Scop::Vec3f(x, y, z), BLOCK_MESH[11].normal, GetAtlasOffset(type, Side::Top) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[11].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[8].position + Scop::Vec3f(x, is_water ? static_cast(y) - 0.2f : y, z), color, BLOCK_MESH[0].normal, GetAtlasOffset(type, Side::Top) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[8].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[9].position + Scop::Vec3f(x, is_water ? static_cast(y) - 0.2f : y, z), color, BLOCK_MESH[9].normal, GetAtlasOffset(type, Side::Top) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[9].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[10].position + Scop::Vec3f(x, is_water ? static_cast(y) - 0.2f : y, z), color, BLOCK_MESH[10].normal, GetAtlasOffset(type, Side::Top) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[10].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[11].position + Scop::Vec3f(x, is_water ? static_cast(y) - 0.2f : y, z), color, BLOCK_MESH[11].normal, GetAtlasOffset(type, Side::Top) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[11].uv))); offset += 4; } - if(!GetBlock(Scop::Vec3i(x, y - 1, z))) + if(GetBlock(Scop::Vec3i(x, y - 1, z)) <= invalid_limit) { - m_mesh_index_data.push_back(offset + 3); - m_mesh_index_data.push_back(offset + 1); - m_mesh_index_data.push_back(offset); - m_mesh_index_data.push_back(offset + 3); - m_mesh_index_data.push_back(offset); - m_mesh_index_data.push_back(offset + 2); + index_data.push_back(offset + 3); + index_data.push_back(offset + 1); + index_data.push_back(offset); + index_data.push_back(offset + 3); + index_data.push_back(offset); + index_data.push_back(offset + 2); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[12].position + Scop::Vec3f(x, y, z), BLOCK_MESH[12].normal, GetAtlasOffset(type, Side::Bottom) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[12].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[13].position + Scop::Vec3f(x, y, z), BLOCK_MESH[13].normal, GetAtlasOffset(type, Side::Bottom) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[13].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[14].position + Scop::Vec3f(x, y, z), BLOCK_MESH[14].normal, GetAtlasOffset(type, Side::Bottom) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[14].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[15].position + Scop::Vec3f(x, y, z), BLOCK_MESH[15].normal, GetAtlasOffset(type, Side::Bottom) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[15].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[12].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[12].normal, GetAtlasOffset(type, Side::Bottom) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[12].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[13].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[13].normal, GetAtlasOffset(type, Side::Bottom) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[13].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[14].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[14].normal, GetAtlasOffset(type, Side::Bottom) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[14].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[15].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[15].normal, GetAtlasOffset(type, Side::Bottom) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[15].uv))); offset += 4; } - if(!GetBlock(Scop::Vec3i(x + 1, y, z))) + if(GetBlock(Scop::Vec3i(x + 1, y, z)) <= invalid_limit) { - m_mesh_index_data.push_back(offset + 2); - m_mesh_index_data.push_back(offset + 3); - m_mesh_index_data.push_back(offset + 1); - m_mesh_index_data.push_back(offset + 2); - m_mesh_index_data.push_back(offset + 1); - m_mesh_index_data.push_back(offset); + index_data.push_back(offset + 2); + index_data.push_back(offset + 3); + index_data.push_back(offset + 1); + index_data.push_back(offset + 2); + index_data.push_back(offset + 1); + index_data.push_back(offset); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[16].position + Scop::Vec3f(x, y, z), BLOCK_MESH[16].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[16].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[17].position + Scop::Vec3f(x, y, z), BLOCK_MESH[17].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[17].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[18].position + Scop::Vec3f(x, y, z), BLOCK_MESH[18].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[18].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[19].position + Scop::Vec3f(x, y, z), BLOCK_MESH[19].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[19].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[16].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[16].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[16].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[17].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[17].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[17].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[18].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[18].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[18].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[19].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[19].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[19].uv))); offset += 4; } - if(!GetBlock(Scop::Vec3i(x - 1, y, z))) + if(GetBlock(Scop::Vec3i(x - 1, y, z)) <= invalid_limit) { - m_mesh_index_data.push_back(offset); - m_mesh_index_data.push_back(offset + 2); - m_mesh_index_data.push_back(offset + 3); - m_mesh_index_data.push_back(offset); - m_mesh_index_data.push_back(offset + 3); - m_mesh_index_data.push_back(offset + 1); + index_data.push_back(offset); + index_data.push_back(offset + 2); + index_data.push_back(offset + 3); + index_data.push_back(offset); + index_data.push_back(offset + 3); + index_data.push_back(offset + 1); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[20].position + Scop::Vec3f(x, y, z), BLOCK_MESH[20].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[20].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[21].position + Scop::Vec3f(x, y, z), BLOCK_MESH[21].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[21].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[22].position + Scop::Vec3f(x, y, z), BLOCK_MESH[22].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[22].uv))); - m_mesh_data.push_back(Scop::Vertex(BLOCK_MESH[23].position + Scop::Vec3f(x, y, z), BLOCK_MESH[23].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[23].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[20].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[20].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[20].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[21].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[21].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[21].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[22].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[22].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[22].uv))); + mesh_data.push_back(Scop::Vertex(BLOCK_MESH[23].position + Scop::Vec3f(x, y, z), color, BLOCK_MESH[23].normal, GetAtlasOffset(type, Side::Side) + (Scop::Vec2f(SPRITE_UNIT) * BLOCK_MESH[23].uv))); offset += 4; } @@ -178,16 +190,30 @@ void Chunk::GenerateMesh() void Chunk::UploadMesh() { - if(p_actor || m_mesh_data.empty() || m_mesh_index_data.empty()) - return; - std::shared_ptr mesh = std::make_shared(); - mesh->AddSubMesh({ std::move(m_mesh_data), std::move(m_mesh_index_data) }); + if(!p_actor && !m_mesh_data.empty() && !m_mesh_index_data.empty()) + { + std::shared_ptr mesh = std::make_shared(); + mesh->AddSubMesh({ std::move(m_mesh_data), std::move(m_mesh_index_data) }); - Scop::Actor& actor = m_world.GetScene().CreateActor(mesh); - actor.GetModelRef().SetMaterial(m_world.GetBlockMaterial(), 0); - actor.SetScale(Scop::Vec3f{ 2.0f }); - actor.SetPosition(Scop::Vec3f(m_position.x, 0.0f, m_position.y)); - p_actor = &actor; + Scop::Actor& actor = m_world.GetScene().CreateActor(mesh); + actor.GetModelRef().SetMaterial(m_world.GetBlockMaterial(), 0); + actor.SetScale(Scop::Vec3f{ 2.0f }); + actor.SetPosition(Scop::Vec3f(m_position.x, 0.0f, m_position.y)); + p_actor = &actor; + } + + if(!p_water_actor && !m_water_mesh_data.empty() && !m_water_mesh_index_data.empty()) + { + std::shared_ptr mesh = std::make_shared(); + mesh->AddSubMesh({ std::move(m_water_mesh_data), std::move(m_water_mesh_index_data) }); + + Scop::Actor& actor = m_world.GetScene().CreateActor(mesh); + actor.GetModelRef().SetMaterial(m_world.GetBlockMaterial(), 0); + actor.SetScale(Scop::Vec3f{ 2.0f }); + actor.SetPosition(Scop::Vec3f(m_position.x, 0.0f, m_position.y)); + actor.SetIsOpaque(false); + p_water_actor = &actor; + } } std::uint32_t Chunk::GetBlock(Scop::Vec3i position) const noexcept diff --git a/Application/Chunk.h b/Application/Chunk.h index 8c7ac37..b7533cc 100644 --- a/Application/Chunk.h +++ b/Application/Chunk.h @@ -20,6 +20,7 @@ class Chunk void UploadMesh(); [[nodiscard]] std::uint32_t GetBlock(Scop::Vec3i position) const noexcept; [[nodiscard]] inline Scop::NonOwningPtr GetActor() const noexcept { return p_actor; } + [[nodiscard]] inline Scop::NonOwningPtr GetWaterActor() const noexcept { return p_water_actor; } [[nodiscard]] inline Scop::Vec2i GetPosition() const noexcept { return m_position; } ~Chunk() = default; @@ -27,11 +28,14 @@ class Chunk private: std::vector m_mesh_data; std::vector m_mesh_index_data; + std::vector m_water_mesh_data; + std::vector m_water_mesh_index_data; std::array, CHUNK_SIZE.x * CHUNK_SIZE.z> m_data; Scop::Vec2i m_offset; // In chunks Scop::Vec2i m_position; // In blocks class World& m_world; Scop::NonOwningPtr p_actor = nullptr; + Scop::NonOwningPtr p_water_actor = nullptr; }; #endif diff --git a/Application/Noise.cpp b/Application/Noise.cpp index b3536b7..15f85cf 100644 --- a/Application/Noise.cpp +++ b/Application/Noise.cpp @@ -159,8 +159,8 @@ const int Noise::ApplyPerlin2DParameters(float x, float y) noexcept // Wrapper t float tmp_amp = c_amplitude; float maxValue = 0.0f; - for(int i = 0; i < this->c_octaves; ++i) - { + for(int i = 0; i < this->c_octaves; ++i) + { total += Perlin3D(x * tmp_freq, y * tmp_freq, z * tmp_freq) * tmp_amp; maxValue += tmp_amp; tmp_amp *= c_persistance; @@ -175,9 +175,7 @@ const int Noise::ApplyPerlin2DParameters(float x, float y) noexcept // Wrapper t { std::array data; std::memset(data.data(), static_cast(BlockType::Air), data.size() * sizeof(std::uint32_t)); - - //std::uint32_t height = std::abs(std::sin((float)pos.x / 20.0f) * std::cos((float)pos.y / 20.0f) * 60.0f) + 1; - + const std::uint32_t height = Perlin2D(pos.x, pos.y); for(std::uint32_t y = 0; y < std::min(height, CHUNK_SIZE.y); y++) @@ -198,7 +196,7 @@ const int Noise::ApplyPerlin2DParameters(float x, float y) noexcept // Wrapper t for(std::uint32_t y = 0; y < WATER_LEVEL; y++) { if(data[y] == static_cast(BlockType::Air)) - data[y] = static_cast(BlockType::Sand); + data[y] = static_cast(BlockType::Water); } return data; } diff --git a/Application/World.cpp b/Application/World.cpp index 4ef4e25..cd40eeb 100644 --- a/Application/World.cpp +++ b/Application/World.cpp @@ -92,6 +92,8 @@ void World::UnloadChunks() { if(it->second.GetActor()) m_scene.RemoveActor(*it->second.GetActor()); + if(it->second.GetWaterActor()) + m_scene.RemoveActor(*it->second.GetWaterActor()); it = m_chunks.erase(it); } else diff --git a/ScopEngine/Runtime/Includes/Graphics/Actor.h b/ScopEngine/Runtime/Includes/Graphics/Actor.h index 83c5251..09f5315 100644 --- a/ScopEngine/Runtime/Includes/Graphics/Actor.h +++ b/ScopEngine/Runtime/Includes/Graphics/Actor.h @@ -21,13 +21,12 @@ namespace Scop inline void AttachScript(std::shared_ptr script) { p_script = script; } - inline void SetColor(Vec4f color) noexcept { m_color = color; } inline void SetPosition(Vec3f position) noexcept { m_position = position; } inline void SetScale(Vec3f scale) noexcept { m_scale = scale; } inline void SetOrientation(Quatf orientation) noexcept { m_orientation = orientation; } inline void SetVisibility(bool show) noexcept { m_is_visible = show; } + inline void SetIsOpaque(bool opaque) noexcept { m_is_opaque = opaque; } - [[nodiscard]] inline const Vec4f& GetColor() const noexcept { return m_color; } [[nodiscard]] inline const Vec3f& GetPosition() const noexcept { return m_position; } [[nodiscard]] inline const Vec3f& GetScale() const noexcept { return m_scale; } [[nodiscard]] inline const Quatf& GetOrientation() const noexcept { return m_orientation; } @@ -35,6 +34,7 @@ namespace Scop [[nodiscard]] inline Model& GetModelRef() noexcept { return m_model; } [[nodiscard]] inline std::uint64_t GetUUID() const noexcept { return m_uuid; } [[nodiscard]] inline bool IsVisible() const noexcept { return m_is_visible; } + [[nodiscard]] inline bool IsOpaque() const noexcept { return m_is_opaque; } ~Actor(); @@ -44,12 +44,12 @@ namespace Scop private: Model m_model; Quatf m_orientation = Quatf::Identity(); - Vec4f m_color = Vec4f{ 1.0f, 1.0f, 1.0f, 1.0f }; Vec3f m_position = Vec3f{ 0.0f, 0.0f, 0.0f }; Vec3f m_scale = Vec3f{ 1.0f, 1.0f, 1.0f }; std::shared_ptr p_script; std::uint64_t m_uuid; bool m_is_visible = true; + bool m_is_opaque = true; }; } diff --git a/ScopEngine/Runtime/Includes/Graphics/Scene.h b/ScopEngine/Runtime/Includes/Graphics/Scene.h index 312003a..af85662 100644 --- a/ScopEngine/Runtime/Includes/Graphics/Scene.h +++ b/ScopEngine/Runtime/Includes/Graphics/Scene.h @@ -67,8 +67,8 @@ namespace Scop void SwitchToParent() const noexcept; [[nodiscard]] inline ForwardData& GetForwardData() noexcept { return m_forward; } - [[nodiscard]] inline const std::map& GetActors() const noexcept { return m_actors; } - [[nodiscard]] inline const std::map& GetSprites() const noexcept { return m_sprites; } + [[nodiscard]] inline const std::unordered_map& GetActors() const noexcept { return m_actors; } + [[nodiscard]] inline const std::unordered_map& GetSprites() const noexcept { return m_sprites; } [[nodiscard]] inline const std::string& GetName() const noexcept { return m_name; } [[nodiscard]] inline GraphicPipeline& GetPipeline() noexcept { return m_pipeline; } [[nodiscard]] inline std::shared_ptr GetCamera() const { return m_descriptor.camera; } @@ -91,9 +91,9 @@ namespace Scop DepthImage m_depth; SceneDescriptor m_descriptor; std::shared_ptr p_skybox; - std::map m_actors; - std::map m_sprites; - std::map m_narrators; + std::unordered_map m_actors; + std::unordered_map m_sprites; + std::unordered_map m_narrators; std::vector m_scene_children; std::string m_name; NonOwningPtr p_parent; diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp index 30e4bc0..c8f3fb4 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp @@ -41,12 +41,7 @@ namespace Scop pipeline.Init(pipeline_descriptor); } - VkCommandBuffer cmd = renderer.GetActiveCommandBuffer(); - pipeline.BindPipeline(cmd, 0, {}); - for(const auto& [_, actor] : scene.GetActors()) - { - if(!actor.IsVisible()) - continue; + auto setup_model = [](const Actor& actor) -> ModelData { ModelData model_data; model_data.model_mat = Mat4f::Identity(); model_data.model_mat.SetTranslation(actor.GetPosition() - actor.GetModel().GetCenter()); @@ -54,8 +49,35 @@ namespace Scop model_data.model_mat = Mat4f::Translate(-actor.GetModel().GetCenter()) * Mat4f::Rotate(actor.GetOrientation()) * model_data.model_mat; model_data.normal_mat = model_data.model_mat; model_data.normal_mat.Inverse().Transpose(); + return model_data; + }; + + std::multimap sorted_actors; + VkCommandBuffer cmd = renderer.GetActiveCommandBuffer(); + pipeline.BindPipeline(cmd, 0, {}); + for(auto& [_, actor] : scene.GetActors()) + { + if(!actor.IsVisible()) + continue; + if(actor.IsOpaque()) + { + auto model_data = setup_model(actor); + RenderCore::Get().vkCmdPushConstants(cmd, pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data); + actor.GetModel().Draw(cmd, *data.matrices_set, pipeline, *data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex()); + } + else + { + float distance = Vec3f::Distance(actor.GetPosition(), scene.GetCamera()->GetPosition()); + sorted_actors.emplace(distance, const_cast(actor)); + } + } + for(auto it = sorted_actors.rbegin(); it != sorted_actors.rend(); ++it) + { + if(!it->second.IsVisible()) + continue; + auto model_data = setup_model(it->second); RenderCore::Get().vkCmdPushConstants(cmd, pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data); - actor.GetModel().Draw(cmd, *data.matrices_set, pipeline, *data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex()); + it->second.GetModel().Draw(cmd, *data.matrices_set, pipeline, *data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex()); } pipeline.EndPipeline(cmd); }