0

私は最近、Opengl VAO を理解する際に問題を抱えていました。現在、VBO を使用して float の配列から三角形を描画するコードがあります。

これがコードです。

float vpp[] = { 0.75f, 0.75f, 0.0f,
                0.75f, -0.75f, 0.0f,
                -0.75f, -0.75f, 0.0f};

// Non Indexed
glGenBuffers(1, &m_mainVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_mainVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vpp), vpp, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_POINTS, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

VAO を実装しようとすると、プログラムは 1 ポイントしか引き出さない。(スクリーン キャップを投稿しますが、できません)。

そして、このコード。

float vp[] = { 0.0f, 0.75f, -0.75f };

//VAO
unsigned short sInds[9] = { 1, 1, 0,
                            1, 2, 0,
                            2, 2, 0};

//Indexed
glGenBuffers(1, &m_mainVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_mainVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vp), vp, GL_STATIC_DRAW);

GLuint elBuf;
glGenBuffers(1, &elBuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elBuf);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 9 * sizeof(unsigned short), sInds, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawElements(GL_POINTS, 3, GL_UNSIGNED_SHORT, sInds);
glDisableClientState(GL_VERTEX_ARRAY);


glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

誰かが私が間違っていることを教えてもらえますか?

4

2 に答える 2

1

あなたのコードは壊れており、それはあなたの「VAO」とは何の関係もありません(またはDatenwolfが指摘したように、VAOの欠如)。

インデックス バッファ内のインデックスが実際に何をするのか理解していないようです。属性 0 を 3 つの浮動小数点値の配列として定義しました。C 用語で、あなたは言った、float attrib0[numberOfPositions][3];. OpenGL が最初のインデックスを確認すると、配列から3 つの値をフェッチします。それはフェッチします:

attrib0[インデックス][0]; attrib0インデックス; attrib0[インデックス][2];

あなたのインデックスは頂点インデックスであり、GL_FLOAT インデックスではありません。配列要素は、それぞれ 1 つの float ではなく、それぞれ 3 つの float です。

あなたがやろうとしていることは、実際には可能でも有用でもありません。また、Datenwolf が指摘したように、VAO とは何の関係もありません (コードで VAO を使用していないため)。VAO とは別のトピックである、インデックス付きレンダリングについて話しているのです。

于 2012-12-04T01:13:01.130 に答える
0

どのOpenGLバージョンを使用していますか?これまでのところ、コードは頂点バッファオブジェクトのみを使用していますが、頂点配列オブジェクトのサポートコードはまだありません。OpenGL-4コアを使用している場合は、最初にVAOを作成する必要があります。そうしないと、何も描画されません。

VAO抽象化を使用する予定がない場合は、コンテキストの作成直後にキャッチオールVAOを作成できます。

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

アップデート:

昨夜は気づかなかったが、ニコル・ボーラは気づいた。2番目のコードスニペットの一部が意味をなさない。vp3つのフロートのみを定義します。現在、頂点シェーダーのセマンティクス(一般的な頂点属性を使用するとシェーダーの使用が義務付けられています)に完全に依存し、これらがどのように解釈されるかが決まります。要素サイズが3のglVertexAttribPointerを呼び出すと、OpenGLに、その頂点属性の各要素に3つのフィールドがあり、それらが一緒にアドレス指定されることが通知されます。

float vp[] = { 0.0f, 0.75f, -0.75f };

              \------------------/ one attribute element

それはあなたの最初の定義でより理にかなっているでしょうvpp

float vpp[] = { 0.75f, 0.75f, 0.0f,

                \----------------/ attribute element 0

                0.75f, -0.75f, 0.0f,

                \-----------------/ attribute element 1

                -0.75f, -0.75f, 0.0f};

                \------------------/ attribute element 2

複数の頂点属性を有効にすると、それらが一緒になっていくつかの属性の長いベクトルを形成します。

glDrawElementsに提供されるインデックスは、個々のフィールドではなく、そのような頂点属性ベクトルをアドレス指定します。

于 2012-12-04T01:02:06.257 に答える