OpenGL顶点缓冲区对象

OpenGL Vertex Buffer Object

本文关键字:对象 缓冲区 顶点 OpenGL      更新时间:2023-10-16

我应该使用GL_COLOR_ARAY将颜色转换为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时,想象一下,现在我想改变颜色变量的一些索引的值,我该怎么做?

您需要三个缓冲区对象。一个用于顶点坐标,一个用于点索引,另一个用于颜色。请注意,顶点缓冲区必须与颜色缓冲区具有相同的长度。如果绘制三角形,索引缓冲区的大小应该可以除以三。到目前为止的理论,现在到您的代码:

// 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。您需要一个额外的颜色缓冲区,索引缓冲区(元素数组缓冲区)只对顶点进行索引(可以说是将顶点连接到三角形)。

完整的例子(我只知道如何管理交错缓冲区布局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);

我希望这能帮助你理解顶点缓冲区等的基本原理;把这个代码粘贴到你的代码库中,但试着理解我在这里做了什么。然后重写你的代码,它完全搞砸了,这表明你不理解基本原理。