I am using OpenGL to render a large number of models by instanced rendering (using LWJGL wrapper). As far as I can tell I have implemented the instancing correctly, although, after profiling, I've come upon an issue.

The program is able to render a million cubes at 60fps when their model (world) transformations are not changing. Once I make them all spin though, the performance drops significantly. I deduced from the profiler that this is due to the way I write the matrix data to the VBO.

My current approach is to give each unique mesh a new VAO (so all instances of cubes come under 1 VAO), have 1 VBO for vertex positions, textures, and normals and 1 instance array (VBO) for storing instance model matrices. All VBOs are interwoven.

In order to make the cubes spin, I need to update the instance VBO every frame. I do that by iterating through every instance and copying the matrix values into the VBO.

The code is something like this:

float[] matrices = new float[models_by_mesh.get(mesh).size() * 16];

for (int i = 0; i < models.size(); i++){
    Model cube = models.get(i);
    float[] matrix = new float[16];
    cube.getModelMatrix(matrix);    //store model matrix into array
    System.arraycopy(matrix, 0, matrices, i * 16, 16);

glBindBuffer(GL_ARRAY_BUFFER, instance_buffers_by_mesh.get(mesh);
glBufferData(GL_ARRAY_BUFFER, matrices, GL_STATIC_DRAW);


I realise that I create new buffer storage and float array every frame by calling glBufferData instead of glBufferSubData but when I write:

//outside loop soon after VBO creation
glBufferData(GL_ARRAY_BUFFER, null, GL_DYNAMIC_DRAW); //or stream

//when updating models
glBufferSubData(GL_ARRAY_BUFFER, 0, matrices)

nothing is displaying; I'm not sure why, perhaps I'm misusing subData but that's another issue.

I have been looking at examples of particle simulators (in OpenGL) and most of them update the instance VBO the same way as me.

I'm not sure what the problem could be and I can't think of a more efficient way of updating the VBO. I'm asking for suggestions / potential improvements with my code.

  • \$\begingroup\$ Might be possible that you're updating the VBO while the GPU hasn't finished rendering using the previous VBO data. \$\endgroup\$ – Rish Apr 23 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.