mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
move BlocksRenderer voxels buffer fill to main thread
This commit is contained in:
parent
0c62951062
commit
c46a6ad3bd
4 changed files with 81 additions and 45 deletions
|
|
@ -28,10 +28,6 @@ BlocksRenderer::BlocksRenderer(
|
|||
cache(cache),
|
||||
settings(settings)
|
||||
{
|
||||
voxelsBuffer = std::make_unique<VoxelsVolume>(
|
||||
CHUNK_W + voxelBufferPadding*2,
|
||||
CHUNK_H,
|
||||
CHUNK_D + voxelBufferPadding*2);
|
||||
blockDefsCache = content.getIndices()->blocks.getDefs();
|
||||
}
|
||||
|
||||
|
|
@ -687,12 +683,9 @@ SortingMeshData BlocksRenderer::renderTranslucent(
|
|||
return sortingMesh;
|
||||
}
|
||||
|
||||
void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) {
|
||||
void BlocksRenderer::build(const Chunk* chunk, const VoxelsVolume& volume) {
|
||||
this->chunk = chunk;
|
||||
voxelsBuffer->setPosition(
|
||||
chunk->x * CHUNK_W - voxelBufferPadding, 0,
|
||||
chunk->z * CHUNK_D - voxelBufferPadding);
|
||||
chunks->getVoxels(*voxelsBuffer, settings.graphics.backlight.get(), chunk->top + 1);
|
||||
this->voxelsBuffer = &volume;
|
||||
if (voxelsBuffer->pickBlockId(
|
||||
chunk->x * CHUNK_W, 0, chunk->z * CHUNK_D
|
||||
) == BLOCK_VOID) {
|
||||
|
|
@ -733,7 +726,7 @@ void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) {
|
|||
indexCount = 0;
|
||||
denseIndexCount = 0;
|
||||
|
||||
denseRender = false; //settings.graphics.denseRender.get();
|
||||
denseRender = false;
|
||||
densePass = false;
|
||||
render(voxels, beginEnds);
|
||||
|
||||
|
|
@ -762,15 +755,18 @@ ChunkMeshData BlocksRenderer::createMesh() {
|
|||
util::Buffer(denseIndexBuffer.get(), denseIndexCount),
|
||||
},
|
||||
util::Buffer(
|
||||
ChunkVertex::ATTRIBUTES, sizeof(ChunkVertex::ATTRIBUTES) / sizeof(VertexAttribute)
|
||||
ChunkVertex::ATTRIBUTES,
|
||||
sizeof(ChunkVertex::ATTRIBUTES) / sizeof(VertexAttribute)
|
||||
)
|
||||
),
|
||||
std::move(sortingMesh)
|
||||
};
|
||||
}
|
||||
|
||||
ChunkMesh BlocksRenderer::render(const Chunk *chunk, const Chunks *chunks) {
|
||||
build(chunk, chunks);
|
||||
ChunkMesh BlocksRenderer::render(
|
||||
const Chunk* chunk, const VoxelsVolume& volume
|
||||
) {
|
||||
build(chunk, volume);
|
||||
|
||||
return ChunkMesh{std::make_unique<Mesh<ChunkVertex>>(
|
||||
vertexBuffer.get(), vertexCount,
|
||||
|
|
@ -781,11 +777,6 @@ ChunkMesh BlocksRenderer::render(const Chunk *chunk, const Chunks *chunks) {
|
|||
), std::move(sortingMesh)};
|
||||
}
|
||||
|
||||
VoxelsVolume* BlocksRenderer::getVoxelsBuffer() const {
|
||||
return voxelsBuffer.get();
|
||||
}
|
||||
|
||||
size_t BlocksRenderer::getMemoryConsumption() const {
|
||||
size_t volume = voxelsBuffer->getW() * voxelsBuffer->getH() * voxelsBuffer->getD();
|
||||
return capacity * (sizeof(ChunkVertex) + sizeof(uint32_t) * 2) + volume * (sizeof(voxel) + sizeof(light_t));
|
||||
return capacity * (sizeof(ChunkVertex) + sizeof(uint32_t) * 2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,13 +32,12 @@ class BlocksRenderer {
|
|||
size_t indexCount;
|
||||
size_t denseIndexCount;
|
||||
size_t capacity;
|
||||
int voxelBufferPadding = 2;
|
||||
bool overflow = false;
|
||||
bool cancelled = false;
|
||||
bool densePass = false;
|
||||
bool denseRender = false;
|
||||
const Chunk* chunk = nullptr;
|
||||
std::unique_ptr<VoxelsVolume> voxelsBuffer;
|
||||
const VoxelsVolume* voxelsBuffer = nullptr;
|
||||
|
||||
const Block* const* blockDefsCache;
|
||||
const ContentGfxCache& cache;
|
||||
|
|
@ -152,9 +151,13 @@ class BlocksRenderer {
|
|||
|
||||
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;
|
||||
|
||||
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:
|
||||
|
|
@ -166,10 +169,11 @@ public:
|
|||
);
|
||||
virtual ~BlocksRenderer();
|
||||
|
||||
void build(const Chunk* chunk, const Chunks* chunks);
|
||||
ChunkMesh render(const Chunk* chunk, const Chunks* chunks);
|
||||
void build(const Chunk* chunk, const VoxelsVolume& volume);
|
||||
ChunkMesh render(
|
||||
const Chunk* chunk, const VoxelsVolume& volume
|
||||
);
|
||||
ChunkMeshData createMesh();
|
||||
VoxelsVolume* getVoxelsBuffer() const;
|
||||
|
||||
size_t getMemoryConsumption() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,24 +12,22 @@
|
|||
#include "window/Camera.hpp"
|
||||
#include "maths/FrustumCulling.hpp"
|
||||
#include "util/listutil.hpp"
|
||||
#include "util/ObjectsPool.hpp"
|
||||
#include "settings.hpp"
|
||||
|
||||
static debug::Logger logger("chunks-render");
|
||||
|
||||
size_t ChunksRenderer::visibleChunks = 0;
|
||||
|
||||
class RendererWorker : public util::Worker<std::shared_ptr<Chunk>, RendererResult> {
|
||||
const Chunks& chunks;
|
||||
class RendererWorker : public util::Worker<RendererJob, RendererResult> {
|
||||
BlocksRenderer renderer;
|
||||
public:
|
||||
RendererWorker(
|
||||
const Level& level,
|
||||
const Chunks& chunks,
|
||||
const ContentGfxCache& cache,
|
||||
const EngineSettings& settings
|
||||
)
|
||||
: chunks(chunks),
|
||||
renderer(
|
||||
: renderer(
|
||||
settings.graphics.denseRender.get()
|
||||
? settings.graphics.chunkMaxVerticesDense.get()
|
||||
: settings.graphics.chunkMaxVertices.get(),
|
||||
|
|
@ -39,8 +37,10 @@ public:
|
|||
) {
|
||||
}
|
||||
|
||||
RendererResult operator()(const std::shared_ptr<Chunk>& chunk) override {
|
||||
renderer.build(chunk.get(), &chunks);
|
||||
RendererResult operator()(const RendererJob& job) override {
|
||||
auto chunk = job.chunk;
|
||||
auto volume = job.volume;
|
||||
renderer.build(chunk.get(), *volume);
|
||||
if (renderer.isCancelled()) {
|
||||
return RendererResult {
|
||||
glm::ivec2(chunk->x, chunk->z), true, ChunkMeshData {}};
|
||||
|
|
@ -51,6 +51,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static util::ObjectsPool<VoxelsVolume> voxelsVolumesPool {};
|
||||
static inline const int VOXELS_BUFFER_PADDING = 2;
|
||||
|
||||
ChunksRenderer::ChunksRenderer(
|
||||
const Level* level,
|
||||
const Chunks& chunks,
|
||||
|
|
@ -67,7 +70,7 @@ ChunksRenderer::ChunksRenderer(
|
|||
"chunks-render-pool",
|
||||
[&]() {
|
||||
return std::make_shared<RendererWorker>(
|
||||
*level, chunks, cache, settings
|
||||
*level, cache, settings
|
||||
);
|
||||
},
|
||||
[&](RendererResult& result) {
|
||||
|
|
@ -87,30 +90,61 @@ ChunksRenderer::ChunksRenderer(
|
|||
level->content, cache, settings
|
||||
);
|
||||
logger.info() << "created " << threadPool.getWorkersCount() << " workers";
|
||||
logger.info() << "memory consumption is "
|
||||
<< renderer->getMemoryConsumption() * threadPool.getWorkersCount()
|
||||
<< " B";
|
||||
logger.info() << "memory consumption is "
|
||||
<< renderer->getMemoryConsumption() *
|
||||
threadPool.getWorkersCount() +
|
||||
voxelsVolumesPool.countTotal() *
|
||||
(sizeof(VoxelsVolume) +
|
||||
(CHUNK_W + VOXELS_BUFFER_PADDING * 2) * CHUNK_H *
|
||||
(CHUNK_D + VOXELS_BUFFER_PADDING * 2) *
|
||||
(sizeof(voxel) + sizeof(light_t)))
|
||||
<< " B";
|
||||
}
|
||||
|
||||
ChunksRenderer::~ChunksRenderer() = default;
|
||||
|
||||
std::shared_ptr<VoxelsVolume> ChunksRenderer::prepareVoxelsVolume(
|
||||
const Chunk& chunk
|
||||
) {
|
||||
auto voxelsBuffer = voxelsVolumesPool.create(
|
||||
CHUNK_W + VOXELS_BUFFER_PADDING * 2,
|
||||
CHUNK_H,
|
||||
CHUNK_D + VOXELS_BUFFER_PADDING * 2
|
||||
);
|
||||
voxelsBuffer->setPosition(
|
||||
chunk.x * CHUNK_W - VOXELS_BUFFER_PADDING, 0,
|
||||
chunk.z * CHUNK_D - VOXELS_BUFFER_PADDING
|
||||
);
|
||||
chunks.getVoxels(
|
||||
*voxelsBuffer, settings.graphics.backlight.get(), chunk.top + 1
|
||||
);
|
||||
return voxelsBuffer;
|
||||
}
|
||||
|
||||
const Mesh<ChunkVertex>* ChunksRenderer::render(
|
||||
const std::shared_ptr<Chunk>& chunk, bool important
|
||||
) {
|
||||
glm::ivec2 key(chunk->x, chunk->z);
|
||||
chunk->flags.modified = false;
|
||||
if (important) {
|
||||
auto mesh = renderer->render(chunk.get(), &chunks);
|
||||
meshes[glm::ivec2(chunk->x, chunk->z)] = ChunkMesh {
|
||||
std::move(mesh.mesh), std::move(mesh.sortingMeshData)
|
||||
};
|
||||
auto voxelsBuffer = prepareVoxelsVolume(*chunk);
|
||||
inwork[key] = true;
|
||||
|
||||
auto mesh = renderer->render(chunk.get(), *voxelsBuffer);
|
||||
meshes[glm::ivec2(chunk->x, chunk->z)] =
|
||||
ChunkMesh {std::move(mesh.mesh), std::move(mesh.sortingMeshData)};
|
||||
return meshes[glm::ivec2(chunk->x, chunk->z)].mesh.get();
|
||||
}
|
||||
glm::ivec2 key(chunk->x, chunk->z);
|
||||
if (inwork.find(key) != inwork.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto voxelsBuffer = prepareVoxelsVolume(*chunk);
|
||||
inwork[key] = true;
|
||||
threadPool.enqueueJob(chunk);
|
||||
chunks.getVoxels(
|
||||
*voxelsBuffer, settings.graphics.backlight.get(), chunk->top + 1
|
||||
);
|
||||
|
||||
threadPool.enqueueJob({chunk, std::move(voxelsBuffer)});
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class Chunks;
|
|||
class Frustum;
|
||||
class BlocksRenderer;
|
||||
class ContentGfxCache;
|
||||
class VoxelsVolume;
|
||||
struct EngineSettings;
|
||||
|
||||
struct ChunksSortEntry {
|
||||
|
|
@ -38,6 +39,11 @@ struct RendererResult {
|
|||
ChunkMeshData meshData;
|
||||
};
|
||||
|
||||
struct RendererJob {
|
||||
std::shared_ptr<Chunk> chunk;
|
||||
std::shared_ptr<VoxelsVolume> volume;
|
||||
};
|
||||
|
||||
class ChunksRenderer {
|
||||
const Chunks& chunks;
|
||||
const Assets& assets;
|
||||
|
|
@ -48,10 +54,11 @@ class ChunksRenderer {
|
|||
std::unordered_map<glm::ivec2, ChunkMesh> meshes;
|
||||
std::unordered_map<glm::ivec2, bool> inwork;
|
||||
std::vector<ChunksSortEntry> indices;
|
||||
util::ThreadPool<std::shared_ptr<Chunk>, RendererResult> threadPool;
|
||||
util::ThreadPool<RendererJob, RendererResult> threadPool;
|
||||
const Mesh<ChunkVertex>* retrieveChunk(
|
||||
size_t index, const Camera& camera, bool culling
|
||||
);
|
||||
std::shared_ptr<VoxelsVolume> prepareVoxelsVolume(const Chunk& chunk);
|
||||
public:
|
||||
ChunksRenderer(
|
||||
const Level* level,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue