VBOs or another way? - c++

I've just finished my basic OpenGL model loader, and now I want to move over to VBOs instead of glBegin() and glEnd(). I read in an article that even VBOs are deprecated.
My question is: Are VBOs really deprecated and is there a better way to draw objects in OpenGL? Should I be using display lists perhaps?

Vertex Buffer Objects are not deprecated. In fact, I believe they are the only (non-deprecated) way to render in OpenGL 3.0 and above.
See the OpenGL page on Vertex Buffer Object.
Legacy Note: Versions of OpenGL prior to 3.0 allowed the use of
client-side data for vertex rendering, but GL 3.0 deprecated this.
Core GL 3.1 and greater forbid client-side vertex data, so VBOs are
the only means for rendering.

Related

Is it possible to write vertex array code that's portable between OpenGL 2.x and 3.x?

The OpenGL 3.0 spec says:
E.1 Profiles and Deprecated Features of OpenGL 3.0
...
Client vertex arrays - all vertex array attribute pointers must refer
to buffer objects (section 2.9.2). The default vertex array object
(the name zero) is also deprecated. Calling VertexAttribPointer when
no buffer object or no vertex array object is bound will generate an
INVALID_OPERATION error, as will calling any array drawing command
when no vertex array object is bound.
The ref page for glEnableVertexAttribArray says:
GL_INVALID_OPERATION is generated by glEnableVertexAttribArray and glDisableVertexAttribArray if no vertex array object is bound.
The message I'm hearing is that comprehensive vertex array code that's fully portable between OpenGL 2.x and OpenGL 3.x/3.2+ is impossible, since 2.x can't use VAOs (which the API surface can strictly enforce -- thanks GLAD!), and 3.x must use VAOs (which...some drivers maaaybe enforce?)
It seems to me that robust code must branch between dedicated 2.x and 3.x codepaths (detected at runtime) at some point. Is this true?
When you use a compatibility profile OpenGL Context, then you can run the code of all previous OpenGL versions. Vertex array object 0 is valid and you can use fixed function attributes, immediate mode (glBegin/glEnd sequences) or even mix them all together.
Compare OpenGL 4.6 API Core Profile Specification and OpenGL 4.6 API Compatibility Profile Specification.
The specification of all OpenGL versions can be found at Khronos OpenGL registry.

How to pass per-instance data (such as positioning) to shader in OpenGL 3.2 with instanced rendering?

I am trying to render cubes using instanced rendering. I got this to work and I render with glDrawArraysInstanced.
However, I now want to pass per-instance data (in this case positioning and colours) to the shader, and I have understood that I am meant to use the function glVertexAttribDivisor to achieve this. The problem is that that function is only available in OpenGL 3.3 and up and I am using 3.2
How can I achieve this in the Right Way in OpenGL 3.2?
Optional solution :
Render points and emit a cube using a geometry shader. Then you can pack everything into one VBO and avoid instanced rendering.
Use transform feedback to modify cube properties if needed.
I didn't find a nice way in 3.2 to do what I wanted so I updated to OpenGL 3.3 instead to be able to use glVertexAttribDivisor to send instance data in attributes.

glEnableClientState deprecated

I want to use GL_POINT_SPRITE_ARB + VBO for my particle system rendering.
I've done all preparations with point_sprites, but stuck at VBO.
It seems that glEnableClientState, is not working. I read that it is deprecated in modern openGL. So, what should i use instead?
glEnableClientState is how you tell OpenGL that you're using a vertex array for a particular fixed-function attribute (gl_Vertex, gl_Color, etc). Those are all removed from core contexts. You should use glEnableVertexAttribArray to enable a generic vertex attribute, and you use glVertexAttribPointer to associate that attribute with a buffer object.

How to render/draw buffer object to framebuffer without glDrawPixels

