Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL handling multiple objects

I'm having a little difficulty with understanding how to handle/render multiple objects with OpenGL. I've looked around and found answers in google and the OpenGL red book that sort of dance around what I'm trying to figure out, but I need to see if I have the idea down right.

My first thought was that I should handle locational data with translation and rotational variables for X,Y, and Z respectively. Store a single mesh in a static VBO for that class, then for each instance I want to render do a for-next loop to

  • load identity
  • transform to the specific object's location / rotation
  • use drawarrays to render the mesh at that location
  • loop to the next object and repeat the above for every object

Does handling the transformations like this for every frame update impact the performance significantly?

another method that someone was mentioning was sticking all of the locational data for every vertex in a single VBO then rendering it with a single call. In this method, I'm assuming to 'create' an object I would need to process each vertex's locational data through a function that would take its local coordinates (through the static array) and add that specific object's locational data to the vertex, then store it in the VBO? If that's the case, how would I handle rotation as well?

The third thought I had was to store a 4x4 matrix in every instance of the object that would hold the translation/rotation information, then when I go to render, I would just load that object's matrix, draw the mesh from the single VBO, then load the next object's matrix, draw from the same VBO, etc....

Finally, I've seen some people suggest having a VBO for every single object and calling drawarray for every single instance. This way seems very inefficient to me, and makes me wonder what the point of having VBO's would be if you are calling it for every mesh. It seems like immediate mode (i understand it's depreciated) would be faster just because you don't have the overhead of creating and binding the VBO for every single object.

Are any/all of these methods of handling/rendering multiple objects valid? If so, what are advantages and disadvantages to each method?

The methods that make the most sense are the ones that have a single VBO per mesh, then either transforming them per update, or loading each object's matrix per update and rendering that way. I'm fairly new to OpenGL and graphics rendering, so I'm trying to fully understand optimal ways to handle the information required to render multiple objects.

like image 805
David Torrey Avatar asked Nov 22 '12 06:11

David Torrey


1 Answers

  • transform to the specific object's location / rotation

That simply means you load a 4x4 matrix to a uniform variable.

Does handling the transformations like this for every frame update impact the performance significantly?

The transformation will be performed in your vertex shader, by multiplying ther aforementioned matrix and by vertex coordinates, in parallel for many vertices.

another method that someone was mentioning was sticking all of the locational data for every vertex in a single VBO then rendering it with a single call. In this method, I'm assuming to 'create' an object I would need to process each vertex's locational data through a function that would take its local coordinates (through the static array) and add that specific object's locational data to the vertex, then store it in the VBO? If that's the case, how would I handle rotation as well?

That does not seem to be a very good idea, because you'll have to upload the data on every frame (or at least when object position/orientation chages).

The third method seems the same as the first, only in OGL3+ terms, wheras the first seem like in OGL 2.x terms :)

Finally, I've seen some people suggest having a VBO for every single object and calling drawarray for every single instance.

Perhaps you misunderstood and they meant VAO, not VBO? WIth a VAO, you upload vertex attributes (in VBOs), bind the VAO, bind each VBO to the appropriate attribute location and do this only once in the beginning. On each frame you simply do:

// Bind the VAO
glBindVertexArray(vao)

// Draw the object
glDrawArrays/glDrawArraysInstanced/etc.

// CLear VAO binding
glBindVertexArray(0)

Note that you can still have vertex attributes for many distinct object in the same VBO, remember glDrawArrays and others have a parameter, which determined from where in the array to start drawing.

like image 121
chill Avatar answered Nov 08 '22 14:11

chill