commit c63216862550a584b6dcb1b0969efed01383ed4f
parent 392c2c87c3bd3600b9275ea31ffc8c2faac6e288
Author: Christian Ermann <christianermann@gmail.com>
Date: Wed, 18 Aug 2021 17:34:47 -0500
Removed mesh double buffering
Diffstat:
5 files changed, 76 insertions(+), 74 deletions(-)
diff --git a/include/chunk.h b/include/chunk.h
@@ -3,6 +3,7 @@
#include "mesh.h"
#include "sdf.h"
+#include "threadpool.h"
#include <pthread.h>
@@ -20,16 +21,14 @@ typedef struct {
UpdateArgs *update_args;
pthread_mutex_t mesh_mutex;
- bool mesh_updated;
+ int mesh_update_count;
} Chunk;
void Chunk_init(Chunk *c);
void Chunk_free(Chunk *c);
void Chunk_updateOrigin(Chunk *c, IVec3 origin);
-
-void Chunk_setUpdateArgs(Chunk *c, SDF f, float isolevel);
-void Chunk_updateFunc(void *arg);
+void Chunk_updateMesh(Chunk *c, SDF f, float isolevel, ThreadPool *pool);
void Chunk_drawMesh(Chunk *c);
diff --git a/include/mesh.h b/include/mesh.h
@@ -14,18 +14,19 @@ typedef struct {
unsigned int index_count;
unsigned int *indices;
- unsigned int draw_index;
- unsigned int write_index;
- unsigned int vao[2];
- unsigned int vbo[2];
- unsigned int ebo[2];
+ unsigned int vao;
+ unsigned int vbo;
+ unsigned int ebo;
+
+ bool buffers_mapped;
} Mesh;
void Mesh_init(Mesh *m, unsigned int vertex_count, unsigned int index_count);
void Mesh_free(Mesh *m);
-void Mesh_swapBuffers(Mesh *m);
+void Mesh_mapBuffers(Mesh *m);
+void Mesh_unmapBuffers(Mesh *m);
void Mesh_draw(const Mesh *m);
diff --git a/src/chunk.c b/src/chunk.c
@@ -1,6 +1,7 @@
#include "chunk.h"
#include "marching_cubes.h"
+#include "threadpool.h"
#include <stdlib.h>
@@ -33,7 +34,7 @@ void Chunk_init(Chunk *c)
c->update_args = UpdateArgs_make(c);
pthread_mutex_init(&c->mesh_mutex, NULL);
- c->mesh_updated = false;
+ c->mesh_update_count = 0;
}
void Chunk_free(Chunk *c)
@@ -138,14 +139,7 @@ static void Chunk_updateMeshData(Chunk *c, SDF f, float isolevel)
}
}
-void Chunk_setUpdateArgs(Chunk *c, SDF f, float isolevel)
-{
- c->update_args->chunk = c;
- c->update_args->f = f;
- c->update_args->isolevel = isolevel;
-}
-
-void Chunk_updateFunc(void *arg)
+static void Chunk_updateMeshFunc(void *arg)
{
UpdateArgs *args = (UpdateArgs*)arg;
@@ -153,11 +147,30 @@ void Chunk_updateFunc(void *arg)
Chunk_updateMeshData(args->chunk, args->f, args->isolevel);
- args->chunk->mesh_updated = true;
+ args->chunk->mesh_update_count -= 1;
pthread_mutex_unlock(&args->chunk->mesh_mutex);
}
+void Chunk_updateMesh(Chunk *c, SDF f, float isolevel, ThreadPool *pool)
+{
+ c->update_args->chunk = c;
+ c->update_args->f = f;
+ c->update_args->isolevel = isolevel;
+
+ pthread_mutex_lock(&c->mesh_mutex);
+
+ if (c->mesh_update_count == 0 && !c->mesh.buffers_mapped)
+ {
+ Mesh_mapBuffers(&c->mesh);
+ }
+ c->mesh_update_count += 1;
+
+ pthread_mutex_unlock(&c->mesh_mutex);
+
+ ThreadPool_addWork(pool, Chunk_updateMeshFunc, c->update_args);
+}
+
void Chunk_updateOrigin(Chunk *c, IVec3 origin)
{
pthread_mutex_lock(&c->mesh_mutex);
@@ -171,10 +184,9 @@ void Chunk_drawMesh(Chunk *c)
{
if (pthread_mutex_trylock(&c->mesh_mutex) == 0)
{
- if (c->mesh_updated)
+ if (c->mesh_update_count == 0 && c->mesh.buffers_mapped)
{
- Mesh_swapBuffers(&c->mesh);
- c->mesh_updated = false;
+ Mesh_unmapBuffers(&c->mesh);
}
pthread_mutex_unlock(&c->mesh_mutex);
}
diff --git a/src/chunk_manager.c b/src/chunk_manager.c
@@ -48,9 +48,7 @@ static void ChunkManager_createChunks(ChunkManager *cm)
cm->origin[2] + cm->offsets[i][2]
};
Chunk_updateOrigin(&cm->chunks[i], chunk_origin);
- Chunk_setUpdateArgs(&cm->chunks[i], cm->f, cm->isolevel);
- ThreadPool_addWork(cm->pool, Chunk_updateFunc,
- cm->chunks[i].update_args);
+ Chunk_updateMesh(&cm->chunks[i], cm->f, cm->isolevel, cm->pool);
}
}
@@ -100,9 +98,8 @@ static void ChunkManager_updateChunkMeshes(ChunkManager *cm)
cm->origin[2] + cm->offsets[i][2]
};
Chunk_updateOrigin(&cm->chunks[j], chunk_origin);
- Chunk_setUpdateArgs(&cm->chunks[j], cm->f, cm->isolevel);
- ThreadPool_addWork(cm->pool, Chunk_updateFunc,
- cm->chunks[j].update_args);
+ Chunk_updateMesh(&cm->chunks[j], cm->f, cm->isolevel,
+ cm->pool);
cm->is_new_offset[i] = false;
cm->is_old_chunk[j] = false;
diff --git a/src/mesh.c b/src/mesh.c
@@ -12,35 +12,24 @@ void Mesh_init(Mesh *m, unsigned int vertex_count, unsigned int index_count)
m->index_capacity = index_count;
m->index_count = 0;
- m->draw_index = 0;
- m->write_index = 1;
+ glGenVertexArrays(1, &m->vao);
+ glBindVertexArray(m->vao);
- glGenVertexArrays(2, m->vao);
- glGenBuffers(2, m->vbo);
- glGenBuffers(2, m->ebo);
- for (int i = 0; i < 2; i++)
- {
- glBindVertexArray(m->vao[i]);
-
- glBindBuffer(GL_ARRAY_BUFFER, m->vbo[i]);
- glBufferData(GL_ARRAY_BUFFER, sizeof *m->vertices * vertex_count, NULL,
- GL_STATIC_DRAW);
-
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), 0);
- glEnableVertexAttribArray(0);
+ glGenBuffers(1, &m->vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, m->vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof *m->vertices * vertex_count, NULL,
+ GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo[i]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof *m->indices * index_count,
- NULL, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vec3), (GLvoid*)0);
+ glEnableVertexAttribArray(0);
- glBindVertexArray(0);
- }
- glBindBuffer(GL_ARRAY_BUFFER, m->vbo[m->write_index]);
- m->vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+ glGenBuffers(1, &m->ebo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof *m->indices * index_count,
+ NULL, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo[m->write_index]);
- m->indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+ glBindVertexArray(0);
}
void Mesh_free(Mesh *m)
@@ -50,40 +39,44 @@ void Mesh_free(Mesh *m)
m->index_capacity = 0;
m->index_count = 0;
-
- glBindBuffer(GL_ARRAY_BUFFER, m->vbo[m->write_index]);
- glUnmapBuffer(GL_ARRAY_BUFFER);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo[m->write_index]);
- glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+ Mesh_unmapBuffers(m);
- glDeleteVertexArrays(2, m->vao);
- glDeleteBuffers(2, m->vbo);
- glDeleteBuffers(2, m->ebo);
+ glDeleteVertexArrays(1, &m->vao);
+ glDeleteBuffers(1, &m->vbo);
+ glDeleteBuffers(1, &m->ebo);
}
-void Mesh_swapBuffers(Mesh *m)
+void Mesh_mapBuffers(Mesh *m)
{
- glBindBuffer(GL_ARRAY_BUFFER, m->vbo[m->draw_index]);
+ glBindBuffer(GL_ARRAY_BUFFER, m->vbo);
m->vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
- glBindBuffer(GL_ARRAY_BUFFER, m->vbo[m->write_index]);
- glUnmapBuffer(GL_ARRAY_BUFFER);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo[m->draw_index]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo);
m->indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo[m->write_index]);
+ m->buffers_mapped = true;
+}
+
+void Mesh_unmapBuffers(Mesh *m)
+{
+ glBindBuffer(GL_ARRAY_BUFFER, m->vbo);
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ m->vertices = NULL;
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ebo);
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+ m->indices = NULL;
- unsigned int temp = m->draw_index;
- m->draw_index = m->write_index;
- m->write_index = temp;
+ m->buffers_mapped = false;
}
void Mesh_draw(const Mesh *m)
{
- glBindVertexArray(m->vao[m->draw_index]);
- glDrawElements(GL_TRIANGLES, m->index_count, GL_UNSIGNED_INT, (GLvoid*)0);
- glBindVertexArray(0);
+ if (!m->buffers_mapped)
+ {
+ glBindVertexArray(m->vao);
+ glDrawElements(GL_TRIANGLES, m->index_count, GL_UNSIGNED_INT, 0);
+ glBindVertexArray(0);
+ }
}