According to opengl spec 4.0 glDrawPixels is deprecated.
For cuda interoperability it seems best to use "opengl buffer objects". (An alternative could be textures or surfaces but these have caching/concurrency issues and are therefore unusable for my cuda kernel).
I simply want to create a cuda kernel which uses this mapped opengl buffer object and uses it as a "pixel array" or a piece of memory holding pixels, later the buffer is unmapped.
I then want the opengl program to draw the buffer object to the framebuffer. I would like to use an opengl api which is not deprecated.
What other ways/apis are there to draw a buffer object to the frame buffer ? (Also render buffers cannot be used since they probably have same issue as cuda arrays/caching issues, so this rules out framebuffer object/extension ?!?).
Is there a gap/missing functionality in opengl 4.0 now that glDrawPixels is deprecated ? Or is there an alternative ?
glDrawPixels has been removed from GL 3.2 and above (it is not deprecated. Deprecated means "available but to be removed in the future"). It was removed because it's generally not a fast way to draw pixel data to the screen.
Your best bet is to use glTexSubImage2D to upload it to a texture, then draw that to the screen. Or blit it from the texture with glBlitFramebuffer.

glEnableClientState with modern OpenGL (glVertexAttribPointer etc)

I'd like to lay out some things I think I've learned, but am unsure about:
VBOs are the way to go. They're created with glGenBuffers and glBufferData.
For maximum flexibility, it's best to pass generic vertex attributes to shaders with glVertexAttribPointer, rather than glVertex, glNormal, etc..
glDrawElements can be used with vertex buffers and an index buffer to efficiently render geometry with lots of shared vertices, such as a landscape mesh.
Assuming all of that is correct so far, here's my question. All of the tutorials I've read about modern OpenGL completely omit glEnableClientState. But the OpenGL man pages say that without glEnableClientState, glDrawElements will do nothing:
http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml
The key passage is: "If GL_VERTEX_ARRAY is not enabled, no geometric primitives are constructed."
This leads me to the following questions:
None of the tutorials use glEnableClientState before calling glDrawElements. Does this mean the man page is wrong or outdated?
GL_VERTEX_ARRAY would seem to be the thing you enable if you're going to use glVertexPointer, and likewise you'd use GL_NORMAL_ARRAY with glNormalPointer, and so on. But if I'm not using those functions, and am instead using generic vertex attributes with glVertexAttribPointer, then why would it be necessary to enable GL_VERTEX_ARRAY?
If GL_VERTEX_ARRAY is not enabled, no geometric primitives are constructed.
That's because the man page is wrong. The man page covers GL 2.1 (and it's still wrong for that), and for whatever reason, the people updating the man page refuse to update the older GL versions for bug fixes.
In GL 2.1, you must use either generic attribute index 0 or GL_VERTEX_ARRAY. In GL 3.1+, you don't need to use any specific attribute indices.
This is because, in GL versions before 3.1, all array rendering functions were defined in terms of calls to glArrayElement, which used immediate mode-based rendering. That means that you need something to provoke the vertex. Recall that, in immediate mode, calling glVertex*() not only sets the vertex position, it also causes the vertex to be sent with the other attributes. Calling glVertexAttrib*(0, ...) does the same thing. That's why older versions require you to use either attribute 0 or GL_VERTEX_ARRAY.
In GL 3.1+, once they took out immediate mode, they had to specify array rendering differently. And because of that, they didn't have to limit themselves to using attribute 0.
If you want API docs for core GL 3.3 works, I suggest you look at the actual API docs for core GL 3.3. Though to be honest, I'd just look at the spec if you want accurate information. Those docs have a lot of misinformation in them. And since they're not actually wiki-pages, that information never gets corrected.
Your first 3 points are correct. And to answer your last half of your question, do not use glEnableClientState for modern OpenGL. Start coding!
VBOS are the way to go. They're created with glGenBuffers and
glBufferData.
VBOs are often used in high-performance applications. You might want to do something simpler first. Vertex arrays can be a good way to go to get started quickly. Because VBOs sit on top of vertex arrays anyway, you'll be using much of the same code when you switch to VBOs, and it might be good to run a test using vertex arrays or indexed vertex arrays first.
For maximum flexibility, it's best to pass generic vertex attributes
to shaders with glVertexAttribPointer, rather than glVertex, glNormal,
etc..
That's a good approach.
glDrawElements can be used with vertex buffers and an index buffer to
efficiently render geometry with lots of shared vertices, such as a
landscape mesh.
Perhaps. You have to be sure the vertices truly are shared, though. A vertex that is in the same location but has a different normal (e.g. for flat shading) isn't truly shared.