From 6d6313cd1036f10bc58b3ceb6f03f2523b52ca69 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 20 Jun 2024 19:45:19 +0300 Subject: [PATCH 01/17] add ModelBatch --- src/graphics/core/Batch3D.cpp | 2 + src/graphics/core/Batch3D.hpp | 2 +- src/graphics/render/ModelBatch.cpp | 103 ++++++++++++++++++++++++++ src/graphics/render/ModelBatch.hpp | 84 +++++++++++++++++++++ src/graphics/render/Skybox.cpp | 1 + src/graphics/render/WorldRenderer.cpp | 8 +- src/graphics/render/WorldRenderer.hpp | 2 + 7 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 src/graphics/render/ModelBatch.cpp create mode 100644 src/graphics/render/ModelBatch.hpp diff --git a/src/graphics/core/Batch3D.cpp b/src/graphics/core/Batch3D.cpp index 7481ec6f9..68e59c789 100644 --- a/src/graphics/core/Batch3D.cpp +++ b/src/graphics/core/Batch3D.cpp @@ -5,7 +5,9 @@ #include #include "../../typedefs.hpp" +#include "../../maths/UVRegion.hpp" +/// xyz, uv, rgba inline constexpr uint B3D_VERTEX_SIZE = 9; Batch3D::Batch3D(size_t capacity) diff --git a/src/graphics/core/Batch3D.hpp b/src/graphics/core/Batch3D.hpp index 6ff42caad..61ef2eb03 100644 --- a/src/graphics/core/Batch3D.hpp +++ b/src/graphics/core/Batch3D.hpp @@ -1,7 +1,6 @@ #ifndef GRAPHICS_CORE_BATCH3D_HPP_ #define GRAPHICS_CORE_BATCH3D_HPP_ -#include "../../maths/UVRegion.hpp" #include "../../typedefs.hpp" #include @@ -10,6 +9,7 @@ class Mesh; class Texture; +struct UVRegion; class Batch3D { std::unique_ptr buffer; diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp new file mode 100644 index 000000000..9d0337901 --- /dev/null +++ b/src/graphics/render/ModelBatch.cpp @@ -0,0 +1,103 @@ +#include "ModelBatch.hpp" + +#include "../core/Mesh.hpp" +#include "../core/Texture.hpp" +#include "../../window/Window.hpp" + +#include +#include +#include + +/// xyz, uv, compressed rgba +inline constexpr uint VERTEX_SIZE = 6; + +static const vattr attrs[] = { + {3}, {2}, {1}, {0} +}; + +static glm::vec3 SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); +inline constexpr glm::vec3 X(1, 0, 0); +inline constexpr glm::vec3 Y(0, 1, 0); +inline constexpr glm::vec3 Z(0, 0, 1); + +ModelBatch::ModelBatch(size_t capacity) + : buffer(std::make_unique(capacity * VERTEX_SIZE)), + capacity(capacity), + index(0), + mesh(std::make_unique(buffer.get(), 0, attrs)), + combined(1.0f) +{ + ubyte pixels[] = { + 255, 255, 255, 255, + }; + blank = std::make_unique(pixels, 1, 1, ImageFormat::rgba8888); +} + +ModelBatch::~ModelBatch() { +} + +void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { + float time = static_cast(Window::time()); + pushMatrix(glm::translate(glm::mat4(1.0f), pos)); + pushMatrix(glm::rotate(glm::mat4(1.0f), time, glm::vec3(0,1,0))); + pushMatrix(glm::translate(glm::mat4(1.0f), glm::vec3(0, glm::sin(time*2), 0))); + box({}, size); + popMatrix(); + popMatrix(); + popMatrix(); +} + +void ModelBatch::box(glm::vec3 pos, glm::vec3 size) { + plane(pos+Z, X*size, Y*size, Z); + plane(pos-Z, -X*size, Y*size, -Z); + + plane(pos+Y, X*size, -Z*size, Y); + plane(pos-Y, X*size, Z*size, -Y); + + plane(pos+X, -Z*size, Y*size, X); + plane(pos-X, Z*size, Y*size, -X); +} + +void ModelBatch::flush() { + if (index == 0) { + return; + } + blank->bind(); + mesh->reload(buffer.get(), index / VERTEX_SIZE); + mesh->draw(); + index = 0; +} + +void ModelBatch::pushMatrix(glm::mat4 matrix) { + matrices.push_back(combined); + combined = matrix * combined; + + decomposed = {}; + glm::quat rotation; + glm::decompose( + combined, + decomposed.scale, + rotation, + decomposed.translation, + decomposed.skew, + decomposed.perspective + ); + decomposed.rotation = glm::toMat3(rotation); +} + +void ModelBatch::popMatrix() { + combined = matrices[matrices.size()-1]; + matrices.erase(matrices.end()-1); + + decomposed = {}; + glm::quat rotation; + glm::decompose( + combined, + decomposed.scale, + rotation, + decomposed.translation, + decomposed.skew, + decomposed.perspective + ); + decomposed.rotation = glm::toMat3(rotation); +} diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp new file mode 100644 index 000000000..848a84d3e --- /dev/null +++ b/src/graphics/render/ModelBatch.hpp @@ -0,0 +1,84 @@ +#ifndef GRAPHICS_RENDER_MODEL_BATCH_HPP_ +#define GRAPHICS_RENDER_MODEL_BATCH_HPP_ + +#include +#include +#include + +class Mesh; +class Texture; + +struct DecomposedMat4 { + glm::vec3 scale; + glm::mat3 rotation; + glm::vec3 translation; + glm::vec3 skew; + glm::vec4 perspective; +}; +#include +class ModelBatch { + std::unique_ptr buffer; + size_t capacity; + size_t index; + + std::unique_ptr mesh; + std::unique_ptr blank; + + glm::mat4 combined; + std::vector matrices; + + DecomposedMat4 decomposed {}; + + inline void vertex( + glm::vec3 pos, glm::vec2 uv, glm::vec4 color + ) { + float* buffer = this->buffer.get(); + pos = combined * glm::vec4(pos, 1.0f); + buffer[index++] = pos.x; + buffer[index++] = pos.y; + buffer[index++] = pos.z; + buffer[index++] = uv.x; + buffer[index++] = uv.y; + + union { + float floating; + uint32_t integer; + } compressed; + + compressed.integer = (static_cast(color.r * 255) & 0xff) << 24; + compressed.integer |= (static_cast(color.g * 255) & 0xff) << 16; + compressed.integer |= (static_cast(color.b * 255) & 0xff) << 8; + compressed.integer |= (static_cast(color.a * 255) & 0xff); + + buffer[index++] = compressed.floating; + } + + inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm) { + norm = decomposed.rotation * norm; + glm::vec4 color {norm.x, norm.y, norm.z, 0.0f}; + color.r = glm::max(0.0f, color.r); + color.g = glm::max(0.0f, color.g); + color.b = glm::max(0.0f, color.b); + + vertex(pos-right-up, {0,0}, color); + vertex(pos+right-up, {1,0}, color); + vertex(pos+right+up, {1,1}, color); + + vertex(pos-right-up, {0,0}, color); + vertex(pos+right+up, {1,1}, color); + vertex(pos-right+up, {0,1}, color); + } +public: + ModelBatch(size_t capacity); + ~ModelBatch(); + + void pushMatrix(glm::mat4 matrix); + void popMatrix(); + + void box(glm::vec3 pos, glm::vec3 size); + + void test(glm::vec3 pos, glm::vec3 size); + void flush(); +}; + +#endif // GRAPHICS_RENDER_MODEL_BATCH_HPP_ diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index c98406da8..65b255a9b 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -9,6 +9,7 @@ #include "../../graphics/core/DrawContext.hpp" #include "../../window/Window.hpp" #include "../../window/Camera.hpp" +#include "../../maths/UVRegion.hpp" #include #include diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 795e4c0d9..fe49d8bc4 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -1,6 +1,7 @@ #include "WorldRenderer.hpp" #include "ChunksRenderer.hpp" +#include "ModelBatch.hpp" #include "Skybox.hpp" #include "../../assets/Assets.hpp" @@ -47,7 +48,8 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl level(frontend->getLevel()), player(player), frustumCulling(std::make_unique()), - lineBatch(std::make_unique()) + lineBatch(std::make_unique()), + modelBatch(std::make_unique(1000)) { renderer = std::make_unique( level, @@ -191,6 +193,10 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); + shader->uniformMatrix("u_model", glm::mat4(1.0f)); + modelBatch->test(glm::vec3(0, 68, 0), glm::vec3(1.0f)); + modelBatch->flush(); + skybox->unbind(); } diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index 27d1a5694..2f3517e14 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -23,6 +23,7 @@ class LevelFrontend; class Skybox; class PostProcessing; class DrawContext; +class ModelBatch; struct EngineSettings; class WorldRenderer { @@ -34,6 +35,7 @@ class WorldRenderer { std::unique_ptr renderer; std::unique_ptr skybox; std::unique_ptr batch3d; + std::unique_ptr modelBatch; bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling); void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); From 3d2deaf36911761d64e518fda8a17beb82b93872 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 20 Jun 2024 20:15:03 +0300 Subject: [PATCH 02/17] add ModelBatch pseudo-lights --- src/graphics/render/ModelBatch.cpp | 12 ++++++++---- src/graphics/render/ModelBatch.hpp | 9 +++++++-- src/graphics/render/WorldRenderer.cpp | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 9d0337901..e1362bb58 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -4,6 +4,7 @@ #include "../core/Texture.hpp" #include "../../window/Window.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include @@ -15,7 +16,6 @@ static const vattr attrs[] = { {3}, {2}, {1}, {0} }; -static glm::vec3 SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); inline constexpr glm::vec3 X(1, 0, 0); inline constexpr glm::vec3 Y(0, 1, 0); inline constexpr glm::vec3 Z(0, 0, 1); @@ -39,12 +39,16 @@ ModelBatch::~ModelBatch() { void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { float time = static_cast(Window::time()); pushMatrix(glm::translate(glm::mat4(1.0f), pos)); - pushMatrix(glm::rotate(glm::mat4(1.0f), time, glm::vec3(0,1,0))); + pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*7*0.1f), glm::vec3(0,1,0))); + pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*11*0.1f), glm::vec3(1,0,0))); + pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*17*0.1f), glm::vec3(0,0,1))); pushMatrix(glm::translate(glm::mat4(1.0f), glm::vec3(0, glm::sin(time*2), 0))); box({}, size); popMatrix(); popMatrix(); popMatrix(); + popMatrix(); + popMatrix(); } void ModelBatch::box(glm::vec3 pos, glm::vec3 size) { @@ -62,7 +66,7 @@ void ModelBatch::flush() { if (index == 0) { return; } - blank->bind(); + // blank->bind(); mesh->reload(buffer.get(), index / VERTEX_SIZE); mesh->draw(); index = 0; @@ -70,7 +74,7 @@ void ModelBatch::flush() { void ModelBatch::pushMatrix(glm::mat4 matrix) { matrices.push_back(combined); - combined = matrix * combined; + combined = combined * matrix; decomposed = {}; glm::quat rotation; diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index 848a84d3e..26b8c601c 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -15,7 +15,7 @@ struct DecomposedMat4 { glm::vec3 skew; glm::vec4 perspective; }; -#include + class ModelBatch { std::unique_ptr buffer; size_t capacity; @@ -29,6 +29,8 @@ class ModelBatch { DecomposedMat4 decomposed {}; + static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; + inline void vertex( glm::vec3 pos, glm::vec2 uv, glm::vec4 color ) { @@ -55,7 +57,10 @@ class ModelBatch { inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm) { norm = decomposed.rotation * norm; - glm::vec4 color {norm.x, norm.y, norm.z, 0.0f}; + float d = glm::dot(norm, SUN_VECTOR); + d = 0.8f + d * 0.2f; + + glm::vec4 color {d, d, d, 0.0f}; color.r = glm::max(0.0f, color.r); color.g = glm::max(0.0f, color.g); color.b = glm::max(0.0f, color.b); diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index fe49d8bc4..4b678dcb7 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -193,6 +193,7 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); + assets->getTexture("gui/menubg")->bind(); shader->uniformMatrix("u_model", glm::mat4(1.0f)); modelBatch->test(glm::vec3(0, 68, 0), glm::vec3(1.0f)); modelBatch->flush(); From 3235740333e36a96f8cc8618a28865405f89aa5b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 20 Jun 2024 21:18:40 +0300 Subject: [PATCH 03/17] add actual lights --- src/graphics/render/ModelBatch.cpp | 28 +++++++++++++++++++-------- src/graphics/render/ModelBatch.hpp | 13 +++++++------ src/graphics/render/WorldRenderer.cpp | 12 ++++++------ 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index e1362bb58..060776f7e 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -3,6 +3,8 @@ #include "../core/Mesh.hpp" #include "../core/Texture.hpp" #include "../../window/Window.hpp" +#include "../../voxels/Chunks.hpp" +#include "../../lighting/Lightmap.hpp" #define GLM_ENABLE_EXPERIMENTAL #include @@ -20,12 +22,13 @@ inline constexpr glm::vec3 X(1, 0, 0); inline constexpr glm::vec3 Y(0, 1, 0); inline constexpr glm::vec3 Z(0, 0, 1); -ModelBatch::ModelBatch(size_t capacity) +ModelBatch::ModelBatch(size_t capacity, Chunks* chunks) : buffer(std::make_unique(capacity * VERTEX_SIZE)), capacity(capacity), index(0), mesh(std::make_unique(buffer.get(), 0, attrs)), - combined(1.0f) + combined(1.0f), + chunks(chunks) { ubyte pixels[] = { 255, 255, 255, 255, @@ -52,14 +55,23 @@ void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { } void ModelBatch::box(glm::vec3 pos, glm::vec3 size) { - plane(pos+Z, X*size, Y*size, Z); - plane(pos-Z, -X*size, Y*size, -Z); + glm::vec3 gpos = combined * glm::vec4(pos, 1.0f); + light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); + glm::vec4 lights ( + Lightmap::extract(light, 0) / 15.0f, + Lightmap::extract(light, 1) / 15.0f, + Lightmap::extract(light, 2) / 15.0f, + Lightmap::extract(light, 3) / 15.0f + ); + + plane(pos+Z, X*size, Y*size, Z, lights); + plane(pos-Z, -X*size, Y*size, -Z, lights); - plane(pos+Y, X*size, -Z*size, Y); - plane(pos-Y, X*size, Z*size, -Y); + plane(pos+Y, X*size, -Z*size, Y, lights); + plane(pos-Y, X*size, Z*size, -Y, lights); - plane(pos+X, -Z*size, Y*size, X); - plane(pos-X, Z*size, Y*size, -X); + plane(pos+X, -Z*size, Y*size, X, lights); + plane(pos-X, Z*size, Y*size, -X, lights); } void ModelBatch::flush() { diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index 26b8c601c..b90811ea5 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -7,6 +7,7 @@ class Mesh; class Texture; +class Chunks; struct DecomposedMat4 { glm::vec3 scale; @@ -29,6 +30,8 @@ class ModelBatch { DecomposedMat4 decomposed {}; + Chunks* chunks; + static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; inline void vertex( @@ -55,15 +58,13 @@ class ModelBatch { buffer[index++] = compressed.floating; } - inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm) { + inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm, glm::vec4 light) { norm = decomposed.rotation * norm; float d = glm::dot(norm, SUN_VECTOR); d = 0.8f + d * 0.2f; - glm::vec4 color {d, d, d, 0.0f}; - color.r = glm::max(0.0f, color.r); - color.g = glm::max(0.0f, color.g); - color.b = glm::max(0.0f, color.b); + glm::vec4 color {d, d, d, 1.0f}; + color *= light; vertex(pos-right-up, {0,0}, color); vertex(pos+right-up, {1,0}, color); @@ -74,7 +75,7 @@ class ModelBatch { vertex(pos-right+up, {0,1}, color); } public: - ModelBatch(size_t capacity); + ModelBatch(size_t capacity, Chunks* chunks); ~ModelBatch(); void pushMatrix(glm::mat4 matrix); diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 4b678dcb7..f27e9040a 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -44,12 +44,12 @@ bool WorldRenderer::showChunkBorders = false; WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* player) - : engine(engine), - level(frontend->getLevel()), - player(player), - frustumCulling(std::make_unique()), - lineBatch(std::make_unique()), - modelBatch(std::make_unique(1000)) + : engine(engine), + level(frontend->getLevel()), + player(player), + frustumCulling(std::make_unique()), + lineBatch(std::make_unique()), + modelBatch(std::make_unique(1000, level->chunks.get())) { renderer = std::make_unique( level, From 57a0377b36c52adf1dc67169233d351afc56c679 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 20 Jun 2024 21:54:06 +0300 Subject: [PATCH 04/17] fix ModelBatch overflow --- src/graphics/render/ModelBatch.cpp | 41 ++++++++++++++------------- src/graphics/render/ModelBatch.hpp | 26 ++++++----------- src/graphics/render/WorldRenderer.cpp | 2 +- 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 060776f7e..c7cfbd2c5 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -22,6 +22,14 @@ inline constexpr glm::vec3 X(1, 0, 0); inline constexpr glm::vec3 Y(0, 1, 0); inline constexpr glm::vec3 Z(0, 0, 1); +struct DecomposedMat4 { + glm::vec3 scale; + glm::mat3 rotation; + glm::vec3 translation; + glm::vec3 skew; + glm::vec4 perspective; +}; + ModelBatch::ModelBatch(size_t capacity, Chunks* chunks) : buffer(std::make_unique(capacity * VERTEX_SIZE)), capacity(capacity), @@ -55,6 +63,9 @@ void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { } void ModelBatch::box(glm::vec3 pos, glm::vec3 size) { + if (index + 36 < capacity*VERTEX_SIZE) { + flush(); + } glm::vec3 gpos = combined * glm::vec4(pos, 1.0f); light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); glm::vec4 lights ( @@ -84,36 +95,28 @@ void ModelBatch::flush() { index = 0; } -void ModelBatch::pushMatrix(glm::mat4 matrix) { - matrices.push_back(combined); - combined = combined * matrix; - - decomposed = {}; +static glm::mat4 extract_rotation(glm::mat4 matrix) { + DecomposedMat4 decomposed = {}; glm::quat rotation; glm::decompose( - combined, + matrix, decomposed.scale, rotation, decomposed.translation, decomposed.skew, decomposed.perspective ); - decomposed.rotation = glm::toMat3(rotation); + return glm::toMat3(rotation); +} + +void ModelBatch::pushMatrix(glm::mat4 matrix) { + matrices.push_back(combined); + combined = combined * matrix; + rotation = extract_rotation(combined); } void ModelBatch::popMatrix() { combined = matrices[matrices.size()-1]; matrices.erase(matrices.end()-1); - - decomposed = {}; - glm::quat rotation; - glm::decompose( - combined, - decomposed.scale, - rotation, - decomposed.translation, - decomposed.skew, - decomposed.perspective - ); - decomposed.rotation = glm::toMat3(rotation); + rotation = extract_rotation(combined); } diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index b90811ea5..8c791fc0d 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -9,14 +9,6 @@ class Mesh; class Texture; class Chunks; -struct DecomposedMat4 { - glm::vec3 scale; - glm::mat3 rotation; - glm::vec3 translation; - glm::vec3 skew; - glm::vec4 perspective; -}; - class ModelBatch { std::unique_ptr buffer; size_t capacity; @@ -27,15 +19,14 @@ class ModelBatch { glm::mat4 combined; std::vector matrices; - - DecomposedMat4 decomposed {}; + glm::mat3 rotation; Chunks* chunks; static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; inline void vertex( - glm::vec3 pos, glm::vec2 uv, glm::vec4 color + glm::vec3 pos, glm::vec2 uv, glm::vec4 light ) { float* buffer = this->buffer.get(); pos = combined * glm::vec4(pos, 1.0f); @@ -50,21 +41,20 @@ class ModelBatch { uint32_t integer; } compressed; - compressed.integer = (static_cast(color.r * 255) & 0xff) << 24; - compressed.integer |= (static_cast(color.g * 255) & 0xff) << 16; - compressed.integer |= (static_cast(color.b * 255) & 0xff) << 8; - compressed.integer |= (static_cast(color.a * 255) & 0xff); + compressed.integer = (static_cast(light.r * 255) & 0xff) << 24; + compressed.integer |= (static_cast(light.g * 255) & 0xff) << 16; + compressed.integer |= (static_cast(light.b * 255) & 0xff) << 8; + compressed.integer |= (static_cast(light.a * 255) & 0xff); buffer[index++] = compressed.floating; } inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm, glm::vec4 light) { - norm = decomposed.rotation * norm; + norm = rotation * norm; float d = glm::dot(norm, SUN_VECTOR); d = 0.8f + d * 0.2f; - glm::vec4 color {d, d, d, 1.0f}; - color *= light; + auto color = light * d; vertex(pos-right-up, {0,0}, color); vertex(pos+right-up, {1,0}, color); diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index f27e9040a..e9d1a7032 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -195,7 +195,7 @@ void WorldRenderer::renderLevel( assets->getTexture("gui/menubg")->bind(); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - modelBatch->test(glm::vec3(0, 68, 0), glm::vec3(1.0f)); + modelBatch->test(glm::vec3(0, 88, 0), glm::vec3(1.0f)); modelBatch->flush(); skybox->unbind(); From a53dc7e0dfee3025eb748203aeee1bb6c14f3a4f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 20 Jun 2024 22:16:09 +0300 Subject: [PATCH 05/17] fix ModelBatch.box(...) --- src/graphics/render/ModelBatch.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index c7cfbd2c5..6ade352a8 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -55,6 +55,7 @@ void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*17*0.1f), glm::vec3(0,0,1))); pushMatrix(glm::translate(glm::mat4(1.0f), glm::vec3(0, glm::sin(time*2), 0))); box({}, size); + box({1.5f,0,0}, size*0.5f); popMatrix(); popMatrix(); popMatrix(); @@ -75,14 +76,14 @@ void ModelBatch::box(glm::vec3 pos, glm::vec3 size) { Lightmap::extract(light, 3) / 15.0f ); - plane(pos+Z, X*size, Y*size, Z, lights); - plane(pos-Z, -X*size, Y*size, -Z, lights); + plane(pos+Z*size, X*size, Y*size, Z, lights); + plane(pos-Z*size, -X*size, Y*size, -Z, lights); - plane(pos+Y, X*size, -Z*size, Y, lights); - plane(pos-Y, X*size, Z*size, -Y, lights); + plane(pos+Y*size, X*size, -Z*size, Y, lights); + plane(pos-Y*size, X*size, Z*size, -Y, lights); - plane(pos+X, -Z*size, Y*size, X, lights); - plane(pos-X, Z*size, Y*size, -X, lights); + plane(pos+X*size, -Z*size, Y*size, X, lights); + plane(pos-X*size, Z*size, Y*size, -X, lights); } void ModelBatch::flush() { From 916d1c14084ac59e7c539965482679a0f23f5884 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 21 Jun 2024 01:43:26 +0300 Subject: [PATCH 06/17] update ModelBatch.box semantics --- src/graphics/render/ModelBatch.cpp | 24 ++++++++++++------------ src/graphics/render/ModelBatch.hpp | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 6ade352a8..2e056efc9 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -48,14 +48,23 @@ ModelBatch::~ModelBatch() { } void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { + glm::vec3 gpos = combined * glm::vec4(pos, 1.0f); + light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); + glm::vec4 lights ( + Lightmap::extract(light, 0) / 15.0f, + Lightmap::extract(light, 1) / 15.0f, + Lightmap::extract(light, 2) / 15.0f, + Lightmap::extract(light, 3) / 15.0f + ); + float time = static_cast(Window::time()); pushMatrix(glm::translate(glm::mat4(1.0f), pos)); pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*7*0.1f), glm::vec3(0,1,0))); pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*11*0.1f), glm::vec3(1,0,0))); pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*17*0.1f), glm::vec3(0,0,1))); pushMatrix(glm::translate(glm::mat4(1.0f), glm::vec3(0, glm::sin(time*2), 0))); - box({}, size); - box({1.5f,0,0}, size*0.5f); + box({}, size, lights); + box({1.5f,0,0}, size*0.5f, lights); popMatrix(); popMatrix(); popMatrix(); @@ -63,19 +72,10 @@ void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { popMatrix(); } -void ModelBatch::box(glm::vec3 pos, glm::vec3 size) { +void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) { if (index + 36 < capacity*VERTEX_SIZE) { flush(); } - glm::vec3 gpos = combined * glm::vec4(pos, 1.0f); - light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); - glm::vec4 lights ( - Lightmap::extract(light, 0) / 15.0f, - Lightmap::extract(light, 1) / 15.0f, - Lightmap::extract(light, 2) / 15.0f, - Lightmap::extract(light, 3) / 15.0f - ); - plane(pos+Z*size, X*size, Y*size, Z, lights); plane(pos-Z*size, -X*size, Y*size, -Z, lights); diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index 8c791fc0d..3028dc0ec 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -41,7 +41,7 @@ class ModelBatch { uint32_t integer; } compressed; - compressed.integer = (static_cast(light.r * 255) & 0xff) << 24; + compressed.integer = (static_cast(light.r * 255) & 0xff) << 24; compressed.integer |= (static_cast(light.g * 255) & 0xff) << 16; compressed.integer |= (static_cast(light.b * 255) & 0xff) << 8; compressed.integer |= (static_cast(light.a * 255) & 0xff); @@ -49,12 +49,12 @@ class ModelBatch { buffer[index++] = compressed.floating; } - inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm, glm::vec4 light) { + inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm, glm::vec4 lights) { norm = rotation * norm; float d = glm::dot(norm, SUN_VECTOR); d = 0.8f + d * 0.2f; - auto color = light * d; + auto color = lights * d; vertex(pos-right-up, {0,0}, color); vertex(pos+right-up, {1,0}, color); @@ -71,7 +71,7 @@ class ModelBatch { void pushMatrix(glm::mat4 matrix); void popMatrix(); - void box(glm::vec3 pos, glm::vec3 size); + void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights); void test(glm::vec3 pos, glm::vec3 size); void flush(); From 6ba38ee16783fa526b83c5682b9445368b85181c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 21 Jun 2024 02:30:35 +0300 Subject: [PATCH 07/17] add graphics/core/Model --- src/graphics/core/Model.cpp | 28 +++++++++++++++++++++++ src/graphics/core/Model.hpp | 33 +++++++++++++++++++++++++++ src/graphics/render/ModelBatch.cpp | 33 ++++++++++++++++++++++++++- src/graphics/render/ModelBatch.hpp | 10 +++++++- src/graphics/render/WorldRenderer.cpp | 13 ++++++++--- 5 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 src/graphics/core/Model.cpp create mode 100644 src/graphics/core/Model.hpp diff --git a/src/graphics/core/Model.cpp b/src/graphics/core/Model.cpp new file mode 100644 index 000000000..01d329733 --- /dev/null +++ b/src/graphics/core/Model.cpp @@ -0,0 +1,28 @@ +#include "Model.hpp" + +using namespace model; + +inline constexpr glm::vec3 X(1, 0, 0); +inline constexpr glm::vec3 Y(0, 1, 0); +inline constexpr glm::vec3 Z(0, 0, 1); + +void Mesh::addPlane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm) { + vertices.push_back({pos-right-up, {0,0}, norm}); + vertices.push_back({pos+right-up, {1,0}, norm}); + vertices.push_back({pos+right+up, {1,1}, norm}); + + vertices.push_back({pos-right-up, {0,0}, norm}); + vertices.push_back({pos+right+up, {1,1}, norm}); + vertices.push_back({pos-right+up, {0,1}, norm}); +} + +void Mesh::addBox(glm::vec3 pos, glm::vec3 size) { + addPlane(pos+Z*size, X*size, Y*size, Z); + addPlane(pos-Z*size, -X*size, Y*size, -Z); + + addPlane(pos+Y*size, X*size, -Z*size, Y); + addPlane(pos-Y*size, X*size, Z*size, -Y); + + addPlane(pos+X*size, -Z*size, Y*size, X); + addPlane(pos-X*size, Z*size, Y*size, -X); +} diff --git a/src/graphics/core/Model.hpp b/src/graphics/core/Model.hpp new file mode 100644 index 000000000..45ea94b9d --- /dev/null +++ b/src/graphics/core/Model.hpp @@ -0,0 +1,33 @@ +#ifndef GRAPHICS_CORE_MODEL_HPP_ +#define GRAPHICS_CORE_MODEL_HPP_ + +#include +#include +#include + +namespace model { + struct Vertex { + glm::vec3 coord; + glm::vec2 uv; + glm::vec3 normal; + }; + + struct Mesh { + std::string texture; + std::vector vertices; + + void addPlane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm); + void addBox(glm::vec3 pos, glm::vec3 size); + }; + + struct Model { + std::vector meshes; + + Mesh& addMesh(const std::string& texture) { + meshes.push_back({texture, {}}); + return meshes[meshes.size()-1]; + } + }; +} + +#endif // GRAPHICS_CORE_MODEL_HPP_ diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 2e056efc9..4645140b0 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -1,7 +1,9 @@ #include "ModelBatch.hpp" #include "../core/Mesh.hpp" +#include "../core/Model.hpp" #include "../core/Texture.hpp" +#include "../../assets/Assets.hpp" #include "../../window/Window.hpp" #include "../../voxels/Chunks.hpp" #include "../../lighting/Lightmap.hpp" @@ -30,12 +32,13 @@ struct DecomposedMat4 { glm::vec4 perspective; }; -ModelBatch::ModelBatch(size_t capacity, Chunks* chunks) +ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks) : buffer(std::make_unique(capacity * VERTEX_SIZE)), capacity(capacity), index(0), mesh(std::make_unique(buffer.get(), 0, attrs)), combined(1.0f), + assets(assets), chunks(chunks) { ubyte pixels[] = { @@ -47,6 +50,34 @@ ModelBatch::ModelBatch(size_t capacity, Chunks* chunks) ModelBatch::~ModelBatch() { } +void ModelBatch::draw(const model::Model& model) { + glm::vec3 gpos = combined * glm::vec4(glm::vec3(), 1.0f); + light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); + glm::vec4 lights ( + Lightmap::extract(light, 0) / 15.0f, + Lightmap::extract(light, 1) / 15.0f, + Lightmap::extract(light, 2) / 15.0f, + Lightmap::extract(light, 3) / 15.0f + ); + for (const auto& mesh : model.meshes) { + auto texture = assets->getTexture(mesh.texture); + if (texture) { + texture->bind(); + } else { + blank->bind(); + } + for (const auto& vert : mesh.vertices) { + auto norm = rotation * vert.normal; + float d = glm::dot(norm, SUN_VECTOR); + d = 0.8f + d * 0.2f; + + auto color = lights * d; + vertex(vert.coord, vert.uv, color); + } + flush(); + } +} + void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { glm::vec3 gpos = combined * glm::vec4(pos, 1.0f); light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index 3028dc0ec..b45ae0d01 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -8,6 +8,11 @@ class Mesh; class Texture; class Chunks; +class Assets; + +namespace model { + struct Model; +} class ModelBatch { std::unique_ptr buffer; @@ -21,6 +26,7 @@ class ModelBatch { std::vector matrices; glm::mat3 rotation; + Assets* assets; Chunks* chunks; static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; @@ -65,7 +71,7 @@ class ModelBatch { vertex(pos-right+up, {0,1}, color); } public: - ModelBatch(size_t capacity, Chunks* chunks); + ModelBatch(size_t capacity, Assets* assets, Chunks* chunks); ~ModelBatch(); void pushMatrix(glm::mat4 matrix); @@ -73,6 +79,8 @@ class ModelBatch { void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights); + void draw(const model::Model& model); + void test(glm::vec3 pos, glm::vec3 size); void flush(); }; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index e9d1a7032..17d0e6c6d 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -32,6 +32,7 @@ #include "../core/PostProcessing.hpp" #include "../core/Shader.hpp" #include "../core/Texture.hpp" +#include "../core/Model.hpp" #include #include @@ -49,7 +50,7 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl player(player), frustumCulling(std::make_unique()), lineBatch(std::make_unique()), - modelBatch(std::make_unique(1000, level->chunks.get())) + modelBatch(std::make_unique(1000, engine->getAssets(), level->chunks.get())) { renderer = std::make_unique( level, @@ -193,10 +194,16 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); + model::Model model {}; + auto& mesh = model.addMesh("gui/warning"); + mesh.addBox({}, glm::vec3(1)); + assets->getTexture("gui/menubg")->bind(); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - modelBatch->test(glm::vec3(0, 88, 0), glm::vec3(1.0f)); - modelBatch->flush(); + //modelBatch->test(glm::vec3(0, 88, 0), glm::vec3(1.0f)); + modelBatch->pushMatrix(glm::translate(glm::mat4(1.0f), glm::vec3(0, 88, 0))); + modelBatch->draw(model); + modelBatch->popMatrix(); skybox->unbind(); } From 1a12a6923ab47ecbe3c127e179ed96f9035b098c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 21 Jun 2024 19:19:20 +0300 Subject: [PATCH 08/17] remove ModelBatch.test(...) --- src/graphics/render/ModelBatch.cpp | 25 ------------------------- src/graphics/render/ModelBatch.hpp | 1 - src/graphics/render/WorldRenderer.cpp | 8 +++++++- 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 4645140b0..ae4fea94c 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -78,31 +78,6 @@ void ModelBatch::draw(const model::Model& model) { } } -void ModelBatch::test(glm::vec3 pos, glm::vec3 size) { - glm::vec3 gpos = combined * glm::vec4(pos, 1.0f); - light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); - glm::vec4 lights ( - Lightmap::extract(light, 0) / 15.0f, - Lightmap::extract(light, 1) / 15.0f, - Lightmap::extract(light, 2) / 15.0f, - Lightmap::extract(light, 3) / 15.0f - ); - - float time = static_cast(Window::time()); - pushMatrix(glm::translate(glm::mat4(1.0f), pos)); - pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*7*0.1f), glm::vec3(0,1,0))); - pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*11*0.1f), glm::vec3(1,0,0))); - pushMatrix(glm::rotate(glm::mat4(1.0f), glm::sin(time*17*0.1f), glm::vec3(0,0,1))); - pushMatrix(glm::translate(glm::mat4(1.0f), glm::vec3(0, glm::sin(time*2), 0))); - box({}, size, lights); - box({1.5f,0,0}, size*0.5f, lights); - popMatrix(); - popMatrix(); - popMatrix(); - popMatrix(); - popMatrix(); -} - void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) { if (index + 36 < capacity*VERTEX_SIZE) { flush(); diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index b45ae0d01..f4e896499 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -81,7 +81,6 @@ class ModelBatch { void draw(const model::Model& model); - void test(glm::vec3 pos, glm::vec3 size); void flush(); }; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 17d0e6c6d..75ed0abd3 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -197,13 +197,19 @@ void WorldRenderer::renderLevel( model::Model model {}; auto& mesh = model.addMesh("gui/warning"); mesh.addBox({}, glm::vec3(1)); + mesh.addBox({}, glm::vec3(2)); + + auto& mesh2 = model.addMesh("gui/error"); + mesh2.addBox({}, glm::vec3(1.25f)); + mesh2.addBox({}, glm::vec3(3.25f)); assets->getTexture("gui/menubg")->bind(); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - //modelBatch->test(glm::vec3(0, 88, 0), glm::vec3(1.0f)); modelBatch->pushMatrix(glm::translate(glm::mat4(1.0f), glm::vec3(0, 88, 0))); + modelBatch->pushMatrix(glm::rotate(glm::mat4(1.0f), static_cast(Window::time()), glm::vec3(1, 0, 0))); modelBatch->draw(model); modelBatch->popMatrix(); + modelBatch->popMatrix(); skybox->unbind(); } From a9640fff362144ed08a4d57738a6307231bd93e5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 21 Jun 2024 20:55:14 +0300 Subject: [PATCH 09/17] add ModelBatch.translate(...), .rotate(...), .scale(...) --- src/graphics/render/ModelBatch.cpp | 12 ++++++++++++ src/graphics/render/ModelBatch.hpp | 4 ++++ src/graphics/render/WorldRenderer.cpp | 15 +++++++++------ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index ae4fea94c..dc2690125 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -116,6 +116,18 @@ static glm::mat4 extract_rotation(glm::mat4 matrix) { return glm::toMat3(rotation); } +void ModelBatch::translate(glm::vec3 vec) { + pushMatrix(glm::translate(glm::mat4(1.0f), vec)); +} + +void ModelBatch::rotate(glm::vec3 axis, float angle) { + pushMatrix(glm::rotate(glm::mat4(1.0f), angle, axis)); +} + +void ModelBatch::scale(glm::vec3 vec) { + pushMatrix(glm::scale(glm::mat4(1.0f), vec)); +} + void ModelBatch::pushMatrix(glm::mat4 matrix) { matrices.push_back(combined); combined = combined * matrix; diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index f4e896499..67b367f5f 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -74,6 +74,10 @@ class ModelBatch { ModelBatch(size_t capacity, Assets* assets, Chunks* chunks); ~ModelBatch(); + void translate(glm::vec3 vec); + void rotate(glm::vec3 axis, float angle); + void scale(glm::vec3 vec); + void pushMatrix(glm::mat4 matrix); void popMatrix(); diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 75ed0abd3..7b3a61209 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -196,20 +196,23 @@ void WorldRenderer::renderLevel( model::Model model {}; auto& mesh = model.addMesh("gui/warning"); - mesh.addBox({}, glm::vec3(1)); - mesh.addBox({}, glm::vec3(2)); + mesh.addBox({}, glm::vec3(0.3f)); + mesh.addBox({}, glm::vec3(0.6f)); auto& mesh2 = model.addMesh("gui/error"); - mesh2.addBox({}, glm::vec3(1.25f)); - mesh2.addBox({}, glm::vec3(3.25f)); + mesh2.addBox({}, glm::vec3(0.7f)); + mesh2.addBox({}, glm::vec3(0.9f)); + float timer = static_cast(Window::time()); assets->getTexture("gui/menubg")->bind(); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - modelBatch->pushMatrix(glm::translate(glm::mat4(1.0f), glm::vec3(0, 88, 0))); - modelBatch->pushMatrix(glm::rotate(glm::mat4(1.0f), static_cast(Window::time()), glm::vec3(1, 0, 0))); + modelBatch->translate({0, 86, 0}); + modelBatch->scale(glm::vec3(glm::sin(timer*6)+1)); + modelBatch->rotate(glm::vec3(1, 0, 0), timer); modelBatch->draw(model); modelBatch->popMatrix(); modelBatch->popMatrix(); + modelBatch->popMatrix(); skybox->unbind(); } From e4f9bd03b776774a6d94807fe91d144fb815aaac Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 22 Jun 2024 20:24:35 +0300 Subject: [PATCH 10/17] add src/coders/obj --- src/coders/commons.cpp | 35 ++++++++ src/coders/commons.hpp | 3 + src/coders/json.cpp | 8 +- src/coders/obj.cpp | 124 ++++++++++++++++++++++++++ src/coders/obj.hpp | 19 ++++ src/data/dynamic.hpp | 10 +++ src/graphics/core/Model.cpp | 13 +++ src/graphics/core/Model.hpp | 5 ++ src/graphics/render/ModelBatch.cpp | 20 +++-- src/graphics/render/WorldRenderer.cpp | 26 +++--- src/graphics/render/WorldRenderer.hpp | 6 ++ 11 files changed, 241 insertions(+), 28 deletions(-) create mode 100644 src/coders/obj.cpp create mode 100644 src/coders/obj.hpp diff --git a/src/coders/commons.cpp b/src/coders/commons.cpp index 1bc111c23..d8d618734 100644 --- a/src/coders/commons.cpp +++ b/src/coders/commons.cpp @@ -163,6 +163,28 @@ void BasicParser::goBack(size_t count) { } } +void BasicParser::reset() { + pos = 0; +} + +char BasicParser::peekInLine() { + while (hasNext()) { + char next = source[pos]; + if (next == '\n') { + return next; + } + if (is_whitespace(next)) { + pos++; + } else { + break; + } + } + if (pos >= source.length()) { + throw error("unexpected end"); + } + return source[pos]; +} + char BasicParser::peek() { skipWhitespace(); if (pos >= source.length()) { @@ -226,6 +248,19 @@ int64_t BasicParser::parseSimpleInt(int base) { return value; } +dynamic::Value BasicParser::parseNumber() { + switch (peek()) { + case '-': + skip(1); + return parseNumber(-1); + case '+': + skip(1); + return parseNumber(1); + default: + return parseNumber(1); + } +} + dynamic::Value BasicParser::parseNumber(int sign) { char c = peek(); int base = 10; diff --git a/src/coders/commons.hpp b/src/coders/commons.hpp index f8f1b0e92..7b6cb3c23 100644 --- a/src/coders/commons.hpp +++ b/src/coders/commons.hpp @@ -87,9 +87,11 @@ class BasicParser { bool isNext(const std::string& substring); void expectNewLine(); void goBack(size_t count=1); + void reset(); int64_t parseSimpleInt(int base); dynamic::Value parseNumber(int sign); + dynamic::Value parseNumber(); std::string parseString(char chr, bool closeRequired=true); parsing_error error(const std::string& message); @@ -99,6 +101,7 @@ class BasicParser { std::string parseName(); bool hasNext(); char peek(); + char peekInLine(); char peekNoJump(); char nextChar(); diff --git a/src/coders/json.cpp b/src/coders/json.cpp index 19b597265..dbe42b5a0 100644 --- a/src/coders/json.cpp +++ b/src/coders/json.cpp @@ -209,9 +209,8 @@ std::unique_ptr Parser::parseList() { Value Parser::parseValue() { char next = peek(); - if (next == '-' || next == '+') { - pos++; - return parseNumber(next == '-' ? -1 : 1); + if (next == '-' || next == '+' || is_digit(next)) { + return parseNumber(); } if (is_identifier_start(next)) { std::string literal = parseName(); @@ -232,9 +231,6 @@ Value Parser::parseValue() { if (next == '[') { return List_sptr(parseList().release()); } - if (is_digit(next)) { - return parseNumber(1); - } if (next == '"' || next == '\'') { pos++; return parseString(next); diff --git a/src/coders/obj.cpp b/src/coders/obj.cpp new file mode 100644 index 000000000..3ecea677d --- /dev/null +++ b/src/coders/obj.cpp @@ -0,0 +1,124 @@ +#include "obj.hpp" + +#include "commons.hpp" +#include "../graphics/core/Model.hpp" + +using namespace model; + +class ObjParser : BasicParser { + std::vector coords {{0, 0, 0}}; + std::vector uvs {{0, 0}}; + std::vector normals {{0, 1, 0}}; + + void parseFace(Mesh& mesh) { + std::vector vertices; + while (hasNext()) { + auto c = peekInLine(); + if (c == '\n') { + break; + } else { + uint indices[3] {}; + uint i = 0; + do { + char next = peekInLine(); + if (is_digit(next)) { + indices[i] = parseSimpleInt(10); + if (peekInLine() == '/') { + pos++; + } + } else if (next == '/') { + pos++; + } else { + break; + } + } while (peekInLine() != '\n' && ++i < 3); + + vertices.push_back(Vertex { + coords[indices[0]], uvs[indices[1]], normals[indices[2]] + }); + } + } + if (peekInLine() != '\n' && hasNext()) { + skipLine(); + } + if (vertices.size() >= 3) { + for (size_t j = 0; j < vertices.size() - 2; j++) { + mesh.vertices.push_back(vertices[0]); + for (size_t i = 1; i < 3; i++) { + mesh.vertices.push_back(vertices[i + j]); + } + } + } + } +public: + ObjParser(const std::string_view file, const std::string_view src) : BasicParser(file, src) { + } + + std::unique_ptr parse() { + // first iteration - collecting vertex data + while (hasNext()) { + if (peek() == '#') { + skipLine(); + continue; + } + auto cmd = parseName(); + if (cmd == "v") { + float x = dynamic::as_number(parseNumber()); + float y = dynamic::as_number(parseNumber()); + float z = dynamic::as_number(parseNumber()); + coords.emplace_back(x, y, z); + } else if (cmd == "vt") { + float u = dynamic::as_number(parseNumber()); + float v = dynamic::as_number(parseNumber()); + uvs.emplace_back(u, v); + } else if (cmd == "vn") { + float x = dynamic::as_number(parseNumber()); + float y = dynamic::as_number(parseNumber()); + float z = dynamic::as_number(parseNumber()); + normals.emplace_back(x, y, z); + } else { + skipLine(); + } + } + // second iteration - building meshes + reset(); + + auto model = std::make_unique(); + std::string texture; + while (hasNext()) { + if (peek() != '#' && parseName() == "usemtl") { + skipWhitespace(); + texture = readUntil('\n'); + break; + } + skipLine(); + } + do { + Mesh* mesh = &model->addMesh(texture); + while (hasNext()) { + if (peek() == '#') { + skipLine(); + continue; + } + auto cmd = parseName(); + if (cmd == "usemtl") { + skipWhitespace(); + texture = readUntil('\n'); + mesh = &model->addMesh(texture); + break; + } else if (cmd == "f") { + parseFace(*mesh); + } + skipLine(); + } + } while(hasNext()); + model->clean(); + return model; + } +}; + +std::unique_ptr obj::parse( + const std::string_view file, const std::string_view src +) { + return ObjParser(file, src).parse(); +} diff --git a/src/coders/obj.hpp b/src/coders/obj.hpp new file mode 100644 index 000000000..64d0f4ce5 --- /dev/null +++ b/src/coders/obj.hpp @@ -0,0 +1,19 @@ +#ifndef CODERS_OBJ_HPP_ +#define CODERS_OBJ_HPP_ + +#include +#include + +/// Wavefont OBJ files parser + +namespace model { + struct Model; +} + +namespace obj { + std::unique_ptr parse( + const std::string_view file, const std::string_view src + ); +} + +#endif // CODERS_OBJ_HPP_ diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index ff0342df3..5dc5dbedc 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -3,6 +3,7 @@ #include "../typedefs.hpp" +#include #include #include #include @@ -47,6 +48,15 @@ namespace dynamic { std::holds_alternative(value); } + inline number_t as_number(const Value& value) { + if (auto num = std::get_if(&value)) { + return *num; + } else if (auto num = std::get_if(&value)) { + return *num; + } + return NAN; + } + class List { public: std::vector values; diff --git a/src/graphics/core/Model.cpp b/src/graphics/core/Model.cpp index 01d329733..78e153547 100644 --- a/src/graphics/core/Model.cpp +++ b/src/graphics/core/Model.cpp @@ -1,5 +1,7 @@ #include "Model.hpp" +#include + using namespace model; inline constexpr glm::vec3 X(1, 0, 0); @@ -26,3 +28,14 @@ void Mesh::addBox(glm::vec3 pos, glm::vec3 size) { addPlane(pos+X*size, -Z*size, Y*size, X); addPlane(pos-X*size, Z*size, Y*size, -X); } + + +void Model::clean() { + meshes.erase( + std::remove_if(meshes.begin(), meshes.end(), + [](const Mesh& mesh){ + return mesh.vertices.empty(); + }), + meshes.end() + ); +} diff --git a/src/graphics/core/Model.hpp b/src/graphics/core/Model.hpp index 45ea94b9d..03d008268 100644 --- a/src/graphics/core/Model.hpp +++ b/src/graphics/core/Model.hpp @@ -23,10 +23,15 @@ namespace model { struct Model { std::vector meshes; + /// @brief Add mesh to the model + /// @param texture texture name + /// @return writeable Mesh Mesh& addMesh(const std::string& texture) { meshes.push_back({texture, {}}); return meshes[meshes.size()-1]; } + /// @brief Remove all empty meshes + void clean(); }; } diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index dc2690125..4bc1be325 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -66,13 +66,19 @@ void ModelBatch::draw(const model::Model& model) { } else { blank->bind(); } - for (const auto& vert : mesh.vertices) { - auto norm = rotation * vert.normal; - float d = glm::dot(norm, SUN_VECTOR); - d = 0.8f + d * 0.2f; - - auto color = lights * d; - vertex(vert.coord, vert.uv, color); + for (size_t i = 0; i < mesh.vertices.size() / 3; i++) { + if (index + VERTEX_SIZE * 3 > capacity) { + flush(); + } + for (size_t j = 0; j < 3; j++) { + const auto& vert = mesh.vertices[i * 3 + j]; + auto norm = rotation * vert.normal; + float d = glm::dot(norm, SUN_VECTOR); + d = 0.8f + d * 0.2f; + + auto color = lights * d; + vertex(vert.coord, vert.uv, color); + } } flush(); } diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 7b3a61209..efb03d80b 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -7,10 +7,12 @@ #include "../../assets/Assets.hpp" #include "../../content/Content.hpp" #include "../../engine.hpp" +#include "../../coders/obj.hpp" #include "../../frontend/LevelFrontend.hpp" #include "../../items/Inventory.hpp" #include "../../items/ItemDef.hpp" #include "../../items/ItemStack.hpp" +#include "../../files/files.hpp" #include "../../logic/PlayerController.hpp" #include "../../maths/FrustumCulling.hpp" #include "../../maths/voxmaths.hpp" @@ -70,6 +72,10 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl settings.graphics.skyboxResolution.get(), assets->getShader("skybox_gen") ); + + auto name = "dingus.obj"; + auto text = files::read_string(fs::path(name)); + model = obj::parse(name, text); } WorldRenderer::~WorldRenderer() { @@ -194,23 +200,13 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); - model::Model model {}; - auto& mesh = model.addMesh("gui/warning"); - mesh.addBox({}, glm::vec3(0.3f)); - mesh.addBox({}, glm::vec3(0.6f)); - - auto& mesh2 = model.addMesh("gui/error"); - mesh2.addBox({}, glm::vec3(0.7f)); - mesh2.addBox({}, glm::vec3(0.9f)); - float timer = static_cast(Window::time()); - assets->getTexture("gui/menubg")->bind(); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - modelBatch->translate({0, 86, 0}); - modelBatch->scale(glm::vec3(glm::sin(timer*6)+1)); - modelBatch->rotate(glm::vec3(1, 0, 0), timer); - modelBatch->draw(model); - modelBatch->popMatrix(); + modelBatch->translate({0, 85, 0}); + //modelBatch->scale(glm::vec3(glm::sin(timer*6)+10)); + modelBatch->rotate(glm::vec3(0, 1, 0), timer*6); + modelBatch->draw(*model); + //modelBatch->popMatrix(); modelBatch->popMatrix(); modelBatch->popMatrix(); diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index 2f3517e14..b6b5dd27e 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -26,6 +26,10 @@ class DrawContext; class ModelBatch; struct EngineSettings; +namespace model { + struct Model; +} + class WorldRenderer { Engine* engine; Level* level; @@ -36,6 +40,8 @@ class WorldRenderer { std::unique_ptr skybox; std::unique_ptr batch3d; std::unique_ptr modelBatch; + + std::unique_ptr model; bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling); void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); From 848d1210995af14f271e0391a7f202ac234fa31f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 22 Jun 2024 21:35:21 +0300 Subject: [PATCH 11/17] remove test code --- src/graphics/render/WorldRenderer.cpp | 15 +-------------- src/graphics/render/WorldRenderer.hpp | 1 - 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index efb03d80b..a09a33b30 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -7,12 +7,10 @@ #include "../../assets/Assets.hpp" #include "../../content/Content.hpp" #include "../../engine.hpp" -#include "../../coders/obj.hpp" #include "../../frontend/LevelFrontend.hpp" #include "../../items/Inventory.hpp" #include "../../items/ItemDef.hpp" #include "../../items/ItemStack.hpp" -#include "../../files/files.hpp" #include "../../logic/PlayerController.hpp" #include "../../maths/FrustumCulling.hpp" #include "../../maths/voxmaths.hpp" @@ -72,10 +70,6 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl settings.graphics.skyboxResolution.get(), assets->getShader("skybox_gen") ); - - auto name = "dingus.obj"; - auto text = files::read_string(fs::path(name)); - model = obj::parse(name, text); } WorldRenderer::~WorldRenderer() { @@ -200,15 +194,8 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); - float timer = static_cast(Window::time()); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - modelBatch->translate({0, 85, 0}); - //modelBatch->scale(glm::vec3(glm::sin(timer*6)+10)); - modelBatch->rotate(glm::vec3(0, 1, 0), timer*6); - modelBatch->draw(*model); - //modelBatch->popMatrix(); - modelBatch->popMatrix(); - modelBatch->popMatrix(); + /// draw models here skybox->unbind(); } diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index b6b5dd27e..af8eeaff1 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -41,7 +41,6 @@ class WorldRenderer { std::unique_ptr batch3d; std::unique_ptr modelBatch; - std::unique_ptr model; bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling); void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); From d54b6b2e58a22b147a49c89bfb51c826095abf6b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 22 Jun 2024 22:30:14 +0300 Subject: [PATCH 12/17] update Assets container - template-based now --- src/assets/Assets.cpp | 75 ---------------------- src/assets/Assets.hpp | 55 ++++++++-------- src/assets/AssetsLoader.cpp | 2 +- src/frontend/ContentGfxCache.cpp | 2 +- src/frontend/LevelFrontend.cpp | 6 +- src/frontend/hud.cpp | 8 +-- src/frontend/screens/MenuScreen.cpp | 4 +- src/graphics/render/BlocksPreview.cpp | 4 +- src/graphics/render/ModelBatch.cpp | 2 +- src/graphics/render/Skybox.cpp | 6 +- src/graphics/render/WorldRenderer.cpp | 14 ++-- src/graphics/ui/GUI.cpp | 2 +- src/graphics/ui/elements/Image.cpp | 2 +- src/graphics/ui/elements/InventoryView.cpp | 9 +-- src/graphics/ui/elements/Label.cpp | 2 +- src/graphics/ui/elements/Plotter.cpp | 2 +- src/graphics/ui/elements/TextBox.cpp | 2 +- src/logic/scripting/lua/libaudio.cpp | 2 +- src/logic/scripting/lua/libgui.cpp | 6 +- src/logic/scripting/lua/libhud.cpp | 6 +- 20 files changed, 68 insertions(+), 143 deletions(-) diff --git a/src/assets/Assets.cpp b/src/assets/Assets.cpp index 73ed5ede9..c7ef69461 100644 --- a/src/assets/Assets.cpp +++ b/src/assets/Assets.cpp @@ -1,72 +1,8 @@ #include "Assets.hpp" -#include "../audio/audio.hpp" -#include "../graphics/core/Texture.hpp" -#include "../graphics/core/Shader.hpp" -#include "../graphics/core/Atlas.hpp" -#include "../graphics/core/Font.hpp" -#include "../frontend/UiDocument.hpp" -#include "../logic/scripting/scripting.hpp" - Assets::~Assets() { } -Texture* Assets::getTexture(const std::string& name) const { - auto found = textures.find(name); - if (found == textures.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr texture, const std::string& name){ - textures.emplace(name, std::move(texture)); -} - - -Shader* Assets::getShader(const std::string& name) const{ - auto found = shaders.find(name); - if (found == shaders.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr shader, const std::string& name){ - shaders.emplace(name, std::move(shader)); -} - -Font* Assets::getFont(const std::string& name) const { - auto found = fonts.find(name); - if (found == fonts.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr font, const std::string& name){ - fonts.emplace(name, std::move(font)); -} - -Atlas* Assets::getAtlas(const std::string& name) const { - auto found = atlases.find(name); - if (found == atlases.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr atlas, const std::string& name){ - atlases.emplace(name, std::move(atlas)); -} - -audio::Sound* Assets::getSound(const std::string& name) const { - auto found = sounds.find(name); - if (found == sounds.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr sound, const std::string& name) { - sounds.emplace(name, std::move(sound)); -} - const std::vector& Assets::getAnimations() { return animations; } @@ -74,14 +10,3 @@ const std::vector& Assets::getAnimations() { void Assets::store(const TextureAnimation& animation) { animations.emplace_back(animation); } - -UiDocument* Assets::getLayout(const std::string& name) const { - auto found = layouts.find(name); - if (found == layouts.end()) - return nullptr; - return found->second.get(); -} - -void Assets::store(std::unique_ptr layout, const std::string& name) { - layouts[name] = std::shared_ptr(std::move(layout)); -} diff --git a/src/assets/Assets.hpp b/src/assets/Assets.hpp index d4b0f31d2..8338eb7ef 100644 --- a/src/assets/Assets.hpp +++ b/src/assets/Assets.hpp @@ -7,57 +7,56 @@ #include #include #include +#include +#include #include -class Texture; -class Shader; -class Font; -class Atlas; class Assets; -class UiDocument; namespace audio { class Sound; } +namespace model { + struct Model; +} + namespace assetload { /// @brief final work to do in the main thread using postfunc = std::function; } class Assets { - std::unordered_map> textures; - std::unordered_map> shaders; - std::unordered_map> fonts; - std::unordered_map> atlases; - std::unordered_map> layouts; - std::unordered_map> sounds; std::vector animations; + + using assets_map = std::unordered_map>; + std::unordered_map assets; public: Assets() {} Assets(const Assets&) = delete; ~Assets(); - - Texture* getTexture(const std::string& name) const; - void store(std::unique_ptr texture, const std::string& name); - - Shader* getShader(const std::string& name) const; - void store(std::unique_ptr shader, const std::string& name); - - Font* getFont(const std::string& name) const; - void store(std::unique_ptr font, const std::string& name); - - Atlas* getAtlas(const std::string& name) const; - void store(std::unique_ptr atlas, const std::string& name); - - audio::Sound* getSound(const std::string& name) const; - void store(std::unique_ptr sound, const std::string& name); const std::vector& getAnimations(); void store(const TextureAnimation& animation); - UiDocument* getLayout(const std::string& name) const; - void store(std::unique_ptr layout, const std::string& name); + template + void store(std::unique_ptr asset, const std::string& name) { + assets[typeid(T)][name].reset(asset.release()); + } + + template + T* get(const std::string& name) const { + const auto& mapIter = assets.find(typeid(T)); + if (mapIter == assets.end()) { + return nullptr; + } + const auto& map = mapIter->second; + const auto& found = map.find(name); + if (found == map.end()) { + return nullptr; + } + return static_cast(found->second.get()); + } }; #endif // ASSETS_ASSETS_HPP_ diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index f55902e92..bf0ac243a 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -212,7 +212,7 @@ bool AssetsLoader::loadExternalTexture( const std::string& name, const std::vector& alternatives ) { - if (assets->getTexture(name) != nullptr) { + if (assets->get(name) != nullptr) { return true; } for (auto& path : alternatives) { diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp index 373e97302..de180760e 100644 --- a/src/frontend/ContentGfxCache.cpp +++ b/src/frontend/ContentGfxCache.cpp @@ -15,7 +15,7 @@ ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) { auto indices = content->getIndices(); sideregions = std::make_unique(indices->countBlockDefs() * 6); - Atlas* atlas = assets->getAtlas("blocks"); + auto atlas = assets->get("blocks"); for (uint i = 0; i < indices->countBlockDefs(); i++) { Block* def = indices->getBlockDef(i); diff --git a/src/frontend/LevelFrontend.cpp b/src/frontend/LevelFrontend.cpp index 7a62ca50c..3dffae5c6 100644 --- a/src/frontend/LevelFrontend.cpp +++ b/src/frontend/LevelFrontend.cpp @@ -30,7 +30,7 @@ LevelFrontend::LevelFrontend(LevelController* controller, Assets* assets) } if (type == BlockInteraction::step) { - auto sound = assets->getSound(material->stepsSound); + auto sound = assets->get(material->stepsSound); audio::play( sound, glm::vec3(), @@ -45,10 +45,10 @@ LevelFrontend::LevelFrontend(LevelController* controller, Assets* assets) audio::Sound* sound = nullptr; switch (type) { case BlockInteraction::placing: - sound = assets->getSound(material->placeSound); + sound = assets->get(material->placeSound); break; case BlockInteraction::destruction: - sound = assets->getSound(material->breakSound); + sound = assets->get(material->breakSound); break; case BlockInteraction::step: break; diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index bc8f2cbfd..53f85bafb 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -208,7 +208,7 @@ void Hud::processInput(bool visible) { } } if (!pause && Events::active(BIND_DEVTOOLS_CONSOLE)) { - showOverlay(assets->getLayout("core:console"), false); + showOverlay(assets->get("core:console"), false); } if (!Window::isFocused() && !pause && !isInventoryOpen()) { setPause(true); @@ -305,7 +305,7 @@ void Hud::openInventory() { inventoryOpen = true; auto inventory = player->getInventory(); - auto inventoryDocument = assets->getLayout("core:inventory"); + auto inventoryDocument = assets->get("core:inventory"); inventoryView = std::dynamic_pointer_cast(inventoryDocument->getRoot()); inventoryView->bind(inventory, content); add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false)); @@ -460,7 +460,7 @@ void Hud::draw(const DrawContext& ctx){ auto batch = ctx.getBatch2D(); batch->begin(); - Shader* uishader = assets->getShader("ui"); + auto uishader = assets->get("ui"); uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjView()); @@ -468,7 +468,7 @@ void Hud::draw(const DrawContext& ctx){ if (!pause && !inventoryOpen && !player->debug) { DrawContext chctx = ctx.sub(); chctx.setBlendMode(BlendMode::inversion); - auto texture = assets->getTexture("gui/crosshair"); + auto texture = assets->get("gui/crosshair"); batch->texture(texture); int chsizex = texture != nullptr ? texture->getWidth() : 16; int chsizey = texture != nullptr ? texture->getHeight() : 16; diff --git a/src/frontend/screens/MenuScreen.cpp b/src/frontend/screens/MenuScreen.cpp index 96b7656c9..74ad04219 100644 --- a/src/frontend/screens/MenuScreen.cpp +++ b/src/frontend/screens/MenuScreen.cpp @@ -35,14 +35,14 @@ void MenuScreen::draw(float delta) { Window::setBgColor(glm::vec3(0.2f)); uicamera->setFov(Window::height); - Shader* uishader = assets->getShader("ui"); + auto uishader = assets->get("ui"); uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjView()); uint width = Window::width; uint height = Window::height; - auto bg = assets->getTexture("gui/menubg"); + auto bg = assets->get("gui/menubg"); batch->begin(); batch->texture(bg); batch->rect( diff --git a/src/graphics/render/BlocksPreview.cpp b/src/graphics/render/BlocksPreview.cpp index eb7e72cf6..88a6f1113 100644 --- a/src/graphics/render/BlocksPreview.cpp +++ b/src/graphics/render/BlocksPreview.cpp @@ -126,8 +126,8 @@ std::unique_ptr BlocksPreview::build( size_t count = indices->countBlockDefs(); size_t iconSize = ITEM_ICON_SIZE; - Shader* shader = assets->getShader("ui3d"); - Atlas* atlas = assets->getAtlas("blocks"); + auto shader = assets->get("ui3d"); + auto atlas = assets->get("blocks"); Viewport viewport(iconSize, iconSize); DrawContext pctx(nullptr, viewport, nullptr); diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 4bc1be325..99aef358a 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -60,7 +60,7 @@ void ModelBatch::draw(const model::Model& model) { Lightmap::extract(light, 3) / 15.0f ); for (const auto& mesh : model.meshes) { - auto texture = assets->getTexture(mesh.texture); + auto texture = assets->get(mesh.texture); if (texture) { texture->bind(); } else { diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index 65b255a9b..493106099 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -59,7 +59,7 @@ Skybox::~Skybox() { } void Skybox::drawBackground(Camera* camera, Assets* assets, int width, int height) { - Shader* backShader = assets->getShader("background"); + auto backShader = assets->get("background"); backShader->use(); backShader->uniformMatrix("u_view", camera->getView(false)); backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(M_PI*0.5f)); @@ -107,7 +107,7 @@ void Skybox::draw( DrawContext ctx = pctx.sub(); ctx.setBlendMode(BlendMode::addition); - Shader* shader = assets->getShader("ui3d"); + auto shader = assets->get("ui3d"); shader->use(); shader->uniformMatrix("u_projview", camera->getProjView(false)); shader->uniformMatrix("u_apply", glm::mat4(1.0f)); @@ -117,7 +117,7 @@ void Skybox::draw( float opacity = glm::pow(1.0f-fog, 7.0f); for (auto& sprite : sprites) { - batch3d->texture(assets->getTexture(sprite.texture)); + batch3d->texture(assets->get(sprite.texture)); float sangle = daytime * M_PI*2 + sprite.phase; float distance = sprite.distance; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index a09a33b30..940cef92a 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -68,7 +68,7 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl auto assets = engine->getAssets(); skybox = std::make_unique( settings.graphics.skyboxResolution.get(), - assets->getShader("skybox_gen") + assets->get("skybox_gen") ); } @@ -154,9 +154,9 @@ void WorldRenderer::renderLevel( Camera* camera, const EngineSettings& settings ) { - Assets* assets = engine->getAssets(); - Atlas* atlas = assets->getAtlas("blocks"); - Shader* shader = assets->getShader("main"); + auto assets = engine->getAssets(); + auto atlas = assets->get("blocks"); + auto shader = assets->get("main"); auto indices = level->content->getIndices(); @@ -292,8 +292,8 @@ void WorldRenderer::draw( const EngineSettings& settings = engine->getSettings(); skybox->refresh(pctx, world->daytime, 1.0f+world->fog*2.0f, 4); - Assets* assets = engine->getAssets(); - Shader* linesShader = assets->getShader("lines"); + auto assets = engine->getAssets(); + auto linesShader = assets->get("lines"); // World render scope with diegetic HUD included { @@ -323,7 +323,7 @@ void WorldRenderer::draw( } // Rendering fullscreen quad with - auto screenShader = assets->getShader("screen"); + auto screenShader = assets->get("screen"); screenShader->use(); screenShader->uniform1f("u_timer", Window::time()); screenShader->uniform1f("u_dayTime", level->getWorld()->daytime); diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 7881d5475..54c04476a 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -205,7 +205,7 @@ void GUI::draw(const DrawContext* pctx, Assets* assets) { menu->setPos((wsize - menu->getSize()) / 2.0f); uicamera->setFov(wsize.y); - Shader* uishader = assets->getShader("ui"); + auto uishader = assets->get("ui"); uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjView()); diff --git a/src/graphics/ui/elements/Image.cpp b/src/graphics/ui/elements/Image.cpp index d99c5a9de..e3b7243e6 100644 --- a/src/graphics/ui/elements/Image.cpp +++ b/src/graphics/ui/elements/Image.cpp @@ -18,7 +18,7 @@ void Image::draw(const DrawContext* pctx, Assets* assets) { glm::vec2 pos = calcPos(); auto batch = pctx->getBatch2D(); - auto texture = assets->getTexture(this->texture); + auto texture = assets->get(this->texture); if (texture && autoresize) { setSize(glm::vec2(texture->getWidth(), texture->getHeight())); } diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index b364425fc..92084c374 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -21,6 +21,7 @@ #include "../../core/Font.hpp" #include "../../core/DrawContext.hpp" #include "../../core/Shader.hpp" +#include "../../core/Texture.hpp" #include "../../render/BlocksPreview.hpp" #include "../GUI.hpp" @@ -155,7 +156,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { batch->setColor(glm::vec4(1.0f)); - auto previews = assets->getAtlas("block-previews"); + auto previews = assets->get("block-previews"); auto indices = content->getIndices(); ItemDef* item = indices->getItemDef(stack.getItemId()); @@ -177,10 +178,10 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { std::string name = item->icon.substr(index+1); UVRegion region(0.0f, 0.0, 1.0f, 1.0f); if (index == std::string::npos) { - batch->texture(assets->getTexture(name)); + batch->texture(assets->get(name)); } else { std::string atlasname = item->icon.substr(0, index); - Atlas* atlas = assets->getAtlas(atlasname); + auto atlas = assets->get(atlasname); if (atlas && atlas->has(name)) { region = atlas->get(name); batch->texture(atlas->getTexture()); @@ -194,7 +195,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { } if (stack.getCount() > 1) { - auto font = assets->getFont("normal"); + auto font = assets->get("normal"); std::wstring text = std::to_wstring(stack.getCount()); int x = pos.x+slotSize-text.length()*8; diff --git a/src/graphics/ui/elements/Label.cpp b/src/graphics/ui/elements/Label.cpp index d4a9019cf..ac31e2a96 100644 --- a/src/graphics/ui/elements/Label.cpp +++ b/src/graphics/ui/elements/Label.cpp @@ -158,7 +158,7 @@ uint Label::getLinesNumber() const { void Label::draw(const DrawContext* pctx, Assets* assets) { auto batch = pctx->getBatch2D(); - auto font = assets->getFont(fontName); + auto font = assets->get(fontName); cache.prepare(font, static_cast(glm::abs(getSize().x))); if (supplier) { diff --git a/src/graphics/ui/elements/Plotter.cpp b/src/graphics/ui/elements/Plotter.cpp index bcb653d7a..28057ae58 100644 --- a/src/graphics/ui/elements/Plotter.cpp +++ b/src/graphics/ui/elements/Plotter.cpp @@ -37,7 +37,7 @@ void Plotter::draw(const DrawContext* pctx, Assets* assets) { } int current_point = static_cast(points[index % dmwidth]); - auto font = assets->getFont("normal"); + auto font = assets->get("normal"); for (int y = 0; y < dmheight; y += labelsInterval) { std::wstring string; if (current_point/16 == y/labelsInterval) { diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index b531bf686..26eaae969 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -33,7 +33,7 @@ TextBox::TextBox(std::wstring placeholder, glm::vec4 padding) void TextBox::draw(const DrawContext* pctx, Assets* assets) { Panel::draw(pctx, assets); - font = assets->getFont(label->getFontName()); + font = assets->get(label->getFontName()); if (!isFocused()) { return; diff --git a/src/logic/scripting/lua/libaudio.cpp b/src/logic/scripting/lua/libaudio.cpp index bec44719d..ec8749713 100644 --- a/src/logic/scripting/lua/libaudio.cpp +++ b/src/logic/scripting/lua/libaudio.cpp @@ -32,7 +32,7 @@ inline audio::speakerid_t play_sound( return 0; } auto assets = scripting::engine->getAssets(); - auto sound = assets->getSound(name); + auto sound = assets->get(name); if (sound == nullptr) { return 0; } diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 258af55aa..7555f48db 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -27,7 +27,7 @@ struct DocumentNode { }; static DocumentNode getDocumentNode(lua::State*, const std::string& name, const std::string& nodeName) { - auto doc = engine->getAssets()->getLayout(name); + auto doc = engine->getAssets()->get(name); if (doc == nullptr) { throw std::runtime_error("document '"+name+"' not found"); } @@ -545,7 +545,7 @@ static int l_gui_setattr(lua::State* L) { static int l_gui_get_env(lua::State* L) { auto name = lua::require_string(L, 1); - auto doc = engine->getAssets()->getLayout(name); + auto doc = engine->getAssets()->get(name); if (doc == nullptr) { throw std::runtime_error("document '"+std::string(name)+"' not found"); } @@ -566,7 +566,7 @@ static int l_gui_str(lua::State* L) { static int l_gui_reindex(lua::State* L) { auto name = lua::require_string(L, 1); - auto doc = engine->getAssets()->getLayout(name); + auto doc = engine->getAssets()->get(name); if (doc == nullptr) { throw std::runtime_error("document '"+std::string(name)+"' not found"); } diff --git a/src/logic/scripting/lua/libhud.cpp b/src/logic/scripting/lua/libhud.cpp index f2bd5535c..5395e7a14 100644 --- a/src/logic/scripting/lua/libhud.cpp +++ b/src/logic/scripting/lua/libhud.cpp @@ -51,7 +51,7 @@ static int l_hud_open_block(lua::State* L) { } auto def = content->getIndices()->getBlockDef(vox->id); auto assets = engine->getAssets(); - auto layout = assets->getLayout(def->uiLayout); + auto layout = assets->get(def->uiLayout); if (layout == nullptr) { throw std::runtime_error("block '"+def->name+"' has no ui layout"); } @@ -71,7 +71,7 @@ static int l_hud_show_overlay(lua::State* L) { bool playerInventory = lua::toboolean(L, 2); auto assets = engine->getAssets(); - auto layout = assets->getLayout(name); + auto layout = assets->get(name); if (layout == nullptr) { throw std::runtime_error("there is no ui layout "+util::quote(name)); } @@ -81,7 +81,7 @@ static int l_hud_show_overlay(lua::State* L) { static UiDocument* require_layout(const char* name) { auto assets = engine->getAssets(); - auto layout = assets->getLayout(name); + auto layout = assets->get(name); if (layout == nullptr) { throw std::runtime_error("layout '"+std::string(name)+"' is not found"); } From ea0add3017090ee5fe6d6a7b0168509c68f4b1b4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 22 Jun 2024 23:43:56 +0300 Subject: [PATCH 13/17] feat: models loading --- src/assets/Assets.hpp | 8 -------- src/assets/AssetsLoader.cpp | 3 +++ src/assets/AssetsLoader.hpp | 3 ++- src/assets/assetload_funcs.cpp | 27 +++++++++++++++++++++++++++ src/assets/assetload_funcs.hpp | 8 +++++++- src/constants.hpp | 1 + src/graphics/render/ModelBatch.cpp | 4 ++-- src/graphics/render/ModelBatch.hpp | 2 +- 8 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/assets/Assets.hpp b/src/assets/Assets.hpp index 8338eb7ef..fd39e8fe0 100644 --- a/src/assets/Assets.hpp +++ b/src/assets/Assets.hpp @@ -13,14 +13,6 @@ class Assets; -namespace audio { - class Sound; -} - -namespace model { - struct Model; -} - namespace assetload { /// @brief final work to do in the main thread using postfunc = std::function; diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index bf0ac243a..65f52da7f 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -30,6 +30,7 @@ AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths) addLoader(AssetType::atlas, assetload::atlas); addLoader(AssetType::layout, assetload::layout); addLoader(AssetType::sound, assetload::sound); + addLoader(AssetType::model, assetload::model); } void AssetsLoader::addLoader(AssetType tag, aloader_func func) { @@ -99,6 +100,7 @@ static std::string assets_def_folder(AssetType tag) { case AssetType::atlas: return TEXTURES_FOLDER; case AssetType::layout: return LAYOUTS_FOLDER; case AssetType::sound: return SOUNDS_FOLDER; + case AssetType::model: return MODELS_FOLDER; } return ""; } @@ -155,6 +157,7 @@ void AssetsLoader::processPreloadConfig(const fs::path& file) { processPreloadList(AssetType::shader, root->list("shaders")); processPreloadList(AssetType::texture, root->list("textures")); processPreloadList(AssetType::sound, root->list("sounds")); + processPreloadList(AssetType::model, root->list("models")); // layouts are loaded automatically } diff --git a/src/assets/AssetsLoader.hpp b/src/assets/AssetsLoader.hpp index b2d819167..91eb1036f 100644 --- a/src/assets/AssetsLoader.hpp +++ b/src/assets/AssetsLoader.hpp @@ -25,7 +25,8 @@ enum class AssetType { font, atlas, layout, - sound + sound, + model, }; class ResPaths; diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 8698d61f7..4a85cb94b 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -9,14 +9,17 @@ #include "../coders/commons.hpp" #include "../coders/imageio.hpp" #include "../coders/json.hpp" +#include "../coders/obj.hpp" #include "../coders/GLSLExtension.hpp" #include "../graphics/core/Shader.hpp" #include "../graphics/core/Texture.hpp" #include "../graphics/core/ImageData.hpp" #include "../graphics/core/Atlas.hpp" #include "../graphics/core/Font.hpp" +#include "../graphics/core/Model.hpp" #include "../graphics/core/TextureAnimation.hpp" #include "../frontend/UiDocument.hpp" +#include "../constants.hpp" #include #include @@ -198,6 +201,30 @@ assetload::postfunc assetload::sound( }; } +assetload::postfunc assetload::model( + AssetsLoader* loader, + const ResPaths* paths, + const std::string& file, + const std::string& name, + const std::shared_ptr& +) { + auto path = paths->find(file+".obj"); + auto text = files::read_string(path); + try { + auto model = obj::parse(path.u8string(), text).release(); + return [=](Assets* assets) { + for (auto& mesh : model->meshes) { + auto filename = TEXTURES_FOLDER+"/"+mesh.texture; + loader->add(AssetType::texture, filename, mesh.texture, nullptr); + } + assets->store(std::unique_ptr(model), name); + }; + } catch (const parsing_error& err) { + std::cerr << err.errorLog() << std::endl; + throw; + } +} + static void read_anim_file( const std::string& animFile, std::vector>& frameList diff --git a/src/assets/assetload_funcs.hpp b/src/assets/assetload_funcs.hpp index f017dcb49..71b3cb935 100644 --- a/src/assets/assetload_funcs.hpp +++ b/src/assets/assetload_funcs.hpp @@ -49,7 +49,6 @@ namespace assetload { const std::string &name, const std::shared_ptr& settings ); - postfunc sound( AssetsLoader*, const ResPaths* paths, @@ -57,6 +56,13 @@ namespace assetload { const std::string &name, const std::shared_ptr& settings ); + postfunc model( + AssetsLoader*, + const ResPaths* paths, + const std::string& file, + const std::string &name, + const std::shared_ptr& settings + ); } #endif // ASSETS_ASSET_LOADERS_HPP_ diff --git a/src/constants.hpp b/src/constants.hpp index e666563aa..76c13a748 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -49,5 +49,6 @@ inline const std::string TEXTURES_FOLDER = "textures"; inline const std::string FONTS_FOLDER = "fonts"; inline const std::string LAYOUTS_FOLDER = "layouts"; inline const std::string SOUNDS_FOLDER = "sounds"; +inline const std::string MODELS_FOLDER = "models"; #endif // CONSTANTS_HPP_ diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 99aef358a..abbfc0735 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -50,7 +50,7 @@ ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks) ModelBatch::~ModelBatch() { } -void ModelBatch::draw(const model::Model& model) { +void ModelBatch::draw(const model::Model* model) { glm::vec3 gpos = combined * glm::vec4(glm::vec3(), 1.0f); light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); glm::vec4 lights ( @@ -59,7 +59,7 @@ void ModelBatch::draw(const model::Model& model) { Lightmap::extract(light, 2) / 15.0f, Lightmap::extract(light, 3) / 15.0f ); - for (const auto& mesh : model.meshes) { + for (const auto& mesh : model->meshes) { auto texture = assets->get(mesh.texture); if (texture) { texture->bind(); diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index 67b367f5f..8b949227f 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -83,7 +83,7 @@ class ModelBatch { void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights); - void draw(const model::Model& model); + void draw(const model::Model* model); void flush(); }; From 94fe5eeb5b5f6f7c73e69db435bd2d2f9c0c7b5b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 23 Jun 2024 01:57:28 +0300 Subject: [PATCH 14/17] update ModelBatch semantics --- src/assets/assetload_funcs.cpp | 6 +-- src/frontend/debug_panel.cpp | 5 ++ src/graphics/core/Mesh.cpp | 2 + src/graphics/core/Mesh.hpp | 1 + src/graphics/render/ModelBatch.cpp | 72 ++++++++++++++++++--------- src/graphics/render/ModelBatch.hpp | 24 ++++++--- src/graphics/render/WorldRenderer.cpp | 22 +++++++- 7 files changed, 97 insertions(+), 35 deletions(-) diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 4a85cb94b..b7fe8ccf7 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -122,9 +122,9 @@ assetload::postfunc assetload::font( ) { auto pages = std::make_shared>>(); for (size_t i = 0; i <= 4; i++) { - std::string name = filename + "_" + std::to_string(i) + ".png"; - name = paths->find(name).string(); - pages->push_back(imageio::read(name)); + std::string pagefile = filename + "_" + std::to_string(i) + ".png"; + pagefile = paths->find(pagefile).string(); + pages->push_back(imageio::read(pagefile)); } return [=](auto assets) { int res = pages->at(0)->getHeight() / 16; diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index d61e021fd..b49abf89a 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -62,6 +62,11 @@ std::shared_ptr create_debug_panel( panel->add(create_label([](){ return L"meshes: " + std::to_wstring(Mesh::meshesCount); })); + panel->add(create_label([](){ + int drawCalls = Mesh::drawCalls; + Mesh::drawCalls = 0; + return L"draw-calls: " + std::to_wstring(drawCalls); + })); panel->add(create_label([](){ return L"speakers: " + std::to_wstring(audio::count_speakers())+ L" streams: " + std::to_wstring(audio::count_streams()); diff --git a/src/graphics/core/Mesh.cpp b/src/graphics/core/Mesh.cpp index 45ba28783..ac4e2b14e 100644 --- a/src/graphics/core/Mesh.cpp +++ b/src/graphics/core/Mesh.cpp @@ -2,6 +2,7 @@ #include int Mesh::meshesCount = 0; +int Mesh::drawCalls = 0; Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs) : ibo(0), @@ -60,6 +61,7 @@ void Mesh::reload(const float* vertexBuffer, size_t vertices, const int* indexBu } void Mesh::draw(unsigned int primitive){ + drawCalls++; glBindVertexArray(vao); if (ibo != 0) { glDrawElements(primitive, indices, GL_UNSIGNED_INT, 0); diff --git a/src/graphics/core/Mesh.hpp b/src/graphics/core/Mesh.hpp index 541d396ed..abff9d5e7 100644 --- a/src/graphics/core/Mesh.hpp +++ b/src/graphics/core/Mesh.hpp @@ -37,6 +37,7 @@ class Mesh { /// @brief Total numbers of alive mesh objects static int meshesCount; + static int drawCalls; }; #endif // GRAPHICS_CORE_MESH_HPP_ diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index abbfc0735..d314e78bf 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -50,8 +50,8 @@ ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks) ModelBatch::~ModelBatch() { } -void ModelBatch::draw(const model::Model* model) { - glm::vec3 gpos = combined * glm::vec4(glm::vec3(), 1.0f); +void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation) { + glm::vec3 gpos = matrix * glm::vec4(glm::vec3(), 1.0f); light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); glm::vec4 lights ( Lightmap::extract(light, 0) / 15.0f, @@ -59,31 +59,44 @@ void ModelBatch::draw(const model::Model* model) { Lightmap::extract(light, 2) / 15.0f, Lightmap::extract(light, 3) / 15.0f ); - for (const auto& mesh : model->meshes) { - auto texture = assets->get(mesh.texture); - if (texture) { - texture->bind(); - } else { - blank->bind(); + setTexture(assets->get(mesh.texture)); + size_t vcount = mesh.vertices.size(); + const auto& vertexData = mesh.vertices.data(); + for (size_t i = 0; i < vcount / 3; i++) { + if (index + VERTEX_SIZE * 3 > capacity * VERTEX_SIZE) { + flush(); } - for (size_t i = 0; i < mesh.vertices.size() / 3; i++) { - if (index + VERTEX_SIZE * 3 > capacity) { - flush(); - } - for (size_t j = 0; j < 3; j++) { - const auto& vert = mesh.vertices[i * 3 + j]; - auto norm = rotation * vert.normal; - float d = glm::dot(norm, SUN_VECTOR); - d = 0.8f + d * 0.2f; - - auto color = lights * d; - vertex(vert.coord, vert.uv, color); - } + for (size_t j = 0; j < 3; j++) { + const auto& vert = vertexData[i * 3 + j]; + auto norm = rotation * vert.normal; + float d = glm::dot(norm, SUN_VECTOR); + d = 0.8f + d * 0.2f; + + auto color = lights * d; + vertex(matrix * glm::vec4(vert.coord, 1.0f), vert.uv, color); } - flush(); } } +void ModelBatch::draw(const model::Model* model) { + for (const auto& mesh : model->meshes) { + entries.push_back({combined, rotation, &mesh}); + } +} + +void ModelBatch::render() { + std::sort(entries.begin(), entries.end(), + [](const DrawEntry& a, const DrawEntry& b) { + return a.mesh->texture < b.mesh->texture; + } + ); + for (auto& entry : entries) { + draw(*entry.mesh, entry.matrix, entry.rotation); + } + flush(); + entries.clear(); +} + void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) { if (index + 36 < capacity*VERTEX_SIZE) { flush(); @@ -98,11 +111,24 @@ void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) { plane(pos-X*size, Z*size, Y*size, -X, lights); } +void ModelBatch::setTexture(Texture* texture) { + if (texture == nullptr) { + texture = blank.get(); + } + if (texture != this->texture) { + flush(); + } + this->texture = texture; +} + void ModelBatch::flush() { if (index == 0) { return; } - // blank->bind(); + if (texture == nullptr) { + texture = blank.get(); + } + texture->bind(); mesh->reload(buffer.get(), index / VERTEX_SIZE); mesh->draw(); index = 0; diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index 8b949227f..ba6f1eeda 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -11,12 +11,13 @@ class Chunks; class Assets; namespace model { + struct Mesh; struct Model; } class ModelBatch { - std::unique_ptr buffer; - size_t capacity; + std::unique_ptr const buffer; + size_t const capacity; size_t index; std::unique_ptr mesh; @@ -28,6 +29,7 @@ class ModelBatch { Assets* assets; Chunks* chunks; + Texture* texture = nullptr; static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; @@ -35,7 +37,6 @@ class ModelBatch { glm::vec3 pos, glm::vec2 uv, glm::vec4 light ) { float* buffer = this->buffer.get(); - pos = combined * glm::vec4(pos, 1.0f); buffer[index++] = pos.x; buffer[index++] = pos.y; buffer[index++] = pos.z; @@ -70,6 +71,18 @@ class ModelBatch { vertex(pos+right+up, {1,1}, color); vertex(pos-right+up, {0,1}, color); } + + void draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation); + void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights); + void setTexture(Texture* texture); + void flush(); + + struct DrawEntry { + glm::mat4 matrix; + glm::mat3 rotation; + const model::Mesh* mesh; + }; + std::vector entries; public: ModelBatch(size_t capacity, Assets* assets, Chunks* chunks); ~ModelBatch(); @@ -80,12 +93,9 @@ class ModelBatch { void pushMatrix(glm::mat4 matrix); void popMatrix(); - - void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights); - void draw(const model::Model* model); - void flush(); + void render(); }; #endif // GRAPHICS_RENDER_MODEL_BATCH_HPP_ diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 940cef92a..ca90013df 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -50,7 +50,7 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl player(player), frustumCulling(std::make_unique()), lineBatch(std::make_unique()), - modelBatch(std::make_unique(1000, engine->getAssets(), level->chunks.get())) + modelBatch(std::make_unique(20'000, engine->getAssets(), level->chunks.get())) { renderer = std::make_unique( level, @@ -195,7 +195,25 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - /// draw models here + if (auto model = assets->get("cube")) { + srand(0); + float timer = Window::time(); + for (size_t i = 0; i < 10000; i++) { + float x = (rand() % 5000)*0.1f; + float y = (rand() % 1000)*0.1f + 60; + float z = (rand() % 5000)*0.1f; + glm::vec3 coord(x, y, z); + int rot = rand() % 1000; + if (frustumCulling->IsBoxVisible(coord, coord)) { + modelBatch->translate(coord); + modelBatch->rotate(glm::vec3(0, 1, 0), timer*3+rot); + modelBatch->draw(model); + modelBatch->popMatrix(); + modelBatch->popMatrix(); + } + } + } + modelBatch->render(); skybox->unbind(); } From 30ac1a58ee34c3c151349edcb4758ea3e0088427 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 23 Jun 2024 02:05:13 +0300 Subject: [PATCH 15/17] remove test code --- src/graphics/render/WorldRenderer.cpp | 21 ++------------------- src/maths/FrustumCulling.hpp | 5 ++--- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index ca90013df..f94939de5 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -107,7 +107,7 @@ bool WorldRenderer::drawChunk( chunk->z * CHUNK_D + CHUNK_D ); - if (!frustumCulling->IsBoxVisible(min, max)) + if (!frustumCulling->isBoxVisible(min, max)) return false; } glm::vec3 coord(chunk->x*CHUNK_W+0.5f, 0.5f, chunk->z*CHUNK_D+0.5f); @@ -195,24 +195,7 @@ void WorldRenderer::renderLevel( drawChunks(level->chunks.get(), camera, shader); shader->uniformMatrix("u_model", glm::mat4(1.0f)); - if (auto model = assets->get("cube")) { - srand(0); - float timer = Window::time(); - for (size_t i = 0; i < 10000; i++) { - float x = (rand() % 5000)*0.1f; - float y = (rand() % 1000)*0.1f + 60; - float z = (rand() % 5000)*0.1f; - glm::vec3 coord(x, y, z); - int rot = rand() % 1000; - if (frustumCulling->IsBoxVisible(coord, coord)) { - modelBatch->translate(coord); - modelBatch->rotate(glm::vec3(0, 1, 0), timer*3+rot); - modelBatch->draw(model); - modelBatch->popMatrix(); - modelBatch->popMatrix(); - } - } - } + // draw entities here modelBatch->render(); skybox->unbind(); diff --git a/src/maths/FrustumCulling.hpp b/src/maths/FrustumCulling.hpp index b2b46ed4e..309fc1ba8 100644 --- a/src/maths/FrustumCulling.hpp +++ b/src/maths/FrustumCulling.hpp @@ -9,7 +9,7 @@ class Frustum Frustum() {}; void update(glm::mat4 projview); - bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const; + bool isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const; private: enum Planes @@ -76,8 +76,7 @@ inline void Frustum::update(glm::mat4 m) } -inline bool Frustum::IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const -{ +inline bool Frustum::isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const { // check box outside/inside of frustum for (int i = 0; i < Count; i++) { From 4fdfeb5e88cd4e957e72ca3514ca365b66ba0497 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 23 Jun 2024 02:07:52 +0300 Subject: [PATCH 16/17] fix msvc build --- src/graphics/render/ModelBatch.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index d314e78bf..67be92e5c 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -13,6 +13,8 @@ #include #include +#include + /// xyz, uv, compressed rgba inline constexpr uint VERTEX_SIZE = 6; From 0c8df834dd6f6943a0f337a35c4873893b113386 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 23 Jun 2024 02:48:29 +0300 Subject: [PATCH 17/17] fix mat4.rotate(...) --- src/logic/scripting/lua/libmat4.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logic/scripting/lua/libmat4.cpp b/src/logic/scripting/lua/libmat4.cpp index 4e989545e..16cc20986 100644 --- a/src/logic/scripting/lua/libmat4.cpp +++ b/src/logic/scripting/lua/libmat4.cpp @@ -121,7 +121,7 @@ inline int l_rotate(lua::State* L) { auto matrix = lua::tomat4(L, 1); auto vec = lua::tovec3(L, 2); auto angle = glm::radians(static_cast(lua::tonumber(L, 3))); - return lua::setmat4(L, 3, glm::rotate(matrix, angle, vec)); + return lua::setmat4(L, 4, glm::rotate(matrix, angle, vec)); } default: { throw std::runtime_error("invalid arguments number (2, 3 or 4 expected)");