Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Drawing a single point without VAO on NVIDIA and AMD

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2013
    Posts
    4

    Drawing a single point without VAO on NVIDIA and AMD

    Assume I would want to draw a single point on the screen. I prepared a minimalistic test case for this. My initial solutions was the following:

    Code :
    void DisplayWithOutVAO()
    {
      glUseProgram(program);
     
      glVertexAttrib2f(0, 0.0f, 0.0f);
      glDrawArrays(GL_POINTS, 0, 1); // Draw dot at 0,0
     
      glUseProgram(0);
     
      glutSwapBuffers();
    }

    I do not bind any buffers and use glVertexAttrib to set the position of the point. This works well on NVIDIA, but when I tested on AMD I could NOT see the point.

    The alternative is to store the single point in a VBO and create an appropriate VAO:

    Code :
    void DisplayWithVAO()
    {
      glUseProgram(program);
     
      glBindVertexArray(vao);
      glDrawArrays(GL_POINTS, 0, 1); // Draw dot at 0,0
      glBindVertexArray(0);
     
      glUseProgram(0);
     
      glutSwapBuffers();
    }
     
    void InitVAO() {
      glGenBuffers(1, &vbo);
      glGenVertexArrays(1, &vao);
     
      float pos[] = { 0.0f, 0.0f };
     
      glBindVertexArray(vao);
      glEnableVertexAttribArray(0);
      glBindBuffer(GL_ARRAY_BUFFER, vbo);
      glBufferData(GL_ARRAY_BUFFER, 2 * sizeof(float), &pos, GL_DYNAMIC_DRAW);
      glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
      glBindVertexArray(0);
    }

    This way of drawing a SINGLE point works on both NVIDIA and AMD. But I'm not satisfied with the overhead of creating VBO and VAO. Especially if the single point changes its position from frame to frame, the solution without VAO (i.e., using glVertexAttrib) is far more elegant.

    Here are my questions:

    1. Am I allowed to render a single point without using a VAO, but using only glVertexAttrib?
    2. Could it be that the solution without VAO does NOT work on AMD due to a driver problem?
    3. What would be the most practical solution of drawing a single point?

    Thanks for your suggestions and comments!

    I'm working under Ubuntu 12.10 with OpenGL 3 (core). For completeness, here is the full test case:

    Code :
    #include <stdio.h>
    #include <string.h>
    #include <GL/glew.h>
    #include <GL/freeglut.h>
     
    GLint program;
    GLuint vbo;
    GLuint vao;
     
    void DisplayWithOutVAO()
    {
        glUseProgram(program);
     
        glVertexAttrib2f(0, 0.0f, 0.0f);
        glDrawArrays(GL_POINTS, 0, 1); // Draw dot at 0,0
     
        glUseProgram(0);
     
        glutSwapBuffers();
    }
     
    void DisplayWithVAO()
    {
        glUseProgram(program);
     
        glBindVertexArray(vao);
        glDrawArrays(GL_POINTS, 0, 1); // Draw dot at 0,0
        glBindVertexArray(0);
     
        glUseProgram(0);
     
        glutSwapBuffers();
    }
     
    void InitProgram() {
        // Create very simple vertex shader
        const GLchar* vsh_src[] = {"#version 330 \n layout(location=0) in vec2 pos; \n void main() { \n gl_Position = vec4(pos, 0, 1); \n } \n"};
        const GLint vsh_len[] = {strlen(vsh_src[0])};
        GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vsh, 1, vsh_src, vsh_len);
        glCompileShader(vsh);
     
        // Create very simple fragment shader
        const GLchar* fsh_src[] = {"#version 330 \n out vec4 col; \n void main() { \n col = vec4(1, 0, 0, 1); \n } \n"};
        const GLint fsh_len[] = {strlen(fsh_src[0])};
        GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fsh, 1, fsh_src, fsh_len);
        glCompileShader(fsh);
     
        // Create program, attach shaders, and bind frag data location
        program = glCreateProgram();
        glAttachShader(program, vsh);
        glAttachShader(program, fsh);
        glBindFragDataLocation(program, 0, "col");
        glLinkProgram(program);
    }
     
    void InitVAO() {
        glGenBuffers(1, &vbo);
        glGenVertexArrays(1, &vao);
     
        float pos[] = { 0.0f, 0.0f };
     
        glBindVertexArray(vao);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, 2 * sizeof(float), &pos, GL_DYNAMIC_DRAW);
        glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
        glBindVertexArray(0);
    }
     
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
        glutInitWindowSize(1024, 768);
        glutInitWindowPosition(100, 100);
        glutCreateWindow("OpenGL");
     
        glutDisplayFunc(DisplayWithVAO);
     
        GLenum status = glewInit();
     
        InitProgram();
        InitVAO();
     
        glutMainLoop();
     
        return 0;
    }

  2. #2
    Junior Member Regular Contributor
    Join Date
    Dec 2009
    Posts
    206
    The answer actually depends on the GL profile you use. In a core profile the glDrawArrays without bound vertex array should work, but in a compatibility profile the glDrawArrays call *requires* a bound Vertex or VertexAttrib(0) array. So in fact the AMD driver would be correct here.

  3. #3
    Junior Member Newbie
    Join Date
    Feb 2013
    Posts
    4
    I see, I have to check for the correct profile. I added two lines to my test case to force the "core" profile.

    Code :
        glutInitContextVersion (3, 3);
        glutInitContextFlags (GLUT_CORE_PROFILE);

    And indeed the test case works fine when using glVertexAttrib only. So it was no driver problem, but a question of selecting the correct profile.

    Thanks a lot for the advice!

  4. #4
    Junior Member Regular Contributor
    Join Date
    Jun 2012
    Posts
    204
    If you see gl spec 3.2, it requires VAO to use else Drawarrays will throw "GL_INVALID_OPERATION" ..

  5. #5
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,190
    Quote Originally Posted by debonair View Post
    If you see gl spec 3.2, it requires VAO to use else Drawarrays will throw "GL_INVALID_OPERATION" ..
    Only in the core profile (as was said). The compatibility profile doesn't require VAOs.

    If you're running on NVidia, you can get better perf through bindless anyway.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •