3

私は現在非常に単純な Cocoa (OSX) プロジェクトを持っています。OpenGL の使用の背後にある一般的な概念を把握しようとしています。ビューに三角形を表示することはできましたが、頂点シェーダーとフラグメント シェーダーを書き始めたときに、従来の OpenGL コア プロファイルを実行していることに気付きました。そのため、コンテキストを生成する前に問題のビューのピクセル形式でプロパティを設定して OpenGL 3.2 プロファイルに切り替えましたが、頂点またはフラグメント シェーダーがなくても三角形がレンダリングされません。

nib でインスタンス化されたビューのコントローラー クラスがあります。その-awakeFromNib上で、ピクセル形式とコンテキストを設定します。

NSOpenGLPixelFormatAttribute attr[] =
{
    NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
    0
};
NSOpenGLPixelFormat *glPixForm = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
[self.mainView setPixelFormat:glPixForm];
self.glContext = [self.mainView openGLContext];

次に、VAO を生成します。

glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);

次に、VBO:

glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

g_vertex_buffer_data、そのバッファーの実際のデータは次のように定義されます。

static const GLfloat g_vertex_buffer_data[] = {
    -1.0f, -1.0f, 0.0f,
    1.0f, -1.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
};

実際に描画するためのコードは次のとおりです。

[_glContext setView:self.mainView];
[_glContext makeCurrentContext];
glViewport(0, 0, [self.mainView frame].size.width, [self.mainView frame].size.height);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer);
glVertexAttribPointer(
                      0,
                      3,
                      GL_FLOAT,
                      GL_FALSE,
                      0,
                      (void*)0
                      );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
glFlush();

NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,配列内のをコメントアウトすると、このコードは三角形をうまく描画しますNSOpenGLPixelFormatAttributeが、OpenGL Core Profile 3.2 を有効にするとすぐに黒く表示されます。ここで私が間違っていることを誰かに教えてもらえますか?

編集: この問題は、頂点シェーダーとフラグメント シェーダーをオンにするかどうかに関係なく発生しますが、役立つ場合に備えてシェーダーを次に示します。

頂点シェーダー:

#version 150

in vec3 position;

void main() {
    gl_Position.xyz = position;
}

フラグメント シェーダー:

#version 150

out vec3 color;

void main() {
    color = vec3(1,0,0);
}

プログラムをリンクする直前に、属性の場所をバインドするために次の呼び出しを行います。

glBindAttribLocation(programID, 0, "position");

編集2:

これがまったく役立つかどうかはわかりませんが、プログラムを実行glGetError()して実行しただけで、実際に を呼び出すまではすべて問題ないように見えglDrawArrays()、その後 が返されますGL_INVALID_OPERATION。なぜこれが発生するのかを理解しようとしていますが、まだ運がありません。

4

1 に答える 1

2

私はこれを理解しました、そして悲しいことにそれは私の側の非常にばかげた間違いです。

問題は、3.2 コア プロファイルを使用する場合、頂点シェーダーとフラグメント シェーダーが必要であり、それらなしではレンダリングできないことだと思います。シェーダーで動作しなかった理由は...待ってください...シェーダープログラムをリンクした後、クラスのivarにprogramIDを保存するのを忘れていたので、後でglUseProgram()を呼び出すとゼロパラメータで呼び出すだけです。

混乱の主な原因の 1 つは、頂点シェーダーやフラグメント シェーダーがなくても 3.2 コア プロファイルが機能することを期待していたことです。

于 2012-10-28T17:32:11.233 に答える