diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index eb70f337..4bfbc176 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -468,8 +468,8 @@ static void lovrGraphicsDrawPrimitive(GLenum mode, int hasNormals, int hasTexCoo unsigned int* indices = state.buffer.indices.data; lovrGraphicsPrepare(); - glBindVertexArray(state.buffer.vao); - glBindBuffer(GL_ARRAY_BUFFER, state.buffer.vbo); + lovrGraphicsBindVertexArray(state.buffer.vao); + lovrGraphicsBindVertexBuffer(state.buffer.vbo); glBufferData(GL_ARRAY_BUFFER, state.buffer.data.length * sizeof(float), data, GL_STREAM_DRAW); glEnableVertexAttribArray(LOVR_SHADER_POSITION); glVertexAttribPointer(LOVR_SHADER_POSITION, 3, GL_FLOAT, GL_FALSE, strideBytes, (void*) 0); @@ -490,14 +490,12 @@ static void lovrGraphicsDrawPrimitive(GLenum mode, int hasNormals, int hasTexCoo } if (useIndices) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state.buffer.ibo); + lovrGraphicsBindIndexBuffer(state.buffer.ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, state.buffer.indices.length * sizeof(unsigned int), indices, GL_STREAM_DRAW); glDrawElements(mode, state.buffer.indices.length, GL_UNSIGNED_INT, NULL); } else { glDrawArrays(mode, 0, state.buffer.data.length / stride); } - - glBindVertexArray(0); } void lovrGraphicsPoints(float* points, int count) { @@ -983,3 +981,25 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl lovrRelease(&lastShader->ref); } } + +// Internal State +void lovrGraphicsBindVertexArray(uint32_t vertexArray) { + if (state.vertexArray != vertexArray) { + state.vertexArray = vertexArray; + glBindVertexArray(vertexArray); + } +} + +void lovrGraphicsBindVertexBuffer(uint32_t vertexBuffer) { + if (state.vertexBuffer != vertexBuffer) { + state.vertexBuffer = vertexBuffer; + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + } +} + +void lovrGraphicsBindIndexBuffer(uint32_t indexBuffer) { + if (state.indexBuffer != indexBuffer) { + state.indexBuffer = indexBuffer; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); + } +} diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index ebdf86c1..40ba9198 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -77,14 +77,6 @@ typedef struct { int transform; int canvas; - struct { - GLuint vao; - GLuint vbo; - GLuint ibo; - vec_float_t data; - vec_uint_t indices; - } buffer; - Color backgroundColor; BlendMode blendMode; BlendAlphaMode blendAlphaMode; @@ -99,6 +91,18 @@ typedef struct { Shader* shader; Winding winding; int wireframe; + + struct { + GLuint vao; + GLuint vbo; + GLuint ibo; + vec_float_t data; + vec_uint_t indices; + } buffer; + + uint32_t vertexArray; + uint32_t vertexBuffer; + uint32_t indexBuffer; } GraphicsState; // Base @@ -166,3 +170,8 @@ void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, floa void lovrGraphicsSphere(Texture* texture, mat4 transform, int segments); void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float az); void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAlign halign, VerticalAlign valign); + +// Internal State +void lovrGraphicsBindVertexArray(uint32_t vao); +void lovrGraphicsBindVertexBuffer(uint32_t vbo); +void lovrGraphicsBindIndexBuffer(uint32_t ibo); diff --git a/src/graphics/mesh.c b/src/graphics/mesh.c index c7ca92a0..4bcf641b 100644 --- a/src/graphics/mesh.c +++ b/src/graphics/mesh.c @@ -9,7 +9,7 @@ static void lovrMeshBindAttributes(Mesh* mesh) { return; } - glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); + lovrGraphicsBindVertexBuffer(mesh->vbo); size_t offset = 0; int i; @@ -87,7 +87,7 @@ Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, Me glGenBuffers(1, &mesh->vbo); glGenBuffers(1, &mesh->ibo); - glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); + lovrGraphicsBindVertexBuffer(mesh->vbo); glBufferData(GL_ARRAY_BUFFER, mesh->count * mesh->stride, NULL, mesh->usage); glGenVertexArrays(1, &mesh->vao); @@ -123,12 +123,12 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform) { lovrGraphicsMatrixTransform(transform); lovrGraphicsBindTexture(mesh->texture); lovrGraphicsPrepare(); - glBindVertexArray(mesh->vao); + lovrGraphicsBindVertexArray(mesh->vao); lovrMeshBindAttributes(mesh); size_t start = mesh->rangeStart; size_t count = mesh->rangeCount; if (mesh->map.length > 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ibo); + lovrGraphicsBindIndexBuffer(mesh->ibo); glDrawElements(mesh->drawMode, mesh->map.length, GL_UNSIGNED_INT, (GLvoid*) start); } else { glDrawArrays(mesh->drawMode, start, count); @@ -168,7 +168,7 @@ void lovrMeshSetVertexMap(Mesh* mesh, unsigned int* map, size_t count) { } else { vec_clear(&mesh->map); vec_pusharr(&mesh->map, map, count); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ibo); + lovrGraphicsBindIndexBuffer(mesh->ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), mesh->map.data, GL_STATIC_DRAW); } } @@ -268,7 +268,7 @@ void* lovrMeshMap(Mesh* mesh, int start, size_t count, int read, int write) { access |= read ? GL_MAP_READ_BIT : 0; access |= write ? GL_MAP_WRITE_BIT : 0; access |= (write && start == 0 && count == mesh->count) ? GL_MAP_INVALIDATE_BUFFER_BIT : 0; - glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); + lovrGraphicsBindVertexBuffer(mesh->vbo); return glMapBufferRange(GL_ARRAY_BUFFER, start * mesh->stride, count * mesh->stride, access); #endif } @@ -279,7 +279,7 @@ void lovrMeshUnmap(Mesh* mesh) { } mesh->isMapped = 0; - glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); + lovrGraphicsBindVertexBuffer(mesh->vbo); #ifdef EMSCRIPTEN int start = mesh->mapStart * mesh->stride;