2013-02-16 253 views
2

我在玩OpenGL顶点颜色。基本上,我画了一个由2个三角形组成的正方形。我能够按照我想要的方式为第一个三角形着色,但第二个三角形没有按照我的预期着色。过去两天我一直在研究这个问题,但我无法弄清楚,所以我在这里寻求一些指导。C++ OpenGL - 顶点颜色

这里是我的代码:

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

第1三角形有正确的颜色:分别是 “红,绿,黄” 的“左下,左上,右上“。

但是,第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三角形有正确的颜色,但不是第二个三角形)

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个位置开始)。

我在这里错过了什么?在过去的两天里,我无法弄清楚哪里出了问题,于是我来到这里寻求一些指导和指导。

预先感谢您。

+0

我对颜色属性和偏移有点困惑,但尝试将'tempOrder'改为'{0,1,2,3,0,2}'。 – 2013-02-16 02:32:39

+0

你以我从未见过的方式做了一切。递增for循环中的迭代器。而不是使用跨度交叉指向数据。复杂度+1。 – Kaliber64 2013-02-16 03:18:37

+0

你正在强奸'for'循环......它什么都不执行,可能只会导致错误(例如,你是否曾经意外删除了身体的一条线) – example 2013-02-16 09:19:31

回答

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只有四种颜色,因为使用的是相同的索引缓冲器指顶点和颜色缓冲区。

+0

Bingo!它工作得很好。非常感谢。我现在明白了。 – TATN 2013-02-16 09:24:09