mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
186 lines
5.6 KiB
C++
186 lines
5.6 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <glm/glm.hpp>
|
|
#include "voxels/voxel.hpp"
|
|
#include "typedefs.hpp"
|
|
|
|
#include "voxels/Block.hpp"
|
|
#include "voxels/Chunk.hpp"
|
|
#include "voxels/VoxelsVolume.hpp"
|
|
#include "maths/util.hpp"
|
|
#include "commons.hpp"
|
|
#include "settings.hpp"
|
|
#include "maths/aabb.hpp"
|
|
|
|
template<typename VertexStructure> class Mesh;
|
|
class Content;
|
|
class Block;
|
|
class Chunk;
|
|
class Chunks;
|
|
class VoxelsVolume;
|
|
class ContentGfxCache;
|
|
struct UVRegion;
|
|
|
|
class BlocksRenderer {
|
|
static const glm::vec3 SUN_VECTOR;
|
|
const Content& content;
|
|
std::unique_ptr<ChunkVertex[]> vertexBuffer;
|
|
std::unique_ptr<uint32_t[]> indexBuffer;
|
|
std::unique_ptr<uint32_t[]> denseIndexBuffer;
|
|
size_t vertexCount;
|
|
size_t vertexOffset;
|
|
size_t indexCount;
|
|
size_t denseIndexCount;
|
|
size_t capacity;
|
|
// Increased to better cover cross-chunk sampling for extended blocks (e.g., 3x3x3)
|
|
int voxelBufferPadding = 4;
|
|
bool overflow = false;
|
|
bool cancelled = false;
|
|
bool densePass = false;
|
|
bool denseRender = false;
|
|
const Chunk* chunk = nullptr;
|
|
std::unique_ptr<VoxelsVolume> voxelsBuffer;
|
|
|
|
const Block* const* blockDefsCache;
|
|
const ContentGfxCache& cache;
|
|
const EngineSettings& settings;
|
|
|
|
util::PseudoRandom randomizer;
|
|
|
|
SortingMeshData sortingMesh;
|
|
// Accumulated local-space AABB over opaque build pass
|
|
AABB localAabb {glm::vec3(0.0f), glm::vec3(0.0f)};
|
|
bool localAabbInit = false;
|
|
|
|
void vertex(
|
|
const glm::vec3& coord,
|
|
float u,
|
|
float v,
|
|
const glm::vec4& light,
|
|
const glm::vec3& normal,
|
|
float emission
|
|
);
|
|
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,
|
|
const glm::vec4& brightness,
|
|
float normalHalfLen,
|
|
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,
|
|
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& X,
|
|
const glm::vec3& Y,
|
|
const glm::vec3& Z,
|
|
const UVRegion& region,
|
|
glm::vec4 tint,
|
|
bool lights
|
|
);
|
|
void faceAO(
|
|
const glm::vec3& coord,
|
|
const glm::vec3& axisX,
|
|
const glm::vec3& axisY,
|
|
const glm::vec3& axisZ,
|
|
const UVRegion& region,
|
|
bool lights
|
|
);
|
|
void blockCube(
|
|
const glm::ivec3& coord,
|
|
const UVRegion(&faces)[6],
|
|
const Block& block,
|
|
blockstate states,
|
|
bool lights,
|
|
bool ao
|
|
);
|
|
void blockAABB(
|
|
const glm::ivec3& coord,
|
|
const UVRegion(&faces)[6],
|
|
const Block* block,
|
|
ubyte rotation,
|
|
bool lights,
|
|
bool ambientOcclusion
|
|
);
|
|
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,
|
|
blockstate states,
|
|
bool lights,
|
|
bool ao
|
|
);
|
|
|
|
bool isOpenForLight(int x, int y, int z) const;
|
|
|
|
// Does block allow to see other blocks sides (is it transparent)
|
|
inline bool isOpen(const glm::ivec3& pos, const Block& def, const Variant& variant) const {
|
|
auto vox = voxelsBuffer->pickBlock(
|
|
chunk->x * CHUNK_W + pos.x, pos.y, chunk->z * CHUNK_D + pos.z
|
|
);
|
|
if (vox.id == BLOCK_VOID) {
|
|
return false;
|
|
}
|
|
const auto& block = *blockDefsCache[vox.id];
|
|
const auto& blockVariant = block.getVariantByBits(vox.state.userbits);
|
|
uint8_t otherDrawGroup = blockVariant.drawGroup;
|
|
if ((otherDrawGroup && (otherDrawGroup != variant.drawGroup)) || !blockVariant.rt.solid) {
|
|
return true;
|
|
}
|
|
if (densePass) {
|
|
return variant.culling == CullingMode::OPTIONAL;
|
|
} else if (variant.culling == CullingMode::OPTIONAL) {
|
|
return false;
|
|
}
|
|
if (variant.culling == CullingMode::DISABLED && vox.id == def.rt.id) {
|
|
return true;
|
|
}
|
|
return !vox.id;
|
|
}
|
|
|
|
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, const int beginEnds[256][2]);
|
|
SortingMeshData renderTranslucent(const voxel* voxels, int beginEnds[256][2]);
|
|
public:
|
|
BlocksRenderer(
|
|
size_t capacity,
|
|
const Content& content,
|
|
const ContentGfxCache& cache,
|
|
const EngineSettings& settings
|
|
);
|
|
virtual ~BlocksRenderer();
|
|
|
|
void build(const Chunk* chunk, const Chunks* chunks);
|
|
ChunkMesh render(const Chunk* chunk, const Chunks* chunks);
|
|
ChunkMeshData createMesh();
|
|
VoxelsVolume* getVoxelsBuffer() const;
|
|
inline const AABB& getLocalAabb() const { return localAabb; }
|
|
|
|
size_t getMemoryConsumption() const;
|
|
|
|
bool isCancelled() const {
|
|
return cancelled;
|
|
}
|
|
};
|