OpenGL顶点缓冲区对象

时间:2013-06-25 13:32:38

标签: c++ opengl opengl-3

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

1 个答案:

答案 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);

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