2

我正在玩 OpenGL 顶点颜色。基本上,我画了一个由 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
}

这就是它的样子:

在此处输入图像描述

第一个三角形具有正确的颜色:“红、绿、黄”分别位于“左下、左上、右上”。

但是,第二个三角形没有正确的颜色:“红、黑、黄(?)”而不是“左下、右下、右上”的“红、绿、黄”。

最初,我想也许我错过了颜色数组中的一些颜色值(因此,它出现了“黑色”,因为“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 个元素,正方形的颜色与之前完全一样(第一个三角形具有正确的颜色,但不是第二个三角形)

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 个顶点传入颜色时,它会为两个三角形着色?是不是应该让第一个三角形变成黑色,第二个三角形变成“红、绿、黄”?

似乎颜色数组的前 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);

我没有使用 alpha 值,所以我在顶点数组中有 18 个浮点数(前 9 个浮点数是三角形坐标,最后 9 个浮点数是三角形颜色。顶点数组从位置 0 开始,而颜色数组从位置 36)。

我在这里想念什么?在过去的 2 天里,我无法弄清楚出了什么问题,所以我来到这里寻求一些指导和指导。

先感谢您。

4

1 回答 1

3

当您为颜色调用 glVertexAttribPointer 时,最后一个参数(指针)在您的情况下应该为 0。指针将是从颜色缓冲区(不是顶点数组)开始到重要数据开始的字节偏移量。Color_Cube 中的颜色从字节 0 开始。

当您指定一个 36 字节的指针时,您是说颜色数据从 Color_Cube 的第 36 个字节开始,这实际上是第 4 种颜色。从那时起,只有 3 种颜色。这就是为什么一个角是黑色的:那个顶点没有颜色。当您只用前三种颜色初始化 Color_Cube 时,从第 36 个字节开始就没有颜色了,整个正方形变成黑色。

还:

Vertices_Cube 有 12 个元素,但 Color_Cube 有 18 个。由于 Vertices_Cube 中只有四个顶点,因此 Color_Cube 中应该只有四种颜色,因为您使用相同的索引缓冲区来引用顶点和颜色缓冲区。

于 2013-02-16T03:45:02.250 回答