   Noob question about VBOs
  I started learning about VBOs, and I think I've understood how to make them work. But what I've found on the internet left me without a general idea of how they should be used in practice. It's all easy and clear when people make you draw a cube, but a complex scene is a different thing...When I first approached VBOs, I thought I had to make one giant buffer where I would store structures representing my vertices - an idea I probably got from the few things I know about Direct3D. Now that I've read a bit more, though, a different approach is starting to shape up in my head, but I have no idea whether this is the actual best practice or it is a complete disaster. So I would like to get some feedback from people with some experience about this. From what I've got, I think I could define one buffer for every object I draw (make it two for color info - but they would mostly be completely white - and three for texture coordinates?). Like, every GraphicObject in my application would have an array of vertices that I would bind to a single VBO (two or three arrays for color and texturing, with one VBO each). When creating any such object, I would fill the arrays and bind the VBO to the arrays, and then, at frame time, call glDrawArrays (or similar). Then, if I wanted to move or alter the object, I would just change the values in the arrays, and, without having to rebind the VBO, the scene would be updated. Is this correct? Is it bad to have, say, 3000 VBOs because I have a thousand objects in my scene? Also, what would I need to do in case the size of the arrays changed - for example, if I wanted to add a new vertex? Would I have to unbind and rebind the VBO? Does the array need to be a static array, or anyway a continguous memory area?   
  Adding a few of my own thoughts:Quote:From what I've got, I think I could define one buffer for every object I draw (make it two for color info - but they would mostly be completely white - and three for texture coordinates?)...Is it bad to have, say, 3000 VBOs because I have a thousand objects in my scene? You're close, but I think you need to clarify "objects" vs "instances". If you have one tree model, and you stamp it 100 times across your scene, you don't need a new VBO for each instance of that tree. For most applications of VBO (game world objects) your vertices should be in model space. Then whenever you want to draw something you send that vbo and the model matrix for that instance, and transform all of the vertices of the VBO to world space on the GPU. To draw your 100 trees you would do something like this:1)bind the tree vbo2)set the model matrix for the first instance3)call glDrawElements(repeat 2-3 for every instance of that tree)4)unbind the tree vboBut you are correct that for every unique object in the world you would have its own set of VBOs (one for vertices, one for color, one for texcoords, or more for whatever other kind of data you need). You can also use an interleaved array to store all of these in a single vbo, but it is optional and either way works just as well.Quote:Then, if I wanted to move or alter the object, I would just change the values in the arrays, and, without having to rebind the VBO, the scene would be updated.If you're just moving an object then you don't want to update the data in the vbo, you just update the model matrix that you use to draw the vbo. If you do need to change the data in the vbo it can be done, but you want to avoid it when you can (always minimize data transmission between app<->gpu as much as possible). If you update the data there are calls that allow you to replace all or sections of data in the vbo, though I don't think you have to unbind it. I don't think you can add new vertices to the middle of the array, though you may be able to append them to the end (I would try to minimize the creation/deletion of individual vertices).Quote:Does the array need to be a static array, or anyway a continguous memory area?When you call glBufferData, you supply a pointer to a contiguous memory area. This area is then copied into OpenGL's memory space and your own copy can then be deleted. If you call glBufferSubData you supply again a pointer to your own subsection of memory, and OpenGL replaces this data into its own memory. You don't manage the actual memory storage for the VBO's yourself.;  I believe it's common practice to use separate VBOs for each object in your scene. However, it is important to make a distinction between the amount of different objects and the amount of instances of these objects you use. If you draw the same cube 100 times, you should use a single set of VBOs to represent the cube's attributes and make 100 drawing calls. For instance, having 1000 different objects is quite a lot. If you do have such a situation, you may want to try to group them together for general efficiency in some way.   ;  Thanks a lot for your replies! Just out of curiosity, apart from being a logical thing to do, is instancing mainly for performance or for memory occupation?I find myself with this problem, though: when drawing my 2D GUI, I have to draw lots of textured rectangles. While it's easy to figure out how to define a single object with default position and texture vertices, how would I apply different colors on a per-instance basis? I would have to do glColor (or equivalent) on a single instance, but this brings back immediate mode, am I right?Also, if I understand correctly, VBOs replace functions such as glVertex*, glColor* and glTexCoord*, but if I want to use textures I still have to use the usual glBind, glTexImage, if I want to apply matrices I use the classic glMatrix, glLoadIdentity... is this right? Essentially, I should only keep away from the glBegin/glEnd construct, correct?   ;Quote:Thanks a lot for your replies! Just out of curiosity, apart from being a logical thing to do, is instancing mainly for performance or for memory occupation?I'd guess its mostly memory, maybe a slight bit of perf from not having to bind a new vbo, but that is probably small. Although if you use up all the vram the driver will have to keep swapping your vbo's in and out of system memory which will be pretty slow.Quote:I find myself with this problem, though: when drawing my 2D GUI, I have to draw lots of textured rectangles. While it's easy to figure out how to define a single object with default position and texture vertices, how would I apply different colors on a per-instance basis? I would have to do glColor (or equivalent) on a single instance, but this brings back immediate mode, am I right?What you'll want to to is start familiarizing yourself with GLSL, the shading language (if you don't know already). If you do call glColor before drawing your vbo and your vbo does not supply color information, then it will draw that quad with the color you sent to glColor. Although of course that is depreciated, so where's the fun in that :)Once you have your shader you can send your color up as a "uniform" to the shader. You tell the shader to draw your vertices with the color stored in the uniform. Then drawing is something like this:1)Bind Shader2)Bind VBO3)Set color uniform to red4)Set the instance matrix5)glDrawElements()(repeat 3-5 with different colors and matrices)You could even have more flexibility to say give all your vertices in the vbo color or textures, and then use the uniform color to tint the square by 20% to whatever color is in the uniform. Quote:Also, if I understand correctly, VBOs replace functions such as glVertex*, glColor* and glTexCoord*, but if I want to use textures I still have to use the usual glBind, glTexImageCorrect on both pointsQuote: if I want to apply matrices I use the classic glMatrix, glLoadIdentity... is this right? Essentially, I should only keep away from the glBegin/glEnd construct, correct?If you want to be perfectly compatible with opengl 3 then you technically shouldn't be using any glMatrix commands either. In opengl 3.2 core it is illegal to draw anything without binding your own shader, and you send the matrices as uniforms to the shader instead of using any glMatrix commands.;  Hmm... guess I'll finally have to learn about shaders, then. Only one more question: how portable/standard are these things (VBOs, shaders, GLSL vs. Cg)? Can I expect current hardware to support my graphics if I use the non-ARB versions of glGenBuffer et similia? What about Vista and Seven? What about - may I say that? - Linux? Thanks for all your directions, they've been very useful to me!   ;  Yes, it's fine.   ;  One thing you have to be careful with is updating VBO's. They're generally meant for "Static" data. If you find yourself constantly updating a VBO, you might have a speed increase rendering from buffers in system memory rather than video memory.   ;Quote:Original post by RavenITAFrom what I've got, I think I could define one buffer for every object I draw (make it two for color info - but they would mostly be completely white - and three for texture coordinates?). Like, every GraphicObject in my application would have an array of vertices that I would bind to a single VBO (two or three arrays for color and texturing, with one VBO each). When creating any such object, I would fill the arrays and bind the VBO to the arrays, and then, at frame time, call glDrawArrays (or similar). Then, if I wanted to move or alter the object, I would just change the values in the arrays, and, without having to rebind the VBO, the scene would be updated. Is this correct? Is it bad to have, say, 3000 VBOs because I have a thousand objects in my scene? Also, what would I need to do in case the size of the arrays changed - for example, if I wanted to add a new vertex? Would I have to unbind and rebind the VBO? Does the array need to be a static array, or anyway a continguous memory area?1 VBO per object? That's not such a great idea.You will keep your vertex, color, texcoords in different VBOs. That's not such a great idea either.If you will be moving objects around, then use a transformation matrix. Why would you edit the vertices?A couple of info here http://www.opengl.org/wiki/VBO_-_moreand you can get more vertex buffer info herehttp://www.opengl.org/wiki/General_OpenGL