diff --git a/src/constants.h b/src/constants.h index 8edca7d6..d89376b7 100644 --- a/src/constants.h +++ b/src/constants.h @@ -32,7 +32,7 @@ inline constexpr itemid_t ITEM_VOID = std::numeric_limits::max(); inline constexpr blockid_t MAX_BLOCKS = BLOCK_VOID; inline constexpr uint vox_index(uint x, uint y, uint z, uint w=CHUNK_W, uint d=CHUNK_D) { - return (y * d + z) * w + x; + return (y * d + z) * w + x; } inline const std::string SHADERS_FOLDER = "shaders"; diff --git a/src/frontend/graphics/BlocksRenderer.cpp b/src/frontend/graphics/BlocksRenderer.cpp index 85d5f337..1630c407 100644 --- a/src/frontend/graphics/BlocksRenderer.cpp +++ b/src/frontend/graphics/BlocksRenderer.cpp @@ -21,105 +21,105 @@ const uint BlocksRenderer::VERTEX_SIZE = 6; const vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); BlocksRenderer::BlocksRenderer(size_t capacity, - const Content* content, - const ContentGfxCache* cache, - const EngineSettings& settings) - : content(content), - vertexOffset(0), - indexOffset(0), - indexSize(0), - capacity(capacity), - cache(cache), - settings(settings) { - vertexBuffer = new float[capacity]; - indexBuffer = new int[capacity]; - voxelsBuffer = new VoxelsVolume(CHUNK_W + 2, CHUNK_H, CHUNK_D + 2); - blockDefsCache = content->getIndices()->getBlockDefs(); + const Content* content, + const ContentGfxCache* cache, + const EngineSettings& settings) + : content(content), + vertexOffset(0), + indexOffset(0), + indexSize(0), + capacity(capacity), + cache(cache), + settings(settings) { + vertexBuffer = new float[capacity]; + indexBuffer = new int[capacity]; + voxelsBuffer = new VoxelsVolume(CHUNK_W + 2, CHUNK_H, CHUNK_D + 2); + blockDefsCache = content->getIndices()->getBlockDefs(); } BlocksRenderer::~BlocksRenderer() { - delete voxelsBuffer; - delete[] vertexBuffer; - delete[] indexBuffer; + delete voxelsBuffer; + delete[] vertexBuffer; + delete[] indexBuffer; } /* Basic vertex add method */ void BlocksRenderer::vertex(const vec3& coord, float u, float v, const vec4& light) { - vertexBuffer[vertexOffset++] = coord.x; - vertexBuffer[vertexOffset++] = coord.y; - vertexBuffer[vertexOffset++] = coord.z; + vertexBuffer[vertexOffset++] = coord.x; + vertexBuffer[vertexOffset++] = coord.y; + vertexBuffer[vertexOffset++] = coord.z; - vertexBuffer[vertexOffset++] = u; - vertexBuffer[vertexOffset++] = v; + vertexBuffer[vertexOffset++] = u; + vertexBuffer[vertexOffset++] = v; - union { - float floating; - uint32_t integer; - } compressed; + union { + float floating; + uint32_t integer; + } compressed; - compressed.integer = (uint32_t(light.r * 255) & 0xff) << 24; - compressed.integer |= (uint32_t(light.g * 255) & 0xff) << 16; - compressed.integer |= (uint32_t(light.b * 255) & 0xff) << 8; - compressed.integer |= (uint32_t(light.a * 255) & 0xff); + compressed.integer = (uint32_t(light.r * 255) & 0xff) << 24; + compressed.integer |= (uint32_t(light.g * 255) & 0xff) << 16; + compressed.integer |= (uint32_t(light.b * 255) & 0xff) << 8; + compressed.integer |= (uint32_t(light.a * 255) & 0xff); - vertexBuffer[vertexOffset++] = compressed.floating; + vertexBuffer[vertexOffset++] = compressed.floating; } 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; + 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; } /* Add face with precalculated lights */ void BlocksRenderer::face(const vec3& coord, - float w, float h, float d, - const vec3& axisX, - const vec3& axisY, + float w, float h, float d, + const vec3& axisX, + const vec3& axisY, const vec3& axisZ, - const UVRegion& region, - const vec4(&lights)[4], - const vec4& tint) { - if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { - overflow = true; - return; - } + const UVRegion& region, + const vec4(&lights)[4], + const vec4& tint) { + if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { + overflow = true; + return; + } vec3 X = axisX * w; vec3 Y = axisY * h; vec3 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); - vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, lights[2] * tint); - vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, lights[3] * tint); - index(0, 1, 3, 1, 2, 3); + 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); + vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, lights[2] * tint); + vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, lights[3] * tint); + index(0, 1, 3, 1, 2, 3); } void BlocksRenderer::vertex(const vec3& coord, - float u, float v, - const vec4& tint, - const vec3& axisX, - const vec3& axisY, - const vec3& axisZ) { + float u, float v, + const vec4& tint, + const vec3& axisX, + const vec3& axisY, + const 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); - vertex(coord, u, v, light * tint); + vec4 light = pickSoftLight(ivec3(round(pos.x), round(pos.y), round(pos.z)), axisX, axisY); + vertex(coord, u, v, light * tint); } void BlocksRenderer::face(const vec3& coord, - const vec3& X, - const vec3& Y, - const vec3& Z, - const UVRegion& region, + const vec3& X, + const vec3& Y, + const vec3& Z, + const UVRegion& region, bool lights) { - if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { - overflow = true; - return; - } + if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) { + overflow = true; + return; + } float s = 0.5f; if (lights) { @@ -146,12 +146,12 @@ void BlocksRenderer::face(const vec3& coord, } 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 UVRegion& texreg, - bool lights) { + const vec3& p2, const vec3& p3, const vec3& p4, + const vec3& X, + const vec3& Y, + const 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; @@ -172,80 +172,80 @@ void BlocksRenderer::tetragonicFace(const vec3& coord, const vec3& p1, // tint.y = normal.y * 0.5f + 0.5f; // tint.z = normal.z * 0.5f + 0.5f; } - vertex(coord + fp1, texreg.u1, texreg.v1, tint); - vertex(coord + fp2, texreg.u2, texreg.v1, tint); - vertex(coord + fp3, texreg.u2, texreg.v2, tint); - vertex(coord + fp4, texreg.u1, texreg.v2, tint); - index(0, 1, 3, 1, 2, 3); + vertex(coord + fp1, texreg.u1, texreg.v1, tint); + vertex(coord + fp2, texreg.u2, texreg.v1, tint); + vertex(coord + fp3, texreg.u2, texreg.v2, tint); + vertex(coord + fp4, texreg.u1, texreg.v2, tint); + index(0, 1, 3, 1, 2, 3); } void BlocksRenderer::blockXSprite(int x, int y, int z, - const vec3& size, - const UVRegion& texface1, - const UVRegion& texface2, - float spread) { - 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}), - pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}) }; + const vec3& size, + const UVRegion& texface1, + const UVRegion& texface2, + float spread) { + 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}), + pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}) }; - int rand = ((x * z + y) ^ (z * y - x)) * (z + y); + int rand = ((x * z + y) ^ (z * y - x)) * (z + y); - float xs = ((float)(char)rand / 512) * spread; - float zs = ((float)(char)(rand >> 8) / 512) * spread; + float xs = ((float)(char)rand / 512) * spread; + float zs = ((float)(char)(rand >> 8) / 512) * spread; - const float w = size.x / 1.41f; - const float 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)); + const float w = size.x / 1.41f; + const float 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)); + 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)); + 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(vec3(x + xs, y, z + zs), + w, size.y, 0, vec3(-1, 0, 1), vec3(0, 1, 0), vec3(), + texface1, lights, vec4(tint)); } // HINT: texture faces order: {east, west, bottom, top, south, north} /* AABB blocks render method */ void BlocksRenderer::blockAABB(const ivec3& icoord, - const UVRegion(&texfaces)[6], - const Block* block, ubyte rotation, + const UVRegion(&texfaces)[6], + const Block* block, ubyte rotation, bool lights) { if (block->hitboxes.empty()) { return; } - AABB hitbox = block->hitboxes[0]; + AABB hitbox = block->hitboxes[0]; for (const auto& box : block->hitboxes) { 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); - if (block->rotatable) { - auto& rotations = block->rotations; - auto& orient = rotations.variants[rotation]; - X = orient.axisX; - Y = orient.axisY; - Z = orient.axisZ; + vec3 size = hitbox.size(); + vec3 X(1, 0, 0); + vec3 Y(0, 1, 0); + vec3 Z(0, 0, 1); + vec3 coord(icoord); + if (block->rotatable) { + auto& rotations = block->rotations; + auto& orient = rotations.variants[rotation]; + X = orient.axisX; + Y = orient.axisY; + Z = orient.axisZ; orient.transform(hitbox); - } + } coord = vec3(icoord) - vec3(0.5f) + hitbox.center(); - + face(coord, X*size.x, Y*size.y, Z*size.z, texfaces[5], lights); // north face(coord, -X*size.x, Y*size.y, -Z*size.z, texfaces[4], lights); // south @@ -257,209 +257,209 @@ void BlocksRenderer::blockAABB(const ivec3& icoord, } void BlocksRenderer::blockCustomModel(const ivec3& icoord, - const Block* block, ubyte rotation, bool lights) { - vec3 X(1, 0, 0); - vec3 Y(0, 1, 0); - vec3 Z(0, 0, 1); - CoordSystem orient(X,Y,Z); - vec3 coord(icoord); - if (block->rotatable) { - auto& rotations = block->rotations; - orient = rotations.variants[rotation]; - X = orient.axisX; - Y = orient.axisY; - Z = orient.axisZ; - } + const Block* block, ubyte rotation, bool lights) { + vec3 X(1, 0, 0); + vec3 Y(0, 1, 0); + vec3 Z(0, 0, 1); + CoordSystem orient(X,Y,Z); + vec3 coord(icoord); + if (block->rotatable) { + auto& rotations = block->rotations; + orient = rotations.variants[rotation]; + X = orient.axisX; + Y = orient.axisY; + Z = orient.axisZ; + } - for (size_t i = 0; i < block->modelBoxes.size(); i++) { - AABB box = block->modelBoxes[i]; - vec3 size = box.size(); - if (block->rotatable) { - orient.transform(box); - } - vec3 center_coord = coord - vec3(0.5f) + box.center(); - face(center_coord, X * size.x, Y * size.y, Z * size.z, block->modelUVs[i * 6 + 5], lights); // north - face(center_coord, -X * size.x, Y * size.y, -Z * size.z, block->modelUVs[i * 6 + 4], lights); // south - face(center_coord, X * size.x, -Z * size.z, Y * size.y, block->modelUVs[i * 6 + 3], lights); // top - face(center_coord, -X * size.x, -Z * size.z, -Y * size.y, block->modelUVs[i * 6 + 2], lights); // bottom - face(center_coord, -Z * size.z, Y * size.y, X * size.x, block->modelUVs[i * 6 + 1], lights); // west - face(center_coord, Z * size.z, Y * size.y, -X * size.x, block->modelUVs[i * 6 + 0], lights); // east - } - - for (size_t i = 0; i < block->modelExtraPoints.size()/4; i++) { - tetragonicFace(coord, - block->modelExtraPoints[i * 4 + 0], - block->modelExtraPoints[i * 4 + 1], - block->modelExtraPoints[i * 4 + 2], - block->modelExtraPoints[i * 4 + 3], - X, Y, Z, - block->modelUVs[block->modelBoxes.size()*6 + i], lights); - } + for (size_t i = 0; i < block->modelBoxes.size(); i++) { + AABB box = block->modelBoxes[i]; + vec3 size = box.size(); + if (block->rotatable) { + orient.transform(box); + } + vec3 center_coord = coord - vec3(0.5f) + box.center(); + face(center_coord, X * size.x, Y * size.y, Z * size.z, block->modelUVs[i * 6 + 5], lights); // north + face(center_coord, -X * size.x, Y * size.y, -Z * size.z, block->modelUVs[i * 6 + 4], lights); // south + face(center_coord, X * size.x, -Z * size.z, Y * size.y, block->modelUVs[i * 6 + 3], lights); // top + face(center_coord, -X * size.x, -Z * size.z, -Y * size.y, block->modelUVs[i * 6 + 2], lights); // bottom + face(center_coord, -Z * size.z, Y * size.y, X * size.x, block->modelUVs[i * 6 + 1], lights); // west + face(center_coord, Z * size.z, Y * size.y, -X * size.x, block->modelUVs[i * 6 + 0], lights); // east + } + + for (size_t i = 0; i < block->modelExtraPoints.size()/4; i++) { + tetragonicFace(coord, + block->modelExtraPoints[i * 4 + 0], + block->modelExtraPoints[i * 4 + 1], + block->modelExtraPoints[i * 4 + 2], + block->modelExtraPoints[i * 4 + 3], + X, Y, Z, + block->modelUVs[block->modelBoxes.size()*6 + i], lights); + } } /* Fastest solid shaded blocks render method */ void BlocksRenderer::blockCube(int x, int y, int z, - const UVRegion(&texfaces)[6], - const Block* block, - ubyte states, + const UVRegion(&texfaces)[6], + const Block* block, + ubyte states, bool lights) { - 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; - auto& orient = rotations.variants[states & BLOCK_ROT_MASK]; - X = orient.axisX; - Y = orient.axisY; - Z = orient.axisZ; - } - - if (isOpen(x+Z.x, y+Z.y, z+Z.z, group)) { - face(coord, X, Y, Z, texfaces[5], lights); - } - if (isOpen(x-Z.x, y-Z.y, z-Z.z, group)) { - face(coord, -X, Y, -Z, texfaces[4], lights); - } - if (isOpen(x+Y.x, y+Y.y, z+Y.z, group)) { - face(coord, X, -Z, Y, texfaces[3], lights); - } - if (isOpen(x-Y.x, y-Y.y, z-Y.z, group)) { - face(coord, X, Z, -Y, texfaces[2], lights); - } - if (isOpen(x+X.x, y+X.y, z+X.z, group)) { - face(coord, -Z, Y, X, texfaces[1], lights); - } - if (isOpen(x-X.x, y-X.y, z-X.z, group)) { - face(coord, Z, Y, -X, texfaces[0], lights); - } + 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; + auto& orient = rotations.variants[states & BLOCK_ROT_MASK]; + X = orient.axisX; + Y = orient.axisY; + Z = orient.axisZ; + } + + if (isOpen(x+Z.x, y+Z.y, z+Z.z, group)) { + face(coord, X, Y, Z, texfaces[5], lights); + } + if (isOpen(x-Z.x, y-Z.y, z-Z.z, group)) { + face(coord, -X, Y, -Z, texfaces[4], lights); + } + if (isOpen(x+Y.x, y+Y.y, z+Y.z, group)) { + face(coord, X, -Z, Y, texfaces[3], lights); + } + if (isOpen(x-Y.x, y-Y.y, z-Y.z, group)) { + face(coord, X, Z, -Y, texfaces[2], lights); + } + if (isOpen(x+X.x, y+X.y, z+X.z, group)) { + face(coord, -Z, Y, X, texfaces[1], lights); + } + if (isOpen(x-X.x, y-X.y, z-X.z, group)) { + face(coord, Z, Y, -X, texfaces[0], 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; + 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, - chunk->z * CHUNK_D + z); - if (id == BLOCK_VOID) - return false; - const Block& block = *blockDefsCache[id]; - if (block.lightPassing) { - return true; - } - return !id; + 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.lightPassing) { + return true; + } + return !id; } 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); - } - else { - return vec4(0.0f); - } + 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); + } + else { + return vec4(0.0f); + } } vec4 BlocksRenderer::pickLight(const ivec3& coord) const { - return pickLight(coord.x, coord.y, coord.z); + return pickLight(coord.x, coord.y, coord.z); } vec4 BlocksRenderer::pickSoftLight(const ivec3& coord, - const ivec3& right, - const ivec3& up) const { - return ( - pickLight(coord) + - pickLight(coord - right) + - pickLight(coord - right - up) + - pickLight(coord - up)) * 0.25f; + const ivec3& right, + const 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 { - return pickSoftLight({int(round(x)), int(round(y)), int(round(z))}, right, up); + const ivec3& right, + const ivec3& up) const { + return pickSoftLight({int(round(x)), int(round(y)), int(round(z))}, right, up); } void BlocksRenderer::render(const voxel* voxels) { - int begin = chunk->bottom * (CHUNK_W * CHUNK_D); - int end = chunk->top * (CHUNK_W * CHUNK_D); - for (const auto drawGroup : *content->drawGroups) { - for (int i = begin; i < end; i++) { - const voxel& vox = voxels[i]; - blockid_t id = vox.id; - const Block& def = *blockDefsCache[id]; - if (id == 0 || def.drawGroup != drawGroup) - continue; - const UVRegion texfaces[6]{ cache->getRegion(id, 0), - cache->getRegion(id, 1), - cache->getRegion(id, 2), - cache->getRegion(id, 3), - cache->getRegion(id, 4), - cache->getRegion(id, 5)}; - int x = i % CHUNK_W; - int y = i / (CHUNK_D * CHUNK_W); - int z = (i / CHUNK_D) % CHUNK_W; - switch (def.model) { - case BlockModel::block: + int begin = chunk->bottom * (CHUNK_W * CHUNK_D); + int end = chunk->top * (CHUNK_W * CHUNK_D); + for (const auto drawGroup : *content->drawGroups) { + for (int i = begin; i < end; i++) { + const voxel& vox = voxels[i]; + blockid_t id = vox.id; + const Block& def = *blockDefsCache[id]; + if (id == 0 || def.drawGroup != drawGroup) + continue; + const UVRegion texfaces[6]{ cache->getRegion(id, 0), + cache->getRegion(id, 1), + cache->getRegion(id, 2), + cache->getRegion(id, 3), + cache->getRegion(id, 4), + cache->getRegion(id, 5)}; + int x = i % CHUNK_W; + int y = i / (CHUNK_D * CHUNK_W); + int z = (i / CHUNK_D) % CHUNK_W; + switch (def.model) { + case BlockModel::block: blockCube(x, y, z, texfaces, &def, vox.states, !def.rt.emissive); - break; - case BlockModel::xsprite: { - blockXSprite(x, y, z, vec3(1.0f), - texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); - break; - } - case BlockModel::aabb: { - blockAABB(ivec3(x,y,z), texfaces, &def, vox.rotation(), !def.rt.emissive); - break; - } - case BlockModel::custom: { - blockCustomModel(ivec3(x, y, z), &def, vox.rotation(), !def.rt.emissive); - break; - } - default: - break; - } - if (overflow) - return; - } - } + break; + case BlockModel::xsprite: { + blockXSprite(x, y, z, vec3(1.0f), + texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); + break; + } + case BlockModel::aabb: { + blockAABB(ivec3(x,y,z), texfaces, &def, vox.rotation(), !def.rt.emissive); + break; + } + case BlockModel::custom: { + blockCustomModel(ivec3(x, y, z), &def, vox.rotation(), !def.rt.emissive); + break; + } + default: + break; + } + if (overflow) + return; + } + } } void BlocksRenderer::build(const Chunk* chunk, const ChunksStorage* chunks) { - this->chunk = chunk; - voxelsBuffer->setPosition(chunk->x * CHUNK_W - 1, 0, chunk->z * CHUNK_D - 1); - chunks->getVoxels(voxelsBuffer, settings.graphics.backlight); - overflow = false; - vertexOffset = 0; - indexOffset = indexSize = 0; - const voxel* voxels = chunk->voxels; - render(voxels); + this->chunk = chunk; + voxelsBuffer->setPosition(chunk->x * CHUNK_W - 1, 0, chunk->z * CHUNK_D - 1); + chunks->getVoxels(voxelsBuffer, settings.graphics.backlight); + overflow = false; + vertexOffset = 0; + indexOffset = indexSize = 0; + const voxel* voxels = chunk->voxels; + render(voxels); } Mesh* BlocksRenderer::createMesh() { - const vattr attrs[]{ {3}, {2}, {1}, {0} }; - size_t vcount = vertexOffset / BlocksRenderer::VERTEX_SIZE; - Mesh* mesh = new Mesh(vertexBuffer, vcount, indexBuffer, indexSize, attrs); - return mesh; + const vattr attrs[]{ {3}, {2}, {1}, {0} }; + size_t vcount = vertexOffset / BlocksRenderer::VERTEX_SIZE; + Mesh* mesh = new Mesh(vertexBuffer, vcount, indexBuffer, indexSize, attrs); + return mesh; } Mesh* BlocksRenderer::render(const Chunk* chunk, const ChunksStorage* chunks) { @@ -468,5 +468,5 @@ Mesh* BlocksRenderer::render(const Chunk* chunk, const ChunksStorage* chunks) { } VoxelsVolume* BlocksRenderer::getVoxelsBuffer() const { - return voxelsBuffer; + return voxelsBuffer; } \ No newline at end of file diff --git a/src/frontend/graphics/BlocksRenderer.h b/src/frontend/graphics/BlocksRenderer.h index 229fd70e..b915edea 100644 --- a/src/frontend/graphics/BlocksRenderer.h +++ b/src/frontend/graphics/BlocksRenderer.h @@ -20,83 +20,83 @@ class ContentGfxCache; class BlocksRenderer { static const glm::vec3 SUN_VECTOR; - static const uint VERTEX_SIZE; - const Content* const content; - float* vertexBuffer; - int* indexBuffer; - size_t vertexOffset; - size_t indexOffset, indexSize; - size_t capacity; + static const uint VERTEX_SIZE; + const Content* const content; + float* vertexBuffer; + int* indexBuffer; + size_t vertexOffset; + size_t indexOffset, indexSize; + size_t capacity; - bool overflow = false; + bool overflow = false; - const Chunk* chunk = nullptr; - VoxelsVolume* voxelsBuffer; + const Chunk* chunk = nullptr; + VoxelsVolume* voxelsBuffer; - const Block* const* blockDefsCache; - const ContentGfxCache* const cache; - const EngineSettings& settings; + const Block* const* blockDefsCache; + const ContentGfxCache* const cache; + const EngineSettings& settings; - 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 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 vertex(const glm::vec3& coord, float u, float v, - const glm::vec4& brightness, - const glm::vec3& axisX, - const glm::vec3& axisY, - const glm::vec3& axisZ); + void vertex(const glm::vec3& coord, float u, float v, + const glm::vec4& brightness, + const glm::vec3& axisX, + const glm::vec3& axisY, + const glm::vec3& axisZ); - void face(const glm::vec3& coord, float w, float h, float d, - const glm::vec3& axisX, - const glm::vec3& axisY, + void face(const glm::vec3& coord, float w, float h, float d, + const glm::vec3& axisX, + const glm::vec3& axisY, const glm::vec3& axisZ, - const UVRegion& region, - const glm::vec4(&lights)[4], - const glm::vec4& tint); - - void face(const glm::vec3& coord, - const glm::vec3& axisX, - const glm::vec3& axisY, - const glm::vec3& axisZ, - const UVRegion& region, + const UVRegion& region, + const glm::vec4(&lights)[4], + const glm::vec4& tint); + + void face(const glm::vec3& coord, + const glm::vec3& axisX, + const glm::vec3& axisY, + const glm::vec3& axisZ, + const UVRegion& region, bool lights); - void tetragonicFace(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); - - void blockCube(int x, int y, int z, const UVRegion(&faces)[6], const Block* block, ubyte states, bool lights); - void blockAABB(const glm::ivec3& coord, + void tetragonicFace(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); + + void blockCube(int x, int y, int z, const UVRegion(&faces)[6], const Block* block, ubyte states, bool lights); + void blockAABB(const glm::ivec3& coord, const UVRegion(&faces)[6], const Block* block, ubyte rotation, bool lights); - void blockXSprite(int x, int y, int z, const glm::vec3& size, const UVRegion& face1, const UVRegion& face2, float spread); - void blockCustomModel(const glm::ivec3& icoord, - const Block* block, ubyte rotation, - bool lights); + void blockXSprite(int x, int y, int z, const glm::vec3& size, const UVRegion& face1, const UVRegion& face2, float spread); + void blockCustomModel(const glm::ivec3& icoord, + const Block* block, ubyte rotation, + bool lights); - bool isOpenForLight(int x, int y, int z) const; - bool isOpen(int x, int y, int z, ubyte group) const; + bool isOpenForLight(int x, int y, int z) const; + bool isOpen(int x, int y, int z, ubyte group) const; - glm::vec4 pickLight(int x, int y, int z) const; - glm::vec4 pickLight(const glm::ivec3& coord) const; - glm::vec4 pickSoftLight(const glm::ivec3& coord, const glm::ivec3& right, const glm::ivec3& up) const; - glm::vec4 pickSoftLight(float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up) const; - void render(const voxel* voxels); + glm::vec4 pickLight(int x, int y, int z) const; + glm::vec4 pickLight(const glm::ivec3& coord) const; + glm::vec4 pickSoftLight(const glm::ivec3& coord, const glm::ivec3& right, const glm::ivec3& up) const; + glm::vec4 pickSoftLight(float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up) const; + void render(const voxel* voxels); public: - BlocksRenderer(size_t capacity, const Content* content, const ContentGfxCache* cache, const EngineSettings& settings); - virtual ~BlocksRenderer(); + BlocksRenderer(size_t capacity, const Content* content, const ContentGfxCache* cache, const EngineSettings& settings); + virtual ~BlocksRenderer(); void build(const Chunk* chunk, const ChunksStorage* chunks); - Mesh* render(const Chunk* chunk, const ChunksStorage* chunks); + Mesh* render(const Chunk* chunk, const ChunksStorage* chunks); Mesh* createMesh(); - VoxelsVolume* getVoxelsBuffer() const; + VoxelsVolume* getVoxelsBuffer() const; }; #endif // GRAPHICS_BLOCKS_RENDERER_H \ No newline at end of file diff --git a/src/frontend/graphics/ChunksRenderer.cpp b/src/frontend/graphics/ChunksRenderer.cpp index 6753bca5..a3bab60c 100644 --- a/src/frontend/graphics/ChunksRenderer.cpp +++ b/src/frontend/graphics/ChunksRenderer.cpp @@ -11,8 +11,8 @@ ChunksRenderer::ChunksRenderer(Level* level, const ContentGfxCache* cache, const EngineSettings& settings) : level(level), cache(cache), settings(settings) { - const int MAX_FULL_CUBES = 3000; - renderer = std::make_unique( + const int MAX_FULL_CUBES = 3000; + renderer = std::make_unique( 9 * 6 * 6 * MAX_FULL_CUBES, level->content, cache, settings ); @@ -88,7 +88,7 @@ void ChunksRenderer::process(std::shared_ptr chunk, BlocksRenderer& rende } std::shared_ptr ChunksRenderer::render(std::shared_ptr chunk, bool important) { - chunk->setModified(false); + chunk->setModified(false); if (important) { Mesh* mesh = renderer->render(chunk.get(), level->chunksStorage.get()); @@ -111,29 +111,29 @@ std::shared_ptr ChunksRenderer::render(std::shared_ptr chunk, bool } void ChunksRenderer::unload(Chunk* chunk) { - auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); - if (found != meshes.end()) { - meshes.erase(found); - } + auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); + if (found != meshes.end()) { + meshes.erase(found); + } } std::shared_ptr ChunksRenderer::getOrRender(std::shared_ptr chunk, bool important) { - auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); - if (found != meshes.end()){ + auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); + if (found != meshes.end()){ if (chunk->isModified()) { render(chunk, important); } - return found->second; - } - return render(chunk, important); + return found->second; + } + return render(chunk, important); } std::shared_ptr ChunksRenderer::get(Chunk* chunk) { - auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); - if (found != meshes.end()) { - return found->second; - } - return nullptr; + auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); + if (found != meshes.end()) { + return found->second; + } + return nullptr; } void ChunksRenderer::update() { diff --git a/src/frontend/graphics/ChunksRenderer.h b/src/frontend/graphics/ChunksRenderer.h index d442d827..e6a65431 100644 --- a/src/frontend/graphics/ChunksRenderer.h +++ b/src/frontend/graphics/ChunksRenderer.h @@ -29,9 +29,9 @@ struct mesh_entry { }; class ChunksRenderer { - std::unique_ptr renderer; - Level* level; - std::unordered_map> meshes; + std::unique_ptr renderer; + Level* level; + std::unordered_map> meshes; std::unordered_map inwork; std::vector threads; @@ -50,16 +50,16 @@ class ChunksRenderer { void threadLoop(int index); void process(std::shared_ptr chunk, BlocksRenderer& renderer); public: - ChunksRenderer(Level* level, - const ContentGfxCache* cache, - const EngineSettings& settings); - virtual ~ChunksRenderer(); + ChunksRenderer(Level* level, + const ContentGfxCache* cache, + const EngineSettings& settings); + virtual ~ChunksRenderer(); - std::shared_ptr render(std::shared_ptr chunk, bool important); - void unload(Chunk* chunk); + std::shared_ptr render(std::shared_ptr chunk, bool important); + void unload(Chunk* chunk); - std::shared_ptr getOrRender(std::shared_ptr chunk, bool important); - std::shared_ptr get(Chunk* chunk); + std::shared_ptr getOrRender(std::shared_ptr chunk, bool important); + std::shared_ptr get(Chunk* chunk); void update(); }; diff --git a/src/frontend/graphics/Skybox.cpp b/src/frontend/graphics/Skybox.cpp index 2e5d8e06..5b08e850 100644 --- a/src/frontend/graphics/Skybox.cpp +++ b/src/frontend/graphics/Skybox.cpp @@ -60,9 +60,9 @@ Skybox::~Skybox() { void Skybox::drawBackground(Camera* camera, Assets* assets, int width, int height) { Shader* backShader = assets->getShader("background"); backShader->use(); - backShader->uniformMatrix("u_view", camera->getView(false)); - backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(M_PI*0.5f)); - backShader->uniform1f("u_ar", float(width)/float(height)); + backShader->uniformMatrix("u_view", camera->getView(false)); + backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(M_PI*0.5f)); + backShader->uniform1f("u_ar", float(width)/float(height)); backShader->uniform1i("u_cubemap", 1); bind(); mesh->draw(); @@ -99,7 +99,7 @@ void Skybox::draw( { const Viewport& viewport = pctx.getViewport(); int width = viewport.getWidth(); - int height = viewport.getHeight(); + int height = viewport.getHeight(); drawBackground(camera, assets, width, height); diff --git a/src/frontend/gui/GUI.cpp b/src/frontend/gui/GUI.cpp index 733fa219..581909d1 100644 --- a/src/frontend/gui/GUI.cpp +++ b/src/frontend/gui/GUI.cpp @@ -18,8 +18,8 @@ using namespace gui; GUI::GUI() { container = std::make_shared(glm::vec2(1000)); uicamera = std::make_unique(glm::vec3(), Window::height); - uicamera->perspective = false; - uicamera->flipped = true; + uicamera->perspective = false; + uicamera->flipped = true; menu = std::make_shared(); container->add(menu); @@ -133,9 +133,9 @@ void GUI::draw(const GfxContext* pctx, Assets* assets) { menu->setPos((wsize - menu->getSize()) / 2.0f); uicamera->setFov(wsize.y); - Shader* uishader = assets->getShader("ui"); - uishader->use(); - uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView()); + Shader* uishader = assets->getShader("ui"); + uishader->use(); + uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView()); pctx->getBatch2D()->begin(); container->draw(pctx, assets); diff --git a/src/frontend/gui/gui_util.cpp b/src/frontend/gui/gui_util.cpp index 81ebb693..24971bc2 100644 --- a/src/frontend/gui/gui_util.cpp +++ b/src/frontend/gui/gui_util.cpp @@ -8,12 +8,10 @@ #include "../../delegates.h" using namespace gui; -using glm::vec2; -using glm::vec4; std::shared_ptr