diff --git a/game/res/shaders/chunk.vert b/game/res/shaders/chunk.vert index 869b992..b981b14 100644 --- a/game/res/shaders/chunk.vert +++ b/game/res/shaders/chunk.vert @@ -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)); } diff --git a/game/src/chunk/chunkman.c b/game/src/chunk/chunkman.c index 6d24e4e..d1508b5 100644 --- a/game/src/chunk/chunkman.c +++ b/game/src/chunk/chunkman.c @@ -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; diff --git a/game/src/chunk/chunkmesh.c b/game/src/chunk/chunkmesh.c index ebca092..0ed1920 100644 --- a/game/src/chunk/chunkmesh.c +++ b/game/src/chunk/chunkmesh.c @@ -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); } diff --git a/game/src/chunk/chunkmesh.h b/game/src/chunk/chunkmesh.h index 3e5e4a7..525f3fe 100644 --- a/game/src/chunk/chunkmesh.h +++ b/game/src/chunk/chunkmesh.h @@ -13,6 +13,7 @@ typedef struct ChunkMesh { unsigned int pbo; + unsigned int hbo; unsigned int mbo; unsigned int ebo; } ChunkMesh;