我在玩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开始。
我在这里缺少什么?在过去的两天里,我无法弄清楚出了什么问题,所以我来到这里寻求一些指针和指导。
提前谢谢。
答案 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中应该只有四种颜色,因为您使用相同的索引缓冲区来引用顶点和颜色缓冲区。