[ClientChunk] Now using a single VBO per chunk.

This commit is contained in:
Quentin Bazin 2021-06-11 06:59:26 +02:00
parent 677992d93c
commit af2f8007f6
5 changed files with 28 additions and 18 deletions

View File

@ -150,7 +150,7 @@ void ChunkRenderer::drawChunks(gk::RenderTarget &target, gk::RenderStates states
states.shader->setUniform("u_modelMatrix", it.second);
target.drawVertexBuffer(it.first->getVBO(layer), GL_TRIANGLES, 0, (GLsizei)verticesCount);
target.drawVertexBuffer(it.first->getVertexBuffer(), GL_TRIANGLES, it.first->getBufferOffset(layer), (GLsizei)verticesCount);
it.first->setHasBeenDrawn(true);
}

View File

@ -83,17 +83,22 @@ void ChunkMeshBuilder::update() {
ClientChunk *chunk = (ClientChunk *)m_world.getChunk(job.chunkData.x, job.chunkData.y, job.chunkData.z);
if (chunk) {
const gk::VertexBuffer &vbo = chunk->getVertexBuffer();
gk::VertexBuffer::bind(&vbo);
vbo.setData(job.totalVertexCount * sizeof(Vertex), nullptr, GL_DYNAMIC_DRAW);
u64 offset = 0;
for (u8 i = 0 ; i < ChunkMeshLayer::Count ; ++i) {
job.vertices[i].shrink_to_fit();
const gk::VertexBuffer &vbo = chunk->getVertexBuffer(i);
gk::VertexBuffer::bind(&vbo);
vbo.setData(job.vertices[i].size() * sizeof(Vertex), job.vertices[i].data(), GL_DYNAMIC_DRAW);
gk::VertexBuffer::bind(nullptr);
vbo.updateData(offset * sizeof(Vertex), job.vertices[i].size() * sizeof(Vertex), job.vertices[i].data());
chunk->setVerticesCount(i, job.vertices[i].size());
offset += job.vertices[i].size();
}
gk::VertexBuffer::bind(nullptr);
}
it = m_futures.erase(it);
@ -307,6 +312,8 @@ inline void ChunkMeshBuilder::addCubeFace(s8f x, s8f y, s8f z, s8f f, ChunkMeshB
addVertex(1);
addVertex(2);
}
job.totalVertexCount += 6;
}
inline void ChunkMeshBuilder::addCross(s8f x, s8f y, s8f z, ChunkMeshBuildingJob &job, const BlockState &blockState) {
@ -371,6 +378,8 @@ inline void ChunkMeshBuilder::addCross(s8f x, s8f y, s8f z, ChunkMeshBuildingJob
job.vertices[ChunkMeshLayer::Flora].emplace_back(vertices[3]);
job.vertices[ChunkMeshLayer::Flora].emplace_back(vertices[1]);
job.vertices[ChunkMeshLayer::Flora].emplace_back(vertices[2]);
job.totalVertexCount += 6;
}
}

View File

@ -97,6 +97,8 @@ struct ChunkMeshBuildingJob {
VerticesArray vertices;
const TextureAtlas *textureAtlas;
u64 totalVertexCount = 0;
};
class ClientWorld;

View File

@ -38,14 +38,12 @@ u64 ClientChunk::chunkUpdateTime = 0;
ClientChunk::ClientChunk(s32 x, s32 y, s32 z, const Dimension &dimension, ClientWorld &world)
: Chunk(x, y, z, (World &)world), m_world(world), m_dimension(dimension)
{
for (auto &vbo : m_vbo) {
vbo.layout().addAttribute(0, "coord3d", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, coord3d)));
vbo.layout().addAttribute(1, "texCoord", 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, texCoord)));
vbo.layout().addAttribute(2, "color", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, color)));
vbo.layout().addAttribute(3, "normal", 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, normal)));
vbo.layout().addAttribute(4, "lightValue", 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, lightValue)));
vbo.layout().addAttribute(5, "ambientOcclusion", 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, ambientOcclusion)));
}
m_vbo.layout().addAttribute(0, "coord3d", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, coord3d)));
m_vbo.layout().addAttribute(1, "texCoord", 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, texCoord)));
m_vbo.layout().addAttribute(2, "color", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, color)));
m_vbo.layout().addAttribute(3, "normal", 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, normal)));
m_vbo.layout().addAttribute(4, "lightValue", 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, lightValue)));
m_vbo.layout().addAttribute(5, "ambientOcclusion", 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<GLvoid *>(offsetof(Vertex, ambientOcclusion)));
}
void ClientChunk::update() {

View File

@ -27,6 +27,8 @@
#ifndef CLIENTCHUNK_HPP_
#define CLIENTCHUNK_HPP_
#include <numeric>
#include <gk/gl/Drawable.hpp>
#include "Chunk.hpp"
@ -59,13 +61,12 @@ class ClientChunk : public Chunk {
bool areAllNeighboursTooFar() const;
const gk::VertexBuffer &getVertexBuffer(u8 layer) { return m_vbo[layer]; }
const gk::VertexBuffer &getVertexBuffer() { return m_vbo; }
GLint getBufferOffset(u8 layer) const { return std::accumulate(m_verticesCount.begin(), m_verticesCount.begin() + layer, 0); }
std::size_t getVerticesCount(u8 layer) const { return m_verticesCount[layer]; }
void setVerticesCount(u8 layer, std::size_t count) { m_verticesCount[layer] = count; }
const gk::VertexBuffer &getVBO(u8 layer) const { return m_vbo[layer]; }
int debugTimesReceived = 0; // Only used by Minimap
static u32 chunkUpdatesPerSec;
@ -77,7 +78,7 @@ class ClientChunk : public Chunk {
const Dimension &m_dimension;
std::array<gk::VertexBuffer, ChunkMeshLayer::Count> m_vbo{};
gk::VertexBuffer m_vbo{};
std::array<std::size_t, ChunkMeshLayer::Count> m_verticesCount{};
bool m_isReadyForMeshing = false;