diff --git a/CMakePresets.json b/CMakePresets.json index bc81fc91..47ba71e3 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -45,6 +45,16 @@ } ], "buildPresets": [ + { + "name": "Debug build", + "configurePreset": "default-vs-msvc-windows", + "configuration": "Debug" + }, + { + "name": "Release build", + "configurePreset": "default-vs-msvc-windows", + "configuration": "Release" + }, { "name": "default-vs-msvc-windows", "configurePreset": "default-vs-msvc-windows", diff --git a/res/shaders/entity.glslv b/res/shaders/entity.glslv index e318db38..3d916e9a 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,8 +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); - 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/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..24ec6cae 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,12 @@ 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); - vec3 light = decomp_light.rgb; - float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz) / + vec3 light = v_light.rgb; + 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); @@ -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); 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..f1f79f3e 100644 --- a/src/graphics/core/Mesh.cpp +++ b/src/graphics/core/Mesh.cpp @@ -1,93 +1,4 @@ -#include "Mesh.hpp" -#include -#include +#include "graphics/core/Mesh.hpp" -int Mesh::meshesCount = 0; -int Mesh::drawCalls = 0; - -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..5e1edcf2 --- /dev/null +++ b/src/graphics/core/Mesh.inl @@ -0,0 +1,91 @@ +#pragma once + +#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(); + } + if(vertexSize!=sizeof(VertexStructure)){ + throw std::runtime_error("Vertex size mismatch!"); + } + + 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..1bcceb9e 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 = 0; + bool normalized = false; + ubyte count = 0; + + + [[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..96e53864 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -1,25 +1,40 @@ #pragma once #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 +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} + }; +}; + +/// @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 +44,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; };