-6

我应该使用 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 时,想象现在我想更改颜色变量的某些索引的值,我该怎么做?

4

1 回答 1

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

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

我希望这可以帮助您理解顶点缓冲区等的基本原理。请不要将此代码复制并粘贴到您的代码库中,但请尝试理解我在这里所做的事情。然后重写你的代码,它完全搞砸了,这表明你不了解基本原理。

于 2013-06-25T14:47:13.860 回答