--- a/src/mesh.c Sat May 10 15:42:56 2025 +0200 +++ b/src/mesh.c Sat May 10 18:51:45 2025 +0200 @@ -44,6 +44,7 @@ } void asc_mesh_free_buffers(AscMesh *mesh, unsigned count) { + if (count == 1 && mesh->vbo == 0) return; // hack to skip this function until we remove it asc_dprintf("Free mesh buffers for %u meshes.", count); GLuint buffers[count]; GLuint arrays[count]; @@ -60,11 +61,52 @@ asc_error_catch_all_gl(); } -void asc_mesh_draw_triangle_strip(AscMesh *mesh) { +void asc_mesh_draw_triangle_strip(const AscMesh *mesh) { glBindVertexArray(mesh->vao); - glDrawArrays(GL_TRIANGLE_STRIP, 0, mesh->vertices); + glDrawArrays(GL_TRIANGLE_STRIP, 0, mesh->vtx_count); #ifndef NDEBUG // only unbind in debug mode to detect accidental re-use of the wrong VAO glBindVertexArray(0); #endif } + +void asc_mesh_destroy(AscMesh *mesh) { + asc_mesh_free_buffers(mesh, 1); + free(mesh->vtx_data); +} + +void asc_mesh_plane_2d(AscMesh *mesh) { + if (mesh->vbo == 0) { + asc_mesh_allocate_buffers(mesh, 1); + } + free(mesh->vtx_data); + asc_dprintf("Create plane in VBO %u and VAO %u", mesh->vbo, mesh->vao); + mesh->vtx_count = 4; + AscMeshVertex2d data[4] = { + { + .pos = {{0.0f, 0.0f}}, + .uv = {{0.0f, 0.0f}}, + } , // bottom left + { + .pos = {{0.0f, 1.0f}}, + .uv = {{0.0f, 1.0f}}, + }, // top left + { + .pos = {{1.0f, 0.0f}}, + .uv = {{1.0f, 0.0f}}, + }, // bottom right + { + .pos = {{1.0f, 1.0f}}, + .uv = {{1.0f, 1.0f}}, + } // top right + }; + mesh->vtx_data = malloc(sizeof(data)); + memcpy(mesh->vtx_data, data, sizeof(data)); + glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(data), mesh->vtx_data, GL_STATIC_DRAW); + glBindVertexArray(mesh->vao); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(AscMeshVertex2d), (void*)offsetof(AscMeshVertex2d, pos)); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(AscMeshVertex2d), (void*)offsetof(AscMeshVertex2d, uv)); + glEnableVertexAttribArray(1); +}