diff --git a/src/rlgl.h b/src/rlgl.h index 61a295187..5c71c4782 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 @@ -2511,6 +2512,14 @@ unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, // Update vertex or index data on GPU (upload new data to one buffer) void rlUpdateMesh(Mesh mesh, int buffer, int num) +{ + rlUpdateMeshAt(mesh, buffer, num, 0); +} + +// 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 @@ -2521,51 +2530,60 @@ void rlUpdateMesh(Mesh mesh, int buffer, int num) case 0: // Update vertices (vertex position) { glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]); - if (num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*num, mesh.vertices, GL_DYNAMIC_DRAW); - else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*num, mesh.vertices); + if (index == 0 && num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*num, mesh.vertices, GL_DYNAMIC_DRAW); + else 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 (num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*num, mesh.texcoords, GL_DYNAMIC_DRAW); - else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*num, mesh.texcoords); + if (index == 0 && num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*num, mesh.texcoords, GL_DYNAMIC_DRAW); + else 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 (num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*num, mesh.normals, GL_DYNAMIC_DRAW); - else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*num, mesh.normals); + if (index == 0 && num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*num, mesh.normals, GL_DYNAMIC_DRAW); + else 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 (num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*num, mesh.colors, GL_DYNAMIC_DRAW); - else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*num, mesh.colors); + if (index == 0 && num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*num, mesh.colors, GL_DYNAMIC_DRAW); + else 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 (num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*num, mesh.tangents, GL_DYNAMIC_DRAW); - else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*num, mesh.tangents); + if (index == 0 && num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*num, mesh.tangents, GL_DYNAMIC_DRAW); + else 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 (num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*num, mesh.texcoords2, GL_DYNAMIC_DRAW); - else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*num, mesh.texcoords2); + if (index == 0 && num >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*num, mesh.texcoords2, GL_DYNAMIC_DRAW); + else 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) { + // the * 3 is because each triangle has 3 indices unsigned short *indices = mesh.indices; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vboId[6]); - if (num >= mesh.triangleCount*3) // 3 indices per triangle - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*indices)*num, indices, GL_DYNAMIC_DRAW); + if (index == 0 && num >= mesh.triangleCount) + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*indices)*num*3, indices, GL_DYNAMIC_DRAW); + else if (index + num >= mesh.triangleCount) + break; else - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(*indices)*num, indices); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*indices)*index*3, sizeof(*indices)*num*3, indices); } break; default: break; }