From 1ffbeb8148659430b89b9529af679ab19fb590fc Mon Sep 17 00:00:00 2001 From: REDxEYE Date: Sat, 29 Mar 2025 22:20:54 +0300 Subject: [PATCH 01/21] Refactor mesh handling to use templated vertex structures for improved type safety and flexibility --- CMakeLists.txt | 8 ++ CMakePresets.json | 7 +- res/shaders/entity.glslv | 4 +- res/shaders/lib/commons.glsl | 15 +- res/shaders/main.glslv | 8 +- src/frontend/debug_panel.cpp | 6 +- src/graphics/core/Batch2D.cpp | 53 +++---- src/graphics/core/Batch2D.hpp | 20 ++- src/graphics/core/Batch3D.cpp | 130 +++++++---------- src/graphics/core/Batch3D.hpp | 23 ++- src/graphics/core/LineBatch.cpp | 37 ++--- src/graphics/core/LineBatch.hpp | 13 +- src/graphics/core/Mesh.cpp | 97 +------------ src/graphics/core/Mesh.hpp | 42 ++++-- src/graphics/core/Mesh.inl | 92 ++++++++++++ src/graphics/core/MeshData.hpp | 35 ++++- src/graphics/core/PostProcessing.cpp | 14 +- src/graphics/core/PostProcessing.hpp | 15 +- src/graphics/render/BlocksRenderer.cpp | 190 ++++++++++++------------- src/graphics/render/BlocksRenderer.hpp | 15 +- src/graphics/render/ChunksRenderer.cpp | 26 ++-- src/graphics/render/ChunksRenderer.hpp | 11 +- src/graphics/render/MainBatch.cpp | 103 +++++++------- src/graphics/render/MainBatch.hpp | 54 +++---- src/graphics/render/ModelBatch.hpp | 4 +- src/graphics/render/Skybox.cpp | 42 +++--- src/graphics/render/Skybox.hpp | 12 +- src/graphics/render/commons.hpp | 36 +++-- 28 files changed, 591 insertions(+), 521 deletions(-) create mode 100644 src/graphics/core/Mesh.inl diff --git a/CMakeLists.txt b/CMakeLists.txt index 6966e81f..0dac68cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,3 +49,11 @@ if(VOXELENGINE_BUILD_TESTS) endif() add_subdirectory(vctest) + +add_custom_target(copy_resources ALL + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/res + ${CMAKE_CURRENT_BINARY_DIR}/res + COMMENT "Copying resource directory to the build directory" +) +add_dependencies(${PROJECT_NAME} copy_resources) \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json index bc81fc91..3992caac 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -46,10 +46,15 @@ ], "buildPresets": [ { - "name": "default-vs-msvc-windows", + "name": "Debug build", "configurePreset": "default-vs-msvc-windows", "configuration": "Debug" }, + { + "name": "Release build", + "configurePreset": "default-vs-msvc-windows", + "configuration": "Release" + }, { "name": "default-ninja-gnu-linux", "configurePreset": "default-ninja-gnu-linux", diff --git a/res/shaders/entity.glslv b/res/shaders/entity.glslv index e318db38..587a4bae 100644 --- a/res/shaders/entity.glslv +++ b/res/shaders/entity.glslv @@ -3,7 +3,7 @@ layout (location = 0) in vec3 v_position; layout (location = 1) in vec2 v_texCoord; layout (location = 2) in vec3 v_color; -layout (location = 3) in float v_light; +layout (location = 3) in vec4 v_light; out vec4 a_color; out vec2 a_texCoord; @@ -31,7 +31,7 @@ void main() { vec3 pos3d = modelpos.xyz - u_cameraPos; modelpos.xyz = apply_planet_curvature(modelpos.xyz, pos3d); - vec4 decomp_light = decompress_light(v_light); + vec4 decomp_light = v_light; vec3 light = decomp_light.rgb; float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) / u_torchlightDistance); diff --git a/res/shaders/lib/commons.glsl b/res/shaders/lib/commons.glsl index a3bdbbc7..3701fcc3 100644 --- a/res/shaders/lib/commons.glsl +++ b/res/shaders/lib/commons.glsl @@ -1,28 +1,17 @@ #ifndef COMMONS_GLSL_ #define COMMONS_GLSL_ - #include -vec4 decompress_light(float compressed_light) { - vec4 result; - int compressed = floatBitsToInt(compressed_light); - result.r = ((compressed >> 24) & 0xFF) / 255.f; - result.g = ((compressed >> 16) & 0xFF) / 255.f; - result.b = ((compressed >> 8) & 0xFF) / 255.f; - result.a = (compressed & 0xFF) / 255.f; - return result; -} - vec3 pick_sky_color(samplerCube cubemap) { vec3 skyLightColor = texture(cubemap, vec3(0.4f, 0.0f, 0.4f)).rgb; skyLightColor *= SKY_LIGHT_TINT; - skyLightColor = min(vec3(1.0), skyLightColor*SKY_LIGHT_MUL); + skyLightColor = min(vec3(1.0f), skyLightColor * SKY_LIGHT_MUL); skyLightColor = max(MIN_SKY_LIGHT, skyLightColor); return skyLightColor; } vec3 apply_planet_curvature(vec3 modelPos, vec3 pos3d) { - modelPos.y -= pow(length(pos3d.xz)*CURVATURE_FACTOR, 3.0); + modelPos.y -= pow(length(pos3d.xz) * CURVATURE_FACTOR, 3.0f); return modelPos; } diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index c8d05d5d..a634e1ba 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -2,7 +2,7 @@ layout (location = 0) in vec3 v_position; layout (location = 1) in vec2 v_texCoord; -layout (location = 2) in float v_light; +layout (location = 2) in vec4 v_light; out vec4 a_color; out vec2 a_texCoord; @@ -27,13 +27,13 @@ uniform vec3 u_torchlightColor; uniform float u_torchlightDistance; void main() { - vec4 modelpos = u_model * vec4(v_position, 1.0); + vec4 modelpos = u_model * vec4(v_position, 1.0f); vec3 pos3d = modelpos.xyz-u_cameraPos; modelpos.xyz = apply_planet_curvature(modelpos.xyz, pos3d); - vec4 decomp_light = decompress_light(v_light); + vec4 decomp_light = v_light; vec3 light = decomp_light.rgb; - float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) / + float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) / u_torchlightDistance); light += torchlight * u_torchlightColor; a_color = vec4(pow(light, vec3(u_gamma)),1.0f); diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index 67b43f5a..06ab5fc8 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -93,11 +93,11 @@ std::shared_ptr create_debug_panel( panel->add(create_label(gui, []() { return L"fps: "+fpsString;})); panel->add(create_label(gui, []() { - return L"meshes: " + std::to_wstring(Mesh::meshesCount); + return L"meshes: " + std::to_wstring(MeshStats::meshesCount); })); panel->add(create_label(gui, []() { - int drawCalls = Mesh::drawCalls; - Mesh::drawCalls = 0; + int drawCalls = MeshStats::drawCalls; + MeshStats::drawCalls = 0; return L"draw-calls: " + std::to_wstring(drawCalls); })); panel->add(create_label(gui, []() { diff --git a/src/graphics/core/Batch2D.cpp b/src/graphics/core/Batch2D.cpp index 73ac9be2..1d2362d2 100644 --- a/src/graphics/core/Batch2D.cpp +++ b/src/graphics/core/Batch2D.cpp @@ -8,15 +8,10 @@ #include -inline constexpr uint B2D_VERTEX_SIZE = 8; Batch2D::Batch2D(size_t capacity) : capacity(capacity), color(1.0f){ - const VertexAttribute attrs[] = { - {2}, {2}, {4}, {0} - }; - - buffer = std::make_unique(capacity * B2D_VERTEX_SIZE); - mesh = std::make_unique(buffer.get(), 0, attrs); + buffer = std::make_unique(capacity ); + mesh = std::make_unique>(buffer.get(), 0, Batch2DVertex::ATTRIBUTES); index = 0; const ubyte pixels[] = { @@ -51,28 +46,20 @@ void Batch2D::vertex( float u, float v, float r, float g, float b, float a ) { - buffer[index++] = x; - buffer[index++] = y; - buffer[index++] = u * region.getWidth() + region.u1; - buffer[index++] = v * region.getHeight() + region.v1; - buffer[index++] = r; - buffer[index++] = g; - buffer[index++] = b; - buffer[index++] = a; + buffer[index].position = {x, y}; + buffer[index].uv = {u * region.getWidth() + region.u1, v * region.getHeight() + region.v1}; + buffer[index].color = {r, g, b, a}; + index++; } void Batch2D::vertex( glm::vec2 point, glm::vec2 uvpoint, float r, float g, float b, float a ) { - buffer[index++] = point.x; - buffer[index++] = point.y; - buffer[index++] = uvpoint.x * region.getWidth() + region.u1; - buffer[index++] = uvpoint.y * region.getHeight() + region.v1; - buffer[index++] = r; - buffer[index++] = g; - buffer[index++] = b; - buffer[index++] = a; + buffer[index].position = point; + buffer[index].uv = {uvpoint.x * region.getWidth() + region.u1, uvpoint.y * region.getHeight() + region.v1}; + buffer[index].color = {r, g, b, a}; + index++; } void Batch2D::texture(const Texture* new_texture){ @@ -99,14 +86,14 @@ void Batch2D::setRegion(UVRegion region) { } void Batch2D::point(float x, float y, float r, float g, float b, float a){ - if (index + 6*B2D_VERTEX_SIZE >= capacity) + if (index + 6 >= capacity) flush(); setPrimitive(DrawPrimitive::point); vertex(x, y, 0, 0, r,g,b,a); } void Batch2D::line(float x1, float y1, float x2, float y2, float r, float g, float b, float a){ - if (index + 6*B2D_VERTEX_SIZE >= capacity) { + if (index + 6 >= capacity) { flush(); } setPrimitive(DrawPrimitive::line); @@ -119,7 +106,7 @@ void Batch2D::rect(float x, float y, float w, float h){ const float g = color.g; const float b = color.b; const float a = color.a; - if (index + 6*B2D_VERTEX_SIZE >= capacity) { + if (index + 6 >= capacity) { flush(); } setPrimitive(DrawPrimitive::triangle); @@ -142,7 +129,7 @@ void Batch2D::rect( bool flippedY, glm::vec4 tint ) { - if (index + 6 * B2D_VERTEX_SIZE >= capacity) { + if (index + 6 >= capacity) { flush(); } setPrimitive(DrawPrimitive::triangle); @@ -230,14 +217,14 @@ void Batch2D::rect( } void Batch2D::lineRect(float x, float y, float w, float h) { - if (index + 8 * B2D_VERTEX_SIZE >= capacity) { + if (index + 8 >= capacity) { flush(); } setPrimitive(DrawPrimitive::line); vertex(x, y, 0.0f, 0.0f, color.r, color.g, color.b, color.a); vertex(x, y+h, 0.0f, 1.0f, color.r, color.g, color.b, color.a); - + vertex(x, y+h, 0.0f, 1.0f, color.r, color.g, color.b, color.a); vertex(x+w, y+h, 1.0f, 1.0f, color.r, color.g, color.b, color.a); @@ -253,7 +240,7 @@ void Batch2D::rect( float u, float v, float tx, float ty, float r, float g, float b, float a ){ - if (index + 6*B2D_VERTEX_SIZE >= capacity) { + if (index + 6 >= capacity) { flush(); } setPrimitive(DrawPrimitive::triangle); @@ -271,7 +258,7 @@ void Batch2D::parallelogram( float u, float v, float tx, float ty, float r, float g, float b, float a ){ - if (index + 6*B2D_VERTEX_SIZE >= capacity) { + if (index + 6 >= capacity) { flush(); } setPrimitive(DrawPrimitive::triangle); @@ -292,7 +279,7 @@ void Batch2D::rect( float r3, float g3, float b3, float r4, float g4, float b4, int sh ){ - if (index + 30*B2D_VERTEX_SIZE >= capacity) { + if (index + 30 >= capacity) { flush(); } setPrimitive(DrawPrimitive::triangle); @@ -378,7 +365,7 @@ void Batch2D::sprite( void Batch2D::flush() { if (index == 0) return; - mesh->reload(buffer.get(), index / B2D_VERTEX_SIZE); + mesh->reload(buffer.get(), index); mesh->draw(gl::to_glenum(primitive)); index = 0; } diff --git a/src/graphics/core/Batch2D.hpp b/src/graphics/core/Batch2D.hpp index 8db99d99..03b2a866 100644 --- a/src/graphics/core/Batch2D.hpp +++ b/src/graphics/core/Batch2D.hpp @@ -1,19 +1,33 @@ #pragma once #include -#include #include #include "commons.hpp" #include "maths/UVRegion.hpp" +#include "MeshData.hpp" +template class Mesh; class Texture; +struct Batch2DVertex { + glm::vec2 position; + glm::vec2 uv; + glm::vec4 color; + + static constexpr VertexAttribute ATTRIBUTES[] { + {GL_FLOAT, false, 2}, + {GL_FLOAT, false,2}, + {GL_FLOAT, false, 4}, + {0} + }; +}; + class Batch2D : public Flushable { - std::unique_ptr buffer; + std::unique_ptr buffer; size_t capacity; - std::unique_ptr mesh; + std::unique_ptr> mesh; std::unique_ptr blank; size_t index; glm::vec4 color; diff --git a/src/graphics/core/Batch3D.cpp b/src/graphics/core/Batch3D.cpp index a81f4ffb..862bc677 100644 --- a/src/graphics/core/Batch3D.cpp +++ b/src/graphics/core/Batch3D.cpp @@ -7,17 +7,12 @@ #include "typedefs.hpp" #include "maths/UVRegion.hpp" -/// xyz, uv, rgba -inline constexpr uint B3D_VERTEX_SIZE = 9; - -Batch3D::Batch3D(size_t capacity) +Batch3D::Batch3D(size_t capacity) : capacity(capacity) { - const VertexAttribute attrs[] = { - {3}, {2}, {4}, {0} - }; - buffer = std::make_unique(capacity * B3D_VERTEX_SIZE); - mesh = std::make_unique(buffer.get(), 0, attrs); + + buffer = std::make_unique(capacity); + mesh = std::make_unique>(buffer.get(), 0, Batch3DVertex::ATTRIBUTES); index = 0; const ubyte pixels[] = { @@ -40,69 +35,54 @@ void Batch3D::vertex( float x, float y, float z, float u, float v, float r, float g, float b, float a ) { - buffer[index++] = x; - buffer[index++] = y; - buffer[index++] = z; - buffer[index++] = u; - buffer[index++] = v; - buffer[index++] = r; - buffer[index++] = g; - buffer[index++] = b; - buffer[index++] = a; + buffer[index].position = {x, y, z}; + buffer[index].uv = {u, v}; + buffer[index].color = {r, g, b, a}; + index++; } void Batch3D::vertex( glm::vec3 coord, float u, float v, float r, float g, float b, float a ) { - buffer[index++] = coord.x; - buffer[index++] = coord.y; - buffer[index++] = coord.z; - buffer[index++] = u; - buffer[index++] = v; - buffer[index++] = r; - buffer[index++] = g; - buffer[index++] = b; - buffer[index++] = a; + buffer[index].position = coord; + buffer[index].uv = {u, v}; + buffer[index].color = {r, g, b, a}; + index++; } void Batch3D::vertex( glm::vec3 point, glm::vec2 uvpoint, float r, float g, float b, float a ) { - buffer[index++] = point.x; - buffer[index++] = point.y; - buffer[index++] = point.z; - buffer[index++] = uvpoint.x; - buffer[index++] = uvpoint.y; - buffer[index++] = r; - buffer[index++] = g; - buffer[index++] = b; - buffer[index++] = a; + buffer[index].position = point; + buffer[index].uv = uvpoint; + buffer[index].color = {r, g, b, a}; + index++; } void Batch3D::face( - const glm::vec3& coord, + const glm::vec3& coord, float w, float h, const glm::vec3& axisX, const glm::vec3& axisY, const UVRegion& region, const glm::vec4& tint ) { - if (index + B3D_VERTEX_SIZE * 6 > capacity) { + if (index + 6 >= capacity) { flush(); } - vertex(coord, region.u1, region.v1, + vertex(coord, region.u1, region.v1, tint.r, tint.g, tint.b, tint.a); - vertex(coord + axisX * w, region.u2, region.v1, + vertex(coord + axisX * w, region.u2, region.v1, tint.r, tint.g, tint.b, tint.a); - vertex(coord + axisX * w + axisY * h, region.u2, region.v2, + vertex(coord + axisX * w + axisY * h, region.u2, region.v2, tint.r, tint.g, tint.b, tint.a); - vertex(coord, region.u1, region.v1, + vertex(coord, region.u1, region.v1, tint.r, tint.g, tint.b, tint.a); vertex(coord + axisX * w + axisY * h, region.u2, region.v2, tint.r, tint.g, tint.b, tint.a); - vertex(coord + axisY * h, region.u1, region.v2, + vertex(coord + axisY * h, region.u1, region.v2, tint.r, tint.g, tint.b, tint.a); } @@ -134,18 +114,18 @@ void Batch3D::sprite( } void Batch3D::sprite( - const glm::vec3& pos, - const glm::vec3& up, - const glm::vec3& right, - float w, float h, - const UVRegion& uv, + const glm::vec3& pos, + const glm::vec3& up, + const glm::vec3& right, + float w, float h, + const UVRegion& uv, const glm::vec4& color ){ const float r = color.r; const float g = color.g; const float b = color.b; const float a = color.a; - if (index + 6*B3D_VERTEX_SIZE >= capacity) { + if (index + 6 >= capacity) { flush(); } @@ -194,17 +174,17 @@ void Batch3D::xSprite( float w, float h, const UVRegion& uv, const glm::vec4& tint, bool shading ) { face( - glm::vec3(-w * 0.25f, 0.0f, -w * 0.25f), - w, h, - glm::vec3(1, 0, 0), - glm::vec3(0, 1, 0), + glm::vec3(-w * 0.25f, 0.0f, -w * 0.25f), + w, h, + glm::vec3(1, 0, 0), + glm::vec3(0, 1, 0), uv, (shading ? do_tint(1.0f)*tint : tint) ); face( - glm::vec3(w * 0.25f, 0.0f, w * 0.5f - w * 0.25f), + glm::vec3(w * 0.25f, 0.0f, w * 0.5f - w * 0.25f), w, h, - glm::vec3(0, 0, -1), - glm::vec3(0, 1, 0), + glm::vec3(0, 0, -1), + glm::vec3(0, 1, 0), uv, (shading ? do_tint(0.9f)*tint : tint) ); } @@ -221,41 +201,41 @@ void Batch3D::cube( const glm::vec3 Z(0.0f, 0.0f, 1.0f); face( - coord+glm::vec3(0.0f, 0.0f, 0.0f), - size.x, size.y, X, Y, texfaces[5], + coord+glm::vec3(0.0f, 0.0f, 0.0f), + size.x, size.y, X, Y, texfaces[5], (shading ? do_tint(0.8)*tint : tint) ); face( - coord+glm::vec3(size.x, 0.0f, -size.z), - size.x, size.y, -X, Y, texfaces[4], + coord+glm::vec3(size.x, 0.0f, -size.z), + size.x, size.y, -X, Y, texfaces[4], (shading ? do_tint(0.8f)*tint : tint) ); face( - coord+glm::vec3(0.0f, size.y, 0.0f), - size.x, size.z, X, -Z, texfaces[3], + coord+glm::vec3(0.0f, size.y, 0.0f), + size.x, size.z, X, -Z, texfaces[3], (shading ? do_tint(1.0f)*tint : tint) ); face( - coord+glm::vec3(0.0f, 0.0f, -size.z), - size.x, size.z, X, Z, texfaces[2], + coord+glm::vec3(0.0f, 0.0f, -size.z), + size.x, size.z, X, Z, texfaces[2], (shading ? do_tint(0.7f)*tint : tint) ); face( - coord+glm::vec3(0.0f, 0.0f, -size.z), - size.z, size.y, Z, Y, texfaces[0], + coord+glm::vec3(0.0f, 0.0f, -size.z), + size.z, size.y, Z, Y, texfaces[0], (shading ? do_tint(0.9f)*tint : tint) ); face( - coord+glm::vec3(size.x, 0.0f, 0.0f), - size.z, size.y, -Z, Y, texfaces[1], + coord+glm::vec3(size.x, 0.0f, 0.0f), + size.z, size.y, -Z, Y, texfaces[1], (shading ? do_tint(0.9f)*tint : tint) ); } void Batch3D::blockCube( - const glm::vec3& size, - const UVRegion(&texfaces)[6], - const glm::vec4& tint, + const glm::vec3& size, + const UVRegion(&texfaces)[6], + const glm::vec4& tint, bool shading ) { cube((1.0f - size) * -0.5f, size, texfaces, tint, shading); @@ -264,27 +244,27 @@ void Batch3D::blockCube( void Batch3D::vertex( const glm::vec3& coord, const glm::vec2& uv, const glm::vec4& tint ) { - if (index + B3D_VERTEX_SIZE >= capacity) { + if (index + 1 >= capacity) { flush(); } vertex(coord, uv, tint.r, tint.g, tint.b, tint.a); } void Batch3D::point(const glm::vec3& coord, const glm::vec4& tint) { - if (index + B3D_VERTEX_SIZE >= capacity) { + if (index + 1 >= capacity) { flushPoints(); } vertex(coord, {}, tint.r, tint.g, tint.b, tint.a); } void Batch3D::flush() { - mesh->reload(buffer.get(), index / B3D_VERTEX_SIZE); + mesh->reload(buffer.get(), index); mesh->draw(); index = 0; } void Batch3D::flushPoints() { - mesh->reload(buffer.get(), index / B3D_VERTEX_SIZE); + mesh->reload(buffer.get(), index); mesh->draw(GL_POINTS); index = 0; } diff --git a/src/graphics/core/Batch3D.hpp b/src/graphics/core/Batch3D.hpp index 020f03bd..6cb03ac0 100644 --- a/src/graphics/core/Batch3D.hpp +++ b/src/graphics/core/Batch3D.hpp @@ -2,19 +2,34 @@ #include "typedefs.hpp" #include "commons.hpp" +#include "MeshData.hpp" #include -#include +#include #include -class Mesh; +template class Mesh; + class Texture; struct UVRegion; +struct Batch3DVertex { + glm::vec3 position; + glm::vec2 uv; + glm::vec4 color; + + static constexpr VertexAttribute ATTRIBUTES[] { + {GL_FLOAT, false, 3}, + {GL_FLOAT, false, 2}, + {GL_FLOAT, false, 4}, + {0} + }; +}; + class Batch3D : public Flushable { - std::unique_ptr buffer; + std::unique_ptr buffer; size_t capacity; - std::unique_ptr mesh; + std::unique_ptr> mesh; std::unique_ptr blank; size_t index; glm::vec4 tint {1.0f}; diff --git a/src/graphics/core/LineBatch.cpp b/src/graphics/core/LineBatch.cpp index aed8a249..a1448768 100644 --- a/src/graphics/core/LineBatch.cpp +++ b/src/graphics/core/LineBatch.cpp @@ -3,12 +3,11 @@ #include -inline constexpr uint LB_VERTEX_SIZE = (3+4); LineBatch::LineBatch(size_t capacity) : capacity(capacity) { - const VertexAttribute attrs[] = { {3},{4}, {0} }; - buffer = std::make_unique(capacity * LB_VERTEX_SIZE * 2); - mesh = std::make_unique(buffer.get(), 0, attrs); + + buffer = std::make_unique(capacity * 2); + mesh = std::make_unique>(buffer.get(), 0, LineVertex::ATTRIBUTES); index = 0; } @@ -16,31 +15,21 @@ LineBatch::~LineBatch(){ } void LineBatch::line( - float x1, float y1, - float z1, float x2, + float x1, float y1, + float z1, float x2, float y2, float z2, float r, float g, float b, float a ) { - if (index + LB_VERTEX_SIZE * 2 >= capacity) { + if (index + 2 >= capacity) { flush(); } - buffer[index] = x1; - buffer[index+1] = y1; - buffer[index+2] = z1; - buffer[index+3] = r; - buffer[index+4] = g; - buffer[index+5] = b; - buffer[index+6] = a; - index += LB_VERTEX_SIZE; + buffer[index].position = {x1,y1,z1}; + buffer[index].color = {r,g,b,a}; + index++; - buffer[index] = x2; - buffer[index+1] = y2; - buffer[index+2] = z2; - buffer[index+3] = r; - buffer[index+4] = g; - buffer[index+5] = b; - buffer[index+6] = a; - index += LB_VERTEX_SIZE; + buffer[index].position = {x2,y2,z2}; + buffer[index].color = {r,g,b,a}; + index++; } void LineBatch::box(float x, float y, float z, float w, float h, float d, @@ -68,7 +57,7 @@ void LineBatch::box(float x, float y, float z, float w, float h, float d, void LineBatch::flush(){ if (index == 0) return; - mesh->reload(buffer.get(), index / LB_VERTEX_SIZE); + mesh->reload(buffer.get(), index); mesh->draw(GL_LINES); index = 0; } diff --git a/src/graphics/core/LineBatch.hpp b/src/graphics/core/LineBatch.hpp index fe77da60..123c5407 100644 --- a/src/graphics/core/LineBatch.hpp +++ b/src/graphics/core/LineBatch.hpp @@ -5,12 +5,21 @@ #include #include "commons.hpp" +#include "MeshData.hpp" +template class Mesh; +struct LineVertex { + glm::vec3 position; + glm::vec4 color; + + static constexpr VertexAttribute ATTRIBUTES[] { {GL_FLOAT,false,3},{GL_FLOAT,false,4}, {0} }; +}; + class LineBatch : public Flushable { - std::unique_ptr mesh; - std::unique_ptr buffer; + std::unique_ptr> mesh; + std::unique_ptr buffer; size_t index; size_t capacity; public: diff --git a/src/graphics/core/Mesh.cpp b/src/graphics/core/Mesh.cpp index 808b88c4..5df57129 100644 --- a/src/graphics/core/Mesh.cpp +++ b/src/graphics/core/Mesh.cpp @@ -1,93 +1,8 @@ -#include "Mesh.hpp" -#include -#include +// +// Created by RED on 24.03.2025. +// -int Mesh::meshesCount = 0; -int Mesh::drawCalls = 0; +#include "graphics/core/Mesh.hpp" -inline size_t calc_vertex_size(const VertexAttribute* attrs) { - size_t vertexSize = 0; - for (int i = 0; attrs[i].size; i++) { - vertexSize += attrs[i].size; - } - assert(vertexSize != 0); - return vertexSize; -} - -Mesh::Mesh(const MeshData& data) - : Mesh(data.vertices.data(), - data.vertices.size() / calc_vertex_size(data.attrs.data()), - data.indices.data(), - data.indices.size(), - data.attrs.data()) {} - -Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const VertexAttribute* attrs) : - ibo(0), - vertices(0), - indices(0) -{ - meshesCount++; - vertexSize = 0; - for (int i = 0; attrs[i].size; i++) { - vertexSize += attrs[i].size; - } - - glGenVertexArrays(1, &vao); - glGenBuffers(1, &vbo); - - reload(vertexBuffer, vertices, indexBuffer, indices); - - // attributes - int offset = 0; - for (int i = 0; attrs[i].size; i++) { - int size = attrs[i].size; - glVertexAttribPointer(i, size, GL_FLOAT, GL_FALSE, vertexSize * sizeof(float), (GLvoid*)(offset * sizeof(float))); - glEnableVertexAttribArray(i); - offset += size; - } - - glBindVertexArray(0); -} - -Mesh::~Mesh(){ - meshesCount--; - glDeleteVertexArrays(1, &vao); - glDeleteBuffers(1, &vbo); - if (ibo != 0) glDeleteBuffers(1, &ibo); -} - -void Mesh::reload(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices){ - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - if (vertexBuffer != nullptr && vertices != 0) { - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, vertexBuffer, GL_STREAM_DRAW); - } else { - glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STREAM_DRAW); - } - if (indexBuffer != nullptr && indices != 0) { - if (ibo == 0) glGenBuffers(1, &ibo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * indices, indexBuffer, GL_STATIC_DRAW); - } - else if (ibo != 0) { - glDeleteBuffers(1, &ibo); - } - this->vertices = vertices; - this->indices = indices; -} - -void Mesh::draw(unsigned int primitive) const { - drawCalls++; - glBindVertexArray(vao); - if (ibo != 0) { - glDrawElements(primitive, indices, GL_UNSIGNED_INT, 0); - } - else { - glDrawArrays(primitive, 0, vertices); - } - glBindVertexArray(0); -} - -void Mesh::draw() const { - draw(GL_TRIANGLES); -} + int MeshStats::meshesCount = 0; + int MeshStats::drawCalls = 0; \ No newline at end of file diff --git a/src/graphics/core/Mesh.hpp b/src/graphics/core/Mesh.hpp index 482c82bf..559c5cc9 100644 --- a/src/graphics/core/Mesh.hpp +++ b/src/graphics/core/Mesh.hpp @@ -1,31 +1,43 @@ #pragma once -#include - -#include "typedefs.hpp" #include "MeshData.hpp" + +struct MeshStats { + static int meshesCount; + static int drawCalls; +}; + + +template class Mesh { unsigned int vao; unsigned int vbo; unsigned int ibo; - size_t vertices; - size_t indices; + size_t vertexCount; + size_t indexCount; size_t vertexSize; + public: - Mesh(const MeshData& data); - Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const VertexAttribute* attrs); - Mesh(const float* vertexBuffer, size_t vertices, const VertexAttribute* attrs) : - Mesh(vertexBuffer, vertices, nullptr, 0, attrs) {}; + explicit Mesh(const MeshData &data); + + Mesh(const VertexStructure *vertexBuffer, size_t vertices, const uint32_t *indexBuffer, size_t indices, + const VertexAttribute *attrs); + + Mesh(const VertexStructure *vertexBuffer, size_t vertices, const VertexAttribute *attrs) : Mesh( + vertexBuffer, vertices, nullptr, 0, attrs) { + }; + ~Mesh(); /// @brief Update GL vertex and index buffers data without changing VAO attributes /// @param vertexBuffer vertex data buffer - /// @param vertices number of vertices in new buffer + /// @param vertexCount number of vertices in new buffer /// @param indexBuffer indices buffer - /// @param indices number of values in indices buffer - void reload(const float* vertexBuffer, size_t vertices, const int* indexBuffer = nullptr, size_t indices = 0); - + /// @param indexCount number of values in indices buffer + void reload(const VertexStructure *vertexBuffer, size_t vertexCount, const uint32_t *indexBuffer = nullptr, + size_t indexCount = 0); + /// @brief Draw mesh with specified primitives type /// @param primitive primitives type void draw(unsigned int primitive) const; @@ -34,6 +46,6 @@ public: void draw() const; /// @brief Total numbers of alive mesh objects - static int meshesCount; - static int drawCalls; }; + +#include "graphics/core/Mesh.inl" diff --git a/src/graphics/core/Mesh.inl b/src/graphics/core/Mesh.inl new file mode 100644 index 00000000..163cf224 --- /dev/null +++ b/src/graphics/core/Mesh.inl @@ -0,0 +1,92 @@ +#pragma once + +#include + +#include "MeshData.hpp" + +template +Mesh::Mesh(const MeshData& data) + : Mesh(data.vertices.data(), + data.vertices.size(), + data.indices.data(), + data.indices.size(), + data.attrs.data()) {} + +template +Mesh::Mesh(const VertexStructure* vertexBuffer, size_t vertices, const uint32_t* indexBuffer, size_t indices, const VertexAttribute* attrs) : + ibo(0), + vao(0), + vbo(0), + vertexCount(0), + indexCount(0) +{ + MeshStats::meshesCount++; + vertexSize = 0; + for (int i = 0; attrs[i].count; i++) { + vertexSize += attrs[i].size(); + } + size_t tmp = sizeof(VertexStructure); + assert(vertexSize==tmp); + + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + + reload(vertexBuffer, vertices, indexBuffer, indices); + + // attributes + int offset = 0; + for (int i = 0; attrs[i].count; i++) { + const VertexAttribute &attr = attrs[i]; + glVertexAttribPointer(i, attr.count, attr.type, attr.normalized, sizeof(VertexStructure), (GLvoid*)(size_t)offset); + glEnableVertexAttribArray(i); + offset += attr.size(); + } + + glBindVertexArray(0); +} +template +Mesh::~Mesh(){ + MeshStats::meshesCount--; + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); + if (ibo != 0) glDeleteBuffers(1, &ibo); +} +template +void Mesh::reload(const VertexStructure *vertexBuffer, size_t vertexCount, const uint32_t *indexBuffer, size_t indexCount) { + this->vertexCount = vertexCount; + this->indexCount = indexCount; + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + if (vertexBuffer != nullptr && vertexCount != 0) { + glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vertexBuffer, GL_STREAM_DRAW); + } else { + glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STREAM_DRAW); + } + + if (indexBuffer != nullptr && indexCount != 0) { + if (ibo == 0) + glGenBuffers(1, &ibo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * indexCount, indexBuffer, GL_STATIC_DRAW); + } else if (ibo != 0) { + glDeleteBuffers(1, &ibo); + } + +} + +template +void Mesh::draw(unsigned int primitive) const { + MeshStats::drawCalls++; + glBindVertexArray(vao); + if (ibo != 0) { + glDrawElements(primitive, indexCount, GL_UNSIGNED_INT, nullptr); + } else { + glDrawArrays(primitive, 0, vertexCount); + } + glBindVertexArray(0); +} + +template +void Mesh::draw() const { + draw(GL_TRIANGLES); +} diff --git a/src/graphics/core/MeshData.hpp b/src/graphics/core/MeshData.hpp index 39220119..bf8c7307 100644 --- a/src/graphics/core/MeshData.hpp +++ b/src/graphics/core/MeshData.hpp @@ -1,19 +1,42 @@ #pragma once -#include +#include +#include #include "typedefs.hpp" #include "util/Buffer.hpp" /// @brief Vertex attribute info struct VertexAttribute { - ubyte size; + uint32_t type; + bool normalized; + ubyte count; + + + [[nodiscard]] uint32_t size() const { + switch (type) { + case GL_FLOAT: + return count * sizeof(float); + case GL_UNSIGNED_INT: + case GL_INT: + return count * sizeof(uint32_t); + case GL_UNSIGNED_SHORT: + case GL_SHORT: + return count * sizeof(uint16_t); + case GL_UNSIGNED_BYTE: + case GL_BYTE: + return count * sizeof(uint8_t); + default: + throw std::runtime_error("VertexAttribute type is not supported"); + } + } }; /// @brief Raw mesh data structure +template struct MeshData { - util::Buffer vertices; - util::Buffer indices; + util::Buffer vertices; + util::Buffer indices; util::Buffer attrs; MeshData() = default; @@ -22,8 +45,8 @@ struct MeshData { /// @param indices nullable indices buffer /// @param attrs vertex attribute sizes (must be null-terminated) MeshData( - util::Buffer vertices, - util::Buffer indices, + util::Buffer vertices, + util::Buffer indices, util::Buffer attrs ) : vertices(std::move(vertices)), indices(std::move(indices)), diff --git a/src/graphics/core/PostProcessing.cpp b/src/graphics/core/PostProcessing.cpp index c15aa8fb..93d85830 100644 --- a/src/graphics/core/PostProcessing.cpp +++ b/src/graphics/core/PostProcessing.cpp @@ -12,12 +12,16 @@ PostProcessing::PostProcessing(size_t effectSlotsCount) : effectSlots(effectSlotsCount) { // Fullscreen quad mesh bulding - float vertices[] { - -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, - -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f + PostProcessingVertex meshData[]{ + {{-1.0f, -1.0f}}, + {{-1.0f, 1.0f}}, + {{1.0f, 1.0f}}, + {{-1.0f, -1.0f}}, + {{1.0f, 1.0f}}, + {{1.0f, -1.0f}}, }; - VertexAttribute attrs[] {{2}, {0}}; - quadMesh = std::make_unique(vertices, 6, attrs); + + quadMesh = std::make_unique>(meshData, 6, PostProcessingVertex::ATTRIBUTES); } PostProcessing::~PostProcessing() = default; diff --git a/src/graphics/core/PostProcessing.hpp b/src/graphics/core/PostProcessing.hpp index 57a081c9..7252c239 100644 --- a/src/graphics/core/PostProcessing.hpp +++ b/src/graphics/core/PostProcessing.hpp @@ -2,14 +2,25 @@ #include #include +#include +#include "MeshData.hpp" -class Mesh; +template class Mesh; class Assets; class Framebuffer; class DrawContext; class ImageData; class PostEffect; +struct PostProcessingVertex { + glm::vec2 position; + + static constexpr VertexAttribute ATTRIBUTES[] { + {GL_FLOAT,false,2}, + {0} + }; +}; + /// @brief Framebuffer with blitting with shaders. /// @attention Current implementation does not support multiple render passes /// for multiple effects. Will be implemented in v0.21 @@ -18,7 +29,7 @@ class PostProcessing { std::unique_ptr fbo; std::unique_ptr fboSecond; /// @brief Fullscreen quad mesh as the post-processing canvas - std::unique_ptr quadMesh; + std::unique_ptr> quadMesh; std::vector> effectSlots; public: PostProcessing(size_t effectSlotsCount); diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 22bab4d8..983a4168 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -11,24 +11,25 @@ const glm::vec3 BlocksRenderer::SUN_VECTOR (0.2275f,0.9388f,-0.1005f); + BlocksRenderer::BlocksRenderer( size_t capacity, const Content& content, const ContentGfxCache& cache, const EngineSettings& settings ) : content(content), - vertexBuffer(std::make_unique(capacity * CHUNK_VERTEX_SIZE)), - indexBuffer(std::make_unique(capacity)), + vertexBuffer(std::make_unique(capacity)), + indexBuffer(std::make_unique(capacity)), + vertexCount(0), vertexOffset(0), - indexOffset(0), - indexSize(0), + indexCount(0), capacity(capacity), cache(cache), - settings(settings) + settings(settings) { voxelsBuffer = std::make_unique( - CHUNK_W + voxelBufferPadding*2, - CHUNK_H, + CHUNK_W + voxelBufferPadding*2, + CHUNK_H, CHUNK_D + voxelBufferPadding*2); blockDefsCache = content.getIndices()->blocks.getDefs(); } @@ -40,39 +41,31 @@ BlocksRenderer::~BlocksRenderer() { void BlocksRenderer::vertex( const glm::vec3& coord, float u, float v, const glm::vec4& light ) { - vertexBuffer[vertexOffset++] = coord.x; - vertexBuffer[vertexOffset++] = coord.y; - vertexBuffer[vertexOffset++] = coord.z; - vertexBuffer[vertexOffset++] = u; - vertexBuffer[vertexOffset++] = v; + vertexBuffer[vertexCount].position = coord; - union { - float floating; - uint32_t integer; - } compressed; + vertexBuffer[vertexCount].uv = {u,v}; - 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); - - vertexBuffer[vertexOffset++] = compressed.floating; + vertexBuffer[vertexCount].color[0] = static_cast(light.r * 255); + vertexBuffer[vertexCount].color[1] = static_cast(light.g * 255); + vertexBuffer[vertexCount].color[2] = static_cast(light.b * 255); + vertexBuffer[vertexCount].color[3] = static_cast(light.a * 255); + vertexCount++; } -void BlocksRenderer::index(int a, int b, int c, int d, int e, int f) { - indexBuffer[indexSize++] = indexOffset + a; - indexBuffer[indexSize++] = indexOffset + b; - indexBuffer[indexSize++] = indexOffset + c; - indexBuffer[indexSize++] = indexOffset + d; - indexBuffer[indexSize++] = indexOffset + e; - indexBuffer[indexSize++] = indexOffset + f; - indexOffset += 4; +void BlocksRenderer::index(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f) { + indexBuffer[indexCount++] = static_cast(vertexOffset + a); + indexBuffer[indexCount++] = static_cast(vertexOffset + b); + indexBuffer[indexCount++] = static_cast(vertexOffset + c); + indexBuffer[indexCount++] = static_cast(vertexOffset + d); + indexBuffer[indexCount++] = static_cast(vertexOffset + e); + indexBuffer[indexCount++] = static_cast(vertexOffset + f); + vertexOffset += 4; } /// @brief Add face with precalculated lights void BlocksRenderer::face( - const glm::vec3& coord, + const glm::vec3& coord, float w, float h, float d, const glm::vec3& axisX, const glm::vec3& axisY, @@ -81,7 +74,7 @@ void BlocksRenderer::face( const glm::vec4(&lights)[4], const glm::vec4& tint ) { - if (vertexOffset + CHUNK_VERTEX_SIZE * 4 > capacity) { + if (vertexCount + 4 >= capacity) { overflow = true; return; } @@ -97,7 +90,7 @@ void BlocksRenderer::face( } void BlocksRenderer::vertexAO( - const glm::vec3& coord, + const glm::vec3& coord, float u, float v, const glm::vec4& tint, const glm::vec3& axisX, @@ -121,7 +114,7 @@ void BlocksRenderer::faceAO( const UVRegion& region, bool lights ) { - if (vertexOffset + CHUNK_VERTEX_SIZE * 4 > capacity) { + if (vertexCount + 4 >= capacity) { overflow = true; return; } @@ -159,7 +152,7 @@ void BlocksRenderer::face( glm::vec4 tint, bool lights ) { - if (vertexOffset + CHUNK_VERTEX_SIZE * 4 > capacity) { + if (vertexCount + 4 >= capacity) { overflow = true; return; } @@ -178,10 +171,10 @@ void BlocksRenderer::face( } void BlocksRenderer::blockXSprite( - int x, int y, int z, - const glm::vec3& size, - const UVRegion& texface1, - const UVRegion& texface2, + int x, int y, int z, + const glm::vec3& size, + const UVRegion& texface1, + const UVRegion& texface2, float spread ) { glm::vec4 lights1[] { @@ -207,12 +200,12 @@ void BlocksRenderer::blockXSprite( face({x + xs, y, z + zs}, w, size.y, 0, {-1, 0, 1}, {0, 1, 0}, glm::vec3(), texface1, lights2, tint); - face({x + xs, y, z + zs}, w, size.y, 0, {1, 0, 1}, {0, 1, 0}, glm::vec3(), + face({x + xs, y, z + zs}, w, size.y, 0, {1, 0, 1}, {0, 1, 0}, glm::vec3(), texface1, lights1, tint); - face({x + xs, y, z + zs}, w, size.y, 0, {-1, 0, -1}, {0, 1, 0}, glm::vec3(), + face({x + xs, y, z + zs}, w, size.y, 0, {-1, 0, -1}, {0, 1, 0}, glm::vec3(), texface2, lights2, tint); - face({x + xs, y, z + zs}, w, size.y, 0, {1, 0, -1}, {0, 1, 0}, glm::vec3(), + face({x + xs, y, z + zs}, w, size.y, 0, {1, 0, -1}, {0, 1, 0}, glm::vec3(), texface2, lights1, tint); } @@ -221,8 +214,8 @@ void BlocksRenderer::blockXSprite( /// @brief AABB blocks render method void BlocksRenderer::blockAABB( const glm::ivec3& icoord, - const UVRegion(&texfaces)[6], - const Block* block, + const UVRegion(&texfaces)[6], + const Block* block, ubyte rotation, bool lights, bool ao @@ -249,7 +242,7 @@ void BlocksRenderer::blockAABB( orient.transform(hitbox); } coord -= glm::vec3(0.5f) - hitbox.center(); - + if (ao) { faceAO(coord, X*size.x, Y*size.y, Z*size.z, texfaces[5], lights); // north faceAO(coord, -X*size.x, Y*size.y, -Z*size.z, texfaces[4], lights); // south @@ -289,7 +282,7 @@ void BlocksRenderer::blockCustomModel( const auto& model = cache.getModel(block->rt.id); for (const auto& mesh : model.meshes) { - if (vertexOffset + CHUNK_VERTEX_SIZE * mesh.vertices.size() > capacity) { + if (vertexCount + mesh.vertices.size() >= capacity) { overflow = true; return; } @@ -314,7 +307,7 @@ void BlocksRenderer::blockCustomModel( r, n ); - indexBuffer[indexSize++] = indexOffset++; + indexBuffer[indexCount++] = vertexOffset++; } } } @@ -322,9 +315,9 @@ void BlocksRenderer::blockCustomModel( /* Fastest solid shaded blocks render method */ void BlocksRenderer::blockCube( - const glm::ivec3& coord, - const UVRegion(&texfaces)[6], - const Block& block, + const glm::ivec3& coord, + const UVRegion(&texfaces)[6], + const Block& block, blockstate states, bool lights, bool ao @@ -340,7 +333,7 @@ void BlocksRenderer::blockCube( Y = orient.axes[1]; Z = orient.axes[2]; } - + if (ao) { if (isOpen(coord + Z, block)) { faceAO(coord, X, Y, Z, texfaces[5], lights); @@ -383,8 +376,8 @@ void BlocksRenderer::blockCube( } bool BlocksRenderer::isOpenForLight(int x, int y, int z) const { - blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x, - y, + blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x, + y, chunk->z * CHUNK_D + z); if (id == BLOCK_VOID) { return false; @@ -398,7 +391,7 @@ bool BlocksRenderer::isOpenForLight(int x, int y, int z) const { glm::vec4 BlocksRenderer::pickLight(int x, int y, int z) const { if (isOpenForLight(x, y, z)) { - light_t light = voxelsBuffer->pickLight(chunk->x * CHUNK_W + x, y, + light_t light = voxelsBuffer->pickLight(chunk->x * CHUNK_W + x, y, chunk->z * CHUNK_D + z); return glm::vec4(Lightmap::extract(light, 0), Lightmap::extract(light, 1), @@ -426,8 +419,8 @@ glm::vec4 BlocksRenderer::pickSoftLight( float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up ) const { return pickSoftLight({ - static_cast(std::round(x)), - static_cast(std::round(y)), + static_cast(std::round(x)), + static_cast(std::round(y)), static_cast(std::round(z))}, right, up); } @@ -466,17 +459,17 @@ void BlocksRenderer::render( def.ambientOcclusion); break; case BlockModel::xsprite: { - blockXSprite(x, y, z, glm::vec3(1.0f), + blockXSprite(x, y, z, glm::vec3(1.0f), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); break; } case BlockModel::aabb: { - blockAABB({x, y, z}, texfaces, &def, vox.state.rotation, + blockAABB({x, y, z}, texfaces, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; } case BlockModel::custom: { - blockCustomModel({x, y, z}, &def, vox.state.rotation, + blockCustomModel({x, y, z}, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; } @@ -529,24 +522,24 @@ SortingMeshData BlocksRenderer::renderTranslucent( def.ambientOcclusion); break; case BlockModel::xsprite: { - blockXSprite(x, y, z, glm::vec3(1.0f), + blockXSprite(x, y, z, glm::vec3(1.0f), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); break; } case BlockModel::aabb: { - blockAABB({x, y, z}, texfaces, &def, vox.state.rotation, + blockAABB({x, y, z}, texfaces, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; } case BlockModel::custom: { - blockCustomModel({x, y, z}, &def, vox.state.rotation, + blockCustomModel({x, y, z}, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; } default: break; } - if (vertexOffset == 0) { + if (vertexCount == 0) { continue; } SortingMeshEntry entry { @@ -555,50 +548,50 @@ SortingMeshData BlocksRenderer::renderTranslucent( y + 0.5f, z + chunk->z * CHUNK_D + 0.5f ), - util::Buffer(indexSize * CHUNK_VERTEX_SIZE), 0}; + util::Buffer(indexCount), 0}; totalSize += entry.vertexData.size(); - for (int j = 0; j < indexSize; j++) { + for (int j = 0; j < indexCount; j++) { std::memcpy( - entry.vertexData.data() + j * CHUNK_VERTEX_SIZE, - vertexBuffer.get() + indexBuffer[j] * CHUNK_VERTEX_SIZE, - sizeof(float) * CHUNK_VERTEX_SIZE + entry.vertexData.data() + j, + vertexBuffer.get() + indexBuffer[j], + sizeof(ChunkVertex) ); - float& vx = entry.vertexData[j * CHUNK_VERTEX_SIZE + 0]; - float& vy = entry.vertexData[j * CHUNK_VERTEX_SIZE + 1]; - float& vz = entry.vertexData[j * CHUNK_VERTEX_SIZE + 2]; + ChunkVertex& vertex = entry.vertexData[j]; if (!aabbInit) { aabbInit = true; - aabb.a = aabb.b = {vx, vy, vz}; + aabb.a = aabb.b = vertex.position; } else { - aabb.addPoint(glm::vec3(vx, vy, vz)); + aabb.addPoint(vertex.position); } - vx += chunk->x * CHUNK_W + 0.5f; - vy += 0.5f; - vz += chunk->z * CHUNK_D + 0.5f; + + vertex.position.x += chunk->x * CHUNK_W + 0.5f; + vertex.position.y += 0.5f; + vertex.position.z += chunk->z * CHUNK_D + 0.5f; } sortingMesh.entries.push_back(std::move(entry)); - vertexOffset = 0; - indexOffset = indexSize = 0; + vertexCount = 0; + vertexOffset = indexCount = 0; } } // additional powerful optimization auto size = aabb.size(); - if ((size.y < 0.01f || size.x < 0.01f || size.z < 0.01f) && + if ((size.y < 0.01f || size.x < 0.01f || size.z < 0.01f) && sortingMesh.entries.size() > 1) { SortingMeshEntry newEntry { sortingMesh.entries[0].position, - util::Buffer(totalSize), + util::Buffer(totalSize), 0 }; size_t offset = 0; for (const auto& entry : sortingMesh.entries) { std::memcpy( newEntry.vertexData.data() + offset, - entry.vertexData.data(), entry.vertexData.size() * sizeof(float) + entry.vertexData.data(), + entry.vertexData.size() * sizeof(ChunkVertex) ); offset += entry.vertexData.size(); } @@ -630,7 +623,7 @@ void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) { const voxel& vox = voxels[i]; blockid_t id = vox.id; const auto& def = *blockDefsCache[id]; - + if (beginEnds[def.drawGroup][0] == 0) { beginEnds[def.drawGroup][0] = i+1; } @@ -639,36 +632,37 @@ void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) { cancelled = false; overflow = false; - vertexOffset = 0; - indexOffset = indexSize = 0; - + vertexCount = 0; + vertexOffset = indexCount = 0; + sortingMesh = renderTranslucent(voxels, beginEnds); - + overflow = false; + vertexCount = 0; vertexOffset = 0; - indexOffset = indexSize = 0; - + indexCount = 0; + render(voxels, beginEnds); } ChunkMeshData BlocksRenderer::createMesh() { - return ChunkMeshData { + return ChunkMeshData{ MeshData( - util::Buffer(vertexBuffer.get(), vertexOffset), - util::Buffer(indexBuffer.get(), indexSize), - util::Buffer( - CHUNK_VATTRS, sizeof(CHUNK_VATTRS) / sizeof(VertexAttribute) + util::Buffer(vertexBuffer.get(), vertexCount), + util::Buffer(indexBuffer.get(), indexCount), + util::Buffer( + ChunkVertex::ATTRIBUTES, sizeof(ChunkVertex::ATTRIBUTES) / sizeof(VertexAttribute) ) ), - std::move(sortingMesh)}; + std::move(sortingMesh) + }; } -ChunkMesh BlocksRenderer::render(const Chunk* chunk, const Chunks* chunks) { +ChunkMesh BlocksRenderer::render(const Chunk *chunk, const Chunks *chunks) { build(chunk, chunks); - size_t vcount = vertexOffset / CHUNK_VERTEX_SIZE; - return ChunkMesh{std::make_unique( - vertexBuffer.get(), vcount, indexBuffer.get(), indexSize, CHUNK_VATTRS + return ChunkMesh{std::make_unique>( + vertexBuffer.get(), vertexCount, indexBuffer.get(), indexCount, ChunkVertex::ATTRIBUTES ), std::move(sortingMesh)}; } diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index c652b6a0..1edcbfcc 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -1,7 +1,5 @@ #pragma once -#include -#include #include #include #include "voxels/voxel.hpp" @@ -10,28 +8,27 @@ #include "voxels/Block.hpp" #include "voxels/Chunk.hpp" #include "voxels/VoxelsVolume.hpp" -#include "graphics/core/MeshData.hpp" #include "maths/util.hpp" #include "commons.hpp" #include "settings.hpp" +template class Mesh; class Content; -class Mesh; class Block; class Chunk; class Chunks; class VoxelsVolume; -class Chunks; class ContentGfxCache; struct UVRegion; class BlocksRenderer { static const glm::vec3 SUN_VECTOR; const Content& content; - std::unique_ptr vertexBuffer; - std::unique_ptr indexBuffer; + std::unique_ptr vertexBuffer; + std::unique_ptr indexBuffer; + size_t vertexCount; size_t vertexOffset; - size_t indexOffset, indexSize; + size_t indexCount; size_t capacity; int voxelBufferPadding = 2; bool overflow = false; @@ -48,7 +45,7 @@ class BlocksRenderer { SortingMeshData sortingMesh; void vertex(const glm::vec3& coord, float u, float v, const glm::vec4& light); - void index(int a, int b, int c, int d, int e, int f); + void index(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f); void vertexAO( const glm::vec3& coord, float u, float v, diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 535baa59..1c5ca1a4 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -74,7 +74,7 @@ ChunksRenderer::ChunksRenderer( if (!result.cancelled) { auto meshData = std::move(result.meshData); meshes[result.key] = ChunkMesh { - std::make_unique(meshData.mesh), + std::make_unique>(meshData.mesh), std::move(meshData.sortingMesh)}; } inwork.erase(result.key); @@ -92,7 +92,7 @@ ChunksRenderer::ChunksRenderer( ChunksRenderer::~ChunksRenderer() { } -const Mesh* ChunksRenderer::render( +const Mesh* ChunksRenderer::render( const std::shared_ptr& chunk, bool important ) { chunk->flags.modified = false; @@ -125,7 +125,7 @@ void ChunksRenderer::clear() { threadPool.clearQueue(); } -const Mesh* ChunksRenderer::getOrRender( +const Mesh* ChunksRenderer::getOrRender( const std::shared_ptr& chunk, bool important ) { auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); @@ -142,7 +142,7 @@ void ChunksRenderer::update() { threadPool.update(); } -const Mesh* ChunksRenderer::retrieveChunk( +const Mesh* ChunksRenderer::retrieveChunk( size_t index, const Camera& camera, Shader& shader, bool culling ) { auto chunk = chunks.getChunks()[index]; @@ -234,14 +234,14 @@ void ChunksRenderer::drawChunks( } static inline void write_sorting_mesh_entries( - float* buffer, const std::vector& chunkEntries + ChunkVertex* buffer, const std::vector& chunkEntries ) { for (const auto& entry : chunkEntries) { const auto& vertexData = entry.vertexData; std::memcpy( buffer, vertexData.data(), - vertexData.size() * sizeof(float) + vertexData.size() * sizeof(ChunkVertex) ); buffer += vertexData.size(); } @@ -288,10 +288,10 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { if (chunkEntries.size() == 1) { auto& entry = chunkEntries.at(0); if (found->second.sortedMesh == nullptr) { - found->second.sortedMesh = std::make_unique( + found->second.sortedMesh = std::make_unique>( entry.vertexData.data(), - entry.vertexData.size() / CHUNK_VERTEX_SIZE, - CHUNK_VATTRS + entry.vertexData.size(), + ChunkVertex::ATTRIBUTES ); } found->second.sortedMesh->draw(); @@ -310,13 +310,13 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { size += entry.vertexData.size(); } - static util::Buffer buffer; + static util::Buffer buffer; if (buffer.size() < size) { - buffer = util::Buffer(size); + buffer = util::Buffer(size); } write_sorting_mesh_entries(buffer.data(), chunkEntries); - found->second.sortedMesh = std::make_unique( - buffer.data(), size / CHUNK_VERTEX_SIZE, CHUNK_VATTRS + found->second.sortedMesh = std::make_unique>( + buffer.data(), size, ChunkVertex::ATTRIBUTES ); } found->second.sortedMesh->draw(); diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index 3e2ca9d9..aa9833af 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -9,12 +8,10 @@ #define GLM_ENABLE_EXPERIMENTAL #include -#include "voxels/Block.hpp" #include "util/ThreadPool.hpp" -#include "graphics/core/MeshData.hpp" #include "commons.hpp" -class Mesh; +template class Mesh; class Chunk; class Level; class Camera; @@ -52,7 +49,7 @@ class ChunksRenderer { std::unordered_map inwork; std::vector indices; util::ThreadPool, RendererResult> threadPool; - const Mesh* retrieveChunk( + const Mesh* retrieveChunk( size_t index, const Camera& camera, Shader& shader, bool culling ); public: @@ -66,13 +63,13 @@ public: ); virtual ~ChunksRenderer(); - const Mesh* render( + const Mesh* render( const std::shared_ptr& chunk, bool important ); void unload(const Chunk* chunk); void clear(); - const Mesh* getOrRender( + const Mesh* getOrRender( const std::shared_ptr& chunk, bool important ); void drawChunks(const Camera& camera, Shader& shader); diff --git a/src/graphics/render/MainBatch.cpp b/src/graphics/render/MainBatch.cpp index a440a43b..bd8d04b9 100644 --- a/src/graphics/render/MainBatch.cpp +++ b/src/graphics/render/MainBatch.cpp @@ -6,18 +6,15 @@ #include "voxels/Chunks.hpp" #include "voxels/Chunk.hpp" -static const VertexAttribute attrs[] = { - {3}, {2}, {3}, {1}, {0} -}; MainBatch::MainBatch(size_t capacity) - : buffer(std::make_unique(capacity * VERTEX_SIZE)), - capacity(capacity), - index(0), - mesh(std::make_unique(buffer.get(), 0, attrs)) { + : buffer(std::make_unique(capacity)), + capacity(capacity), + index(0), + mesh(std::make_unique>(buffer.get(), 0, MainBatchVertex::ATTRIBUTES)) { const ubyte pixels[] = { - 255, 255, 255, 255, + 255, 255, 255, 255, }; ImageData image(ImageFormat::rgba8888, 1, 1, pixels); blank = Texture::from(&image); @@ -25,7 +22,7 @@ MainBatch::MainBatch(size_t capacity) MainBatch::~MainBatch() = default; -void MainBatch::setTexture(const Texture* texture) { +void MainBatch::setTexture(const Texture *texture) { if (texture == nullptr) { texture = blank.get(); } @@ -33,10 +30,10 @@ void MainBatch::setTexture(const Texture* texture) { flush(); } this->texture = texture; - region = UVRegion {0.0f, 0.0f, 1.0f, 1.0f}; + region = UVRegion{0.0f, 0.0f, 1.0f, 1.0f}; } -void MainBatch::setTexture(const Texture* texture, const UVRegion& region) { +void MainBatch::setTexture(const Texture *texture, const UVRegion ®ion) { setTexture(texture); this->region = region; } @@ -49,7 +46,7 @@ void MainBatch::flush() { texture = blank.get(); } texture->bind(); - mesh->reload(buffer.get(), index / VERTEX_SIZE); + mesh->reload(buffer.get(), index); mesh->draw(); index = 0; } @@ -60,76 +57,76 @@ void MainBatch::begin() { } void MainBatch::prepare(int vertices) { - if (index + VERTEX_SIZE * vertices > capacity * VERTEX_SIZE) { + if (index * vertices > capacity) { flush(); } } glm::vec4 MainBatch::sampleLight( - const glm::vec3& pos, const Chunks& chunks, bool backlight + const glm::vec3 &pos, const Chunks &chunks, bool backlight ) { light_t light = chunks.getLight( - std::floor(pos.x), - std::floor(std::min(CHUNK_H-1.0f, pos.y)), - std::floor(pos.z)); + std::floor(pos.x), + std::floor(std::min(CHUNK_H - 1.0f, pos.y)), + std::floor(pos.z)); light_t minIntensity = backlight ? 1 : 0; - return glm::vec4( - glm::max(Lightmap::extract(light, 0), minIntensity) / 15.0f, - glm::max(Lightmap::extract(light, 1), minIntensity) / 15.0f, - glm::max(Lightmap::extract(light, 2), minIntensity) / 15.0f, - glm::max(Lightmap::extract(light, 3), minIntensity) / 15.0f - ); + return { + (float) glm::max(Lightmap::extract(light, 0), minIntensity) / 15.0f, + (float) glm::max(Lightmap::extract(light, 1), minIntensity) / 15.0f, + (float) glm::max(Lightmap::extract(light, 2), minIntensity) / 15.0f, + (float) glm::max(Lightmap::extract(light, 3), minIntensity) / 15.0f + }; } inline glm::vec4 do_tint(float value) { - return glm::vec4(value, value, value, 1.0f); + return {value, value, value, 1.0f}; } void MainBatch::cube( - const glm::vec3& coord, - const glm::vec3& size, - const UVRegion(&texfaces)[6], - const glm::vec4& tint, - bool shading + const glm::vec3 &coord, + const glm::vec3 &size, + const UVRegion(&texfaces)[6], + const glm::vec4 &tint, + bool shading ) { const glm::vec3 X(1.0f, 0.0f, 0.0f); const glm::vec3 Y(0.0f, 1.0f, 0.0f); const glm::vec3 Z(0.0f, 0.0f, 1.0f); quad( - coord + Z * size.z * 0.5f, - X, Y, glm::vec2(size.x, size.y), - (shading ? do_tint(0.8) * tint : tint), - glm::vec3(1.0f), texfaces[5] + coord + Z * size.z * 0.5f, + X, Y, glm::vec2(size.x, size.y), + (shading ? do_tint(0.8) * tint : tint), + glm::vec3(1.0f), texfaces[5] ); quad( - coord - Z * size.z * 0.5f, - -X, Y, glm::vec2(size.x, size.y), - (shading ? do_tint(0.9f) * tint : tint), - glm::vec3(1.0f), texfaces[4] + coord - Z * size.z * 0.5f, + -X, Y, glm::vec2(size.x, size.y), + (shading ? do_tint(0.9f) * tint : tint), + glm::vec3(1.0f), texfaces[4] ); quad( - coord + Y * size.y * 0.5f, - -X, Z, glm::vec2(size.x, size.z), - (shading ? do_tint(1.0f) * tint : tint), - glm::vec3(1.0f), texfaces[3] + coord + Y * size.y * 0.5f, + -X, Z, glm::vec2(size.x, size.z), + (shading ? do_tint(1.0f) * tint : tint), + glm::vec3(1.0f), texfaces[3] ); quad( - coord - Y * size.y * 0.5f, - X, Z, glm::vec2(size.x, size.z), - (shading ? do_tint(0.7f) * tint : tint), - glm::vec3(1.0f), texfaces[2] + coord - Y * size.y * 0.5f, + X, Z, glm::vec2(size.x, size.z), + (shading ? do_tint(0.7f) * tint : tint), + glm::vec3(1.0f), texfaces[2] ); quad( - coord + X * size.x * 0.5f, - -Z, Y, glm::vec2(size.z, size.y), - (shading ? do_tint(0.8f) * tint : tint), - glm::vec3(1.0f), texfaces[1] + coord + X * size.x * 0.5f, + -Z, Y, glm::vec2(size.z, size.y), + (shading ? do_tint(0.8f) * tint : tint), + glm::vec3(1.0f), texfaces[1] ); quad( - coord - X * size.x * 0.5f, - Z, Y, glm::vec2(size.z, size.y), - (shading ? do_tint(0.9f) * tint : tint), - glm::vec3(1.0f), texfaces[1] + coord - X * size.x * 0.5f, + Z, Y, glm::vec2(size.z, size.y), + (shading ? do_tint(0.9f) * tint : tint), + glm::vec3(1.0f), texfaces[1] ); } diff --git a/src/graphics/render/MainBatch.hpp b/src/graphics/render/MainBatch.hpp index 36bf7a8e..d5afb569 100644 --- a/src/graphics/render/MainBatch.hpp +++ b/src/graphics/render/MainBatch.hpp @@ -1,30 +1,47 @@ #pragma once +#include #include -#include +#include #include #include "typedefs.hpp" #include "maths/UVRegion.hpp" +#include "graphics/core/MeshData.hpp" +template class Mesh; class Texture; class Chunks; +struct MainBatchVertex { + glm::vec3 position; + glm::vec2 uv; + glm::vec3 tint; + std::array color; + + static constexpr VertexAttribute ATTRIBUTES[] = { + {GL_FLOAT, false, 3}, + {GL_FLOAT, false, 2}, + {GL_FLOAT, false, 3}, + {GL_UNSIGNED_BYTE, true, 4}, + {0} + }; +}; + class MainBatch { - std::unique_ptr const buffer; + std::unique_ptr const buffer; size_t const capacity; size_t index; UVRegion region {0.0f, 0.0f, 1.0f, 1.0f}; - std::unique_ptr mesh; + std::unique_ptr> mesh; std::unique_ptr blank; const Texture* texture = nullptr; public: /// xyz, uv, color, compressed lights - static inline constexpr uint VERTEX_SIZE = 9; MainBatch(size_t capacity); @@ -47,27 +64,16 @@ public: const glm::vec4& light, const glm::vec3& tint ) { - float* buffer = this->buffer.get(); - buffer[index++] = pos.x; - buffer[index++] = pos.y; - buffer[index++] = pos.z; - buffer[index++] = uv.x * region.getWidth() + region.u1; - buffer[index++] = uv.y * region.getHeight() + region.v1; - buffer[index++] = tint.x; - buffer[index++] = tint.y; - buffer[index++] = tint.z; + MainBatchVertex* buffer = this->buffer.get(); + buffer[index].position = pos; + buffer[index].uv = {uv.x * region.getWidth() + region.u1,uv.y * region.getHeight() + region.v1}; + buffer[index].tint = tint; - union { - float floating; - uint32_t integer; - } compressed; - - 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; + buffer[index].color[0] = static_cast(light.r * 255); + buffer[index].color[1] = static_cast(light.g * 255); + buffer[index].color[2] = static_cast(light.b * 255); + buffer[index].color[3] = static_cast(light.a * 255); + index++; } inline void quad( diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index 4faf0ea8..e9323786 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -1,14 +1,12 @@ #pragma once -#include "maths/UVRegion.hpp" - #include #include #include #include #include -class Mesh; +template class Mesh; class Texture; class Chunks; class Assets; diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index 479bef85..b724de32 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -24,10 +24,10 @@ const int STARS_COUNT = 3000; const int STARS_SEED = 632; -Skybox::Skybox(uint size, Shader& shader) - : size(size), - shader(shader), - batch3d(std::make_unique(4096)) +Skybox::Skybox(uint size, Shader& shader) + : size(size), + shader(shader), + batch3d(std::make_unique(4096)) { auto cubemap = std::make_unique(size, size, ImageFormat::rgb888); @@ -35,12 +35,16 @@ Skybox::Skybox(uint size, Shader& shader) glGenFramebuffers(1, &fboid); fbo = std::make_unique(fboid, 0, std::move(cubemap)); - float vertices[] { - -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, - -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f + SkyboxVertex vertices[]{ + {{-1.0f, -1.0f}}, + {{-1.0f, 1.0f}}, + {{1.0f, 1.0f}}, + {{-1.0f, -1.0f}}, + {{1.0f, 1.0f}}, + {{1.0f, -1.0f}} }; - VertexAttribute attrs[] {{2}, {0}}; - mesh = std::make_unique(vertices, 6, attrs); + + mesh = std::make_unique>(vertices, 6, SkyboxVertex::ATTRIBUTES); sprites.push_back(skysprite { "misc/moon", @@ -95,11 +99,11 @@ void Skybox::drawStars(float angle, float opacity) { } void Skybox::draw( - const DrawContext& pctx, - const Camera& camera, - const Assets& assets, + const DrawContext& pctx, + const Camera& camera, + const Assets& assets, float daytime, - float fog) + float fog) { const glm::uvec2& viewport = pctx.getViewport(); @@ -116,7 +120,7 @@ void Skybox::draw( float angle = daytime * glm::pi() * 2.0f; float opacity = glm::pow(1.0f-fog, 7.0f); - + for (auto& sprite : sprites) { batch3d->texture(assets.get(sprite.texture)); @@ -129,7 +133,7 @@ void Skybox::draw( if (!sprite.emissive) { tint *= 0.6f+std::cos(angle)*0.4; } - batch3d->sprite(pos, glm::vec3(0, 0, 1), + batch3d->sprite(pos, glm::vec3(0, 0, 1), up, 1, 1, UVRegion(), tint); } @@ -153,7 +157,7 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, uint quality) cubemap->bind(); shader.use(); t *= glm::pi()*2.0f; - + lightDir = glm::normalize(glm::vec3(sin(t), -cos(t), 0.0f)); shader.uniform1i("u_quality", quality); shader.uniform1f("u_mie", mie); @@ -171,7 +175,7 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, uint quality) } prevMie = mie; prevT = t; - + cubemap->unbind(); glActiveTexture(GL_TEXTURE0); } @@ -190,7 +194,7 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) { {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, - + {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, @@ -200,7 +204,7 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) { {1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, - + {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}, diff --git a/src/graphics/render/Skybox.hpp b/src/graphics/render/Skybox.hpp index a539ae07..6b01cd1e 100644 --- a/src/graphics/render/Skybox.hpp +++ b/src/graphics/render/Skybox.hpp @@ -6,17 +6,23 @@ #include #include "typedefs.hpp" #include "maths/fastmaths.hpp" +#include "graphics/core/MeshData.hpp" -class Mesh; +template class Mesh; class Shader; class Assets; class Camera; class Batch3D; -class Shader; class Cubemap; class Framebuffer; class DrawContext; +struct SkyboxVertex { + glm::vec2 position; + + static constexpr VertexAttribute ATTRIBUTES[] {{GL_FLOAT,false,2}, {0}}; +}; + struct skysprite { std::string texture; float phase; @@ -32,7 +38,7 @@ class Skybox { FastRandom random; glm::vec3 lightDir; - std::unique_ptr mesh; + std::unique_ptr> mesh; std::unique_ptr batch3d; std::vector sprites; int frameid = 0; diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 79b77393..1c697545 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -1,25 +1,43 @@ #pragma once #include +#include #include +#include #include #include "graphics/core/MeshData.hpp" #include "util/Buffer.hpp" -/// @brief Chunk mesh vertex attributes -inline const VertexAttribute CHUNK_VATTRS[]{ {3}, {2}, {1}, {0} }; -/// @brief Chunk mesh vertex size divided by sizeof(float) -inline constexpr int CHUNK_VERTEX_SIZE = 6; + +/// @brief Chunk mesh vertex format +#pragma pack(push, 2) +struct ChunkVertex { + glm::vec3 position; + glm::vec2 uv; + std::array color; + + static constexpr VertexAttribute ATTRIBUTES[] = { + {GL_FLOAT, false, 3}, + {GL_FLOAT, false, 2}, + {GL_UNSIGNED_BYTE, true, 4}, + {0} + }; +}; +#pragma pack(pop) + +/// @brief Chunk mesh vertex attributes + +template class Mesh; struct SortingMeshEntry { glm::vec3 position; - util::Buffer vertexData; + util::Buffer vertexData; long long distance; - inline bool operator<(const SortingMeshEntry& o) const noexcept { + inline bool operator<(const SortingMeshEntry &o) const noexcept { return distance > o.distance; } }; @@ -29,12 +47,12 @@ struct SortingMeshData { }; struct ChunkMeshData { - MeshData mesh; + MeshData mesh; SortingMeshData sortingMesh; }; struct ChunkMesh { - std::unique_ptr mesh; + std::unique_ptr > mesh; SortingMeshData sortingMeshData; - std::unique_ptr sortedMesh = nullptr; + std::unique_ptr > sortedMesh = nullptr; }; From 9bb6cdfec2e543e604cc51b5e0dd2078fe5bc1db Mon Sep 17 00:00:00 2001 From: REDxEYE Date: Sat, 29 Mar 2025 22:22:29 +0300 Subject: [PATCH 02/21] Remove debug code --- CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0dac68cd..6966e81f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,11 +49,3 @@ if(VOXELENGINE_BUILD_TESTS) endif() add_subdirectory(vctest) - -add_custom_target(copy_resources ALL - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/res - ${CMAKE_CURRENT_BINARY_DIR}/res - COMMENT "Copying resource directory to the build directory" -) -add_dependencies(${PROJECT_NAME} copy_resources) \ No newline at end of file From 90605c6d5f15ce422d02a14e23aa5eca84165f41 Mon Sep 17 00:00:00 2001 From: REDxEYE Date: Sat, 29 Mar 2025 22:26:36 +0300 Subject: [PATCH 03/21] Replace assert with std::runtime_error --- src/graphics/core/Mesh.inl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/graphics/core/Mesh.inl b/src/graphics/core/Mesh.inl index 163cf224..756353b3 100644 --- a/src/graphics/core/Mesh.inl +++ b/src/graphics/core/Mesh.inl @@ -25,8 +25,9 @@ Mesh::Mesh(const VertexStructure* vertexBuffer, size_t vertices for (int i = 0; attrs[i].count; i++) { vertexSize += attrs[i].size(); } - size_t tmp = sizeof(VertexStructure); - assert(vertexSize==tmp); + if(vertexSize!=sizeof(VertexStructure)){ + throw std::runtime_error("Vertex size mismatch!"); + } glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); From 40a515227a8c22e8eab35aa0cc2d09d05559445b Mon Sep 17 00:00:00 2001 From: REDxEYE Date: Sun, 30 Mar 2025 01:54:31 +0300 Subject: [PATCH 04/21] Remove unused pragma pack --- src/graphics/render/commons.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 1c697545..9a54e7fe 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -12,7 +12,6 @@ /// @brief Chunk mesh vertex format -#pragma pack(push, 2) struct ChunkVertex { glm::vec3 position; glm::vec2 uv; @@ -25,7 +24,6 @@ struct ChunkVertex { {0} }; }; -#pragma pack(pop) /// @brief Chunk mesh vertex attributes From 0e73f6533134166de35755c7a83b568bc90a1c13 Mon Sep 17 00:00:00 2001 From: REDxEYE Date: Sun, 30 Mar 2025 01:59:39 +0300 Subject: [PATCH 05/21] Cleanup --- res/shaders/entity.glslv | 5 ++--- res/shaders/main.glslv | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/res/shaders/entity.glslv b/res/shaders/entity.glslv index 587a4bae..3d916e9a 100644 --- a/res/shaders/entity.glslv +++ b/res/shaders/entity.glslv @@ -31,8 +31,7 @@ void main() { vec3 pos3d = modelpos.xyz - u_cameraPos; modelpos.xyz = apply_planet_curvature(modelpos.xyz, pos3d); - vec4 decomp_light = v_light; - vec3 light = decomp_light.rgb; + vec3 light = v_light.rgb; float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) / u_torchlightDistance); light += torchlight * u_torchlightColor; @@ -41,7 +40,7 @@ void main() { a_dir = modelpos.xyz - u_cameraPos; vec3 skyLightColor = pick_sky_color(u_cubemap); - a_color.rgb = max(a_color.rgb, skyLightColor.rgb*decomp_light.a) * v_color; + a_color.rgb = max(a_color.rgb, skyLightColor.rgb*v_light.a) * v_color; a_color.a = u_opacity; float dist = length(u_view * u_model * vec4(pos3d * FOG_POS_SCALE, 0.0)); diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index a634e1ba..24ec6cae 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -31,8 +31,7 @@ void main() { vec3 pos3d = modelpos.xyz-u_cameraPos; modelpos.xyz = apply_planet_curvature(modelpos.xyz, pos3d); - vec4 decomp_light = v_light; - vec3 light = decomp_light.rgb; + vec3 light = v_light.rgb; float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) / u_torchlightDistance); light += torchlight * u_torchlightColor; @@ -41,7 +40,7 @@ void main() { a_dir = modelpos.xyz - u_cameraPos; vec3 skyLightColor = pick_sky_color(u_cubemap); - a_color.rgb = max(a_color.rgb, skyLightColor.rgb*decomp_light.a); + a_color.rgb = max(a_color.rgb, skyLightColor.rgb*v_light.a); a_distance = length(u_view * u_model * vec4(pos3d * FOG_POS_SCALE, 0.0)); float depth = (a_distance / 256.0); From 9730454b907ba7f6831d5a6b162b09c6fbfda146 Mon Sep 17 00:00:00 2001 From: REDxEYE Date: Sun, 30 Mar 2025 02:03:50 +0300 Subject: [PATCH 06/21] Add back `default-vs-msvc-windows` preset used in CI --- CMakePresets.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakePresets.json b/CMakePresets.json index 3992caac..47ba71e3 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -55,6 +55,11 @@ "configurePreset": "default-vs-msvc-windows", "configuration": "Release" }, + { + "name": "default-vs-msvc-windows", + "configurePreset": "default-vs-msvc-windows", + "configuration": "Debug" + }, { "name": "default-ninja-gnu-linux", "configurePreset": "default-ninja-gnu-linux", From 3a54a37b062eb9354a4d9565a88dfd5e96ab0932 Mon Sep 17 00:00:00 2001 From: REDxEYE Date: Thu, 3 Apr 2025 14:26:25 +0300 Subject: [PATCH 07/21] Remove unnecessary glew includes. Remove copyright from Mesh.cpp Add default initializers for VertexAttribute --- src/graphics/core/Mesh.cpp | 4 ---- src/graphics/core/Mesh.inl | 2 -- src/graphics/core/MeshData.hpp | 6 +++--- src/graphics/render/commons.hpp | 1 - 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/graphics/core/Mesh.cpp b/src/graphics/core/Mesh.cpp index 5df57129..f1f79f3e 100644 --- a/src/graphics/core/Mesh.cpp +++ b/src/graphics/core/Mesh.cpp @@ -1,7 +1,3 @@ -// -// Created by RED on 24.03.2025. -// - #include "graphics/core/Mesh.hpp" int MeshStats::meshesCount = 0; diff --git a/src/graphics/core/Mesh.inl b/src/graphics/core/Mesh.inl index 756353b3..5e1edcf2 100644 --- a/src/graphics/core/Mesh.inl +++ b/src/graphics/core/Mesh.inl @@ -1,7 +1,5 @@ #pragma once -#include - #include "MeshData.hpp" template diff --git a/src/graphics/core/MeshData.hpp b/src/graphics/core/MeshData.hpp index bf8c7307..1bcceb9e 100644 --- a/src/graphics/core/MeshData.hpp +++ b/src/graphics/core/MeshData.hpp @@ -8,9 +8,9 @@ /// @brief Vertex attribute info struct VertexAttribute { - uint32_t type; - bool normalized; - ubyte count; + uint32_t type = 0; + bool normalized = false; + ubyte count = 0; [[nodiscard]] uint32_t size() const { diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 9a54e7fe..96e53864 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include "graphics/core/MeshData.hpp" From 7a344a31c2567c7d6df98021b5953e0fff8f55dd Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 23:13:38 +0300 Subject: [PATCH 08/21] =?UTF-8?q?fix=20warning:=20=E2=80=98Mesh::ibo=E2=80=99=20will=20be=20initialized=20after=20[-Wreord?= =?UTF-8?q?er]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/graphics/core/Mesh.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/core/Mesh.inl b/src/graphics/core/Mesh.inl index 5e1edcf2..72351dd4 100644 --- a/src/graphics/core/Mesh.inl +++ b/src/graphics/core/Mesh.inl @@ -12,9 +12,9 @@ Mesh::Mesh(const MeshData& data) template Mesh::Mesh(const VertexStructure* vertexBuffer, size_t vertices, const uint32_t* indexBuffer, size_t indices, const VertexAttribute* attrs) : - ibo(0), vao(0), vbo(0), + ibo(0), vertexCount(0), indexCount(0) { From ec0dbae3f7636606cddebc8f67dde2c8856ae47b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 23:27:45 +0300 Subject: [PATCH 09/21] remove extra glew includes --- src/coders/png.cpp | 1 - src/graphics/core/Batch2D.cpp | 2 -- src/graphics/core/Batch3D.cpp | 1 - src/graphics/core/MeshData.hpp | 9 ++++----- src/graphics/render/WorldRenderer.cpp | 1 - 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/coders/png.cpp b/src/coders/png.cpp index ddf5fea8..ce40e9cc 100644 --- a/src/coders/png.cpp +++ b/src/coders/png.cpp @@ -1,7 +1,6 @@ #include "png.hpp" #include -#include #include diff --git a/src/graphics/core/Batch2D.cpp b/src/graphics/core/Batch2D.cpp index 1d2362d2..0da82ccd 100644 --- a/src/graphics/core/Batch2D.cpp +++ b/src/graphics/core/Batch2D.cpp @@ -4,8 +4,6 @@ #include "gl_util.hpp" #include "maths/UVRegion.hpp" -#include - #include diff --git a/src/graphics/core/Batch3D.cpp b/src/graphics/core/Batch3D.cpp index 862bc677..bd79b127 100644 --- a/src/graphics/core/Batch3D.cpp +++ b/src/graphics/core/Batch3D.cpp @@ -3,7 +3,6 @@ #include "Mesh.hpp" #include "Texture.hpp" -#include #include "typedefs.hpp" #include "maths/UVRegion.hpp" diff --git a/src/graphics/core/MeshData.hpp b/src/graphics/core/MeshData.hpp index 1bcceb9e..53229584 100644 --- a/src/graphics/core/MeshData.hpp +++ b/src/graphics/core/MeshData.hpp @@ -12,20 +12,19 @@ struct VertexAttribute { bool normalized = false; ubyte count = 0; - [[nodiscard]] uint32_t size() const { switch (type) { case GL_FLOAT: - return count * sizeof(float); + return count * sizeof(GLfloat); case GL_UNSIGNED_INT: case GL_INT: - return count * sizeof(uint32_t); + return count * sizeof(GLint); case GL_UNSIGNED_SHORT: case GL_SHORT: - return count * sizeof(uint16_t); + return count * sizeof(GLshort); case GL_UNSIGNED_BYTE: case GL_BYTE: - return count * sizeof(uint8_t); + return count * sizeof(GLbyte); default: throw std::runtime_error("VertexAttribute type is not supported"); } diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 04a0e427..79a9edfc 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -1,6 +1,5 @@ #include "WorldRenderer.hpp" -#include #include #include From 47b74722316ada28e25168e64eb24a73f7520a20 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 00:35:54 +0300 Subject: [PATCH 10/21] remove GLEW from MeshData.hpp & format Mesh.inl --- src/graphics/core/Batch2D.hpp | 9 ++- src/graphics/core/Batch3D.hpp | 9 ++- src/graphics/core/LineBatch.hpp | 5 +- src/graphics/core/Mesh.inl | 87 ++++++++++++++++++---------- src/graphics/core/MeshData.hpp | 32 +++++----- src/graphics/core/PostProcessing.hpp | 5 +- src/graphics/core/gl_util.hpp | 21 +++++++ src/graphics/render/MainBatch.hpp | 11 ++-- src/graphics/render/Skybox.hpp | 4 +- src/graphics/render/commons.hpp | 12 ++-- 10 files changed, 125 insertions(+), 70 deletions(-) diff --git a/src/graphics/core/Batch2D.hpp b/src/graphics/core/Batch2D.hpp index 03b2a866..6f29a1df 100644 --- a/src/graphics/core/Batch2D.hpp +++ b/src/graphics/core/Batch2D.hpp @@ -17,11 +17,10 @@ struct Batch2DVertex { glm::vec4 color; static constexpr VertexAttribute ATTRIBUTES[] { - {GL_FLOAT, false, 2}, - {GL_FLOAT, false,2}, - {GL_FLOAT, false, 4}, - {0} - }; + {VertexAttribute::Type::FLOAT, false, 2}, + {VertexAttribute::Type::FLOAT, false, 2}, + {VertexAttribute::Type::FLOAT, false, 4}, + {{}, 0}}; }; class Batch2D : public Flushable { diff --git a/src/graphics/core/Batch3D.hpp b/src/graphics/core/Batch3D.hpp index 6cb03ac0..c3fb3775 100644 --- a/src/graphics/core/Batch3D.hpp +++ b/src/graphics/core/Batch3D.hpp @@ -19,11 +19,10 @@ struct Batch3DVertex { glm::vec4 color; static constexpr VertexAttribute ATTRIBUTES[] { - {GL_FLOAT, false, 3}, - {GL_FLOAT, false, 2}, - {GL_FLOAT, false, 4}, - {0} - }; + {VertexAttribute::Type::FLOAT, false, 3}, + {VertexAttribute::Type::FLOAT, false, 2}, + {VertexAttribute::Type::FLOAT, false, 4}, + {{}, 0}}; }; class Batch3D : public Flushable { diff --git a/src/graphics/core/LineBatch.hpp b/src/graphics/core/LineBatch.hpp index 123c5407..eb32e1ee 100644 --- a/src/graphics/core/LineBatch.hpp +++ b/src/graphics/core/LineBatch.hpp @@ -14,7 +14,10 @@ struct LineVertex { glm::vec3 position; glm::vec4 color; - static constexpr VertexAttribute ATTRIBUTES[] { {GL_FLOAT,false,3},{GL_FLOAT,false,4}, {0} }; + static constexpr VertexAttribute ATTRIBUTES[] { + {VertexAttribute::Type::FLOAT, false, 3}, + {VertexAttribute::Type::FLOAT, false, 4}, + {{}, 0}}; }; class LineBatch : public Flushable { diff --git a/src/graphics/core/Mesh.inl b/src/graphics/core/Mesh.inl index 72351dd4..33812958 100644 --- a/src/graphics/core/Mesh.inl +++ b/src/graphics/core/Mesh.inl @@ -1,29 +1,34 @@ #pragma once #include "MeshData.hpp" +#include "gl_util.hpp" -template +template Mesh::Mesh(const MeshData& data) - : Mesh(data.vertices.data(), - data.vertices.size(), - data.indices.data(), - data.indices.size(), - data.attrs.data()) {} + : Mesh( + data.vertices.data(), + data.vertices.size(), + data.indices.data(), + data.indices.size(), + data.attrs.data() + ) { +} -template -Mesh::Mesh(const VertexStructure* vertexBuffer, size_t vertices, const uint32_t* indexBuffer, size_t indices, const VertexAttribute* attrs) : - vao(0), - vbo(0), - ibo(0), - vertexCount(0), - indexCount(0) -{ +template +Mesh::Mesh( + const VertexStructure* vertexBuffer, + size_t vertices, + const uint32_t* indexBuffer, + size_t indices, + const VertexAttribute* attrs +) + : vao(0), vbo(0), ibo(0), vertexCount(0), indexCount(0) { MeshStats::meshesCount++; vertexSize = 0; for (int i = 0; attrs[i].count; i++) { vertexSize += attrs[i].size(); } - if(vertexSize!=sizeof(VertexStructure)){ + if (vertexSize != sizeof(VertexStructure)) { throw std::runtime_error("Vertex size mismatch!"); } @@ -35,45 +40,69 @@ Mesh::Mesh(const VertexStructure* vertexBuffer, size_t vertices // attributes int offset = 0; for (int i = 0; attrs[i].count; i++) { - const VertexAttribute &attr = attrs[i]; - glVertexAttribPointer(i, attr.count, attr.type, attr.normalized, sizeof(VertexStructure), (GLvoid*)(size_t)offset); + const VertexAttribute& attr = attrs[i]; + glVertexAttribPointer( + i, + attr.count, + gl::to_glenum(attr.type), + attr.normalized, + sizeof(VertexStructure), + (GLvoid*)(size_t)offset + ); glEnableVertexAttribArray(i); offset += attr.size(); } glBindVertexArray(0); } -template -Mesh::~Mesh(){ + +template +Mesh::~Mesh() { MeshStats::meshesCount--; glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); - if (ibo != 0) glDeleteBuffers(1, &ibo); + if (ibo != 0) { + glDeleteBuffers(1, &ibo); + } } -template -void Mesh::reload(const VertexStructure *vertexBuffer, size_t vertexCount, const uint32_t *indexBuffer, size_t indexCount) { + +template +void Mesh::reload( + const VertexStructure* vertexBuffer, + size_t vertexCount, + const uint32_t* indexBuffer, + size_t indexCount +) { this->vertexCount = vertexCount; this->indexCount = indexCount; glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); if (vertexBuffer != nullptr && vertexCount != 0) { - glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vertexBuffer, GL_STREAM_DRAW); + glBufferData( + GL_ARRAY_BUFFER, + vertexCount * vertexSize, + vertexBuffer, + GL_STREAM_DRAW + ); } else { glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STREAM_DRAW); } if (indexBuffer != nullptr && indexCount != 0) { - if (ibo == 0) - glGenBuffers(1, &ibo); + if (ibo == 0) glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * indexCount, indexBuffer, GL_STATIC_DRAW); + glBufferData( + GL_ELEMENT_ARRAY_BUFFER, + sizeof(uint32_t) * indexCount, + indexBuffer, + GL_STATIC_DRAW + ); } else if (ibo != 0) { glDeleteBuffers(1, &ibo); } - } -template +template void Mesh::draw(unsigned int primitive) const { MeshStats::drawCalls++; glBindVertexArray(vao); @@ -85,7 +114,7 @@ void Mesh::draw(unsigned int primitive) const { glBindVertexArray(0); } -template +template void Mesh::draw() const { draw(GL_TRIANGLES); } diff --git a/src/graphics/core/MeshData.hpp b/src/graphics/core/MeshData.hpp index 53229584..80f66366 100644 --- a/src/graphics/core/MeshData.hpp +++ b/src/graphics/core/MeshData.hpp @@ -1,30 +1,36 @@ #pragma once #include -#include #include "typedefs.hpp" #include "util/Buffer.hpp" /// @brief Vertex attribute info struct VertexAttribute { - uint32_t type = 0; + enum class Type { + FLOAT, + INT, UNSIGNED_INT, + SHORT, UNSIGNED_SHORT, + BYTE, UNSIGNED_BYTE + }; + + Type type = Type::FLOAT; bool normalized = false; ubyte count = 0; [[nodiscard]] uint32_t size() const { switch (type) { - case GL_FLOAT: - return count * sizeof(GLfloat); - case GL_UNSIGNED_INT: - case GL_INT: - return count * sizeof(GLint); - case GL_UNSIGNED_SHORT: - case GL_SHORT: - return count * sizeof(GLshort); - case GL_UNSIGNED_BYTE: - case GL_BYTE: - return count * sizeof(GLbyte); + case Type::FLOAT: + return count * sizeof(float); + case Type::UNSIGNED_INT: + case Type::INT: + return count * sizeof(int32_t); + case Type::UNSIGNED_SHORT: + case Type::SHORT: + return count * sizeof(int16_t); + case Type::UNSIGNED_BYTE: + case Type::BYTE: + return count * sizeof(int8_t); default: throw std::runtime_error("VertexAttribute type is not supported"); } diff --git a/src/graphics/core/PostProcessing.hpp b/src/graphics/core/PostProcessing.hpp index 7252c239..c6b3ae14 100644 --- a/src/graphics/core/PostProcessing.hpp +++ b/src/graphics/core/PostProcessing.hpp @@ -16,9 +16,8 @@ struct PostProcessingVertex { glm::vec2 position; static constexpr VertexAttribute ATTRIBUTES[] { - {GL_FLOAT,false,2}, - {0} - }; + {VertexAttribute::Type::FLOAT, false, 2}, + {{}, 0}}; }; /// @brief Framebuffer with blitting with shaders. diff --git a/src/graphics/core/gl_util.hpp b/src/graphics/core/gl_util.hpp index 3e34b923..f3446fea 100644 --- a/src/graphics/core/gl_util.hpp +++ b/src/graphics/core/gl_util.hpp @@ -2,6 +2,7 @@ #include "commons.hpp" #include "ImageData.hpp" +#include "MeshData.hpp" #include @@ -23,4 +24,24 @@ namespace gl { }; return primitives[static_cast(primitive)]; } + + inline GLenum to_glenum(VertexAttribute::Type type) { + using Type = VertexAttribute::Type; + switch (type) { + case Type::FLOAT: + return GL_FLOAT; + case Type::UNSIGNED_INT: + return GL_UNSIGNED_INT; + case Type::INT: + return GL_INT; + case Type::UNSIGNED_SHORT: + return GL_UNSIGNED_SHORT; + case Type::SHORT: + return GL_SHORT; + case Type::UNSIGNED_BYTE: + return GL_UNSIGNED_BYTE; + case Type::BYTE: + return GL_BYTE; + } + } } diff --git a/src/graphics/render/MainBatch.hpp b/src/graphics/render/MainBatch.hpp index d5afb569..2ca1d3d0 100644 --- a/src/graphics/render/MainBatch.hpp +++ b/src/graphics/render/MainBatch.hpp @@ -21,12 +21,11 @@ struct MainBatchVertex { std::array color; static constexpr VertexAttribute ATTRIBUTES[] = { - {GL_FLOAT, false, 3}, - {GL_FLOAT, false, 2}, - {GL_FLOAT, false, 3}, - {GL_UNSIGNED_BYTE, true, 4}, - {0} - }; + {VertexAttribute::Type::FLOAT, false, 3}, + {VertexAttribute::Type::FLOAT, false, 2}, + {VertexAttribute::Type::FLOAT, false, 3}, + {VertexAttribute::Type::UNSIGNED_BYTE, true, 4}, + {{}, 0}}; }; class MainBatch { diff --git a/src/graphics/render/Skybox.hpp b/src/graphics/render/Skybox.hpp index 6b01cd1e..f469b155 100644 --- a/src/graphics/render/Skybox.hpp +++ b/src/graphics/render/Skybox.hpp @@ -20,7 +20,9 @@ class DrawContext; struct SkyboxVertex { glm::vec2 position; - static constexpr VertexAttribute ATTRIBUTES[] {{GL_FLOAT,false,2}, {0}}; + static constexpr VertexAttribute ATTRIBUTES[] { + {VertexAttribute::Type::FLOAT, false, 2}, + {{}, 0}}; }; struct skysprite { diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 96e53864..3f193500 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -3,13 +3,12 @@ #include #include #include +#include #include #include "graphics/core/MeshData.hpp" #include "util/Buffer.hpp" - - /// @brief Chunk mesh vertex format struct ChunkVertex { glm::vec3 position; @@ -17,11 +16,10 @@ struct ChunkVertex { std::array color; static constexpr VertexAttribute ATTRIBUTES[] = { - {GL_FLOAT, false, 3}, - {GL_FLOAT, false, 2}, - {GL_UNSIGNED_BYTE, true, 4}, - {0} - }; + {VertexAttribute::Type::FLOAT, false, 3}, + {VertexAttribute::Type::FLOAT, false, 2}, + {VertexAttribute::Type::UNSIGNED_BYTE, true, 4}, + {{}, 0}}; }; /// @brief Chunk mesh vertex attributes From e357a4eb9f33ee83138e37c6e5981d730decf90a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 01:13:44 +0300 Subject: [PATCH 11/21] remove Mesh constructor 'attrs' argument & format Mesh.hpp --- src/graphics/core/Batch2D.cpp | 2 +- src/graphics/core/Batch3D.cpp | 2 +- src/graphics/core/LineBatch.cpp | 2 +- src/graphics/core/Mesh.hpp | 33 ++++++++++++++------------ src/graphics/core/Mesh.inl | 28 ++++++++++++---------- src/graphics/core/MeshData.hpp | 5 ++-- src/graphics/core/PostProcessing.cpp | 2 +- src/graphics/core/gl_util.hpp | 1 + src/graphics/render/BlocksRenderer.cpp | 2 +- src/graphics/render/ChunksRenderer.cpp | 6 ++--- src/graphics/render/MainBatch.cpp | 2 +- src/graphics/render/Skybox.cpp | 2 +- src/voxels/Chunks.cpp | 1 - 13 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/graphics/core/Batch2D.cpp b/src/graphics/core/Batch2D.cpp index 0da82ccd..38224a3f 100644 --- a/src/graphics/core/Batch2D.cpp +++ b/src/graphics/core/Batch2D.cpp @@ -9,7 +9,7 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), color(1.0f){ buffer = std::make_unique(capacity ); - mesh = std::make_unique>(buffer.get(), 0, Batch2DVertex::ATTRIBUTES); + mesh = std::make_unique>(buffer.get(), 0); index = 0; const ubyte pixels[] = { diff --git a/src/graphics/core/Batch3D.cpp b/src/graphics/core/Batch3D.cpp index bd79b127..43d161f6 100644 --- a/src/graphics/core/Batch3D.cpp +++ b/src/graphics/core/Batch3D.cpp @@ -11,7 +11,7 @@ Batch3D::Batch3D(size_t capacity) buffer = std::make_unique(capacity); - mesh = std::make_unique>(buffer.get(), 0, Batch3DVertex::ATTRIBUTES); + mesh = std::make_unique>(buffer.get(), 0); index = 0; const ubyte pixels[] = { diff --git a/src/graphics/core/LineBatch.cpp b/src/graphics/core/LineBatch.cpp index a1448768..9e33398a 100644 --- a/src/graphics/core/LineBatch.cpp +++ b/src/graphics/core/LineBatch.cpp @@ -7,7 +7,7 @@ LineBatch::LineBatch(size_t capacity) : capacity(capacity) { buffer = std::make_unique(capacity * 2); - mesh = std::make_unique>(buffer.get(), 0, LineVertex::ATTRIBUTES); + mesh = std::make_unique>(buffer.get(), 0); index = 0; } diff --git a/src/graphics/core/Mesh.hpp b/src/graphics/core/Mesh.hpp index 559c5cc9..3d428322 100644 --- a/src/graphics/core/Mesh.hpp +++ b/src/graphics/core/Mesh.hpp @@ -8,35 +8,40 @@ struct MeshStats { static int drawCalls; }; - -template +template class Mesh { unsigned int vao; unsigned int vbo; unsigned int ibo; size_t vertexCount; size_t indexCount; - size_t vertexSize; - public: - explicit Mesh(const MeshData &data); + explicit Mesh(const MeshData& data); - Mesh(const VertexStructure *vertexBuffer, size_t vertices, const uint32_t *indexBuffer, size_t indices, - const VertexAttribute *attrs); + Mesh( + const VertexStructure* vertexBuffer, + size_t vertices, + const uint32_t* indexBuffer, + size_t indices + ); - Mesh(const VertexStructure *vertexBuffer, size_t vertices, const VertexAttribute *attrs) : Mesh( - vertexBuffer, vertices, nullptr, 0, attrs) { - }; + Mesh(const VertexStructure* vertexBuffer, size_t vertices) + : Mesh(vertexBuffer, vertices, nullptr, 0) {}; ~Mesh(); - /// @brief Update GL vertex and index buffers data without changing VAO attributes + /// @brief Update GL vertex and index buffers data without changing VAO + /// attributes /// @param vertexBuffer vertex data buffer /// @param vertexCount number of vertices in new buffer /// @param indexBuffer indices buffer /// @param indexCount number of values in indices buffer - void reload(const VertexStructure *vertexBuffer, size_t vertexCount, const uint32_t *indexBuffer = nullptr, - size_t indexCount = 0); + void reload( + const VertexStructure* vertexBuffer, + size_t vertexCount, + const uint32_t* indexBuffer = nullptr, + size_t indexCount = 0 + ); /// @brief Draw mesh with specified primitives type /// @param primitive primitives type @@ -44,8 +49,6 @@ public: /// @brief Draw mesh as triangles void draw() const; - - /// @brief Total numbers of alive mesh objects }; #include "graphics/core/Mesh.inl" diff --git a/src/graphics/core/Mesh.inl b/src/graphics/core/Mesh.inl index 33812958..390c2f9a 100644 --- a/src/graphics/core/Mesh.inl +++ b/src/graphics/core/Mesh.inl @@ -3,14 +3,21 @@ #include "MeshData.hpp" #include "gl_util.hpp" +inline constexpr size_t calc_size(const VertexAttribute attrs[]) { + size_t vertexSize = 0; + for (int i = 0; attrs[i].count; i++) { + vertexSize += attrs[i].size(); + } + return vertexSize; +} + template Mesh::Mesh(const MeshData& data) : Mesh( data.vertices.data(), data.vertices.size(), data.indices.data(), - data.indices.size(), - data.attrs.data() + data.indices.size() ) { } @@ -19,18 +26,15 @@ Mesh::Mesh( const VertexStructure* vertexBuffer, size_t vertices, const uint32_t* indexBuffer, - size_t indices, - const VertexAttribute* attrs + size_t indices ) : vao(0), vbo(0), ibo(0), vertexCount(0), indexCount(0) { + static_assert( + calc_size(VertexStructure::ATTRIBUTES) == sizeof(VertexStructure) + ); + + const auto& attrs = VertexStructure::ATTRIBUTES; MeshStats::meshesCount++; - vertexSize = 0; - for (int i = 0; attrs[i].count; i++) { - vertexSize += attrs[i].size(); - } - if (vertexSize != sizeof(VertexStructure)) { - throw std::runtime_error("Vertex size mismatch!"); - } glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); @@ -80,7 +84,7 @@ void Mesh::reload( if (vertexBuffer != nullptr && vertexCount != 0) { glBufferData( GL_ARRAY_BUFFER, - vertexCount * vertexSize, + vertexCount * sizeof(VertexStructure), vertexBuffer, GL_STREAM_DRAW ); diff --git a/src/graphics/core/MeshData.hpp b/src/graphics/core/MeshData.hpp index 80f66366..82954b23 100644 --- a/src/graphics/core/MeshData.hpp +++ b/src/graphics/core/MeshData.hpp @@ -18,7 +18,7 @@ struct VertexAttribute { bool normalized = false; ubyte count = 0; - [[nodiscard]] uint32_t size() const { + [[nodiscard]] constexpr uint32_t size() const { switch (type) { case Type::FLOAT: return count * sizeof(float); @@ -31,9 +31,8 @@ struct VertexAttribute { case Type::UNSIGNED_BYTE: case Type::BYTE: return count * sizeof(int8_t); - default: - throw std::runtime_error("VertexAttribute type is not supported"); } + return 0; } }; diff --git a/src/graphics/core/PostProcessing.cpp b/src/graphics/core/PostProcessing.cpp index 93d85830..2968cb4d 100644 --- a/src/graphics/core/PostProcessing.cpp +++ b/src/graphics/core/PostProcessing.cpp @@ -21,7 +21,7 @@ PostProcessing::PostProcessing(size_t effectSlotsCount) {{1.0f, -1.0f}}, }; - quadMesh = std::make_unique>(meshData, 6, PostProcessingVertex::ATTRIBUTES); + quadMesh = std::make_unique>(meshData, 6); } PostProcessing::~PostProcessing() = default; diff --git a/src/graphics/core/gl_util.hpp b/src/graphics/core/gl_util.hpp index f3446fea..da2abfb5 100644 --- a/src/graphics/core/gl_util.hpp +++ b/src/graphics/core/gl_util.hpp @@ -43,5 +43,6 @@ namespace gl { case Type::BYTE: return GL_BYTE; } + return 0; } } diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 983a4168..79cca542 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -662,7 +662,7 @@ ChunkMesh BlocksRenderer::render(const Chunk *chunk, const Chunks *chunks) { build(chunk, chunks); return ChunkMesh{std::make_unique>( - vertexBuffer.get(), vertexCount, indexBuffer.get(), indexCount, ChunkVertex::ATTRIBUTES + vertexBuffer.get(), vertexCount, indexBuffer.get(), indexCount ), std::move(sortingMesh)}; } diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 1c5ca1a4..199d818b 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -289,9 +289,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { auto& entry = chunkEntries.at(0); if (found->second.sortedMesh == nullptr) { found->second.sortedMesh = std::make_unique>( - entry.vertexData.data(), - entry.vertexData.size(), - ChunkVertex::ATTRIBUTES + entry.vertexData.data(), entry.vertexData.size() ); } found->second.sortedMesh->draw(); @@ -316,7 +314,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { } write_sorting_mesh_entries(buffer.data(), chunkEntries); found->second.sortedMesh = std::make_unique>( - buffer.data(), size, ChunkVertex::ATTRIBUTES + buffer.data(), size ); } found->second.sortedMesh->draw(); diff --git a/src/graphics/render/MainBatch.cpp b/src/graphics/render/MainBatch.cpp index bd8d04b9..34976819 100644 --- a/src/graphics/render/MainBatch.cpp +++ b/src/graphics/render/MainBatch.cpp @@ -11,7 +11,7 @@ MainBatch::MainBatch(size_t capacity) : buffer(std::make_unique(capacity)), capacity(capacity), index(0), - mesh(std::make_unique>(buffer.get(), 0, MainBatchVertex::ATTRIBUTES)) { + mesh(std::make_unique>(buffer.get(), 0)) { const ubyte pixels[] = { 255, 255, 255, 255, diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index b724de32..d78b3917 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -44,7 +44,7 @@ Skybox::Skybox(uint size, Shader& shader) {{1.0f, -1.0f}} }; - mesh = std::make_unique>(vertices, 6, SkyboxVertex::ATTRIBUTES); + mesh = std::make_unique>(vertices, 6); sprites.push_back(skysprite { "misc/moon", diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index ce533889..60422c60 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -10,7 +10,6 @@ #include "coders/byte_utils.hpp" #include "content/Content.hpp" #include "world/files/WorldFiles.hpp" -#include "graphics/core/Mesh.hpp" #include "lighting/Lightmap.hpp" #include "maths/aabb.hpp" #include "maths/rays.hpp" From 8de408fd10d313853f6136819ee475df8d5f4db3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 12:36:34 +0300 Subject: [PATCH 12/21] refactor: remove unused abstraction --- src/coders/png.cpp | 4 +- src/graphics/core/Cubemap.cpp | 2 +- src/graphics/core/Cubemap.hpp | 4 +- src/graphics/core/Framebuffer.cpp | 4 +- src/graphics/core/GLTexture.cpp | 101 ------------------------- src/graphics/core/GLTexture.hpp | 31 -------- src/graphics/core/Texture.cpp | 101 ++++++++++++++++++++++++- src/graphics/core/Texture.hpp | 36 +++++---- src/graphics/core/TextureAnimation.cpp | 2 +- 9 files changed, 128 insertions(+), 157 deletions(-) delete mode 100644 src/graphics/core/GLTexture.cpp delete mode 100644 src/graphics/core/GLTexture.hpp diff --git a/src/coders/png.cpp b/src/coders/png.cpp index ce40e9cc..4121b052 100644 --- a/src/coders/png.cpp +++ b/src/coders/png.cpp @@ -6,7 +6,7 @@ #include "debug/Logger.hpp" #include "io/io.hpp" -#include "graphics/core/GLTexture.hpp" +#include "graphics/core/Texture.hpp" #include "graphics/core/ImageData.hpp" static debug::Logger logger("png-coder"); @@ -205,7 +205,7 @@ std::unique_ptr png::load_image(const ubyte* bytes, size_t size) { std::unique_ptr png::load_texture(const ubyte* bytes, size_t size) { auto image = load_image(bytes, size); - auto texture = GLTexture::from(image.get()); + auto texture = Texture::from(image.get()); texture->setNearestFilter(); return texture; } diff --git a/src/graphics/core/Cubemap.cpp b/src/graphics/core/Cubemap.cpp index 3267b25e..13bba31b 100644 --- a/src/graphics/core/Cubemap.cpp +++ b/src/graphics/core/Cubemap.cpp @@ -4,7 +4,7 @@ #include Cubemap::Cubemap(uint width, uint height, ImageFormat imageFormat) - : GLTexture(0, width, height) + : Texture(0, width, height) { glGenTextures(1, &id); glBindTexture(GL_TEXTURE_CUBE_MAP, id); diff --git a/src/graphics/core/Cubemap.hpp b/src/graphics/core/Cubemap.hpp index 3a80bda8..4ca1b988 100644 --- a/src/graphics/core/Cubemap.hpp +++ b/src/graphics/core/Cubemap.hpp @@ -1,9 +1,9 @@ #pragma once -#include "GLTexture.hpp" +#include "Texture.hpp" /// @brief Cubemap texture -class Cubemap : public GLTexture { +class Cubemap : public Texture { public: Cubemap(uint width, uint height, ImageFormat format); diff --git a/src/graphics/core/Framebuffer.cpp b/src/graphics/core/Framebuffer.cpp index 12f7637c..b0a452f4 100644 --- a/src/graphics/core/Framebuffer.cpp +++ b/src/graphics/core/Framebuffer.cpp @@ -1,7 +1,7 @@ #include "Framebuffer.hpp" #include -#include "GLTexture.hpp" +#include "Texture.hpp" Framebuffer::Framebuffer(uint fbo, uint depth, std::unique_ptr texture) : fbo(fbo), depth(depth), texture(std::move(texture)) @@ -25,7 +25,7 @@ static std::unique_ptr create_texture(int width, int height, int format glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); - return std::make_unique(tex, width, height); + return std::make_unique(tex, width, height); } Framebuffer::Framebuffer(uint width, uint height, bool alpha) diff --git a/src/graphics/core/GLTexture.cpp b/src/graphics/core/GLTexture.cpp deleted file mode 100644 index f3d752d1..00000000 --- a/src/graphics/core/GLTexture.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "GLTexture.hpp" -#include "gl_util.hpp" - -#include -#include -#include - -uint Texture::MAX_RESOLUTION = 1024; // Window.initialize overrides it - -GLTexture::GLTexture(uint id, uint width, uint height) - : Texture(width, height), id(id) { -} - -GLTexture::GLTexture(const ubyte* data, uint width, uint height, ImageFormat imageFormat) - : Texture(width, height) { - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - GLenum format = gl::to_glenum(imageFormat); - glTexImage2D( - GL_TEXTURE_2D, 0, format, width, height, 0, - format, GL_UNSIGNED_BYTE, static_cast(data) - ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - glBindTexture(GL_TEXTURE_2D, 0); -} - -GLTexture::~GLTexture() { - glDeleteTextures(1, &id); -} - -void GLTexture::bind() const { - glBindTexture(GL_TEXTURE_2D, id); -} - -void GLTexture::unbind() const { - glBindTexture(GL_TEXTURE_2D, 0); -} - -void GLTexture::reload(const ImageData& image) { - width = image.getWidth(); - height = image.getHeight(); - reload(image.getData()); -} - -void GLTexture::reload(const ubyte* data) { - glBindTexture(GL_TEXTURE_2D, id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, static_cast(data)); - glBindTexture(GL_TEXTURE_2D, 0); -} - -std::unique_ptr GLTexture::readData() { - auto data = std::make_unique(width * height * 4); - glBindTexture(GL_TEXTURE_2D, id); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.get()); - glBindTexture(GL_TEXTURE_2D, 0); - return std::make_unique( - ImageFormat::rgba8888, width, height, std::move(data) - ); -} - -void GLTexture::setNearestFilter() { - bind(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindTexture(GL_TEXTURE_2D, 0); -} - -void GLTexture::setMipMapping(bool flag, bool pixelated) { - bind(); - if (flag) { - glTexParameteri( - GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - pixelated ? GL_NEAREST : GL_LINEAR_MIPMAP_NEAREST - ); - } else { - glTexParameteri( - GL_TEXTURE_2D, - GL_TEXTURE_MIN_FILTER, - pixelated ? GL_NEAREST : GL_LINEAR - ); - } - glBindTexture(GL_TEXTURE_2D, 0); -} - -std::unique_ptr GLTexture::from(const ImageData* image) { - uint width = image->getWidth(); - uint height = image->getHeight(); - void* data = image->getData(); - return std::make_unique(static_cast(data), width, height, image->getFormat()); -} - -uint GLTexture::getId() const { - return id; -} diff --git a/src/graphics/core/GLTexture.hpp b/src/graphics/core/GLTexture.hpp deleted file mode 100644 index 64fb5489..00000000 --- a/src/graphics/core/GLTexture.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "Texture.hpp" - -class GLTexture : public Texture { -protected: - uint id; -public: - GLTexture(uint id, uint width, uint height); - GLTexture(const ubyte* data, uint width, uint height, ImageFormat format); - virtual ~GLTexture(); - - virtual void bind() const override; - virtual void unbind() const override; - virtual void reload(const ubyte* data); - - void setNearestFilter(); - - virtual void reload(const ImageData& image) override; - - virtual void setMipMapping(bool flag, bool pixelated) override; - - virtual std::unique_ptr readData() override; - virtual uint getId() const override; - - virtual UVRegion getUVRegion() const override { - return UVRegion(0.0f, 0.0f, 1.0f, 1.0f); - } - - static std::unique_ptr from(const ImageData* image); -}; diff --git a/src/graphics/core/Texture.cpp b/src/graphics/core/Texture.cpp index 2484383e..1dc18a65 100644 --- a/src/graphics/core/Texture.cpp +++ b/src/graphics/core/Texture.cpp @@ -1,6 +1,103 @@ #include "Texture.hpp" -#include "GLTexture.hpp" +#include "gl_util.hpp" + +#include +#include +#include + +uint Texture::MAX_RESOLUTION = 1024; // Window.initialize overrides it + +Texture::Texture(uint id, uint width, uint height) + : id(id), width(width), height(height) { +} + +Texture::Texture(const ubyte* data, uint width, uint height, ImageFormat imageFormat) + : width(width), height(height) { + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + GLenum format = gl::to_glenum(imageFormat); + glTexImage2D( + GL_TEXTURE_2D, 0, format, width, height, 0, + format, GL_UNSIGNED_BYTE, static_cast(data) + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + glBindTexture(GL_TEXTURE_2D, 0); +} + +Texture::~Texture() { + glDeleteTextures(1, &id); +} + +void Texture::bind() const { + glBindTexture(GL_TEXTURE_2D, id); +} + +void Texture::unbind() const { + glBindTexture(GL_TEXTURE_2D, 0); +} + +void Texture::reload(const ImageData& image) { + width = image.getWidth(); + height = image.getHeight(); + reload(image.getData()); +} + +void Texture::reload(const ubyte* data) { + glBindTexture(GL_TEXTURE_2D, id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, static_cast(data)); + glBindTexture(GL_TEXTURE_2D, 0); +} + +std::unique_ptr Texture::readData() { + auto data = std::make_unique(width * height * 4); + glBindTexture(GL_TEXTURE_2D, id); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.get()); + glBindTexture(GL_TEXTURE_2D, 0); + return std::make_unique( + ImageFormat::rgba8888, width, height, std::move(data) + ); +} + +void Texture::setNearestFilter() { + bind(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glBindTexture(GL_TEXTURE_2D, 0); +} + +void Texture::setMipMapping(bool flag, bool pixelated) { + bind(); + if (flag) { + glTexParameteri( + GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, + pixelated ? GL_NEAREST : GL_LINEAR_MIPMAP_NEAREST + ); + } else { + glTexParameteri( + GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, + pixelated ? GL_NEAREST : GL_LINEAR + ); + } + glBindTexture(GL_TEXTURE_2D, 0); +} std::unique_ptr Texture::from(const ImageData* image) { - return GLTexture::from(image); + uint width = image->getWidth(); + uint height = image->getHeight(); + void* data = image->getData(); + return std::make_unique( + static_cast(data), width, height, image->getFormat() + ); +} + +uint Texture::getId() const { + return id; } diff --git a/src/graphics/core/Texture.hpp b/src/graphics/core/Texture.hpp index 483c93da..59568619 100644 --- a/src/graphics/core/Texture.hpp +++ b/src/graphics/core/Texture.hpp @@ -8,33 +8,39 @@ class Texture { protected: + uint id; uint width; uint height; - - Texture(uint width, uint height) : width(width), height(height) {} public: - static uint MAX_RESOLUTION; + Texture(uint id, uint width, uint height); + Texture(const ubyte* data, uint width, uint height, ImageFormat format); + virtual ~Texture(); - virtual ~Texture() {} + virtual void bind() const; + virtual void unbind() const; + void reload(const ubyte* data); - virtual void bind() const = 0; - virtual void unbind() const = 0; + void setNearestFilter(); - virtual void reload(const ImageData& image) = 0; + void reload(const ImageData& image); - virtual std::unique_ptr readData() = 0; + void setMipMapping(bool flag, bool pixelated); - virtual uint getWidth() const { + std::unique_ptr readData(); + uint getId() const; + + UVRegion getUVRegion() const { + return UVRegion(0.0f, 0.0f, 1.0f, 1.0f); + } + + uint getWidth() const { return width; } - virtual uint getHeight() const { + + uint getHeight() const { return height; } - virtual UVRegion getUVRegion() const = 0; - - virtual uint getId() const = 0; - - virtual void setMipMapping(bool flag, bool pixelated) = 0; static std::unique_ptr from(const ImageData* image); + static uint MAX_RESOLUTION; }; diff --git a/src/graphics/core/TextureAnimation.cpp b/src/graphics/core/TextureAnimation.cpp index fd49e508..73af95a2 100644 --- a/src/graphics/core/TextureAnimation.cpp +++ b/src/graphics/core/TextureAnimation.cpp @@ -1,5 +1,5 @@ #include "TextureAnimation.hpp" -#include "GLTexture.hpp" +#include "Texture.hpp" #include "Framebuffer.hpp" #include From 718f5d1089b7b8c0c7a16729d19453bc66c38b10 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 15:18:14 +0300 Subject: [PATCH 13/21] rename BlockModel to BlockModelType --- src/content/ContentBuilder.cpp | 2 +- src/content/loading/BlockLoader.cpp | 12 +++++----- src/core_defs.cpp | 2 +- src/frontend/ContentGfxCache.cpp | 2 +- src/graphics/render/BlockWrapsRenderer.cpp | 4 ++-- src/graphics/render/BlocksPreview.cpp | 10 ++++---- src/graphics/render/BlocksRenderer.cpp | 16 ++++++------- src/graphics/render/ModelsGenerator.cpp | 10 ++++---- src/logic/scripting/lua/libs/libblock.cpp | 2 +- src/voxels/Block.hpp | 28 ++++++++++------------ 10 files changed, 43 insertions(+), 45 deletions(-) diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp index caab68976..d295e252 100644 --- a/src/content/ContentBuilder.cpp +++ b/src/content/ContentBuilder.cpp @@ -28,7 +28,7 @@ std::unique_ptr ContentBuilder::build() { // Generating runtime info def.rt.id = blockDefsIndices.size(); def.rt.emissive = *reinterpret_cast(def.emission); - def.rt.solid = def.model == BlockModel::block; + def.rt.solid = def.model == BlockModelType::BLOCK; def.rt.extended = def.size.x > 1 || def.size.y > 1 || def.size.z > 1; const float EPSILON = 0.01f; diff --git a/src/content/loading/BlockLoader.cpp b/src/content/loading/BlockLoader.cpp index d8ef7cdd..8f92cbe8 100644 --- a/src/content/loading/BlockLoader.cpp +++ b/src/content/loading/BlockLoader.cpp @@ -86,11 +86,11 @@ template<> void ContentUnitLoader::loadUnit( } // block model - std::string modelTypeName = BlockModelMeta.getNameString(def.model); + std::string modelTypeName = BlockModelTypeMeta.getNameString(def.model); root.at("model").get(modelTypeName); root.at("model-name").get(def.modelName); - if (BlockModelMeta.getItem(modelTypeName, def.model)) { - if (def.model == BlockModel::custom && def.customModelRaw == nullptr) { + if (BlockModelTypeMeta.getItem(modelTypeName, def.model)) { + if (def.model == BlockModelType::CUSTOM && def.customModelRaw == nullptr) { if (root.has("model-primitives")) { def.customModelRaw = root["model-primitives"]; } else if (def.modelName.empty()) { @@ -99,7 +99,7 @@ template<> void ContentUnitLoader::loadUnit( } } else if (!modelTypeName.empty()) { logger.error() << "unknown model: " << modelTypeName; - def.model = BlockModel::none; + def.model = BlockModelType::NONE; } std::string cullingModeName = CullingModeMeta.getNameString(def.culling); @@ -171,9 +171,9 @@ template<> void ContentUnitLoader::loadUnit( "block " + util::quote(def.name) + ": invalid block size" ); } - if (def.model == BlockModel::block && + if (def.model == BlockModelType::BLOCK && (def.size.x != 1 || def.size.y != 1 || def.size.z != 1)) { - def.model = BlockModel::aabb; + def.model = BlockModelType::AABB; def.hitboxes = {AABB(def.size)}; } } diff --git a/src/core_defs.cpp b/src/core_defs.cpp index 07eebee5..52d95c32 100644 --- a/src/core_defs.cpp +++ b/src/core_defs.cpp @@ -19,7 +19,7 @@ void corecontent::setup(Input& input, ContentBuilder& builder) { block.skyLightPassing = true; block.obstacle = false; block.selectable = false; - block.model = BlockModel::none; + block.model = BlockModelType::NONE; block.pickingItem = CORE_EMPTY; } { diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp index 574c22a5..731419f0 100644 --- a/src/frontend/ContentGfxCache.cpp +++ b/src/frontend/ContentGfxCache.cpp @@ -35,7 +35,7 @@ void ContentGfxCache::refresh(const Block& def, const Atlas& atlas) { sideregions[def.rt.id * 6 + side] = atlas.get(TEXTURE_NOTFOUND); } } - if (def.model == BlockModel::custom) { + if (def.model == BlockModelType::CUSTOM) { auto model = assets.require(def.modelName); // temporary dirty fix tbh if (def.modelName.find(':') == std::string::npos) { diff --git a/src/graphics/render/BlockWrapsRenderer.cpp b/src/graphics/render/BlockWrapsRenderer.cpp index ca10a2b9..3feb6da4 100644 --- a/src/graphics/render/BlockWrapsRenderer.cpp +++ b/src/graphics/render/BlockWrapsRenderer.cpp @@ -45,7 +45,7 @@ void BlockWrapsRenderer::draw(const BlockWrapper& wrapper) { if (vox->id != BLOCK_VOID) { const auto& def = level.content.getIndices()->blocks.require(vox->id); switch (def.model) { - case BlockModel::block: + case BlockModelType::BLOCK: batch->cube( glm::vec3(wrapper.position) + glm::vec3(0.5f), glm::vec3(1.01f), @@ -54,7 +54,7 @@ void BlockWrapsRenderer::draw(const BlockWrapper& wrapper) { false ); break; - case BlockModel::aabb: { + case BlockModelType::AABB: { const auto& aabb = (def.rotatable ? def.rt.hitboxes[vox->state.rotation] : def.hitboxes) diff --git a/src/graphics/render/BlocksPreview.cpp b/src/graphics/render/BlocksPreview.cpp index 982d7f47..8af6a75d 100644 --- a/src/graphics/render/BlocksPreview.cpp +++ b/src/graphics/render/BlocksPreview.cpp @@ -33,16 +33,16 @@ std::unique_ptr BlocksPreview::draw( glm::vec3 offset(0.1f, 0.5f, 0.1f); switch (def.model) { - case BlockModel::none: + case BlockModelType::NONE: // something went wrong... break; - case BlockModel::block: + case BlockModelType::BLOCK: shader.uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset)); batch.blockCube(glm::vec3(size * 0.63f), texfaces, glm::vec4(1.0f), !def.rt.emissive); batch.flush(); break; - case BlockModel::aabb: + case BlockModelType::AABB: { glm::vec3 hitbox {}; for (const auto& box : def.hitboxes) { @@ -60,7 +60,7 @@ std::unique_ptr BlocksPreview::draw( } batch.flush(); break; - case BlockModel::custom:{ + case BlockModelType::CUSTOM:{ glm::vec3 pmul = glm::vec3(size * 0.63f); glm::vec3 hitbox = glm::vec3(1.0f); glm::vec3 poff = glm::vec3(0.0f, 0.0f, 1.0f); @@ -78,7 +78,7 @@ std::unique_ptr BlocksPreview::draw( } break; } - case BlockModel::xsprite: { + case BlockModelType::XSPRITE: { shader.uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset)); glm::vec3 right = glm::normalize(glm::vec3(1.f, 0.f, -1.f)); batch.sprite( diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 79cca542..9b0d91e1 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -454,21 +454,21 @@ void BlocksRenderer::render( int y = i / (CHUNK_D * CHUNK_W); int z = (i / CHUNK_D) % CHUNK_W; switch (def.model) { - case BlockModel::block: + case BlockModelType::BLOCK: blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless, def.ambientOcclusion); break; - case BlockModel::xsprite: { + case BlockModelType::XSPRITE: { blockXSprite(x, y, z, glm::vec3(1.0f), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); break; } - case BlockModel::aabb: { + case BlockModelType::AABB: { blockAABB({x, y, z}, texfaces, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; } - case BlockModel::custom: { + case BlockModelType::CUSTOM: { blockCustomModel({x, y, z}, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; @@ -517,21 +517,21 @@ SortingMeshData BlocksRenderer::renderTranslucent( int y = i / (CHUNK_D * CHUNK_W); int z = (i / CHUNK_D) % CHUNK_W; switch (def.model) { - case BlockModel::block: + case BlockModelType::BLOCK: blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless, def.ambientOcclusion); break; - case BlockModel::xsprite: { + case BlockModelType::XSPRITE: { blockXSprite(x, y, z, glm::vec3(1.0f), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); break; } - case BlockModel::aabb: { + case BlockModelType::AABB: { blockAABB({x, y, z}, texfaces, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; } - case BlockModel::custom: { + case BlockModelType::CUSTOM: { blockCustomModel({x, y, z}, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; diff --git a/src/graphics/render/ModelsGenerator.cpp b/src/graphics/render/ModelsGenerator.cpp index 4d2858bf..d010e835 100644 --- a/src/graphics/render/ModelsGenerator.cpp +++ b/src/graphics/render/ModelsGenerator.cpp @@ -50,7 +50,7 @@ static inline UVRegion get_region_for( void ModelsGenerator::prepare(Content& content, Assets& assets) { for (auto& [name, def] : content.blocks.getDefs()) { - if (def->model == BlockModel::custom && def->modelName.empty()) { + if (def->model == BlockModelType::CUSTOM && def->modelName.empty()) { assets.store( std::make_unique( loadCustomBlockModel( @@ -74,7 +74,7 @@ void ModelsGenerator::prepare(Content& content, Assets& assets) { model::Model ModelsGenerator::fromCustom( const Assets& assets, - const std::vector& modelBoxes, + const std::vector& modelBoxes, const std::vector& modelTextures, const std::vector& points, bool lighting @@ -131,11 +131,11 @@ model::Model ModelsGenerator::generate( if (def.iconType == ItemIconType::BLOCK) { auto model = assets.require("block"); const auto& blockDef = content.blocks.require(def.icon); - if (blockDef.model == BlockModel::xsprite) { + if (blockDef.model == BlockModelType::XSPRITE) { return create_flat_model( "blocks:" + blockDef.textureFaces.at(0), assets ); - } else if (blockDef.model == BlockModel::custom) { + } else if (blockDef.model == BlockModelType::CUSTOM) { model = assets.require(blockDef.modelName); for (auto& mesh : model.meshes) { mesh.scale(glm::vec3(0.2f)); @@ -145,7 +145,7 @@ model::Model ModelsGenerator::generate( for (auto& mesh : model.meshes) { mesh.lighting = !blockDef.shadeless; switch (blockDef.model) { - case BlockModel::aabb: { + case BlockModelType::AABB: { glm::vec3 size = blockDef.hitboxes.at(0).size(); float m = glm::max(size.x, glm::max(size.y, size.z)); m = glm::min(1.0f, m); diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index 8963926f..ab872fb2 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -312,7 +312,7 @@ static int l_get_textures(lua::State* L) { static int l_get_model(lua::State* L) { if (auto def = require_block(L)) { - return lua::pushlstring(L, BlockModelMeta.getName(def->model)); + return lua::pushlstring(L, BlockModelTypeMeta.getName(def->model)); } return 0; } diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 9e3a28df..dc9980c9 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -81,25 +81,25 @@ struct BlockRotProfile { static inline std::string PANE_NAME = "pane"; }; -enum class BlockModel { +enum class BlockModelType { /// @brief invisible - none, + NONE, /// @brief default cube shape - block, + BLOCK, /// @brief X-shape (grass) - xsprite, + XSPRITE, /// @brief box shape sized as block hitbox - aabb, + AABB, /// @brief custom model defined in json - custom + CUSTOM }; -VC_ENUM_METADATA(BlockModel) - {"none", BlockModel::none}, - {"block", BlockModel::block}, - {"X", BlockModel::xsprite}, - {"aabb", BlockModel::aabb}, - {"custom", BlockModel::custom}, +VC_ENUM_METADATA(BlockModelType) + {"none", BlockModelType::NONE}, + {"block", BlockModelType::BLOCK}, + {"X", BlockModelType::XSPRITE}, + {"aabb", BlockModelType::AABB}, + {"custom", BlockModelType::CUSTOM}, VC_ENUM_END enum class CullingMode { @@ -114,8 +114,6 @@ VC_ENUM_METADATA(CullingMode) {"disabled", CullingMode::DISABLED}, VC_ENUM_END -using BoxModel = AABB; - /// @brief Common kit of block properties applied to groups of blocks struct BlockMaterial : Serializable { std::string name; @@ -155,7 +153,7 @@ public: uint8_t drawGroup = 0; /// @brief Block model type - BlockModel model = BlockModel::block; + BlockModelType model = BlockModelType::BLOCK; /// @brief Custom model raw data dv::value customModelRaw = nullptr; From 20e3a961f951c3845622a176f0ef1630a5cf9eb6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 18:21:56 +0300 Subject: [PATCH 14/21] add BlockModel struct --- src/assets/AssetsLoader.cpp | 8 ++++---- src/content/ContentBuilder.cpp | 2 +- src/content/loading/BlockLoader.cpp | 23 ++++++++++++---------- src/core_defs.cpp | 2 +- src/frontend/ContentGfxCache.cpp | 6 +++--- src/graphics/render/BlockWrapsRenderer.cpp | 2 +- src/graphics/render/BlocksPreview.cpp | 2 +- src/graphics/render/BlocksRenderer.cpp | 4 ++-- src/graphics/render/ModelsGenerator.cpp | 14 ++++++------- src/logic/scripting/lua/libs/libblock.cpp | 2 +- src/voxels/Block.cpp | 1 - src/voxels/Block.hpp | 19 +++++++++++------- 12 files changed, 46 insertions(+), 39 deletions(-) diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index cdbb28e2..80c1186d 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -257,12 +257,12 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) { } } for (const auto& [_, def] : content->blocks.getDefs()) { - if (!def->modelName.empty() && - def->modelName.find(':') == std::string::npos) { + if (!def->model.name.empty() && + def->model.name.find(':') == std::string::npos) { loader.add( AssetType::MODEL, - MODELS_FOLDER + "/" + def->modelName, - def->modelName + MODELS_FOLDER + "/" + def->model.name, + def->model.name ); } } diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp index d295e252..c8b599ea 100644 --- a/src/content/ContentBuilder.cpp +++ b/src/content/ContentBuilder.cpp @@ -28,7 +28,7 @@ std::unique_ptr ContentBuilder::build() { // Generating runtime info def.rt.id = blockDefsIndices.size(); def.rt.emissive = *reinterpret_cast(def.emission); - def.rt.solid = def.model == BlockModelType::BLOCK; + def.rt.solid = def.model.type == BlockModelType::BLOCK; def.rt.extended = def.size.x > 1 || def.size.y > 1 || def.size.z > 1; const float EPSILON = 0.01f; diff --git a/src/content/loading/BlockLoader.cpp b/src/content/loading/BlockLoader.cpp index 8f92cbe8..5e3b09be 100644 --- a/src/content/loading/BlockLoader.cpp +++ b/src/content/loading/BlockLoader.cpp @@ -86,20 +86,23 @@ template<> void ContentUnitLoader::loadUnit( } // block model - std::string modelTypeName = BlockModelTypeMeta.getNameString(def.model); + auto& model = def.model; + std::string modelTypeName = BlockModelTypeMeta.getNameString(model.type); root.at("model").get(modelTypeName); - root.at("model-name").get(def.modelName); - if (BlockModelTypeMeta.getItem(modelTypeName, def.model)) { - if (def.model == BlockModelType::CUSTOM && def.customModelRaw == nullptr) { + root.at("model-name").get(def.model.name); + if (BlockModelTypeMeta.getItem(modelTypeName, model.type)) { + if (model.type == BlockModelType::CUSTOM && def.model.customRaw == nullptr) { if (root.has("model-primitives")) { - def.customModelRaw = root["model-primitives"]; - } else if (def.modelName.empty()) { - throw std::runtime_error(name + ": no 'model-primitives' or 'model-name' found"); + def.model.customRaw = root["model-primitives"]; + } else if (def.model.name.empty()) { + throw std::runtime_error( + name + ": no 'model-primitives' or 'model-name' found" + ); } } } else if (!modelTypeName.empty()) { logger.error() << "unknown model: " << modelTypeName; - def.model = BlockModelType::NONE; + model.type = BlockModelType::NONE; } std::string cullingModeName = CullingModeMeta.getNameString(def.culling); @@ -171,9 +174,9 @@ template<> void ContentUnitLoader::loadUnit( "block " + util::quote(def.name) + ": invalid block size" ); } - if (def.model == BlockModelType::BLOCK && + if (model.type == BlockModelType::BLOCK && (def.size.x != 1 || def.size.y != 1 || def.size.z != 1)) { - def.model = BlockModelType::AABB; + model.type = BlockModelType::AABB; def.hitboxes = {AABB(def.size)}; } } diff --git a/src/core_defs.cpp b/src/core_defs.cpp index 52d95c32..fdc880da 100644 --- a/src/core_defs.cpp +++ b/src/core_defs.cpp @@ -19,7 +19,7 @@ void corecontent::setup(Input& input, ContentBuilder& builder) { block.skyLightPassing = true; block.obstacle = false; block.selectable = false; - block.model = BlockModelType::NONE; + block.model.type = BlockModelType::NONE; block.pickingItem = CORE_EMPTY; } { diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp index 731419f0..31199a90 100644 --- a/src/frontend/ContentGfxCache.cpp +++ b/src/frontend/ContentGfxCache.cpp @@ -35,10 +35,10 @@ void ContentGfxCache::refresh(const Block& def, const Atlas& atlas) { sideregions[def.rt.id * 6 + side] = atlas.get(TEXTURE_NOTFOUND); } } - if (def.model == BlockModelType::CUSTOM) { - auto model = assets.require(def.modelName); + if (def.model.type == BlockModelType::CUSTOM) { + auto model = assets.require(def.model.name); // temporary dirty fix tbh - if (def.modelName.find(':') == std::string::npos) { + if (def.model.name.find(':') == std::string::npos) { for (auto& mesh : model.meshes) { size_t pos = mesh.texture.find(':'); if (pos == std::string::npos) { diff --git a/src/graphics/render/BlockWrapsRenderer.cpp b/src/graphics/render/BlockWrapsRenderer.cpp index 3feb6da4..3a5f118c 100644 --- a/src/graphics/render/BlockWrapsRenderer.cpp +++ b/src/graphics/render/BlockWrapsRenderer.cpp @@ -44,7 +44,7 @@ void BlockWrapsRenderer::draw(const BlockWrapper& wrapper) { } if (vox->id != BLOCK_VOID) { const auto& def = level.content.getIndices()->blocks.require(vox->id); - switch (def.model) { + switch (def.model.type) { case BlockModelType::BLOCK: batch->cube( glm::vec3(wrapper.position) + glm::vec3(0.5f), diff --git a/src/graphics/render/BlocksPreview.cpp b/src/graphics/render/BlocksPreview.cpp index 8af6a75d..34c3e7df 100644 --- a/src/graphics/render/BlocksPreview.cpp +++ b/src/graphics/render/BlocksPreview.cpp @@ -32,7 +32,7 @@ std::unique_ptr BlocksPreview::draw( cache.getRegion(id, 4), cache.getRegion(id, 5)}; glm::vec3 offset(0.1f, 0.5f, 0.1f); - switch (def.model) { + switch (def.model.type) { case BlockModelType::NONE: // something went wrong... break; diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 9b0d91e1..6e838ea5 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -453,7 +453,7 @@ void BlocksRenderer::render( int x = i % CHUNK_W; int y = i / (CHUNK_D * CHUNK_W); int z = (i / CHUNK_D) % CHUNK_W; - switch (def.model) { + switch (def.model.type) { case BlockModelType::BLOCK: blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless, def.ambientOcclusion); @@ -516,7 +516,7 @@ SortingMeshData BlocksRenderer::renderTranslucent( int x = i % CHUNK_W; int y = i / (CHUNK_D * CHUNK_W); int z = (i / CHUNK_D) % CHUNK_W; - switch (def.model) { + switch (def.model.type) { case BlockModelType::BLOCK: blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless, def.ambientOcclusion); diff --git a/src/graphics/render/ModelsGenerator.cpp b/src/graphics/render/ModelsGenerator.cpp index d010e835..8d180182 100644 --- a/src/graphics/render/ModelsGenerator.cpp +++ b/src/graphics/render/ModelsGenerator.cpp @@ -50,16 +50,16 @@ static inline UVRegion get_region_for( void ModelsGenerator::prepare(Content& content, Assets& assets) { for (auto& [name, def] : content.blocks.getDefs()) { - if (def->model == BlockModelType::CUSTOM && def->modelName.empty()) { + if (def->model.type == BlockModelType::CUSTOM && def->model.name.empty()) { assets.store( std::make_unique( loadCustomBlockModel( - def->customModelRaw, assets, !def->shadeless + def->model.customRaw, assets, !def->shadeless ) ), name + ".model" ); - def->modelName = def->name + ".model"; + def->model.name = def->name + ".model"; } } for (auto& [name, def] : content.items.getDefs()) { @@ -131,12 +131,12 @@ model::Model ModelsGenerator::generate( if (def.iconType == ItemIconType::BLOCK) { auto model = assets.require("block"); const auto& blockDef = content.blocks.require(def.icon); - if (blockDef.model == BlockModelType::XSPRITE) { + if (blockDef.model.type == BlockModelType::XSPRITE) { return create_flat_model( "blocks:" + blockDef.textureFaces.at(0), assets ); - } else if (blockDef.model == BlockModelType::CUSTOM) { - model = assets.require(blockDef.modelName); + } else if (blockDef.model.type == BlockModelType::CUSTOM) { + model = assets.require(blockDef.model.name); for (auto& mesh : model.meshes) { mesh.scale(glm::vec3(0.2f)); } @@ -144,7 +144,7 @@ model::Model ModelsGenerator::generate( } for (auto& mesh : model.meshes) { mesh.lighting = !blockDef.shadeless; - switch (blockDef.model) { + switch (blockDef.model.type) { case BlockModelType::AABB: { glm::vec3 size = blockDef.hitboxes.at(0).size(); float m = glm::max(size.x, glm::max(size.y, size.z)); diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index ab872fb2..031611ee 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -312,7 +312,7 @@ static int l_get_textures(lua::State* L) { static int l_get_model(lua::State* L) { if (auto def = require_block(L)) { - return lua::pushlstring(L, BlockModelTypeMeta.getName(def->model)); + return lua::pushlstring(L, BlockModelTypeMeta.getName(def->model.type)); } return 0; } diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index e7153665..b7b0d836 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -143,7 +143,6 @@ void Block::cloneTo(Block& dst) { if (particles) { dst.particles = std::make_unique(*particles); } - dst.customModelRaw = customModelRaw; } static std::set> RESERVED_BLOCK_FIELDS { diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index dc9980c9..378cbb5d 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -94,6 +94,16 @@ enum class BlockModelType { CUSTOM }; +struct BlockModel { + BlockModelType type = BlockModelType::BLOCK; + + /// @brief Custom model raw data + dv::value customRaw = nullptr; + + /// @brief Custom model name (generated or an asset) + std::string name = ""; +}; + VC_ENUM_METADATA(BlockModelType) {"none", BlockModelType::NONE}, {"block", BlockModelType::BLOCK}, @@ -152,13 +162,8 @@ public: /// @brief Influences visible block sides for transparent blocks uint8_t drawGroup = 0; - /// @brief Block model type - BlockModelType model = BlockModelType::BLOCK; - - /// @brief Custom model raw data - dv::value customModelRaw = nullptr; - - std::string modelName = ""; + /// @brief Block model + BlockModel model {}; /// @brief Culling mode CullingMode culling = CullingMode::DEFAULT; From c913165f9f85f68c0aa25f3332e4a42958c29dc4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 19:39:13 +0300 Subject: [PATCH 15/21] fix tetragons normals calculation --- src/graphics/render/ModelsGenerator.cpp | 36 ++++++++++++------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/graphics/render/ModelsGenerator.cpp b/src/graphics/render/ModelsGenerator.cpp index 8d180182..acd6366f 100644 --- a/src/graphics/render/ModelsGenerator.cpp +++ b/src/graphics/render/ModelsGenerator.cpp @@ -95,32 +95,30 @@ model::Model ModelsGenerator::fromCustom( modelBoxes[i].center(), modelBoxes[i].size() * 0.5f, boxtexfaces ); } - glm::vec3 norm {0, 1, 0}; for (size_t i = 0; i < points.size() / 4; i++) { auto texture = modelTextures[modelBoxes.size() * 6 + i]; + const glm::vec3& v0 = points[i * 4]; + const glm::vec3& v1 = points[i * 4 + 1]; + const glm::vec3& v2 = points[i * 4 + 2]; + const glm::vec3& v3 = points[i * 4 + 3]; + + glm::vec3 edge1 = v1 - v0; + glm::vec3 edge2 = v2 - v0; + + glm::vec3 norm = glm::cross(edge1, edge2); + norm = glm::normalize(norm); + auto& mesh = model.addMesh(texture); mesh.lighting = lighting; auto reg = get_region_for(texture, assets); - mesh.vertices.push_back( - {points[i * 4 + 0], glm::vec2(reg.u1, reg.v1), norm} - ); - mesh.vertices.push_back( - {points[i * 4 + 1], glm::vec2(reg.u2, reg.v1), norm} - ); - mesh.vertices.push_back( - {points[i * 4 + 2], glm::vec2(reg.u2, reg.v2), norm} - ); - mesh.vertices.push_back( - {points[i * 4 + 0], glm::vec2(reg.u1, reg.v1), norm} - ); - mesh.vertices.push_back( - {points[i * 4 + 2], glm::vec2(reg.u2, reg.v2), norm} - ); - mesh.vertices.push_back( - {points[i * 4 + 3], glm::vec2(reg.u1, reg.v2), norm} - ); + mesh.vertices.push_back({v0, glm::vec2(reg.u1, reg.v1), norm}); + mesh.vertices.push_back({v1, glm::vec2(reg.u2, reg.v1), norm}); + mesh.vertices.push_back({v2, glm::vec2(reg.u2, reg.v2), norm}); + mesh.vertices.push_back({v0, glm::vec2(reg.u1, reg.v1), norm}); + mesh.vertices.push_back({v2, glm::vec2(reg.u2, reg.v2), norm}); + mesh.vertices.push_back({v3, glm::vec2(reg.u1, reg.v2), norm}); } return model; } From 6bca93a1cd70a1579c58b84abc12b37bac719a8c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 21:02:49 +0300 Subject: [PATCH 16/21] improve custom models AO --- src/graphics/render/BlocksRenderer.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 6e838ea5..5e8c9400 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -289,23 +289,30 @@ void BlocksRenderer::blockCustomModel( for (int triangle = 0; triangle < mesh.vertices.size() / 3; triangle++) { auto r = mesh.vertices[triangle * 3 + (triangle % 2) * 2].coord - mesh.vertices[triangle * 3 + 1].coord; + r = r.x * X + r.y * Y + r.z * Z; r = glm::normalize(r); for (int i = 0; i < 3; i++) { const auto& vertex = mesh.vertices[triangle * 3 + i]; - auto n = vertex.normal.x * X + vertex.normal.y * Y + + auto n = vertex.normal.x * X + + vertex.normal.y * Y + vertex.normal.z * Z; float d = glm::dot(n, SUN_VECTOR); - d = 0.8f + d * 0.2f; + d = 0.7f + d * 0.3f; const auto& vcoord = vertex.coord - 0.5f; - vertexAO( + + glm::vec3 t = glm::cross(r, n); + glm::vec4 aoColor {1.0f, 1.0f, 1.0f, 1.0f}; + if (ao) { + auto p = coord + vcoord.x * X + vcoord.y * Y + + vcoord.z * Z + r * 0.5f + t * 0.5f + n * 0.5f; + aoColor = pickSoftLight(p.x, p.y, p.z, glm::ivec3(r), glm::ivec3(t)); + } + this->vertex( coord + vcoord.x * X + vcoord.y * Y + vcoord.z * Z, vertex.uv.x, vertex.uv.y, - glm::vec4(d, d, d, d), - glm::cross(r, n), - r, - n + glm::vec4(d, d, d, d) * aoColor ); indexBuffer[indexCount++] = vertexOffset++; } From b72599e7ee3edb2639e080607a342e69f932c674 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 21:17:24 +0300 Subject: [PATCH 17/21] feat: custom models simple culling --- src/graphics/render/BlocksRenderer.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 5e8c9400..d497d777 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -292,16 +292,21 @@ void BlocksRenderer::blockCustomModel( r = r.x * X + r.y * Y + r.z * Z; r = glm::normalize(r); + const auto& v0 = mesh.vertices[triangle * 3]; + auto n = v0.normal.x * X + v0.normal.y * Y + v0.normal.z * Z; + + if (!isOpen(coord + n, *block)) { + continue; + } + + float d = glm::dot(n, SUN_VECTOR); + d = 0.7f + d * 0.3f; + glm::vec3 t = glm::cross(r, n); + for (int i = 0; i < 3; i++) { const auto& vertex = mesh.vertices[triangle * 3 + i]; - auto n = vertex.normal.x * X + - vertex.normal.y * Y + - vertex.normal.z * Z; - float d = glm::dot(n, SUN_VECTOR); - d = 0.7f + d * 0.3f; const auto& vcoord = vertex.coord - 0.5f; - glm::vec3 t = glm::cross(r, n); glm::vec4 aoColor {1.0f, 1.0f, 1.0f, 1.0f}; if (ao) { auto p = coord + vcoord.x * X + vcoord.y * Y + From 9a68886cd54fc640d1f3bc7d01c51fa8f3b74da7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 22:02:24 +0300 Subject: [PATCH 18/21] feat: additional culling checks --- src/graphics/render/BlocksRenderer.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index d497d777..fe13d4b8 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -265,6 +265,19 @@ void BlocksRenderer::blockAABB( } } +static bool is_aligned(const glm::vec3& v, float e = 1e-6f) { + if (std::abs(v.y) < e && std::abs(v.z) < e && std::abs(v.x) > e) { + return true; + } + if (std::abs(v.x) < e && std::abs(v.z) < e && std::abs(v.y) > e) { + return true; + } + if (std::abs(v.x) < e && std::abs(v.y) < e && std::abs(v.z) > e) { + return true; + } + return false; +} + void BlocksRenderer::blockCustomModel( const glm::ivec3& icoord, const Block* block, ubyte rotation, bool lights, bool ao ) { @@ -295,7 +308,7 @@ void BlocksRenderer::blockCustomModel( const auto& v0 = mesh.vertices[triangle * 3]; auto n = v0.normal.x * X + v0.normal.y * Y + v0.normal.z * Z; - if (!isOpen(coord + n, *block)) { + if (!isOpen(glm::floor(coord + n * 1e-4f), *block) && is_aligned(r) && is_aligned(n)) { continue; } From 9edff1b0f1c02583b553b682576768abc7751640 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 27 Apr 2025 22:14:48 +0300 Subject: [PATCH 19/21] remove an extra check --- src/graphics/render/BlocksRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index fe13d4b8..10e24fad 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -308,7 +308,7 @@ void BlocksRenderer::blockCustomModel( const auto& v0 = mesh.vertices[triangle * 3]; auto n = v0.normal.x * X + v0.normal.y * Y + v0.normal.z * Z; - if (!isOpen(glm::floor(coord + n * 1e-4f), *block) && is_aligned(r) && is_aligned(n)) { + if (!isOpen(glm::floor(coord + n * 1e-4f), *block) && is_aligned(n)) { continue; } From 87dc9ed167002a87330830985fea5c4d3f024e1c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 29 Apr 2025 12:00:13 +0300 Subject: [PATCH 20/21] minor refactor --- src/graphics/render/BlocksRenderer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 10e24fad..83086975 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -9,8 +9,8 @@ #include "lighting/Lightmap.hpp" #include "frontend/ContentGfxCache.hpp" -const glm::vec3 BlocksRenderer::SUN_VECTOR (0.2275f,0.9388f,-0.1005f); - +const glm::vec3 BlocksRenderer::SUN_VECTOR(0.528265f, 0.833149f, -0.163704f); +const float DIRECTIONAL_LIGHT_FACTOR = 0.3f; BlocksRenderer::BlocksRenderer( size_t capacity, @@ -122,7 +122,7 @@ void BlocksRenderer::faceAO( float s = 0.5f; if (lights) { float d = glm::dot(glm::normalize(Z), SUN_VECTOR); - d = 0.7f + d * 0.3f; + d = (1.0f - DIRECTIONAL_LIGHT_FACTOR) + d * DIRECTIONAL_LIGHT_FACTOR; auto axisX = glm::normalize(X); auto axisY = glm::normalize(Y); @@ -160,7 +160,7 @@ void BlocksRenderer::face( float s = 0.5f; if (lights) { float d = glm::dot(glm::normalize(Z), SUN_VECTOR); - d = 0.7f + d * 0.3f; + d = (1.0f - DIRECTIONAL_LIGHT_FACTOR) + d * DIRECTIONAL_LIGHT_FACTOR; tint *= d; } vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint); @@ -313,7 +313,7 @@ void BlocksRenderer::blockCustomModel( } float d = glm::dot(n, SUN_VECTOR); - d = 0.7f + d * 0.3f; + d = (1.0f - DIRECTIONAL_LIGHT_FACTOR) + d * DIRECTIONAL_LIGHT_FACTOR; glm::vec3 t = glm::cross(r, n); for (int i = 0; i < 3; i++) { From 4e5199d89a34fedaab8693102d5bdb6b13d6170f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 29 Apr 2025 15:59:52 +0300 Subject: [PATCH 21/21] feat: lights debug mode --- res/shaders/main.glslf | 3 +++ src/engine/Engine.cpp | 3 ++- src/frontend/screens/LevelScreen.cpp | 19 ++++++++++++------- src/graphics/render/WorldRenderer.cpp | 5 +++++ src/graphics/render/WorldRenderer.hpp | 3 +++ src/graphics/render/commons.hpp | 2 -- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/res/shaders/main.glslf b/res/shaders/main.glslf index bccbd53a..d856acc2 100644 --- a/res/shaders/main.glslf +++ b/res/shaders/main.glslf @@ -7,10 +7,13 @@ out vec4 f_color; uniform sampler2D u_texture0; uniform samplerCube u_cubemap; uniform bool u_alphaClip; +uniform bool u_debugLights; void main() { vec3 fogColor = texture(u_cubemap, a_dir).rgb; vec4 tex_color = texture(u_texture0, a_texCoord); + if (u_debugLights) + tex_color.rgb = vec3(1.0); float alpha = a_color.a * tex_color.a; if (u_alphaClip) { if (alpha < 0.2f) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 63db4490..6596733f 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -203,7 +203,8 @@ void Engine::updateHotkeys() { if (input->jpressed(Keycode::F2)) { saveScreenshot(); } - if (input->jpressed(Keycode::F8)) { + if (input->pressed(Keycode::LEFT_CONTROL) && input->pressed(Keycode::F3) && + input->jpressed(Keycode::U)) { gui->toggleDebug(); } if (input->jpressed(Keycode::F11)) { diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 76f7e950..210ef802 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -184,16 +184,21 @@ void LevelScreen::saveWorldPreview() { void LevelScreen::updateHotkeys() { auto& settings = engine.getSettings(); - if (input.jpressed(Keycode::O)) { - settings.graphics.frustumCulling.toggle(); - } if (input.jpressed(Keycode::F1)) { hudVisible = !hudVisible; } - if (input.jpressed(Keycode::F3)) { - debug = !debug; - hud->setDebug(debug); - renderer->setDebug(debug); + if (!input.pressed(Keycode::LEFT_CONTROL)) { + if (input.jpressed(Keycode::F3)) { + debug = !debug; + hud->setDebug(debug); + renderer->setDebug(debug); + } + } else if (input.pressed(Keycode::F3)) { + if (input.jpressed(Keycode::L)) { + renderer->toggleLightsDebug(); + } else if (input.jpressed(Keycode::O)) { + settings.graphics.frustumCulling.toggle(); + } } } diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 79a9edfc..20640a78 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -118,6 +118,7 @@ void WorldRenderer::setupWorldShader( shader.uniform1f("u_gamma", settings.graphics.gamma.get()); shader.uniform1f("u_fogFactor", fogFactor); shader.uniform1f("u_fogCurve", settings.graphics.fogCurve.get()); + shader.uniform1i("u_debugLights", lightsDebug); shader.uniform1f("u_weatherFogOpacity", weather.fogOpacity()); shader.uniform1f("u_weatherFogDencity", weather.fogDencity()); shader.uniform1f("u_weatherFogCurve", weather.fogCurve()); @@ -442,6 +443,10 @@ void WorldRenderer::setDebug(bool flag) { debug = flag; } +void WorldRenderer::toggleLightsDebug() { + lightsDebug = !lightsDebug; +} + Weather& WorldRenderer::getWeather() { return weather; } diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index fbcf5480..fbfd4998 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -48,6 +48,7 @@ class WorldRenderer { float timer = 0.0f; bool debug = false; + bool lightsDebug = false; /// @brief Render block selection lines void renderBlockSelection(); @@ -107,5 +108,7 @@ public: void setDebug(bool flag); + void toggleLightsDebug(); + Weather& getWeather(); }; diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 3f193500..cfc2f16c 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -22,8 +22,6 @@ struct ChunkVertex { {{}, 0}}; }; -/// @brief Chunk mesh vertex attributes - template class Mesh;