Use indexing to drastically reduce the number of vertices
parent
c955c07ab4
commit
c111d5c1b7
|
@ -43,7 +43,7 @@ CMAKE_AR:FILEPATH=emar
|
||||||
|
|
||||||
//Choose the type of build, options are: None Debug Release RelWithDebInfo
|
//Choose the type of build, options are: None Debug Release RelWithDebInfo
|
||||||
// MinSizeRel ...
|
// MinSizeRel ...
|
||||||
CMAKE_BUILD_TYPE:STRING=Debug
|
CMAKE_BUILD_TYPE:STRING=Release
|
||||||
|
|
||||||
//Enable/Disable color output during build.
|
//Enable/Disable color output during build.
|
||||||
CMAKE_COLOR_MAKEFILE:BOOL=ON
|
CMAKE_COLOR_MAKEFILE:BOOL=ON
|
||||||
|
|
|
@ -6,5 +6,5 @@ CXX_DEFINES =
|
||||||
|
|
||||||
CXX_INCLUDES = @CMakeFiles/FinalProject.dir/includes_CXX.rsp
|
CXX_INCLUDES = @CMakeFiles/FinalProject.dir/includes_CXX.rsp
|
||||||
|
|
||||||
CXX_FLAGS = -g -std=c++17 -std=gnu++17
|
CXX_FLAGS = -O3 -DNDEBUG -std=c++17 -std=gnu++17
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
/usr/bin/em++ -g -sMAX_WEBGL_VERSION=2 -s ASSERTIONS=1 -sUSE_GLFW=3 --preload-file 'assets' @CMakeFiles/FinalProject.dir/objects1 -o FinalProject.js @CMakeFiles/FinalProject.dir/linkLibs.rsp
|
/usr/bin/em++ -O3 -DNDEBUG -sMAX_WEBGL_VERSION=2 -s ASSERTIONS=1 -sUSE_GLFW=3 --preload-file 'assets' @CMakeFiles/FinalProject.dir/objects1 -o FinalProject.js @CMakeFiles/FinalProject.dir/linkLibs.rsp
|
||||||
|
|
|
@ -327,4 +327,5 @@ CMakeFiles/FinalProject.dir/src/main.cpp.o: \
|
||||||
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/render/camera.h \
|
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/render/camera.h \
|
||||||
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/world/chunk/world.h \
|
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/world/chunk/world.h \
|
||||||
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/world/chunk/storage.h \
|
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/world/chunk/storage.h \
|
||||||
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/world/chunk/typedefs.h
|
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/world/chunk/typedefs.h \
|
||||||
|
/home/brett/Documents/Brock/CS\ 3P98/Final\ Project/include/world/registry.h
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -12,7 +12,7 @@ if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||||
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
set(CMAKE_INSTALL_CONFIG_NAME "Release")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -6,5 +6,5 @@ CXX_DEFINES =
|
||||||
|
|
||||||
CXX_INCLUDES = @CMakeFiles/BLT.dir/includes_CXX.rsp
|
CXX_INCLUDES = @CMakeFiles/BLT.dir/includes_CXX.rsp
|
||||||
|
|
||||||
CXX_FLAGS = -g -std=c++17 -std=gnu++17
|
CXX_FLAGS = -O3 -DNDEBUG -std=c++17 -std=gnu++17
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -12,7 +12,7 @@ if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||||
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
set(CMAKE_INSTALL_CONFIG_NAME "Release")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||||
endif()
|
endif()
|
||||||
|
|
Binary file not shown.
|
@ -12,6 +12,7 @@
|
||||||
#include "blt/std/logging.h"
|
#include "blt/std/logging.h"
|
||||||
#include <world/chunk/typedefs.h>
|
#include <world/chunk/typedefs.h>
|
||||||
#include <world/registry.h>
|
#include <world/registry.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
// contains storage classes for block IDs inside chunks plus eventual lookup of block states
|
// contains storage classes for block IDs inside chunks plus eventual lookup of block states
|
||||||
|
|
||||||
|
@ -51,26 +52,24 @@ namespace fp {
|
||||||
|
|
||||||
class mesh_storage {
|
class mesh_storage {
|
||||||
private:
|
private:
|
||||||
std::vector<float> vertices;
|
std::unordered_map<vertex, unsigned int, _static::vertex_hash, _static::vertex_equality> created_vertices_index;
|
||||||
inline void add_and_translate(const float* array, const block_pos& pos) {
|
std::vector<vertex> vertices;
|
||||||
// since a chunk mesh contains all the faces for all the blocks inside the chunk
|
std::vector<unsigned int> indices;
|
||||||
// we can add the translated values of predefined "unit" faces. This is for the simple "fast" chunk mesh generator.
|
|
||||||
for (int i = 0; i < VTX_ARR_SIZE; i+=3){
|
|
||||||
auto new_x = array[i] + (float)pos.x;
|
|
||||||
auto new_y = array[i + 1] + (float)pos.y;
|
|
||||||
auto new_z = array[i + 2] + (float)pos.z;
|
|
||||||
// BLT_TRACE("Creating translated vertex {%f, %f, %f} from array position [%d, %d, %d]", new_x, new_y, new_z, i, i + 1, i + 2);
|
|
||||||
vertices.push_back(new_x);
|
|
||||||
vertices.push_back(new_y);
|
|
||||||
vertices.push_back(new_z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* since a chunk mesh contains all the faces for all the blocks inside the chunk
|
||||||
|
* we can add the translated values of predefined "unit" faces. This is for the simple "fast" chunk mesh generator.
|
||||||
|
* @param face the direction the face is facing to be added to the mesh.
|
||||||
|
* @param pos position of the face
|
||||||
|
*/
|
||||||
void addFace(face face, const block_pos& pos);
|
void addFace(face face, const block_pos& pos);
|
||||||
|
|
||||||
inline std::vector<float>& getVertices() {
|
inline std::vector<vertex>& getVertices() {
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
inline std::vector<unsigned int>& getIndices() {
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace mesh {
|
namespace mesh {
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
constexpr int CHUNK_SIZE = 32;
|
constexpr int CHUNK_SIZE = 32;
|
||||||
const int CHUNK_SHIFT = (int)(log(CHUNK_SIZE) / log(2));
|
const int CHUNK_SHIFT = (int)(log(CHUNK_SIZE) / log(2));
|
||||||
// size that the base vertex arrays are assumed to be (per face)
|
// size that the base vertex arrays are assumed to be (per face)
|
||||||
constexpr int VTX_ARR_SIZE = 18;
|
constexpr int VTX_ARR_SIZE = 4;
|
||||||
|
|
||||||
|
constexpr float EPSILON = 0.0001f;
|
||||||
|
|
||||||
namespace fp {
|
namespace fp {
|
||||||
|
|
||||||
|
@ -52,6 +54,13 @@ namespace fp {
|
||||||
block_pos(float x, float y, float z): block_pos(int(x), int(y), int(z)) {}
|
block_pos(float x, float y, float z): block_pos(int(x), int(y), int(z)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// to ensure this is a POD we define the vertex as a C-struct. This allows us to store one large vertex array and pass that to the GPU
|
||||||
|
// instead of sending arrays for the positions, UVs, normals, etc.
|
||||||
|
// since OpenGL allows us to specify attributes based on offsets from the same VBO.
|
||||||
|
typedef struct {
|
||||||
|
float x, y, z;
|
||||||
|
} vertex;
|
||||||
|
|
||||||
namespace _static {
|
namespace _static {
|
||||||
|
|
||||||
// std::unordered_map requires a type. As a result the functions are encapsulated.
|
// std::unordered_map requires a type. As a result the functions are encapsulated.
|
||||||
|
@ -64,12 +73,30 @@ namespace fp {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vertex_hash {
|
||||||
|
inline size_t operator()(const vertex& pos) const {
|
||||||
|
size_t p1 = std::hash<float>()(pos.x);
|
||||||
|
size_t p2 = std::hash<float>()(pos.y);
|
||||||
|
size_t p3 = std::hash<float>()(pos.z);
|
||||||
|
return (p1 ^ (p2 << 1)) ^ p3;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct chunk_pos_equality {
|
struct chunk_pos_equality {
|
||||||
inline bool operator()(const chunk_pos& p1, const chunk_pos& p2) const {
|
inline bool operator()(const chunk_pos& p1, const chunk_pos& p2) const {
|
||||||
return p1.x == p2.x && p1.y == p2.y && p1.z == p2.z;
|
return p1.x == p2.x && p1.y == p2.y && p1.z == p2.z;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vertex_equality {
|
||||||
|
inline bool operator()(const vertex& p1, const vertex& p2) const {
|
||||||
|
return p1.x >= p2.x - EPSILON && p1.x <= p2.x + EPSILON && p1.y >= p2.y - EPSILON && p1.y <= p2.y + EPSILON && p1.z >= p2.z - EPSILON && p1.z <= p2.z + EPSILON;
|
||||||
|
}
|
||||||
|
// inline bool operator()(const vertex& p1, const vertex& p2) const {
|
||||||
|
// return p1.x == p2.x && p1.y == p2.y && p1.z == p2.z;
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif //FINALPROJECT_CHUNK_TYPEDEFS_H
|
#endif //FINALPROJECT_CHUNK_TYPEDEFS_H
|
||||||
|
|
|
@ -85,7 +85,8 @@ namespace fp {
|
||||||
|
|
||||||
// since they both use the same amount of memory we will only store the vertices and draw with drawArrays, since it is less complex.
|
// since they both use the same amount of memory we will only store the vertices and draw with drawArrays, since it is less complex.
|
||||||
// set up the VBOs which will be later updated when the mesh is generated.
|
// set up the VBOs which will be later updated when the mesh is generated.
|
||||||
chunk_vao->bindVBO(new VBO(ARRAY_BUFFER, nullptr, 0), 0, 3);
|
chunk_vao->bindVBO(new VBO(ARRAY_BUFFER, nullptr, 0), 0, 3, GL_FLOAT, 3 * sizeof(float), 0);
|
||||||
|
chunk_vao->bindElementVBO(new VBO(ELEMENT_BUFFER, nullptr, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
~chunk() {
|
~chunk() {
|
||||||
|
|
|
@ -45,8 +45,10 @@ int main() {
|
||||||
chunk_shader = new fp::shader(shader_chunk_vert, shader_chunk_frag);
|
chunk_shader = new fp::shader(shader_chunk_vert, shader_chunk_frag);
|
||||||
world = new fp::world();
|
world = new fp::world();
|
||||||
|
|
||||||
|
world->setBlock({0,0,0}, 1);
|
||||||
|
|
||||||
for (int i = 1; i < CHUNK_SIZE; i++)
|
for (int i = 1; i < CHUNK_SIZE; i++)
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 2; j++)
|
||||||
for (int k = 5; k < CHUNK_SIZE; k++)
|
for (int k = 5; k < CHUNK_SIZE; k++)
|
||||||
world->setBlock({i,j,k}, 1);
|
world->setBlock({i,j,k}, 1);
|
||||||
world->setBlock({-2, 2, 2}, 1);
|
world->setBlock({-2, 2, 2}, 1);
|
||||||
|
|
|
@ -8,69 +8,55 @@
|
||||||
|
|
||||||
constexpr float scale = 0.5f;
|
constexpr float scale = 0.5f;
|
||||||
|
|
||||||
const float x_positive_vertices[VTX_ARR_SIZE] = {
|
const fp::vertex x_positive_vertices[VTX_ARR_SIZE] = {
|
||||||
// +x first triangle
|
{scale, scale, scale}, // +x top right
|
||||||
scale, -scale, scale, // +x top left
|
{scale, scale, -scale}, // +x bottom right
|
||||||
scale, scale, -scale, // +x bottom right
|
{scale, -scale, -scale}, // +x bottom left
|
||||||
scale, scale, scale, // +x top right
|
{scale, -scale, scale} // +x top left
|
||||||
// +x second triangle
|
|
||||||
scale, -scale, scale, // +x top left
|
|
||||||
scale, -scale, -scale, // +x bottom left
|
|
||||||
scale, scale, -scale, // +x bottom right
|
|
||||||
};
|
};
|
||||||
const float x_negative_vertices[VTX_ARR_SIZE] = {
|
const fp::vertex x_negative_vertices[VTX_ARR_SIZE] = {
|
||||||
// -x first triangle
|
{-scale, scale, scale}, // -x top right
|
||||||
-scale, scale, scale, // -x top right
|
{-scale, scale, -scale}, // -x bottom right
|
||||||
-scale, scale, -scale, // -x bottom right
|
{-scale, -scale, -scale}, // -x bottom left
|
||||||
-scale, -scale, scale, // -x top left
|
{-scale, -scale, scale} // -x top left
|
||||||
// -x second triangle
|
|
||||||
-scale, scale, -scale, // -x bottom right
|
|
||||||
-scale, -scale, -scale, // -x bottom left
|
|
||||||
-scale, -scale, scale, // -x top left
|
|
||||||
};
|
};
|
||||||
const float y_positive_vertices[VTX_ARR_SIZE] = {
|
const fp::vertex y_positive_vertices[VTX_ARR_SIZE] = {
|
||||||
// first triangle
|
{scale, scale, scale}, // +y top right
|
||||||
scale, scale, -scale, // top left
|
{-scale, scale, scale}, // +y bottom right
|
||||||
-scale, scale, scale, // bottom right
|
{-scale, scale, -scale}, // +y bottom left
|
||||||
scale, scale, scale, // top right
|
{scale, scale, -scale}, // +y top left
|
||||||
// second triangle
|
|
||||||
scale, scale, -scale, // top left
|
|
||||||
-scale, scale, -scale, // bottom left
|
|
||||||
-scale, scale, scale, // bottom right
|
|
||||||
};
|
};
|
||||||
const float y_negative_vertices[VTX_ARR_SIZE] = {
|
const fp::vertex y_negative_vertices[VTX_ARR_SIZE] = {
|
||||||
// first triangle
|
{scale, -scale, scale}, // -y top right
|
||||||
scale, -scale, scale, // top right
|
{-scale, -scale, scale}, // -y bottom right
|
||||||
-scale, -scale, scale, // bottom right
|
{-scale, -scale, -scale}, // -y bottom left
|
||||||
scale, -scale, -scale, // top left
|
{scale, -scale, -scale}, // -y top left
|
||||||
// second triangle
|
|
||||||
-scale, -scale, scale, // bottom right
|
|
||||||
-scale, -scale, -scale, // bottom left
|
|
||||||
scale, -scale, -scale, // top left
|
|
||||||
};
|
};
|
||||||
const float z_positive_vertices[VTX_ARR_SIZE] = {
|
const fp::vertex z_positive_vertices[VTX_ARR_SIZE] = {
|
||||||
// first triangle
|
{scale, scale, scale}, // +z top right
|
||||||
-scale, scale, scale, // top left
|
{scale, -scale, scale}, // +z bottom right
|
||||||
scale, -scale, scale, // bottom right
|
{-scale, -scale, scale}, // +z bottom left
|
||||||
scale, scale, scale, // top right
|
{-scale, scale, scale}, // +z top left
|
||||||
// second triangle
|
|
||||||
-scale, scale, scale, // top left
|
|
||||||
-scale, -scale, scale, // bottom left
|
|
||||||
scale, -scale, scale, // bottom right
|
|
||||||
};
|
};
|
||||||
const float z_negative_vertices[VTX_ARR_SIZE] = {
|
const fp::vertex z_negative_vertices[VTX_ARR_SIZE] = {
|
||||||
// first triangle
|
{scale, scale, -scale}, // -z top right
|
||||||
scale, scale, -scale, // top right
|
{scale, -scale, -scale}, // -z bottom right
|
||||||
scale, -scale, -scale, // bottom right
|
{-scale, -scale, -scale}, // -z bottom left
|
||||||
-scale, scale, -scale, // top left
|
{-scale, scale, -scale}, // -z top left
|
||||||
// second triangle
|
};
|
||||||
scale, -scale, -scale, // bottom right
|
|
||||||
-scale, -scale, -scale, // bottom left
|
// indices are the same on all axis but are flipped between negative / positive as a result of back-face culling.
|
||||||
-scale, scale, -scale, // top left
|
const std::vector<unsigned int> negative_indices = {
|
||||||
|
0, 1, 3,
|
||||||
|
1, 2, 3
|
||||||
|
};
|
||||||
|
const std::vector<unsigned int> positive_indices = {
|
||||||
|
3, 1, 0,
|
||||||
|
3, 2, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// always ordered the same as the enum!
|
// always ordered the same as the enum!
|
||||||
const float* face_decode[] = {
|
const fp::vertex* face_decode[] = {
|
||||||
x_positive_vertices,
|
x_positive_vertices,
|
||||||
x_negative_vertices,
|
x_negative_vertices,
|
||||||
y_positive_vertices,
|
y_positive_vertices,
|
||||||
|
@ -80,5 +66,35 @@ const float* face_decode[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void fp::mesh_storage::addFace(fp::face face, const block_pos& pos) {
|
void fp::mesh_storage::addFace(fp::face face, const block_pos& pos) {
|
||||||
add_and_translate(face_decode[face], pos);
|
const auto* face_vertices = face_decode[face];
|
||||||
|
// negatives are odd numbered, positives are even.
|
||||||
|
const auto& face_indices = face % 2 == 0 ? positive_indices : negative_indices;
|
||||||
|
|
||||||
|
vertex translated_face_vertices[VTX_ARR_SIZE];
|
||||||
|
|
||||||
|
// generate translated vertices
|
||||||
|
for (int i = 0; i < VTX_ARR_SIZE; i++) {
|
||||||
|
translated_face_vertices[i].x = face_vertices[i].x + (float) pos.x;
|
||||||
|
translated_face_vertices[i].y = face_vertices[i].y + (float) pos.y;
|
||||||
|
translated_face_vertices[i].z = face_vertices[i].z + (float) pos.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int face_index : face_indices) {
|
||||||
|
// vertex associated with the index
|
||||||
|
auto index_vertex = translated_face_vertices[face_index];
|
||||||
|
// search to see if the vertex exists already inside the vertices face_vertices
|
||||||
|
auto find_existing_vertex = created_vertices_index.find(index_vertex);
|
||||||
|
if (find_existing_vertex == created_vertices_index.end()) {
|
||||||
|
// vertex doesn't already exist in the face_vertices.
|
||||||
|
// the current size contains the position we are inserting the vertex into. This is our index in the vertex face_vertices
|
||||||
|
auto current_index_pos = vertices.size();
|
||||||
|
vertices.push_back(index_vertex);
|
||||||
|
// Since we are inserting using the order of the face_indices this will ensure that the triangle vertices are ordered correctly (outward facing)
|
||||||
|
created_vertices_index.insert({index_vertex, current_index_pos});
|
||||||
|
indices.push_back(current_index_pos);
|
||||||
|
} else {
|
||||||
|
// does exist in the face_vertices we can use that knowledge to reduce the total # of vertices
|
||||||
|
indices.push_back(find_existing_vertex->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ void fp::world::generateFullMesh(mesh_storage* mesh, fp::chunk* chunk) {
|
||||||
// checks to outside the bounds of the chunk should not have faces added. this will be handled by the partial mesh!
|
// checks to outside the bounds of the chunk should not have faces added. this will be handled by the partial mesh!
|
||||||
bool outside = false;
|
bool outside = false;
|
||||||
|
|
||||||
for (int i = 1; i < CHUNK_SIZE - 1; i++) {
|
for (int i = 0; i < CHUNK_SIZE; i++) {
|
||||||
for (int j = 1; j < CHUNK_SIZE - 1; j++) {
|
for (int j = 0; j < CHUNK_SIZE; j++) {
|
||||||
for (int k = 1; k < CHUNK_SIZE - 1; k++) {
|
for (int k = 0; k < CHUNK_SIZE; k++) {
|
||||||
auto block = chunk->storage->get({i, j, k});
|
auto block = chunk->storage->get({i, j, k});
|
||||||
// opaque visibility is always 0. Non-zero values (true) are what we care about since opaque blocks are completely hidden
|
// opaque visibility is always 0. Non-zero values (true) are what we care about since opaque blocks are completely hidden
|
||||||
if (!fp::registry::get(block).visibility) {
|
if (!fp::registry::get(block).visibility) {
|
||||||
|
@ -46,7 +46,6 @@ inline void checkEdgeFaces(
|
||||||
}
|
}
|
||||||
|
|
||||||
void fp::world::generateEdgeMesh(mesh_storage* mesh, fp::chunk* chunk) {
|
void fp::world::generateEdgeMesh(mesh_storage* mesh, fp::chunk* chunk) {
|
||||||
BLT_TRACE("NOPE");
|
|
||||||
// don't try to regen the chunk mesh unless there is a chance all neighbours are not null
|
// don't try to regen the chunk mesh unless there is a chance all neighbours are not null
|
||||||
if (chunk->status != chunk_update_status::NEIGHBOUR_CREATE)
|
if (chunk->status != chunk_update_status::NEIGHBOUR_CREATE)
|
||||||
return;
|
return;
|
||||||
|
@ -54,7 +53,6 @@ void fp::world::generateEdgeMesh(mesh_storage* mesh, fp::chunk* chunk) {
|
||||||
chunk_neighbours neighbours{};
|
chunk_neighbours neighbours{};
|
||||||
getNeighbours(chunk->pos, neighbours);
|
getNeighbours(chunk->pos, neighbours);
|
||||||
|
|
||||||
BLT_TRACE("GOODBYE");
|
|
||||||
|
|
||||||
// if none of the neighbours exist we cannot continue!
|
// if none of the neighbours exist we cannot continue!
|
||||||
for (auto* neighbour : neighbours.neighbours) {
|
for (auto* neighbour : neighbours.neighbours) {
|
||||||
|
@ -75,8 +73,6 @@ void fp::world::generateEdgeMesh(mesh_storage* mesh, fp::chunk* chunk) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BLT_TRACE("HELLO");
|
|
||||||
|
|
||||||
chunk->status = NONE;
|
chunk->status = NONE;
|
||||||
chunk->dirtiness = REFRESH;
|
chunk->dirtiness = REFRESH;
|
||||||
}
|
}
|
||||||
|
@ -91,8 +87,6 @@ void fp::world::generateChunkMesh(fp::chunk* chunk) {
|
||||||
if (chunk->dirtiness == PARTIAL_MESH) { // partial chunk mesh (had null neighbours)
|
if (chunk->dirtiness == PARTIAL_MESH) { // partial chunk mesh (had null neighbours)
|
||||||
generateEdgeMesh(chunk->mesh, chunk);
|
generateEdgeMesh(chunk->mesh, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
chunk->dirtiness = REFRESH;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fp::world::update() {
|
void fp::world::update() {
|
||||||
|
@ -114,14 +108,18 @@ void fp::world::render(fp::shader& shader) {
|
||||||
|
|
||||||
if (chunk->dirtiness == REFRESH) {
|
if (chunk->dirtiness == REFRESH) {
|
||||||
auto& vertices = chunk->mesh->getVertices();
|
auto& vertices = chunk->mesh->getVertices();
|
||||||
|
auto& indices = chunk->mesh->getIndices();
|
||||||
|
|
||||||
|
// 11436 vert, 137,232 bytes
|
||||||
|
|
||||||
BLT_INFO("Chunk [%d, %d, %d] mesh updated with %d vertices and %d indices taking (%d, %d) bytes!",
|
BLT_INFO("Chunk [%d, %d, %d] mesh updated with %d vertices and %d indices taking (%d, %d) bytes!",
|
||||||
chunk->pos.x, chunk->pos.y, chunk->pos.z,
|
chunk->pos.x, chunk->pos.y, chunk->pos.z,
|
||||||
vertices.size(), 0, vertices.size() * sizeof(float), 0 * sizeof(unsigned int));
|
vertices.size(), indices.size(), vertices.size() * sizeof(vertex), indices.size() * sizeof(unsigned int));
|
||||||
|
|
||||||
// upload the new vertices to the GPU
|
// upload the new vertices to the GPU
|
||||||
chunk->chunk_vao->getVBO(0)->update(vertices);
|
chunk->chunk_vao->getVBO(0)->update(vertices);
|
||||||
chunk->render_size = vertices.size() / 3;
|
chunk->chunk_vao->getVBO(-1)->update(indices);
|
||||||
|
chunk->render_size = indices.size();
|
||||||
|
|
||||||
// delete the memory from the CPU.
|
// delete the memory from the CPU.
|
||||||
delete (chunk->mesh);
|
delete (chunk->mesh);
|
||||||
|
@ -135,7 +133,8 @@ void fp::world::render(fp::shader& shader) {
|
||||||
shader.setMatrix("translation", translation);
|
shader.setMatrix("translation", translation);
|
||||||
chunk->chunk_vao->bind();
|
chunk->chunk_vao->bind();
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, (int) chunk->render_size);
|
//glDrawArrays(GL_TRIANGLES, 0, (int) chunk->render_size);
|
||||||
|
glDrawElements(GL_TRIANGLES, (int)chunk->render_size, GL_UNSIGNED_INT, nullptr);
|
||||||
glDisableVertexAttribArray(0);
|
glDisableVertexAttribArray(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue