C ++ OpenGL - 顶点颜色

时间:2013-02-16 01:47:09

标签: c++ opengl

我在玩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
}

这就是它的样子:

enter image description here

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

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

最初,我想也许我错过了颜色数组中的一些颜色值(因此,它显示为“黑色”,因为“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开始。

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

提前谢谢。

1 个答案:

答案 0 :(得分: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中应该只有四种颜色,因为您使用相同的索引缓冲区来引用顶点和颜色缓冲区。