我应该使用GL_COLOR_ARRAY将颜色转换为VBO吗?我在我的代码中使用过它。除了将顶点转换为VBO之外,我还使用了GL_ARRAY_BUFFER。目的是将颜色和顶点变量都传输到VBO(GPU)。我很困惑,我做了一切来运行这个程序但是
still gives me a segmentation fault.
GLuint vboIds[2];
QVector<QVector3D> vertices;
float* colors;
初始化: 顶点数组的长度为(6 * ANGLE_COUNT = 360 * RANGE_COUNT = 100)
initializeGLFunctions();
// Generate 2 VBOs
glGenBuffers(2, vboIds);
// Transfer vertex data to VBO 0
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
glBufferData(GL_ARRAY_BUFFER, 6 * ANGLE_COUNT * RANGE_COUNT * sizeof(QVector3D), vertices.constData(), GL_STATIC_DRAW);
// Transfer index data to VBO 1
glBindBuffer(GL_COLOR_ARRAY, vboIds[1]);
glBufferData(GL_COLOR_ARRAY, 6 * ANGLE_COUNT * RANGE_COUNT * sizeof(GLushort), colors, GL_STATIC_DRAW);
到目前为止,我将顶点初始化为数组缓冲区到上述长度以及颜色缓冲区。
渲染功能:
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[1]);
int vertexLocation = shaderProgram->attributeLocation("vertex");
shaderProgram->enableAttributeArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 6 * ANGLE_COUNT * RANGE_COUNT * sizeof(vertices.constData()), (const void *)0);
int Color = shaderProgram->attributeLocation("color");
shaderProgram->enableAttributeArray(Color);
glVertexAttribPointer(Color, 2, GL_FLOAT, GL_FALSE, 6 * ANGLE_COUNT * RANGE_COUNT *sizeof(colors), 0);
//glDrawElements(GL_TRIANGLES, 6 * ANGLE_COUNT * RANGE_COUNT, GL_UNSIGNED_SHORT, 0);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
我不明白为什么这个程序无法运行。此外,当我将颜色和顶点传递给VBO时,想象一下我现在想要更改一些颜色变量索引的值,我该怎么做?
答案 0 :(得分:0)
您需要三个缓冲区对象。一个用于顶点坐标,一个用于顶点索引,一个用于颜色。请注意,顶点缓冲区必须与颜色缓冲区具有相同的长度。如果绘制三角形,则索引缓冲区的大小应该可以除以3。到目前为止理论,现在到你的代码:
// Transfer index data to VBO 1
glBindBuffer(GL_COLOR_ARRAY, vboIds[1]);
glBufferData(GL_COLOR_ARRAY, 6 * ANGLE_COUNT * RANGE_COUNT * sizeof(GLushort), colors, GL_STATIC_DRAW);
//...
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[1]);
使用GL_ARRAY_BUFFER
代替GL_COLOR_ARRAY
。
你的颜色需要一个额外的缓冲区,索引缓冲区(element-array-buffer)只是索引顶点(可以说是将顶点连接到三角形)。
完整示例(我只知道如何管理交错缓冲区布局atm,所以我稍微更改了数据设置,我也没有使用索引缓冲区,因为我假设顶点已经按照三角形的方式布局绘):
struct vertexData
{
float x, y, z;
float r, g, b;
};
//...
size_t numVerts = 6 * ANGLE_COUNT * RANGE_COUNT;
vertexData *verts = new vertexData[numVerts];
for(size_t i = 0; i < numVerts; i++)
{
verts[i].x = vertices[i][0];
verts[i].y = vertices[i][1];
verts[i].z = vertices[i][2];
//I assume you have three floats per color per vertex
verts[i].r = colors[i*3+0];
verts[i].g = colors[i*3+1];
verts[i].b = colors[i*3+2];
}
GLuint vboIds[1] = {0};
glGenBuffers(1, vboIds); //only one buffer needed
// Transfer vertex data to VBO 0
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
glBufferData(GL_ARRAY_BUFFER, numVerts * sizeof(vertexData), verts, GL_STATIC_DRAW);
delete[] verts; //no longer needed
//...
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
int vertexLocation = shaderProgram->attributeLocation("vertex");
shaderProgram->enableAttributeArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(vertexData), NULL);
int colorLocation = shaderProgram->attributeLocation("color");
shaderProgram->enableAttributeArray(Color);
glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, sizeof(vertexData), (const char*)(sizeof(float)*3));
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLES, 0, numVerts);
我希望这可以帮助您理解顶点缓冲区的基本原理等。请不要将此代码复制并粘贴到您的代码库中,但要尝试理解我在这里做了什么。然后重写你的代码,这完全搞砸了,这表明你不懂基本原则。