2

私はOpenGLの頂点の色で遊んでいます。基本的には2つの三角形からなる正方形を描きました。1つ目の三角形は思い通りに色付けできましたが、2つ目の三角形は思ったとおりに色付けされませんでした。私は過去2日間問題を調査してきましたが、それを理解できなかったので、ここでいくつかのガイダンスを求めています。

これが私のコードです:

void Construct_Cube()
{
    //---------------------
    //Init cube's vertices

    float Vertices_Temp[] = 
    {
        0, 0, 0, //bottom-left corner
        0, 1, 0, //top-left
        1, 1, 0, //top-right
        1, 0, 0  //bottom-right
    };

    for(int i = 0; i < (sizeof(Vertices_Temp) / sizeof(GLfloat)); i++)
    {
        Vertices_Cube.push_back(Vertices_Temp[i]);
    }

    //---------------------------
    //Init cube's draw order list
    int tempOrder[] = { 0, 1, 2, 0, 3, 2};

    for(int i = 0; i < (sizeof(tempOrder) / sizeof(int)); i++)
    {
        drawOrder_Cube.push_back(tempOrder[i]);
    }

    //------------------
    //Init cube's color
    Color_Cube.resize(18);

    //Color of each triangle (Red-Green-Yellow)
    for(int i = 0; i < 18;)
    {
        Color_Cube[i++] = 1.0f;
        Color_Cube[i++] = 0.0f;
        Color_Cube[i++] = 0.0f;

        Color_Cube[i++] = 0.0f;
        Color_Cube[i++] = 1.0f;
        Color_Cube[i++] = 0.0f;

        Color_Cube[i++] = 1.0f;
        Color_Cube[i++] = 1.0f;
        Color_Cube[i++] = 0.0f;
    }

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

    //-------------------
    //Buffer for vertices
    glGenBuffers(1, &VBO_Cube_Vertices);
    glBindBuffer(GL_ARRAY_BUFFER, VBO_Cube_Vertices);
    glEnableVertexAttribArray(0);

    //Passing CartesianSys coord data into the ARRAY_BUFFER
    glBufferData(GL_ARRAY_BUFFER, (Vertices_Cube.size())*sizeof(float), &Vertices_Cube[0], GL_STATIC_DRAW);
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); //size = 3 (X,Y,Z)

    //----------------
    //Buffer for color
    glGenBuffers(1, &VBO_Cube_Color);
    glBindBuffer(GL_ARRAY_BUFFER, VBO_Cube_Color);
    glEnableVertexAttribArray(1);

    glBufferData(GL_ARRAY_BUFFER, (Color_Cube.size())*sizeof(float), &Color_Cube[0], GL_STATIC_DRAW);
    glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, (void *)36); //size = 3 (R,G,B)

    glBindVertexArray(0); //Unbind VAO
}

void draw()
{
    glBindVertexArray(VAO_Cube); //Bind VAO
    glDrawElements(GL_TRIANGLES, drawOrder_Cube.size(), GL_UNSIGNED_INT, &drawOrder_Cube[0]);
    glBindVertexArray(0); //Unbind VAO
}

これはそれがどのように見えたかでした:

ここに画像の説明を入力してください

最初の三角形は正しい色でした:「左下、左上、右上」にそれぞれ「赤、緑、黄色」。

ただし、2番目の三角形の色が正しくありませんでした。「左下、右下、右上」の「赤、緑、黄色」ではなく、「赤、黒、黄色(?)」です。

最初は、カラー配列の一部のカラー値を見逃したのではないかと思いました(したがって、「0」がデフォルト値であるため、「ブラック」と表示されました)。ただし、カラー配列(Color_Cube [])は適切に初期化されました。正方形の6つの頂点に対して18のカラー要素があります。

しかし、カラー配列で少し遊んだ後、私は何か奇妙なことに気づきました。

配列の最初の9つの要素のみを初期化すると、正方形がすべて黒になります。

for(int i = 0; i < 9;)
{
    Color_Cube[i++] = 1.0f;
    Color_Cube[i++] = 0.0f;
    Color_Cube[i++] = 0.0f;

    Color_Cube[i++] = 0.0f;
    Color_Cube[i++] = 1.0f;
    Color_Cube[i++] = 0.0f;

    Color_Cube[i++] = 1.0f;
    Color_Cube[i++] = 1.0f;
    Color_Cube[i++] = 0.0f;
}

なぜ真っ黒になったのですか?最初の三角形を着色することになっていましたか?

次に、配列の最後の9つの要素を初期化すると、正方形は以前とまったく同じように色付けされます(1番目の三角形は正しい色になりますが、2番目の三角形は色付けされません)

for(int i = 9; i < 18;)
{
    Color_Cube[i++] = 1.0f;
    Color_Cube[i++] = 0.0f;
    Color_Cube[i++] = 0.0f;

    Color_Cube[i++] = 0.0f;
    Color_Cube[i++] = 1.0f;
    Color_Cube[i++] = 0.0f;

    Color_Cube[i++] = 1.0f;
    Color_Cube[i++] = 1.0f;
    Color_Cube[i++] = 0.0f;
}

最後の3つの頂点の色だけを渡したのに、なぜ両方の三角形が色付けされたのですか?1番目の三角形を黒にし、2番目の三角形を「赤、緑、黄色」にすることになっていましたか?

カラー配列の最初の9つの要素は完全に無視されているように見えました。なぜ???

それで、私はそこで困惑しました。glVertexAttribPointer()のオフセット値を間違えたのではないかと思いました。ただし、これらの関数を再確認したところ、問題は見られなかったか、何かが足りない可能性があります。

//Buffer for vertices
glEnableVertexAttribArray(0);
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);

//Buffer for color
glEnableVertexAttribArray(1);
glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, (void *)36);

アルファ値を使用していないので、頂点配列に合計18個のフロートがあります(最初の9個のフロートは三角形の座標で、最後の9個のフロートは三角形の色です。頂点配列は位置0から始まり、カラー配列は場所36)。

ここで何が欠けていますか?過去2日間、何が悪かったのかわからなかったので、ここに来て、アドバイスとガイダンスを求めました。

前もって感謝します。

4

1 に答える 1

3

色に対してglVertexAttribPointerを呼び出す場合、最後のパラメーター(ポインター)は0である必要があります。ポインターは、カラーバッファー(頂点配列ではない)の先頭から重要なデータの先頭までのバイト単位のオフセットになります。Color_Cubeの色はバイト0から始まります。

36バイトのポインタを指定すると、カラーデータはColor_Cubeの36番目のバイト(実際には4番目の色)から始まることを意味します。この時点から3色しかありません。そのため、1つのコーナーが黒になります。その頂点には色がありません。Color_Cubeを最初の3色だけで初期化すると、36バイト目以降は色がなくなり、正方形全体が黒くなりました。

また:

Vertices_Cubeには12個の要素がありますが、Color_Cubeには18個の要素があります。Vertices_Cubeには4つの頂点しかないため、同じインデックスバッファーを使用して頂点とカラーバッファーを参照しているため、Color_Cubeには4つの色しかありません。

于 2013-02-16T03:45:02.250 に答える