OpenGL顶点缓冲区对象
OpenGL Vertex Buffer Object
我应该使用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);
我希望这能帮助你理解顶点缓冲区等的基本原理;把这个代码粘贴到你的代码库中,但试着理解我在这里做了什么。然后重写你的代码,它完全搞砸了,这表明你不理解基本原理。
相关文章:
- 在 cpp 中的平面缓冲区中序列化对象
- 在共享缓冲区内存中创建 ::std::string 对象
- Opengl 3/4 : 我可以将相同的缓冲区对象绑定到不同的目标吗?
- 绘制一个对象,比较模具缓冲区的两个不同值
- 如何分配适合容纳 T 类型对象的缓冲区(可能过度对齐、可能有运算符 new 等)
- 如何将带有缓冲区的对象从插件发送到节点线程安全
- 使用 OpengGLES2(角度)从帧缓冲区对象读取
- 使用(非对象)API 时改变表数组C++而不重新创建整个平面缓冲区
- 如何将统一缓冲区对象数组加载到着色器中?
- 将矩阵建模为单个统一缓冲区对象
- 如何将图像缓冲区传递到OpenCV垫子对象
- 为什么存储对象地址在缓冲区中会导致内存泄漏并删除它们
- 在C 中,是否有可能在不兼容类型的std ::向量对象之间传输不同类型的缓冲区
- 多采样框架渲染对象和深度缓冲区
- 我是否需要删除传递给谷歌协议缓冲区(protobuf)的对象
- 如何使用 new 和 delete 与 OpenGL 的缓冲区对象一起使用?
- OpenGL:缓冲区对象/着色器超出范围
- OpenGL-缓冲区更新下一个渲染对象
- FlatBuffers C++从缓冲区转换为对象,仅适用于root_type(而Java具有所有)
- 为什么我的顶点缓冲区对象出现访问冲突错误?