GL3: support VB-less vertex shader

GL3 should support vertex shaders which read no input from vertex buffers. Vertex shaders can use gl_VertexID to create an index to sample all inputs from textures.

Not sure if this is allowed in the GL3 spec or not?

Current workaround?

Setup a dummy VBO of just one vertex. Assume driver will allow assumed past end of buffer reads from VBO (even though actual shader doesn’t use/access vertex buffer inputs).

GL3 should support vertex shaders which read no input from vertex buffers. Vertex shaders can use gl_VertexID to create an index to sample all inputs from textures.

Who’s to say that you can’t? You can set vertex attributes (if any) to be static, and call glDrawArrays with whatever number you want.

I’ve wanted this too - it’s sometimes useful to draw things completely procedurally without any input at all. I hope they do away with the requirement of having the vertex attribute array.

EDIT: Korval has a point, this probably is possible with GL3…

I’m not quite sure what you want… The GPU has many hundreds of threads with many cores running in parallel. How does a shader run on one vertex in parallel? Might was well draw using your CPU, wouldn’t it be faster?

No. What we’re talking about is running the vertex shader with some vertex count (and instance count possibly), without any attributes bound. The shader would use gl_VertexID and gl_InstanceID to procedurally transform vertices, instead of pulling data from the gl_Vertex attribute. (Or, as was originally mentioned, use the IDs to pull data from textures instead.)

I understand now. I would think it does bounds checking though.
Another workaround.
Send in 2+ textures:

  1. vertices.
  2. indices to first texture.
    Make one vertex, call glDrawArrays with the one vertex repeated “n” times, use gl_instanceID to index the texture index.
    What’s the advantage though?

I think section of the spec below says you cannot. Of course I could just be reading it wrong.

"
E.1. PROFILES AND DEPRECATED FEATURES OF OPENGL 3.0 page 406

(Bug 3236 in margin on withchanges version)

Client vertex arrays - all vertex array attribute pointers must refer to buffer objects (section 2.9.1). 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.
"

However there is still this, which might be what you are referring to?

"
E.1. PROFILES AND DEPRECATED FEATURES OF OPENGL 3.0 page 405

(Bug 3618 in the withchanges margin)

However, VertexAttrib* and the current vertex attribute state are retained in order to provide default attribute values for disabled attribute arrays.
"

But sounds to me that you cannot have all VBOs off, just ones off will default to VertexAttrib*.

BTW, as a dummy check to confirm my guess, I did at one time try doing this instanced with a single vert per instance, and performance via NVidia drivers was awful as expected (Linux, a bunch of months ago). Of course I could have done many verts per instance, but I wanted worst case.

Since then I’ve been doing lots of drawing without vertex buffers and without instancing (using the one vert in VBO trick), with very good performance. And this whole thing is proving to be extremely useful (for me).

I’ve noticed the same - and it also causes problems when mixing it with transform feedback (seems that only the first instance is recorded, but maybe that’s changed now).

I have found instancing to be useful when drawing a mesh with many triangle strips… I can just store one strip on the GPU, and instance that a bunch of times and transform procedurally in the vertex shader (but this has some duplication along the edges). Of course, if no attributes had to be bound, I could draw the mesh with nothing at all on the GPU - but it isn’t a huge deal.

But sounds to me that you cannot have all VBOs off, just ones off will default to VertexAttrib*.

You could give it a try. It is what you’re looking for, after all.

So what you are saying is bind your dummy one element VBO and then disable it.

So what you are saying is bind your dummy one element VBO and then disable it.

No. I’m saying use one vertex attribute that is not bound to a buffer object or a pointer, but is instead a static value (set with glVertexAttrib3f, for example). Your shader should take one vertex attribute/input, and you should hook it into that particular attrib. Then call glDrawArrays with some number of arrays.

The way I understand it, this section doesn’t say you can’t have a VAO with no VBOs bound. I’m just not sure whether GL3 removes the requirement for an array/buffer bound to attribute 0, like OpenGL ES 2.0 did.