diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 382a410d..5b6f1257 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -4,9 +4,6 @@ #include "maths/UVRegion.hpp" #include "constants.hpp" #include "content/Content.hpp" -#include "voxels/Block.hpp" -#include "voxels/Chunk.hpp" -#include "voxels/VoxelsVolume.hpp" #include "voxels/ChunksStorage.hpp" #include "lighting/Lightmap.hpp" #include "frontend/ContentGfxCache.hpp" @@ -14,12 +11,8 @@ #include -using glm::ivec3; -using glm::vec3; -using glm::vec4; - const uint BlocksRenderer::VERTEX_SIZE = 6; -const vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); +const glm::vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); BlocksRenderer::BlocksRenderer( size_t capacity, @@ -46,8 +39,10 @@ BlocksRenderer::BlocksRenderer( BlocksRenderer::~BlocksRenderer() { } -/* Basic vertex add method */ -void BlocksRenderer::vertex(const vec3& coord, float u, float v, const vec4& light) { +/// Basic vertex add method +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; @@ -80,22 +75,22 @@ void BlocksRenderer::index(int a, int b, int c, int d, int e, int f) { /// @brief Add face with precalculated lights void BlocksRenderer::face( - const vec3& coord, + const glm::vec3& coord, float w, float h, float d, - const vec3& axisX, - const vec3& axisY, - const vec3& axisZ, + const glm::vec3& axisX, + const glm::vec3& axisY, + const glm::vec3& axisZ, const UVRegion& region, - const vec4(&lights)[4], - const vec4& tint + const glm::vec4(&lights)[4], + const glm::vec4& tint ) { if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { overflow = true; return; } - vec3 X = axisX * w; - vec3 Y = axisY * h; - vec3 Z = axisZ * d; + auto X = axisX * w; + auto Y = axisY * h; + auto Z = axisZ * d; float s = 0.5f; vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, lights[0] * tint); vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, lights[1] * tint); @@ -105,23 +100,27 @@ void BlocksRenderer::face( } void BlocksRenderer::vertexAO( - const vec3& coord, + const glm::vec3& coord, float u, float v, - const vec4& tint, - const vec3& axisX, - const vec3& axisY, - const vec3& axisZ + const glm::vec4& tint, + const glm::vec3& axisX, + const glm::vec3& axisY, + const glm::vec3& axisZ ) { - vec3 pos = coord+axisZ*0.5f+(axisX+axisY)*0.5f; - vec4 light = pickSoftLight(ivec3(round(pos.x), round(pos.y), round(pos.z)), axisX, axisY); + auto pos = coord+axisZ*0.5f+(axisX+axisY)*0.5f; + auto light = pickSoftLight( + glm::ivec3(std::round(pos.x), std::round(pos.y), std::round(pos.z)), + axisX, + axisY + ); vertex(coord, u, v, light * tint); } void BlocksRenderer::faceAO( - const vec3& coord, - const vec3& X, - const vec3& Y, - const vec3& Z, + const glm::vec3& coord, + const glm::vec3& X, + const glm::vec3& Y, + const glm::vec3& Z, const UVRegion& region, bool lights ) { @@ -135,11 +134,11 @@ void BlocksRenderer::faceAO( float d = glm::dot(glm::normalize(Z), SUN_VECTOR); d = 0.8f + d * 0.2f; - vec3 axisX = glm::normalize(X); - vec3 axisY = glm::normalize(Y); - vec3 axisZ = glm::normalize(Z); + auto axisX = glm::normalize(X); + auto axisY = glm::normalize(Y); + auto axisZ = glm::normalize(Z); - vec4 tint(d); + glm::vec4 tint(d); vertexAO(coord + (-X - Y + Z) * s, region.u1, region.v1, tint, axisX, axisY, axisZ); vertexAO(coord + ( X - Y + Z) * s, region.u2, region.v1, tint, axisX, axisY, axisZ); vertexAO(coord + ( X + Y + Z) * s, region.u2, region.v2, tint, axisX, axisY, axisZ); @@ -155,12 +154,12 @@ void BlocksRenderer::faceAO( } void BlocksRenderer::face( - const vec3& coord, - const vec3& X, - const vec3& Y, - const vec3& Z, + const glm::vec3& coord, + const glm::vec3& X, + const glm::vec3& Y, + const glm::vec3& Z, const UVRegion& region, - vec4 tint, + glm::vec4 tint, bool lights ) { if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { @@ -182,21 +181,22 @@ void BlocksRenderer::face( } void BlocksRenderer::tetragonicFace( - const vec3& coord, - const vec3& p1, const vec3& p2, const vec3& p3, const vec3& p4, - const vec3& X, const vec3& Y, const vec3& Z, + const glm::vec3& coord, + const glm::vec3& p1, const glm::vec3& p2, + const glm::vec3& p3, const glm::vec3& p4, + const glm::vec3& X, const glm::vec3& Y, const glm::vec3& Z, const UVRegion& texreg, bool lights ) { - const vec3 fp1 = (p1.x - 0.5f) * X + (p1.y - 0.5f) * Y + (p1.z - 0.5f) * Z; - const vec3 fp2 = (p2.x - 0.5f) * X + (p2.y - 0.5f) * Y + (p2.z - 0.5f) * Z; - const vec3 fp3 = (p3.x - 0.5f) * X + (p3.y - 0.5f) * Y + (p3.z - 0.5f) * Z; - const vec3 fp4 = (p4.x - 0.5f) * X + (p4.y - 0.5f) * Y + (p4.z - 0.5f) * Z; + const auto fp1 = (p1.x - 0.5f) * X + (p1.y - 0.5f) * Y + (p1.z - 0.5f) * Z; + const auto fp2 = (p2.x - 0.5f) * X + (p2.y - 0.5f) * Y + (p2.z - 0.5f) * Z; + const auto fp3 = (p3.x - 0.5f) * X + (p3.y - 0.5f) * Y + (p3.z - 0.5f) * Z; + const auto fp4 = (p4.x - 0.5f) * X + (p4.y - 0.5f) * Y + (p4.z - 0.5f) * Z; - vec4 tint(1.0f); + glm::vec4 tint(1.0f); if (lights) { - vec3 dir = glm::cross(fp2 - fp1, fp3 - fp1); - vec3 normal = glm::normalize(dir); + auto dir = glm::cross(fp2 - fp1, fp3 - fp1); + auto normal = glm::normalize(dir); float d = glm::dot(normal, SUN_VECTOR); d = 0.8f + d * 0.2f; @@ -216,12 +216,12 @@ void BlocksRenderer::tetragonicFace( void BlocksRenderer::blockXSprite( int x, int y, int z, - const vec3& size, + const glm::vec3& size, const UVRegion& texface1, const UVRegion& texface2, float spread ) { - vec4 lights[] { + glm::vec4 lights[] { pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}), pickSoftLight({x + 1, y + 1, z}, {1, 0, 0}, {0, 1, 0}), pickSoftLight({x + 1, y + 1, z}, {1, 0, 0}, {0, 1, 0}), @@ -233,28 +233,24 @@ void BlocksRenderer::blockXSprite( float zs = ((float)(char)(rand >> 8) / 512) * spread; const float w = size.x / 1.41f; - const float tint = 0.8f; + const glm::vec4 tint (0.8f); - face(vec3(x + xs, y, z + zs), - w, size.y, 0, vec3(1, 0, 1), vec3(0, 1, 0), vec3(), - texface1, lights, vec4(tint)); - face(vec3(x + xs, y, z + zs), - w, size.y, 0, vec3(-1, 0, -1), vec3(0, 1, 0), vec3(), - texface1, lights, vec4(tint)); + face({x + xs, y, z + zs}, w, size.y, 0, {1, 0, 1}, {0, 1, 0}, glm::vec3(), + texface1, lights, tint); + face({x + xs, y, z + zs}, w, size.y, 0, {-1, 0, -1}, {0, 1, 0}, glm::vec3(), + texface1, lights, tint); - face(vec3(x + xs, y, z + zs), - w, size.y, 0, vec3(1, 0, -1), vec3(0, 1, 0), vec3(), - texface2, lights, vec4(tint)); - face(vec3(x + xs, y, z + zs), - w, size.y, 0, vec3(-1, 0, 1), vec3(0, 1, 0), vec3(), - texface2, lights, vec4(tint)); + face({x + xs, y, z + zs}, w, size.y, 0, {1, 0, -1}, {0, 1, 0}, glm::vec3(), + texface2, lights, tint); + face({x + xs, y, z + zs}, w, size.y, 0, {-1, 0, 1}, {0, 1, 0}, glm::vec3(), + texface2, lights, tint); } // HINT: texture faces order: {east, west, bottom, top, south, north} /// @brief AABB blocks render method void BlocksRenderer::blockAABB( - const ivec3& icoord, + const glm::ivec3& icoord, const UVRegion(&texfaces)[6], const Block* block, ubyte rotation, @@ -269,11 +265,11 @@ void BlocksRenderer::blockAABB( hitbox.a = glm::min(hitbox.a, box.a); hitbox.b = glm::max(hitbox.b, box.b); } - vec3 size = hitbox.size(); - vec3 X(1, 0, 0); - vec3 Y(0, 1, 0); - vec3 Z(0, 0, 1); - vec3 coord(icoord); + auto size = hitbox.size(); + glm::vec3 X(1, 0, 0); + glm::vec3 Y(0, 1, 0); + glm::vec3 Z(0, 0, 1); + glm::vec3 coord(icoord); if (block->rotatable) { auto& rotations = block->rotations; auto& orient = rotations.variants[rotation]; @@ -282,7 +278,7 @@ void BlocksRenderer::blockAABB( Z = orient.axisZ; orient.transform(hitbox); } - coord = vec3(icoord) - vec3(0.5f) + hitbox.center(); + coord -= glm::vec3(0.5f) - hitbox.center(); if (ao) { faceAO(coord, X*size.x, Y*size.y, Z*size.z, texfaces[5], lights); // north @@ -307,13 +303,13 @@ void BlocksRenderer::blockAABB( } void BlocksRenderer::blockCustomModel( - const ivec3& icoord, const Block* block, ubyte rotation, bool lights, bool ao + const glm::ivec3& icoord, const Block* block, ubyte rotation, bool lights, bool ao ) { - vec3 X(1, 0, 0); - vec3 Y(0, 1, 0); - vec3 Z(0, 0, 1); + glm::vec3 X(1, 0, 0); + glm::vec3 Y(0, 1, 0); + glm::vec3 Z(0, 0, 1); CoordSystem orient(X,Y,Z); - vec3 coord(icoord); + glm::vec3 coord(icoord); if (block->rotatable) { auto& rotations = block->rotations; orient = rotations.variants[rotation]; @@ -324,11 +320,11 @@ void BlocksRenderer::blockCustomModel( for (size_t i = 0; i < block->modelBoxes.size(); i++) { AABB box = block->modelBoxes[i]; - vec3 size = box.size(); + auto size = box.size(); if (block->rotatable) { orient.transform(box); } - vec3 center_coord = coord - vec3(0.5f) + box.center(); + glm::vec3 center_coord = coord - glm::vec3(0.5f) + box.center(); faceAO(center_coord, X * size.x, Y * size.y, Z * size.z, block->modelUVs[i * 6 + 5], lights); // north faceAO(center_coord, -X * size.x, Y * size.y, -Z * size.z, block->modelUVs[i * 6 + 4], lights); // south faceAO(center_coord, X * size.x, -Z * size.z, Y * size.y, block->modelUVs[i * 6 + 3], lights); // top @@ -350,21 +346,21 @@ void BlocksRenderer::blockCustomModel( /* Fastest solid shaded blocks render method */ void BlocksRenderer::blockCube( - int x, int y, int z, + const glm::ivec3& coord, const UVRegion(&texfaces)[6], - const Block* block, + const Block& block, blockstate states, bool lights, bool ao ) { - ubyte group = block->drawGroup; + ubyte group = block.drawGroup; - vec3 X(1, 0, 0); - vec3 Y(0, 1, 0); - vec3 Z(0, 0, 1); - vec3 coord(x, y, z); - if (block->rotatable) { - auto& rotations = block->rotations; + glm::ivec3 X(1, 0, 0); + glm::ivec3 Y(0, 1, 0); + glm::ivec3 Z(0, 0, 1); + + if (block.rotatable) { + auto& rotations = block.rotations; auto& orient = rotations.variants[states.rotation]; X = orient.axisX; Y = orient.axisY; @@ -372,61 +368,46 @@ void BlocksRenderer::blockCube( } if (ao) { - if (isOpen(x+Z.x, y+Z.y, z+Z.z, group)) { + if (isOpen(coord + Z, group)) { faceAO(coord, X, Y, Z, texfaces[5], lights); } - if (isOpen(x-Z.x, y-Z.y, z-Z.z, group)) { + if (isOpen(coord - Z, group)) { faceAO(coord, -X, Y, -Z, texfaces[4], lights); } - if (isOpen(x+Y.x, y+Y.y, z+Y.z, group)) { + if (isOpen(coord + Y, group)) { faceAO(coord, X, -Z, Y, texfaces[3], lights); } - if (isOpen(x-Y.x, y-Y.y, z-Y.z, group)) { + if (isOpen(coord - Y, group)) { faceAO(coord, X, Z, -Y, texfaces[2], lights); } - if (isOpen(x+X.x, y+X.y, z+X.z, group)) { + if (isOpen(coord + X, group)) { faceAO(coord, -Z, Y, X, texfaces[1], lights); } - if (isOpen(x-X.x, y-X.y, z-X.z, group)) { + if (isOpen(coord - X, group)) { faceAO(coord, Z, Y, -X, texfaces[0], lights); } } else { - if (isOpen(x+Z.x, y+Z.y, z+Z.z, group)) { - face(coord, X, Y, Z, texfaces[5], pickLight({x, y, z+1}), lights); + if (isOpen(coord + Z, group)) { + face(coord, X, Y, Z, texfaces[5], pickLight(coord + Z), lights); } - if (isOpen(x-Z.x, y-Z.y, z-Z.z, group)) { - face(coord, -X, Y, -Z, texfaces[4], pickLight({x, y, z-1}), lights); + if (isOpen(coord - Z, group)) { + face(coord, -X, Y, -Z, texfaces[4], pickLight(coord - Z), lights); } - if (isOpen(x+Y.x, y+Y.y, z+Y.z, group)) { - face(coord, X, -Z, Y, texfaces[3], pickLight({x, y+1, z}), lights); + if (isOpen(coord + Y, group)) { + face(coord, X, -Z, Y, texfaces[3], pickLight(coord + Y), lights); } - if (isOpen(x-Y.x, y-Y.y, z-Y.z, group)) { - face(coord, X, Z, -Y, texfaces[2], pickLight({x, y-1, z}), lights); + if (isOpen(coord - Y, group)) { + face(coord, X, Z, -Y, texfaces[2], pickLight(coord - Y), lights); } - if (isOpen(x+X.x, y+X.y, z+X.z, group)) { - face(coord, -Z, Y, X, texfaces[1], pickLight({x+1, y, z}), lights); + if (isOpen(coord + X, group)) { + face(coord, -Z, Y, X, texfaces[1], pickLight(coord + X), lights); } - if (isOpen(x-X.x, y-X.y, z-X.z, group)) { - face(coord, Z, Y, -X, texfaces[0], pickLight({x-1, y, z}), lights); + if (isOpen(coord - X, group)) { + face(coord, Z, Y, -X, texfaces[0], pickLight(coord - X), lights); } } } -// Does block allow to see other blocks sides (is it transparent) -bool BlocksRenderer::isOpen(int x, int y, int z, ubyte group) const { - blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x, - y, - chunk->z * CHUNK_D + z); - if (id == BLOCK_VOID) { - return false; - } - const Block& block = *blockDefsCache[id]; - if ((block.drawGroup != group && block.lightPassing) || !block.rt.solid) { - return true; - } - return !id; -} - bool BlocksRenderer::isOpenForLight(int x, int y, int z) const { blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x, y, @@ -441,39 +422,39 @@ bool BlocksRenderer::isOpenForLight(int x, int y, int z) const { return !id; } -vec4 BlocksRenderer::pickLight(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, chunk->z * CHUNK_D + z); - return vec4(Lightmap::extract(light, 0) / 15.0f, - Lightmap::extract(light, 1) / 15.0f, - Lightmap::extract(light, 2) / 15.0f, - Lightmap::extract(light, 3) / 15.0f); + return glm::vec4(Lightmap::extract(light, 0), + Lightmap::extract(light, 1), + Lightmap::extract(light, 2), + Lightmap::extract(light, 3)) / 15.0f; } else { - return vec4(0.0f); + return glm::vec4(0.0f); } } -vec4 BlocksRenderer::pickLight(const ivec3& coord) const { +glm::vec4 BlocksRenderer::pickLight(const glm::ivec3& coord) const { return pickLight(coord.x, coord.y, coord.z); } -vec4 BlocksRenderer::pickSoftLight(const ivec3& coord, - const ivec3& right, - const ivec3& up) const { +glm::vec4 BlocksRenderer::pickSoftLight( + const glm::ivec3& coord, const glm::ivec3& right, const glm::ivec3& up +) const { return (pickLight(coord) + pickLight(coord - right) + pickLight(coord - right - up) + pickLight(coord - up)) * 0.25f; } -vec4 BlocksRenderer::pickSoftLight(float x, float y, float z, - const ivec3& right, - const ivec3& up) const { +glm::vec4 BlocksRenderer::pickSoftLight( + float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up +) const { return pickSoftLight({ - static_cast(round(x)), - static_cast(round(y)), - static_cast(round(z))}, + static_cast(std::round(x)), + static_cast(std::round(y)), + static_cast(std::round(z))}, right, up); } @@ -485,7 +466,7 @@ void BlocksRenderer::render(const voxel* voxels) { const voxel& vox = voxels[i]; blockid_t id = vox.id; blockstate state = vox.state; - const Block& def = *blockDefsCache[id]; + const auto& def = *blockDefsCache[id]; if (id == 0 || def.drawGroup != drawGroup || state.segment) { continue; } @@ -502,21 +483,21 @@ void BlocksRenderer::render(const voxel* voxels) { int z = (i / CHUNK_D) % CHUNK_W; switch (def.model) { case BlockModel::block: - blockCube(x, y, z, texfaces, &def, vox.state, !def.shadeless, + blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless, def.ambientOcclusion); break; case BlockModel::xsprite: { - blockXSprite(x, y, z, vec3(1.0f), + blockXSprite(x, y, z, glm::vec3(1.0f), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); break; } case BlockModel::aabb: { - blockAABB(ivec3(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(ivec3(x, y, z), &def, vox.state.rotation, + blockCustomModel({x, y, z}, &def, vox.state.rotation, !def.shadeless, def.ambientOcclusion); break; } diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index ef827091..69cb75e4 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -7,6 +7,10 @@ #include "voxels/voxel.hpp" #include "typedefs.hpp" +#include "voxels/Block.hpp" +#include "voxels/Chunk.hpp" +#include "voxels/VoxelsVolume.hpp" + class Content; class Mesh; class Block; @@ -84,9 +88,9 @@ class BlocksRenderer { bool lights ); void blockCube( - int x, int y, int z, + const glm::ivec3& coord, const UVRegion(&faces)[6], - const Block* block, + const Block& block, blockstate states, bool lights, bool ao @@ -115,7 +119,22 @@ class BlocksRenderer { ); bool isOpenForLight(int x, int y, int z) const; - bool isOpen(int x, int y, int z, ubyte group) const; + + + // Does block allow to see other blocks sides (is it transparent) + inline constexpr bool isOpen(const glm::ivec3& pos, ubyte group) const { + auto id = voxelsBuffer->pickBlockId( + chunk->x * CHUNK_W + pos.x, pos.y, chunk->z * CHUNK_D + pos.z + ); + if (id == BLOCK_VOID) { + return false; + } + const auto& block = *blockDefsCache[id]; + if ((block.drawGroup != group && block.lightPassing) || !block.rt.solid) { + return true; + } + return !id; + } glm::vec4 pickLight(int x, int y, int z) const; glm::vec4 pickLight(const glm::ivec3& coord) const;