I have a really obscure problem that I hope somebody can help with. I have implemented vertex skinning on the CPU (the GPU was too slow because the bad performance of looking up a bone transform in a vertex shader) using a background thread on OSX. I do not need a shared context because no GL calls are made. I allocate a buffer in the process heap big enough to hold my character's vertices. I skin and animate that buffer on the background thread. In the main thread I simply glBufferSubData() that buffer down to my VBO, synchronizing with the end of the buffer update so I don't get tearing in my verts. The VBO has previously been bound to a VAO (one VAO per VBO per character instance). So I only have to bind the VAO and draw my mesh. Not very difficult so far. A single IBO is bound to all VAO's per character instance.
Here's the rub. If I only have one character instance the code works perfectly. I have a lovely little warrior princess doing her idle animation. The moment I add a second instance nothing happens--only the first instance renders.
So the big question is what am I doing wrong? I'm pretty sure my VBO, IBO and VAOs are correct. There's a separate VBO and VAO per instance. I turned off indexing (no IBO) and still the instances fail to draw so it's not that IMHO. I've verified the state using the Mac OpenGL Profiler and everything looks good per instance. Is there some kind of weird flushing not going on due to my glBufferSubData call. glMapBuffer was just too slow!
If you need source code to look at I can upload that easily enough. Just wondering if anyone's heard of weirdness like what I'm seeing when dealing with buffer objects in OpenGL on the Mac.
Related
I believe I misunderstood the limits of VAO's.
I have 3 VAO's, one for each vertex spec. format.
Focusing on the VAO intended for menus/quads rendering in homogeneous screen coordinates, how many buffers can I have connected to the same array index of a single VAO ?
Due to results in my program I am inclined to believe every separate instance rendered should have it's own VAO. However, I am still able to draw two instances using one VAO, although with incorrect results. (Cursor takes up fullscreen and position doesn't change, rendered overtop fullscreen TitleMenu).
I'm fairly certain I already know the answer is have a VAO for each instance with differing array buffer data, would just like confirmation I have rationalized this correctly.
Also, are the buffers bound to the VAO copied to the VAO and can be deleted?
Does a glVertexAttribPointer() need to be called again to update the information in a VAO ? Or is buffering data to the original buffer sufficient ?
I'm creating a tile-based renderer where each tile has a vertex model. However, from each vertex model only a small portion is rendered in one frame. These subsets change every frame.
What would be the fastest way to render this? I can think of the following options:
Make one draw call for every model. Every model is stored in full on the gpu. For every draw call, the full vbo is switched every time. Indices are then used to pick the appropriate small portion for the actual rendering.
Make one draw call with one vbo which gets assembled every frame by copying the necessary (small) subset of all the other vbos (the data is copied within vram).
Make one draw call with one vbo, but the vbo is recreated every frame with the (small) subset from CPU data using glBufferData.
Which do you think is fastest, or can you think of something faster?
One deciding factor is obviously if switching between larger VBOs is more expensive than switching between smaller VBOs.
It is a bad idea to make a lot of drawcalls. In OpenGL,you will be CPU bound by this method, so it is better to batch a lot of models.
Actually, I would go for this method. All static geometry is inside one and only one VBO and one VAO. It does not mean that you only have "one draw call". However, you should use glMultiDraw*Indirect.
The idea burried that is you have to use compute shaders to perform culling on GPU, and use something like GL_INDIRECT_PARAMETERS extensions with your multi indirect draw call.
Indirect Drawing
For all dynamic geometry, you can use a persistent buffer.
To answer your question about changing vao/vbo. Change VAO, or use glBindVertexBuffer should not make a big overhead.
But you should profile it, it can depends on your driver / hardware :)
So I've been learning OpenGL 3.3 on https://open.gl/ and I got really confused about some stuff.
VAO-s. By my understanding they are used to store the glVertexAttribPointer calls.
VBO-s. They store vertecies. So if I am making something with multiple objects do I need a VBO for every object?
Shader Programs - Why do we need multiple ones and what exactly do they do ?
What exactly does this line do : glBindFragDataLocation(shaderProgram, 0, "outColor");
The most important thing is how does all of this fit into a big program? For what exactly are used the VAO-s? Most tutorials just cover the things just to drawing a cube or 2 with hard coded vertices, so how would one go to managing scenes with a lot of objects? I've read this thread and got a little bit of understanding on how the scene management happens and all but still I can't figure out how to connect the OpenGL stuff to it all.
1-Yes. VAOs store vertex array bindings in general. When you see that you're doing lots of calls that does enabling, disabling and changing of GPU states, you can do all that at some early point in the program and then use VAOs to take a "snapshot" ,of what is bound and what isn't, at that point in time. Later, during your actual draw calls, all you need to do is bind that VAO again to set all the vertex states to what they were then. Just like how VBOs are faster that immediate mode because they send all vertices at once, VAOs work faster by changing many vertex states at once.
2-VBOs are just another way to send your glPosition, glColor..etc coordinates to the GPU to render on screen. The idea is, unlike with immediate mode where you send your vertex data one by one with the gl*Attribute* calls, is to upload all your vertices to the GPU in advance and retrieve their location as an ID. At time of rendering, you're only going to point the GPU (you bind the VBO id to something like GL_ARRAY_BUFFER, and use glVertexAttribPointer to specify details of how you stored the vertices data) to that location and issue your order to render. That obviously saves lots of time by doing things overhead, and so it's much faster.
As for whether one should have one VBO per object or even one VBO for all the objects is up to the programmer and the structure of the objects they want to render. After all, VBOs themselves are just a bunch of data you stored in the GPU, and you tell the computer how they're arranged using the glVertexAttribPointer calls.
3-Shaders are used to define a pipeline - a routine - of what happens to the vertices, colors, normals..etc after they've been sent to the GPU until they're rendered as fragments or pixels on the screen. When you send vertices over to the GPU, they're often still 3D coordinates, but the screen is a 2D sheet of pixels. There still comes the process of re-positioning these vertices according to the ProjectionModelView matrices (job of vertex shader) and then "flattening" or rasterizing the 3D geometry (geometry shader) into a 2D plane. Then it follows with coloring the flattened 2D scene (fragment shader) and finally lighting the pixels on your screen accordingly. In OpenGL versions 1.5 core and below, you didn't have much control over those stages as it was all fixed (hence the term fixed pipeline). Just think about what you could do in any of these shader stages and you will see that there is a lot of awesome things you can do with them. For example, in the fragment shader, just before you send the fragment color to the GPU, negate the sign of the color and add 1 to have colors of objects rendered with that shader inverted!
As for how many shaders one needs to use, again, it's up to the programmer to decide whether to have many or not. They could merge all the functionalities they need into one big giant shader (uber shader) and switch these functionalities on and off with boolean uniforms (very often considered as a bad practice), or have every shader do a certain thing and bind the right one according to what they need.
What exactly does this line do :
glBindFragDataLocation(shaderProgram, 0, "outColor");
It means that whatever is stored in the out declared variable "outColor" at the end of the fragment shader execution will be sent to the GPU as the final primary fragment color.
The most important thing is how does all of this fit into a big
program? For what exactly are used the VAO-s? Most tutorials just
cover the things just to drawing a cube or 2 with hard coded vertices,
so how would one go to managing scenes with a lot of objects? I've
read this thread and got a little bit of understanding on how the
scene management happens and all but still I can't figure out how to
connect the OpenGL stuff to it all.
They all work together to draw your nice colored shapes on the screen. VBOs are the structures where the vertices of your scene are stored (all aligned in an ugly fashion), VertexAttribPointer calls to tell the GPU how the data in the VBO is arranged, VAOs to store all these VertexAttribPointer instructions ahead of time and send them all at once with simply binding one during rendering in your main loop, and shaders to give you more control during the process of drawing your scene on the screen.
All of this can sound overwhelming at first, but with practice you will get used to it.
I'm a bit confused as to how to set up my application to send data to my shaders and be drawn. I know that I have to generate a VAO, bind it, generate buffer objects, bind them, populate it with data and create an attribute pointer to reference the data in the buffer object, because the openGL red book told me to... but I don't actually know what is happening in the process. could someone explain the process of this step by step and explain what is happening; to clear this up for me, and anybody else who doesn't quite understand this process. Also what does the VAO actually do? I know I can just reference the data in a buffer object with an attribute pointer and it will work fine, so what's the point in a VAO?
A Vertex Array Object (VAO) is an object which contains a group of Vertex Buffer Objects and is designed to store the information for a complete rendered object or a complete render batch. If you wouldn't use VAOs, for each batch you would have to bind all the VBOs one by one. With all VBOs in the batch in a VAO, you would just have to bind the VAO once instead of binding all the VBOs.
A Vertex Buffer Object (VBO) is a memory buffer in the high speed memory of your video card designed to hold information about vertices. VBOs can store information such as normals, texcoords, vertices, etc. This is why you have to let the shaders know whats inside the VBO using attribute pointers. VBOs offer substantial performance gains over immediate mode rendering primarily because the data resides in the video device memory rather than the system memory and so it can be rendered directly by the video device.
You have to bind the VBOs or VAOs to let OpenGL know what you are going to draw with the next draw call or that you are going to work with certain VBOs and tell OpenGL to have them ready for use.
So I'm trying to implement VBOs but I can't find a good tutorial or documentation of the proper usage of them. I'm guessing you make a VBO when some object needs it and then when the next frame comes about it's drawn/redrawn. But here is where I'm confused:
How do I draw multiple VBOs?
How do I modify a VBO?
When and where do I make a new VBO?
I'm really sorry and I'm just learning OpenGL so excuse me for that! But it's hard to find a tutorial that doesn't just make one VBO, and doesn't make that VBO at the same time it's drawn.
Mainly what I'm asking for is a better understanding of how VBOs work, where they are stored, and how they are drawn. How many VBOs is too many? When I call glVertexPointer() what exactly happens with stored VBOs? What if I'm trying to draw VBOs of different types? (just use triangles?)
How do I draw multiple VBOs?
VBOs are data storage, just like textures. There's a function called glBindBuffer which binds a VBO for subsequent access through glVertexAttribPointer.
How do I modify a VBO?
glBufferSubData
or
buf = glMapBuffer(...);
modify_on(buf);
glUnmapBuffer(...);
When and where do I make a new VBO?
Whenever the existing VBOs no longer can satisfy your demands. Either because they're to small, full or don't match your data type.