[Chunk|ChunkBuilder] Small improvements.
This commit is contained in:
parent
91c2e33ae3
commit
5f38eaaeb0
@ -22,7 +22,7 @@ class Block {
|
|||||||
public:
|
public:
|
||||||
Block(u32 id);
|
Block(u32 id);
|
||||||
|
|
||||||
glm::vec4 getTexCoords(int face);
|
glm::vec4 getTexCoords(int face) const;
|
||||||
|
|
||||||
u32 id() const { return m_id; }
|
u32 id() const { return m_id; }
|
||||||
void setId(u32 id) { m_id = id; }
|
void setId(u32 id) { m_id = id; }
|
||||||
|
@ -14,14 +14,23 @@
|
|||||||
#ifndef CHUNKBUILDER_HPP_
|
#ifndef CHUNKBUILDER_HPP_
|
||||||
#define CHUNKBUILDER_HPP_
|
#define CHUNKBUILDER_HPP_
|
||||||
|
|
||||||
#include <utility>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Types.hpp"
|
||||||
|
#include "Vertex.hpp"
|
||||||
|
|
||||||
|
class Block;
|
||||||
class Chunk;
|
class Chunk;
|
||||||
class VertexBuffer;
|
class VertexBuffer;
|
||||||
|
|
||||||
class ChunkBuilder {
|
class ChunkBuilder {
|
||||||
public:
|
public:
|
||||||
std::size_t buildChunk(const Chunk &chunk, const VertexBuffer &vbo);
|
std::size_t buildChunk(const Chunk &chunk, const VertexBuffer &vbo);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addFace(u8 x, u8 y, u8 z, u8 i, const Block *block, const Block *surroundingBlock);
|
||||||
|
|
||||||
|
std::vector<Vertex> m_vertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHUNKBUILDER_HPP_
|
#endif // CHUNKBUILDER_HPP_
|
||||||
|
@ -17,7 +17,7 @@ Block::Block(u32 id) {
|
|||||||
m_id = id;
|
m_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec4 Block::getTexCoords(int face) {
|
glm::vec4 Block::getTexCoords(int face) const {
|
||||||
u32 id = m_id;
|
u32 id = m_id;
|
||||||
|
|
||||||
// 0 -> right
|
// 0 -> right
|
||||||
|
@ -67,20 +67,11 @@ void Chunk::draw(RenderTarget &target, RenderStates states) const {
|
|||||||
// drawOutlines(target, states);
|
// drawOutlines(target, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Use the renderer to do that
|
void Chunk::drawOutlines(RenderTarget &target, RenderStates states) const {
|
||||||
void Chunk::drawOutlines(RenderTarget &, RenderStates states) const {
|
states.texture = nullptr;
|
||||||
Shader::bind(states.shader);
|
|
||||||
VertexBuffer::bind(&m_vbo);
|
|
||||||
|
|
||||||
states.shader->enableVertexAttribArray("coord3d");
|
|
||||||
|
|
||||||
for(u32 i = 0 ; i < m_verticesCount ; i += 4) {
|
for(u32 i = 0 ; i < m_verticesCount ; i += 4) {
|
||||||
glDrawArrays(GL_LINE_LOOP, i, 4);
|
target.draw(m_vbo, GL_LINE_LOOP, i, 4, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
states.shader->disableVertexAttribArray("coord3d");
|
|
||||||
|
|
||||||
VertexBuffer::bind(nullptr);
|
|
||||||
Shader::bind(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,52 +13,47 @@
|
|||||||
*/
|
*/
|
||||||
#include "Chunk.hpp"
|
#include "Chunk.hpp"
|
||||||
#include "ChunkBuilder.hpp"
|
#include "ChunkBuilder.hpp"
|
||||||
#include "Vertex.hpp"
|
|
||||||
|
static const float cubeCoords[6 * 4 * 3] = {
|
||||||
|
// Left
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 1,
|
||||||
|
0, 1, 1,
|
||||||
|
0, 1, 0,
|
||||||
|
|
||||||
|
// Right
|
||||||
|
1, 0, 1,
|
||||||
|
1, 0, 0,
|
||||||
|
1, 1, 0,
|
||||||
|
1, 1, 1,
|
||||||
|
|
||||||
|
// Bottom
|
||||||
|
0, 0, 0,
|
||||||
|
1, 0, 0,
|
||||||
|
1, 0, 1,
|
||||||
|
0, 0, 1,
|
||||||
|
|
||||||
|
// Top
|
||||||
|
0, 1, 1,
|
||||||
|
1, 1, 1,
|
||||||
|
1, 1, 0,
|
||||||
|
0, 1, 0,
|
||||||
|
|
||||||
|
// Front
|
||||||
|
1, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 1, 0,
|
||||||
|
1, 1, 0,
|
||||||
|
|
||||||
|
// Back
|
||||||
|
0, 0, 1,
|
||||||
|
1, 0, 1,
|
||||||
|
1, 1, 1,
|
||||||
|
0, 1, 1,
|
||||||
|
};
|
||||||
|
|
||||||
std::size_t ChunkBuilder::buildChunk(const Chunk &chunk, const VertexBuffer &vbo) {
|
std::size_t ChunkBuilder::buildChunk(const Chunk &chunk, const VertexBuffer &vbo) {
|
||||||
static const float cubeCoords[6 * 4 * 3] = {
|
m_vertices.reserve(Chunk::width * Chunk::height * Chunk::depth * 6 * 4);
|
||||||
// Left
|
|
||||||
0, 0, 0,
|
|
||||||
0, 0, 1,
|
|
||||||
0, 1, 1,
|
|
||||||
0, 1, 0,
|
|
||||||
|
|
||||||
// Right
|
|
||||||
1, 0, 1,
|
|
||||||
1, 0, 0,
|
|
||||||
1, 1, 0,
|
|
||||||
1, 1, 1,
|
|
||||||
|
|
||||||
// Bottom
|
|
||||||
0, 0, 0,
|
|
||||||
1, 0, 0,
|
|
||||||
1, 0, 1,
|
|
||||||
0, 0, 1,
|
|
||||||
|
|
||||||
// Top
|
|
||||||
0, 1, 1,
|
|
||||||
1, 1, 1,
|
|
||||||
1, 1, 0,
|
|
||||||
0, 1, 0,
|
|
||||||
|
|
||||||
// Front
|
|
||||||
1, 0, 0,
|
|
||||||
0, 0, 0,
|
|
||||||
0, 1, 0,
|
|
||||||
1, 1, 0,
|
|
||||||
|
|
||||||
// Back
|
|
||||||
0, 0, 1,
|
|
||||||
1, 0, 1,
|
|
||||||
1, 1, 1,
|
|
||||||
0, 1, 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<Vertex> vertices;
|
|
||||||
vertices.reserve(Chunk::width * Chunk::height * Chunk::depth * 6 * 4);
|
|
||||||
|
|
||||||
// Needed in the loop (avoid a lot of glm::vec3 creation)
|
|
||||||
glm::vec3 a, b, c, v1, v2, normal;
|
|
||||||
|
|
||||||
for(u8 z = 0 ; z < Chunk::depth ; z++) {
|
for(u8 z = 0 ; z < Chunk::depth ; z++) {
|
||||||
for(u8 y = 0 ; y < Chunk::height ; y++) {
|
for(u8 y = 0 ; y < Chunk::height ; y++) {
|
||||||
@ -76,68 +71,76 @@ std::size_t ChunkBuilder::buildChunk(const Chunk &chunk, const VertexBuffer &vbo
|
|||||||
};
|
};
|
||||||
|
|
||||||
for(u8 i = 0 ; i < 6 ; i++) {
|
for(u8 i = 0 ; i < 6 ; i++) {
|
||||||
// Skip hidden faces
|
addFace(x, y, z, i, block, surroundingBlocks[i]);
|
||||||
if(surroundingBlocks[i] && surroundingBlocks[i]->id()
|
|
||||||
&& (surroundingBlocks[i]->isOpaque() || block->id() == surroundingBlocks[i]->id()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Three points of the face
|
|
||||||
a.x = cubeCoords[i * 12 + 0];
|
|
||||||
a.y = cubeCoords[i * 12 + 1];
|
|
||||||
a.z = cubeCoords[i * 12 + 2];
|
|
||||||
|
|
||||||
b.x = cubeCoords[i * 12 + 3];
|
|
||||||
b.y = cubeCoords[i * 12 + 4];
|
|
||||||
b.z = cubeCoords[i * 12 + 5];
|
|
||||||
|
|
||||||
c.x = cubeCoords[i * 12 + 6];
|
|
||||||
c.y = cubeCoords[i * 12 + 7];
|
|
||||||
c.z = cubeCoords[i * 12 + 8];
|
|
||||||
|
|
||||||
// Computing two vectors
|
|
||||||
v1 = b - a;
|
|
||||||
v2 = c - a;
|
|
||||||
|
|
||||||
// Computing face normal (already normalized because cubeCoords are normalized)
|
|
||||||
normal = glm::cross(v1, v2);
|
|
||||||
|
|
||||||
const glm::vec4 &blockTexCoords = block->getTexCoords(i);
|
|
||||||
float faceTexCoords[2 * 4] = {
|
|
||||||
blockTexCoords.x, blockTexCoords.w,
|
|
||||||
blockTexCoords.z, blockTexCoords.w,
|
|
||||||
blockTexCoords.z, blockTexCoords.y,
|
|
||||||
blockTexCoords.x, blockTexCoords.y
|
|
||||||
};
|
|
||||||
|
|
||||||
// Store vertex information
|
|
||||||
for(u8 j = 0 ; j < 4 ; j++) {
|
|
||||||
Vertex vertex;
|
|
||||||
|
|
||||||
vertex.coord3d[0] = x + cubeCoords[i * 12 + j * 3];
|
|
||||||
vertex.coord3d[1] = y + cubeCoords[i * 12 + j * 3 + 1];
|
|
||||||
vertex.coord3d[2] = z + cubeCoords[i * 12 + j * 3 + 2];
|
|
||||||
vertex.coord3d[3] = static_cast<GLfloat>(block->id());
|
|
||||||
|
|
||||||
vertex.normal[0] = normal.x;
|
|
||||||
vertex.normal[1] = normal.y;
|
|
||||||
vertex.normal[2] = normal.z;
|
|
||||||
|
|
||||||
vertex.texCoord[0] = faceTexCoords[j * 2];
|
|
||||||
vertex.texCoord[1] = faceTexCoords[j * 2 + 1];
|
|
||||||
|
|
||||||
vertices.emplace_back(vertex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vertices.shrink_to_fit();
|
m_vertices.shrink_to_fit();
|
||||||
|
|
||||||
VertexBuffer::bind(&vbo);
|
VertexBuffer::bind(&vbo);
|
||||||
vbo.setData(vertices.size() * sizeof(Vertex), vertices.data(), GL_DYNAMIC_DRAW);
|
vbo.setData(m_vertices.size() * sizeof(Vertex), m_vertices.data(), GL_DYNAMIC_DRAW);
|
||||||
VertexBuffer::bind(nullptr);
|
VertexBuffer::bind(nullptr);
|
||||||
|
|
||||||
return vertices.size();
|
std::size_t verticesCount = m_vertices.size();
|
||||||
|
m_vertices.clear();
|
||||||
|
return verticesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChunkBuilder::addFace(u8 x, u8 y, u8 z, u8 i, const Block *block, const Block *surroundingBlock) {
|
||||||
|
// Skip hidden faces
|
||||||
|
if(surroundingBlock && surroundingBlock->id()
|
||||||
|
&& (surroundingBlock->isOpaque() || block->id() == surroundingBlock->id()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
static glm::vec3 a, b, c, v1, v2, normal;
|
||||||
|
|
||||||
|
// Three points of the face
|
||||||
|
a.x = cubeCoords[i * 12 + 0];
|
||||||
|
a.y = cubeCoords[i * 12 + 1];
|
||||||
|
a.z = cubeCoords[i * 12 + 2];
|
||||||
|
|
||||||
|
b.x = cubeCoords[i * 12 + 3];
|
||||||
|
b.y = cubeCoords[i * 12 + 4];
|
||||||
|
b.z = cubeCoords[i * 12 + 5];
|
||||||
|
|
||||||
|
c.x = cubeCoords[i * 12 + 6];
|
||||||
|
c.y = cubeCoords[i * 12 + 7];
|
||||||
|
c.z = cubeCoords[i * 12 + 8];
|
||||||
|
|
||||||
|
// Computing two vectors
|
||||||
|
v1 = b - a;
|
||||||
|
v2 = c - a;
|
||||||
|
|
||||||
|
// Computing face normal (already normalized because cubeCoords are normalized)
|
||||||
|
normal = glm::cross(v1, v2);
|
||||||
|
|
||||||
|
const glm::vec4 &blockTexCoords = block->getTexCoords(i);
|
||||||
|
float faceTexCoords[2 * 4] = {
|
||||||
|
blockTexCoords.x, blockTexCoords.w,
|
||||||
|
blockTexCoords.z, blockTexCoords.w,
|
||||||
|
blockTexCoords.z, blockTexCoords.y,
|
||||||
|
blockTexCoords.x, blockTexCoords.y
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store vertex information
|
||||||
|
for(u8 j = 0 ; j < 4 ; j++) {
|
||||||
|
Vertex vertex;
|
||||||
|
|
||||||
|
vertex.coord3d[0] = x + cubeCoords[i * 12 + j * 3];
|
||||||
|
vertex.coord3d[1] = y + cubeCoords[i * 12 + j * 3 + 1];
|
||||||
|
vertex.coord3d[2] = z + cubeCoords[i * 12 + j * 3 + 2];
|
||||||
|
vertex.coord3d[3] = static_cast<GLfloat>(block->id());
|
||||||
|
|
||||||
|
vertex.normal[0] = normal.x;
|
||||||
|
vertex.normal[1] = normal.y;
|
||||||
|
vertex.normal[2] = normal.z;
|
||||||
|
|
||||||
|
vertex.texCoord[0] = faceTexCoords[j * 2];
|
||||||
|
vertex.texCoord[1] = faceTexCoords[j * 2 + 1];
|
||||||
|
|
||||||
|
m_vertices.emplace_back(vertex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user