Optimize ChunkMesh generation/rendering
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#version 100
|
||||
|
||||
attribute vec4 position;
|
||||
attribute vec2 position;
|
||||
attribute float height;
|
||||
attribute vec4 material;
|
||||
|
||||
varying vec2 f_uv;
|
||||
@@ -13,9 +14,10 @@ uniform vec3 chunk_position;
|
||||
|
||||
void main ()
|
||||
{
|
||||
f_uv = position.xz / 4.0;
|
||||
f_uv = position.xy / 4.0;
|
||||
f_material = material;
|
||||
f_height = position.y;
|
||||
|
||||
gl_Position = projection * view * (position + vec4(chunk_position, 0.0));
|
||||
f_height = height;
|
||||
|
||||
vec4 pos = vec4 (position.x, height, position.y, 1.0);
|
||||
gl_Position = projection * view * (pos + vec4(chunk_position, 0.0));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#include "chunkman.h"
|
||||
|
||||
/* TODO: Sort chunks by distance to player, and generate them like
|
||||
that. Will require having a queue or similar structure. */
|
||||
|
||||
extern int render_distance;
|
||||
|
||||
int n_frame_chunks;
|
||||
|
||||
+37
-20
@@ -8,17 +8,18 @@ ChunkMesh *
|
||||
ChunkMesh_build (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc)
|
||||
/* nd --- down neighbor; nr --- right neighbor; nc --- corner neighbor */
|
||||
{
|
||||
vec3 *positions = malloc (sizeof (vec3) * CHUNKMESH_SIZE);
|
||||
float *materials = malloc (sizeof (float) * 4 * CHUNKMESH_SIZE);
|
||||
ivec2 *positions = malloc (sizeof (ivec2) * CHUNKMESH_SIZE);
|
||||
float *heights = malloc (sizeof (float) * CHUNKMESH_SIZE);
|
||||
ivec4 *materials = malloc (sizeof (ivec4) * CHUNKMESH_SIZE);
|
||||
unsigned int *indices = malloc (sizeof (unsigned int) * CHUNK_SIZE * 6);
|
||||
|
||||
int m_i = 0, i_i = 0;
|
||||
int i_i = 0;
|
||||
for (int z = 0; z < CHUNKMESH_DIM; ++z)
|
||||
{
|
||||
for (int x = 0; x < CHUNKMESH_DIM; ++x)
|
||||
{
|
||||
float height = chunk->heightmap[INDEX (x, z)];
|
||||
float material_id = chunk->materialmap[INDEX (x, z)];
|
||||
char material_id = chunk->materialmap[INDEX (x, z)];
|
||||
|
||||
if (x == CHUNK_DIM && z < CHUNK_DIM && nr != NULL)
|
||||
{
|
||||
@@ -38,11 +39,14 @@ ChunkMesh_build (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc)
|
||||
material_id = nc->materialmap[INDEX (0, 0)];
|
||||
}
|
||||
|
||||
glm_vec3_copy ((vec3) { x, height, z }, positions[CMINDEX (x, z)]);
|
||||
materials[m_i++] = material_id == 1 ? 1 : 0;
|
||||
materials[m_i++] = material_id == 2 ? 1 : 0;
|
||||
materials[m_i++] = material_id == 3 ? 1 : 0;
|
||||
materials[m_i++] = material_id == 4 ? 1 : 0;
|
||||
positions[CMINDEX (x, z)][0] = x;
|
||||
heights[CMINDEX (x, z)] = height;
|
||||
positions[CMINDEX (x, z)][1] = z;
|
||||
|
||||
materials[CMINDEX (x, z)][0] = material_id == 1 ? 1 : 0;
|
||||
materials[CMINDEX (x, z)][1] = material_id == 2 ? 1 : 0;
|
||||
materials[CMINDEX (x, z)][2] = material_id == 3 ? 1 : 0;
|
||||
materials[CMINDEX (x, z)][3] = material_id == 4 ? 1 : 0;
|
||||
|
||||
if (x < CHUNK_DIM && z < CHUNK_DIM)
|
||||
{
|
||||
@@ -70,23 +74,30 @@ ChunkMesh_build (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc)
|
||||
|
||||
ChunkMesh *mesh = malloc (sizeof (ChunkMesh));
|
||||
glGenBuffers (1, &mesh->pbo);
|
||||
glGenBuffers (1, &mesh->hbo);
|
||||
glGenBuffers (1, &mesh->mbo);
|
||||
glGenBuffers (1, &mesh->ebo);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof (vec3) * CHUNKMESH_SIZE, positions, GL_STATIC_DRAW);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof (ivec2) * CHUNKMESH_SIZE, positions, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray (0);
|
||||
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (vec3), 0);
|
||||
glVertexAttribPointer (0, 2, GL_INT, GL_FALSE, sizeof (ivec2), 0);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof (float) * 4 * CHUNKMESH_SIZE, materials, GL_STATIC_DRAW);
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->hbo);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof (float) * CHUNKMESH_SIZE, heights, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray (1);
|
||||
glVertexAttribPointer (1, 4, GL_FLOAT, GL_FALSE, sizeof (float) * 4, 0);
|
||||
glVertexAttribPointer (1, 1, GL_FLOAT, GL_FALSE, sizeof (float), 0);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof (ivec4) * CHUNKMESH_SIZE, materials, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray (2);
|
||||
glVertexAttribPointer (2, 4, GL_INT, GL_FALSE, sizeof (ivec4), 0);
|
||||
|
||||
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
|
||||
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (unsigned int) * CHUNK_SIZE * 6, indices, GL_STATIC_DRAW);
|
||||
|
||||
free (positions);
|
||||
free (heights);
|
||||
free (materials);
|
||||
free (indices);
|
||||
|
||||
@@ -96,21 +107,27 @@ ChunkMesh_build (Chunk *chunk, Chunk *nr, Chunk *nd, Chunk *nc)
|
||||
void
|
||||
ChunkMesh_bind (ChunkMesh *mesh)
|
||||
/* The EBO is the same for all chunk meshes, so we can bind it just
|
||||
once before we render them all. */
|
||||
once before we render them all. Same for the PBO. The only thing
|
||||
that changes is the heights and materials. */
|
||||
{
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo);
|
||||
glEnableVertexAttribArray (0);
|
||||
glVertexAttribPointer (0, 2, GL_INT, GL_FALSE, sizeof (ivec2), 0);
|
||||
|
||||
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
|
||||
}
|
||||
|
||||
void
|
||||
ChunkMesh_render (ChunkMesh *mesh, bool wireframe)
|
||||
{
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo);
|
||||
glEnableVertexAttribArray (0);
|
||||
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (vec3), 0);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo);
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->hbo);
|
||||
glEnableVertexAttribArray (1);
|
||||
glVertexAttribPointer (1, 4, GL_FLOAT, GL_FALSE, sizeof (float) * 4, 0);
|
||||
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float), 0);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, mesh->mbo);
|
||||
glEnableVertexAttribArray (2);
|
||||
glVertexAttribPointer (2, 4, GL_INT, GL_FALSE, sizeof (ivec4), 0);
|
||||
|
||||
glDrawElements (wireframe ? GL_LINES : GL_TRIANGLES, CHUNK_SIZE * 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
typedef struct ChunkMesh
|
||||
{
|
||||
unsigned int pbo;
|
||||
unsigned int hbo;
|
||||
unsigned int mbo;
|
||||
unsigned int ebo;
|
||||
} ChunkMesh;
|
||||
|
||||
Reference in New Issue
Block a user