[ARB_direct_state_access] Problems with VAO - Blank Screen

Hey,

Finally got myself an OpenGL 4.5 capable hardware and I have been playing around with the DSA.

Yet, I can’t seem to get a simple rendering example to work.

For instance I have converted the following old code (_vao = vertex array object, _vbo = buffer object):


        glBindVertexArray(_vao);
        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0 , nullptr);
        glEnableVertexAttribArray(0);

into:


        glEnableVertexArrayAttrib(_vao, 0);
        glVertexArrayAttribBinding(_vao, 0, 0);
        glVertexArrayAttribFormat(_vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
        glVertexArrayVertexBuffer(_vao, 0, _vbo, 0, 0);

The contents of the buffer are vertices for a sphere which are later drawn with glDrawArrays().

If I use the old approach with the DSA style glCreate* functions for the VAO and buffer, it works fine. However if I switch to the new approach (based on the code in https://www.opengl.org/registry/specs/ARB/direct_state_access.txt examples sections), I get a blank screen.

Do i need to update my shaders to compile with #version 450?

Am i missing something crucial?

Thanks!

Are you binding the VAO before launching your batch call (glDrawArrays)?

Yes, I am.

Later in the code. If I leave everything else unchanged, it revert the code to the old approach and use a mix of DSA and non-DSA it works. As soon as I use pure DSA i get a blank screen.

I’m using Linux (mint 17) with at GTX 750TI and NVidia binary drivers 346.35.

I am creating an OpenGL 4.5 Core context via SDL 2.0.3.

Edit: I am also running with the debug output enabled and neither it nor glGetError() report anything along the execution of the program.

Full code:


glCreateBuffers(1, &_vbo);
glCreateVertexArrays(1, &_vao);
...
glNamedBufferStorage(_vbo, p_entry->entry.size, p_entry->ptr, 0);
...
/* 
// if i use this code it works
glBindVertexArray(_vao);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0 , nullptr);
glEnableVertexAttribArray(0);
*/

// if i use this code i get a blank screen
glEnableVertexArrayAttrib(_vao, 0);
glVertexArrayAttribBinding(_vao, 0, 0);
glVertexArrayAttribFormat(_vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexArrayVertexBuffer(_vao, 0, _vbo, 0, 0);

...

glBindVertexArray(_vao);
glDrawArrays (GL_TRIANGLES, 0, p_model->header().nVertices);


output from glxinfo:


glxinfo | grep OpenGL
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce GTX 750 Ti/PCIe/SSE2
OpenGL core profile version string: 4.3.0 NVIDIA 346.35
OpenGL core profile shading language version string: 4.30 NVIDIA via Cg compiler
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 4.5.0 NVIDIA 346.35
OpenGL shading language version string: 4.50 NVIDIA
OpenGL context flags: (none)
OpenGL profile mask: (none)
OpenGL extensions:



OpenGL core profile version string: 4.3.0 NVIDIA 346.35
OpenGL core profile shading language version string: 4.30 NVIDIA via Cg compiler

OpenGL version string: 4.5.0 NVIDIA 346.35
OpenGL shading language version string: 4.50 NVIDIA

Huh? That would seem to be a contradiction.

However, the one piece of information that they do agree on is the driver version 346.35. And… that version only has beta support for 4.5. You should try the more recent 347.09 version, which has full support for 4.5.

[QUOTE=Alfonse Reinheart;1263895]Huh? That would seem to be a contradiction.

However, the one piece of information that they do agree on is the driver version 346.35. And… that version only has beta support for 4.5. You should try the more recent 347.09 version, which has full support for 4.5.[/QUOTE]

I have checked the download site and cannot find the version you speak of. 346.35 is the highest version number I can find, even when checking for beta downloads.

Furthermore, during the day I managed to get this code running on a NVidia Shield Tablet , which also supports opengl 4.5, with android ndk r10d and I also have the same problem.

It’s right there on the “Download drivers” page. Just click the “drivers” button in the upper-left and you’ll find it.

Ah I see now. My main development environment is Linux x86_64 and they only have version 346.35 for that. That link is for the windows version.

Thanks for the info though.

So I found out the correct sequence that should be used get DSA with VAOs to work. (see below). It now works on both my desktop and the shield tablet.

The stride parameter should be the total offset each for all entries in the buffer for one vertex attribute. In my case it was 12 ( 3 * sizeof(float)). If you have more elements in the buffer it should be the sum of both (e.g.: Vec3 + Vec2 : stride = 20).


        glVertexArrayAttribBinding(_vao, 0, 0); // step 1: set attrib binding
        glVertexArrayAttribFormat(_vao, 0, 3, GL_FLOAT, GL_FALSE, 0); // step2: specificy format
        glEnableVertexArrayAttrib(_vao, 0); // step 3: enable the attribe
        glVertexArrayVertexBuffer(_vao, 0, _vbo, 0, 12); // last step: 

BTW, it’s not the order, it’s the stride. You could do all of those in an arbitrary order, and it still should have worked, as long as you passed the right stride. Good catch on the stride though.

The stride issue (now that you pointed it out) is that glVertexAttribPointer is able to compute a tight stride if you pass zero, while glBindVertexBuffer​/glVertexArrayVertexBuffer cannot. So you have to compute it yourself.

I just checked, and I’m rather surprised that those functions don’t give an error for a zero stride. I suppose that it’s reasonable if the VBO is also zero.

[QUOTE=Alfonse Reinheart;1263901]BTW, it’s not the order, it’s the stride. You could do all of those in an arbitrary order, and it still should have worked, as long as you passed the right stride. Good catch on the stride though.

The stride issue (now that you pointed it out) is that glVertexAttribPointer is able to compute a tight stride if you pass zero, while glBindVertexBuffer​/glVertexArrayVertexBuffer cannot. So you have to compute it yourself.

I just checked, and I’m rather surprised that those functions don’t give an error for a zero stride. I suppose that it’s reasonable if the VBO is also zero.[/QUOTE]

Yes, that’s why I was quite puzzled myself.

Regarding the VBO part, are you referring to the _vbo variable (which is set to 1 in my case)?

Not so much the variable as the function parameter itself. That is, under most circumstances, passing a zero stride is not helpful, so I was wondering why OpenGL doesn’t raise an error when it is zero.

But what I realized is that a zero stride is OK if you’re passing 0 for the buffer object at the same time. The purpose in passing a 0 buffer is to remove the vertex buffer binding from that binding index. So if you’re removing a vertex buffer binding, then a zero stride is fine, since you have no buffer for a stride to work with.

[QUOTE=Alfonse Reinheart;1263925]Not so much the variable as the function parameter itself. That is, under most circumstances, passing a zero stride is not helpful, so I was wondering why OpenGL doesn’t raise an error when it is zero.

But what I realized is that a zero stride is OK if you’re passing 0 for the buffer object at the same time. The purpose in passing a 0 buffer is to remove the vertex buffer binding from that binding index. So if you’re removing a vertex buffer binding, then a zero stride is fine, since you have no buffer for a stride to work with.[/QUOTE]

I see. Thanks for the clarification.:slight_smile: