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

流过昼夜 提交于 2019-11-29 16:46:10
the swine

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.

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);
user3627355

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!