Running a vertex shader without any per-vertex attribute

Hi all,
First up I tried to find a similar post but could not so i thought I would post it in.

Basically, I have already implemented this but I want to know the inner workings of glDrawArrays fucntion as regards the per-vertex attributes when rendering a set of points.

I have an entirely vertex shader based particle system that uses no per-vertex attributes in the vertex shader ( iuse vertexID so dynamically position the particle). It works on both ATI and NVIDIA hardware without a problem (I have tested it with the latest drivers for both vendors)

The application side I generate and bind a vertex array object.


glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID);

If I call the glDrawArrays function after this setup only, it works on NVIDIA hardware however on ATI it does not work (no errors but my particles dont show up). So, I added in a buffer object and enabled attribute 0 and vertexattribarray like this


glGenBuffers(1, &vboVerticesID); 
glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID);
glBufferData (GL_ARRAY_BUFFER, 1, 0, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,1,GL_UNSIGNED_BYTE, GL_FALSE,0,0);

If I call the glDrawArrays after this setup, it works on both ATI and NVIDIA hardware.

So I want to know

  1. why is it so that when I invoke glDrawArrays call without the buffer object, enable vertex attrib/vertex attrib pointer call, I get nothing on screen on ATI but these calls seem redundant on NVIDIA hardware (looks like a driver bug to me)?
  2. Even though I pass in 1 byte in my buffer object, what other attributes will glDrawArray pass to my vertex shader when I have not given any myself? When i have explicitly enabled vertex attrib 0, and passed 1 byte to it, will pass 1 value but what about the values for other 99 particles when I make a glDrawArrays call like this glDrawArrays(GL_POINTS,0, 100);?

PS: Really sorry if this seems stupid.
Thanks,
Mobeen

Are you using the latest AMD drivers? If so, then it is a driver bug (assuming you’re using a core OpenGL context). Once that I was pretty sure they’d fixed.

When i have explicitly enabled vertex attrib 0, and passed 1 byte to it, will pass 1 value but what about the values for other 99 particles when I make a glDrawArrays call like this glDrawArrays(GL_POINTS,0, 100);?

Well, you get undefined behavior, up to and including application termination or GPU failure! Seriously, don’t do that.

If you’re going to use an attribute array, then make sure that there is space there for all of the data you request from glDrawArrays. If you can’t find a way to make AMD drivers play nice with an empty VAO, then you’re going to have to allocate a buffer object big enough to have one byte for each vertex you intend to use. You never need to initialize that data, but you will need to allocate it.

HI Alfonse,
Thanks for the reply.

If you’re going to use an attribute array, then make sure that there is space there for all of the data you request from glDrawArrays.

Even if I dont have the attribute declared and used in the vertex shader? Is it ok to have a vertex shader without an attribute?

Hello,

in old OpenGL (2.1) and thus in compatibility profile, attribute 0 has to be defined. In core, you can live without any attributes. If you need an attribute to work in compatibility, try a fixed value attribute (no buffer data, just one fixed value, see glVertexAttrib) this way you wont have the problem of a too small buffer. It is fine to have a VS without input attributes, in fact, a valid vertex shader can be as small as:

#version 330 core
void main(){}

Try “attribute less rendering” (Attribute-less rendering | RenderingPipeline), IIRC the chapter “Programmable Vertex Pulling” from OpenGL Insights (http://openglinsights.com) covers this idea also.

Hi Menzel,
Ok thanks for the links it makes sense now.

Thanks.
Mobeen