How can I make OpenGL draw something using VBOs in XCODE?

后端 未结 3 785
温柔的废话
温柔的废话 2020-12-21 21:14

Good evening,

Right now I\'m trying to run the following code using Xcode, but it has been impossible so far. The code is a from a simple tutorial I found online, an

相关标签:
3条回答
  • 2020-12-21 21:45

    Since you do not have a shader, OpenGL does not know how to interpret your vertex attribute 0, as it only knows about position, color, etc. but knows nothing about generic attributes. If you want to keep the code shader-free, you need to use the named attributes:

    static void RenderSceneCB()
    {
        glClear(GL_COLOR_BUFFER_BIT);
    
        glEnableClientState(GL_VERTEX_ARRAY); // or GL_NORMAL_ARRAY, etc.
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glVertexPointer(3, GL_FLOAT, GL_FALSE, 0, 0); // or glNormalPointer(), etc.
    
        glDrawArrays(GL_TRIANGLES, 0, 3);
    
        glDisableClientState(GL_VERTEX_ARRAY);
    
        glutSwapBuffers();
    }
    

    Note that your code may actually work on some GPUs as they will map the generic attributes to the same "slots" as the named attributes, and zero would then be interpreted as position (typically NVidia is (errorneously) less strict with these issues and on my GTX 680 the provided code indeed displays a white triangle).

    You can use MiniShader, just put the following code after CreateVertexBuffer();:

    minish::InitializeGLExts(); // initialize shading extensions
    const char *vs =
        "layout(location = 0) in vec3 pos;\n"
        // the layout specifier binds this variable to vertex attribute 0
        "void main()\n"
        "{\n"
        "    gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0);\n"
        "}\n";
    const char *fs = "void main() { gl_FragColor=vec4(.0, 1.0, .0, 1.0); }"; // green
    minish::CompileShader(vs, fs);
    

    Note that writing the vertex shader just like that will likely lead to problems, as no version is specified. The layout qualifier is only available in GLSL 330, but gl_ModelViewProjectionMatrix is deprecated after GLSL 120. So we need to add something like this to the beginning of the vertex shader:

        "#version 140\n" // need at least 140 for GL_ARB_explicit_attrib_location
    
        "#extension GL_ARB_explicit_attrib_location : require\n"
        // required for layout(location)
    
        "#extension GL_ARB_compatibility : require\n"
        // still need gl_ModelViewProjectionMatrix
        // (which is otherwise deprecated after version 120)
        // also, GL_ARB_compatibility is not supported in version 330 (and above)
    

    Alternately, we can just use GLSL 330 (or greater) but then the modelview-projection matrix needs to be passed through an uniform (which also needs to be properly set in the CPU code):

        "#version 330\n"
        "uniform mat4 MVP;\n"
        "layout(location = 0) in vec3 pos;\n"
        "void main()\n"
        "{\n"
        "    gl_Position = MVP * vec4(pos, 1.0);\n"
        "}\n";
    

    Note that this answer is an extended duplicate of my answer to Triangle doesn't render.

    0 讨论(0)
  • 2020-12-21 21:52

    you can see How to set up vertex attributes in OpenGL? You need to bind a VAO before setting attribute pointers.

    0 讨论(0)
  • 2020-12-21 22:05

    You're trying to use generic vertex attributes with the legacy fixed pipeline. I don't think that can work. For the fixed pipeline, you'll also have to use the legacy calls for setting up and enabling the position array. Replace your call to glEnableVertexAttribArray() with this:

    glEnableClientState(GL_VERTEX_ARRAY);
    

    and your glVertexAttribPointer() call with this:

    glVertexPointer(3, GL_FLOAT, 0, 0);
    
    0 讨论(0)
提交回复
热议问题