Rendering in opengl 3.1+ without VBO using client side vertex array - c++

I want to know if its possible to draw in opengl 3.1+ core profile using vertex arrays ( client side rendering not immediate mode) without using the VBO. I know in opengl 3.1+ core profile use of VAO is essential. I want to know if its possible to draw without using VBO by using vertex arrays (client side vertex array not immediate mode).
PS I am talking about client side vertex array not immediate mode. I want to know if I can create a VAO without VBO
I read this somewhere in opengl spec Immediate-mode vertex attribute specification, client-side vertex arrays is depricated. Vertex Attributes must be stored in one or more Buffer Objects, or be specified explicitly using glVertexAttrib*()​. Since OpenGL 3.2 using Vertex Array Objects is mandatory. So does this means I can specify vertex array data using the glVertexAttriPointer like this
glBindVertexArray(m_vaoHandle);
glEnableVertexAttribArray(m_attributes[POSITION_HANDLE]);
glVertexAttribPointer(m_attributes[POSITION_HANDLE], 3, GL_FLOAT, false, 0,vertexArray);
glEnableVertexAttribArray(m_attributes[TEXCOORDINATE_HANDLE]);
glVertexAttribPointer(m_attributes[TEXCOORDINATE_HANDLE], 2, GL_FLOAT, false, 0, textureArray);
glBindVertexArray(0);
Here vertexArray and textureArray are two arrays on CPU not VBO. Then while drawing them
glUseProgram(m_Program);
// Explicitly unbind buffer so attrib pointer knows to slurp in array.
glBindBuffer(GL_ARRAY_BUFFER, 0);
//bind vertex array object
glBindVertexArray(m_vaoHandle);
glDrawArrays(mode, 0, numVertices);
glBindVertexArray(0);
If its possible in OpenGL 3.1+, I would also like to know if its possible in OpenGLES 3.0

The core profile of OpenGL 3.2+ removed the ability to use client-side vertex arrays.
OpenGL ES 2.0 does allow the use of client-side vertex arrays, as do all higher versions of ES. However, the vertex shader input variable gl_VertexID (added in GLSL ES 3.00) is undefined when using client-side arrays. Oh, and client-side vertex arrays in ES 3.0 are mentioned in appendix F.1: Legacy Features. About them, it says:
The following features are present to maintain backward compatibility with OpenGL ES 2.0, but their use in not recommended as it is likely for these features to be removed in a future version.
While I wouldn't expect them to ever go away, clearly you are being advised not to use them.
As to the question of whether VAOs can work with client-side pointers at all, yes (when client-side pointers are supported at all, of course). VAOs always store vertex array state, no matter where those arrays come from. Calling glVertexAttribPointer with a client-side pointer will store the pointer inside the current VAO, just like it would store the buffer object+offset inside the VAO.

As an appendix to the accepted answer, you can 'kind of' emulate client arrays with UBO/SSBO.
On the other hand, it should not be too hard to implement your own 'client pointer' implementation via a hidden VBO and glBufferData.

Related

How does glDrawArrays know what to draw?

I am following some begginer OpenGL tutorials, and am a bit confused about this snippet of code:
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); //Bind GL_ARRAY_BUFFER to our handle
glEnableVertexAttribArray(0); //?
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); //Information about the array, 3 points for each vertex, using the float type, don't normalize, no stepping, and an offset of 0. I don't know what the first parameter does however, and how does this function know which array to deal with (does it always assume we're talking about GL_ARRAY_BUFFER?
glDrawArrays(GL_POINTS, 0, 1); //Draw the vertices, once again how does this know which vertices to draw? (Does it always use the ones in GL_ARRAY_BUFFER)
glDisableVertexAttribArray(0); //?
glBindBuffer(GL_ARRAY_BUFFER, 0); //Unbind
I don't understand how glDrawArrays knows which vertices to draw, and what all the stuff to do with glEnableVertexAttribArray is. Could someone shed some light on the situation?
The call to glBindBuffer tells OpenGL to use vertexBufferObject whenever it needs the GL_ARRAY_BUFFER.
glEnableVertexAttribArray means that you want OpenGL to use vertex attribute arrays; without this call the data you supplied will be ignored.
glVertexAttribPointer, as you said, tells OpenGL what to do with the supplied array data, since OpenGL doesn't inherently know what format that data will be in.
glDrawArrays uses all of the above data to draw points.
Remember that OpenGL is a big state machine. Most calls to OpenGL functions modify a global state that you can't directly access. That's why the code ends with glDisableVertexAttribArray and glBindBuffer(..., 0): you have to put that global state back when you're done using it.
DrawArrays takes data from ARRAY_BUFFER.
Data are 'mapped' according to your setup in glVertexAttribPointer which tells what is the definition of your vertex.
In your example you have one vertex attrib (glEnableVertexAttribArray) at position 0 (you can normally have 16 vertex attribs, each 4 floats).
Then you tell that each attrib will be obtained by reading 3 GL_FLOATS from the buffer starting from position 0.
Complementary to the other answers, here some pointers to OpenGL documentation. According to Wikipedia [1], development of OpenGL has ceased in 2016 in favor of the successor API "Vulkan" [2,3]. The latest OpenGL specification is 4.6 of 2017, but it has only few additions over 3.2 [1].
The code snippet in the original question does not require the full OpenGL API, but only a subset that is codified as OpenGL ES (originally intended for embedded systems) [4]. For instance, the widely used GUI development platform Qt uses OpenGL ES 3.X [5].
The maintainer of OpenGL is the Khronos consortium [1,6]. The reference of the latest OpenGL release is at [7], but has some inconsistencies (4.6 linked to 4.5 pages). If in doubt, use the 3.2 reference at [8].
A collection of tutorials is at [9].
https://en.wikipedia.org/wiki/OpenGL
https://en.wikipedia.org/wiki/Vulkan
https://vulkan.org
https://en.wikipedia.org/wiki/OpenGL_ES
see links in function references like https://doc.qt.io/qt-6/qopenglfunctions.html#glVertexAttribPointer
https://registry.khronos.org
https://www.khronos.org/opengl
https://registry.khronos.org/OpenGL-Refpages/es3
http://www.opengl-tutorial.org

OpenGL - glVertexAttribPointer with multiple VBOs and VAOs using the same shader

I have multiple VBOs and matching VAOs set up in my rendering engine. I am a bit confused about using glVertexAttribPointer. I have set it and it renders fine but I am curious if I am using one shader (a basic diffuse) with all of these different objects, do I set glVertexAttribPointer each time I create a VAO. I guess what's throwing me is I am trying to figure out if my setting an attribute pointer, is that set in the shader or the vertex array object. I assume it's the vertex array object but am hoping for some clarification.
Vertex attribute pointers are per vertex array object (VAO). The OpenGL 4.3 specification on page 318 in the description of glGetVertexAttribPointerv specifies: The value returned is queried from the currently bound vertex array object.

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.

Opengl, DrawArrays without binding VBO

I am rendering array of points with a custom vertex shader.
Shaders looks like:
void mainVP()
in varying int in_vertex_id : VERTEXID
{
foo(in_vertex_id);
}
So the only thing I need - is vertex id.
But I need a lot of vertices and I don't want to store fake VBO for them (it takes around 16mb of memory).
I tried to run my code without binding any VBO. It works.
So my rendering looks like:
size_t num_vertices = ...
glDrawArrays(GL_POINTS, 0, num_vertices);
But can I be sure that rendering without binding VBO is safe?
But can I be sure that rendering without binding VBO is safe?
You can't.
The OpenGL specification's core profile (3.2 and above) clearly states that it should be allowed, that you can render with all attributes disabled. The OpenGL specification's compatibility profile or any versions before 3.2 just as clearly state that you cannot do this.
Of course, that doesn't matter anyway. NVIDIA drivers allow you to do this on any OpenGL version and profile. ATI's drivers don't allow you to do it on any OpenGL version or profile. They're both driver bugs, just in different ways.
You'll just have to accept that you need a dummy vertex attribute. However:
But I need a lot of vertices and I don't want to store fake VBO for them (it takes around 16mb of memory).
A dummy attribute would take up 4 bytes (a single float, or a 4-vector of normalized bytes. Remember: you don't care about the data). So you could fit 4 million of them in 16MB.
Alternatively, you could use instanced rendering via glDrawArraysInstanced. There, you just render one vertex, but with num_vertices instances. Your shader will have to use the instance ID, of course.

Using a framebuffer as a vertex buffer without moving the data to the CPU

In OpenGL, is there a way to use framebuffer data as vertex data without moving the data through the CPU? Ideally, a framebuffer object could be recast as a vertex buffer object directly on the GPU. I'd like to use the fragment shader to generate a mesh and then render that mesh.
There's a couple ways you could go about this, the first has already been mentioned by spudd86 (except you need to use GL_PIXEL_PACK_BUFFER, that's the one that's written to by glReadPixels).
The other is to use a framebuffer object and then read from its texture in your vertex shader, mapping from a vertex id (that you would have to manage) to a texture location. If this is a one-time operation though I'd go with copying it over to a PBO and then binding into GL_ARRAY_BUFFER and then just using it as a VBO.
Just use the functions to do the copy and let the driver figure out how to do what you want, chances are as long as you copy directly into the vertex buffer it won't actually do a copy but will just make your VBO a reference to the data.
The main thing to be careful of is that some drivers may not like you using something you told it was for vertex data with an operation for pixel data...
Edit: probably something like the following may or may not work... (IIRC the spec says it should)
int vbo;
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, vbo);
// use appropriate pixel formats and size
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
// draw stuff
Edited to correct buffer bindings thanks Phineas
The specification for GL_pixel_buffer_object gives an example demonstrating how to render to a vertex array under "Usage Examples".
The following extensions are helpful for solving this problem:
GL_texture_float - floating point internal formats to use for the color buffer attachment
GL_color_buffer_float - disable automatic clamping for fragment colors and glReadPixels
GL_pixel_buffer_object - operations for transferring pixel data to buffer objects
If you can do your work in a vertex/geometry shader, you can use transform feedback to write directly into a buffer object. This also has the option of skip the rasterizer and fragment shading.
Transform feedback is available as EXT_transform_feedback or core version since GL 3.0 (and the ARB equivalent).