web-dev-qa-db-ja.com

GL_INVALID_OPERATIONを発生させるglVertexAttribPointer

非常に基本的なOpenGL3.2(コアプロファイル)アプリケーションをまとめようとしています。三角形の頂点位置を含むVBOを作成することになっている次のコードでは、glVertexAttribPointerの呼び出しが失敗し、OpenGLエラーGL_INVALID_OPERATIONが発生します。これはどういう意味ですか、どうすれば修正できますか?

GLuint vbo, attribLocation = glGetAttribLocation(...);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLfloat vertices[] = { 0, 1, 0, 1, 0, 0, -1, 0, 0 };
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(attribLocation);
// At this point, glGetError() returns GL_NO_ERROR.
glVertexAttribPointer(attribLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
// At this point, glGetError() returns GL_INVALID_OPERATION.
30
robinjam

まず、いくつかの予備知識を邪魔にならないようにしましょう。

glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

これをやめなさい。あなたはすでにコアOpenGLコンテキストを要求しました。上位互換性は必要ありません、そしてそれはあなたのために何もしません。これは、3.0で廃止されたものの、削除されなかったときの古いフラグでした。あなたはそれを必要としません。

しかし、それはあなたの問題を引き起こしていません。これは:

glEnableVertexAttribArray(program.getAttrib("in_Position"));
// A call to getGLError() at this point prints nothing.
glVertexAttribPointer(program.getAttrib("in_Position"), 3, GL_FLOAT, GL_FALSE, 0, 0);
// A call to getGLError() at this point prints "OpenGL error 1282".

まず、ここには明らかなドライバのバグがあります。これは、glEnableVertexAttribArrayalsoGL_INVALID_OPERATIONエラーを発行しているはずだからです。または、チェックしたときに間違えました。

なぜ両方の関数がエラーになるのですか? Vertex Array Object を使用しなかったため。 glEnableVertexAttribArray 現在のVAOの状態を設定します。現在のVAOがないため、エラーが発生します。 glVertexAttribPointer についても同じことが言えます。それらのページの両方のエラーのリストにも含まれています。

互換性のコンテキストではVAOは必要ありませんが、コアのコンテキストでは必要です。あなたが求めたもの。だから...あなたは1つが必要です:

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

それをセットアップのどこかに置くと、プログラムが機能します。

55
Nicol Bolas