diff --git a/src/rlgl.h b/src/rlgl.h index 61a295187..362496be0 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -505,6 +505,7 @@ RLAPI bool rlRenderTextureComplete(RenderTexture target); // Ver // Vertex data management RLAPI void rlLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids RLAPI void rlUpdateMesh(Mesh mesh, int buffer, int num); // Update vertex or index data on GPU (upload new data to one buffer) +RLAPI void rlUpdateMeshAt(Mesh mesh, int buffer, int num, int index); // Update vertex or index data on GPU, at index RLAPI void rlDrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform RLAPI void rlUnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU @@ -2580,6 +2581,79 @@ void rlUpdateMesh(Mesh mesh, int buffer, int num) #endif } +// Update vertex or index data on GPU, at index +// WARNING: error checking is in place that will cause the data to not be +// updated if offset + size exceeds what the buffer can hold +void rlUpdateMeshAt(Mesh mesh, int buffer, int num, int index) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // Activate mesh VAO + if (vaoSupported) glBindVertexArray(mesh.vaoId); + + switch (buffer) + { + case 0: // Update vertices (vertex position) + { + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]); + if (index + num >= mesh.vertexCount) break; + else glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*3*index, sizeof(float)*3*num, mesh.vertices); + + } break; + case 1: // Update texcoords (vertex texture coordinates) + { + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]); + if (index + num >= mesh.vertexCount) break; + else glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*2*index, sizeof(float)*2*num, mesh.texcoords); + + } break; + case 2: // Update normals (vertex normals) + { + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]); + if (index + num >= mesh.vertexCount) break; + else glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*3*index, sizeof(float)*3*num, mesh.normals); + + } break; + case 3: // Update colors (vertex colors) + { + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]); + if (index + num >= mesh.vertexCount) break; + else glBufferSubData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*index, sizeof(unsigned char)*4*num, mesh.colors); + + } break; + case 4: // Update tangents (vertex tangents) + { + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]); + if (index + num >= mesh.vertexCount) break; + else glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*4*index, sizeof(float)*4*num, mesh.tangents); + } break; + case 5: // Update texcoords2 (vertex second texture coordinates) + { + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]); + if (index + num >= mesh.vertexCount) break; + else glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*2*index, sizeof(float)*2*num, mesh.texcoords2); + } break; + case 6: // Update indices (triangle index buffer) + { + unsigned short *indices = mesh.indices; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vboId[6]); + if (index + num >= mesh.triangleCount*3) // 3 indices per triangle + break; + else + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*indices)*index, sizeof(*indices)*num, indices); + } break; + default: break; + } + + // Unbind the current VAO + if (vaoSupported) glBindVertexArray(0); + + // Another option would be using buffer mapping... + //mesh.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); + // Now we can modify vertices + //glUnmapBuffer(GL_ARRAY_BUFFER); +#endif +} + // Draw a 3d mesh with material and transform void rlDrawMesh(Mesh mesh, Material material, Matrix transform) {