opengl es VBO用法 - 无几何渲染
Posted
技术标签:
【中文标题】opengl es VBO用法 - 无几何渲染【英文标题】:opengl es VBO usage - no geometry rendering 【发布时间】:2012-10-02 13:50:45 【问题描述】:我正在尝试为我的渲染代码设置 VBO 以获得更多 fps。它适用于顶点位置、颜色和纹理坐标的单独 VBO,但在传输到交错的顶点数据后,没有几何渲染。 这是我的设置函数:
const GLsizeiptr data_size = NUMBER_OF_CUBE_VERTICES * 9 *sizeof(float);
// allocate a new buffer
glGenBuffers(1, &cubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, data_size, data, GL_STATIC_DRAW);
float* ptr = (float*)data;
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), (ptr + 0));
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), (ptr + 3));
glEnableVertexAttribArray(ATTRIB_COLOR);
glVertexAttribPointer(ATTRIB_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), (ptr + 7));
glEnableVertexAttribArray(ATTRIB_TEXCOORD0);
glGenBuffers(1, &cubeIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUMBER_OF_CUBE_INDICES*sizeof(GLubyte), s_cubeIndices, GL_STATIC_DRAW);
数据数组如下所示:
static float data[] =
// position // // color // //UV//
-1.0, +1.0, +1.0, 255,0,0,255, 0,0,
-1.0, -1.0, +1.0, 0,255,0,255, 0,0,
+1.0, +1.0, +1.0, 255,0,255,255, 0,0,
+1.0, -1.0, +1.0, 255,0,0,255, 0,0,
+1.0, +1.0, +1.0, 255,0,0,255, 0,0,
+1.0, -1.0, +1.0, 255,0,0,255, 0,0,
+1.0, +1.0, -1.0, 255,255,0,255, 0,0,
+1.0, -1.0, -1.0, 255,0,0,255, 0,0,
+1.0, +1.0, -1.0, 255,0,255,255, 0,0,
+1.0, -1.0, -1.0, 255,255,0,255, 0,0,
-1.0, +1.0, -1.0, 0,255,0,255, 0,0,
-1.0, -1.0, -1.0, 255,0,0,255, 0,0,
-1.0, +1.0, -1.0, 0,0,255,255, 0,0,
-1.0, -1.0, -1.0, 255,0,0,255, 0,0,
-1.0, +1.0, +1.0, 255,255,0,255, 0,0,
-1.0, -1.0, +1.0, 255,0,0,255, 0,0,
;
这是我的渲染代码:
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeIBO);
glDrawElements(GL_TRIANGLE_STRIP, NUMBER_OF_CUBE_INDICES, GL_UNSIGNED_BYTE, s_cubeIndices);
我还尝试在没有索引缓冲区的情况下使用 DrawArrays 函数,但结果是相同的 - 没有渲染几何图形。 当我的程序运行时,输出窗口中也有 GLError 1282。 如有任何帮助,我将不胜感激,谢谢。
【问题讨论】:
由于我没有看到Vertex
的定义,sizeof(struct Vertex)
是否会等于sizeof(GLfloat)*9
(该数据数组中每个顶点的步幅)?
这是顶点结构: struct Vertex GLfloat x, y, z; GLfloat r, g, b, a; GL浮动 u, v; ;所以是的,它只是 GLFloat*9
【参考方案1】:
当您使用缓冲区对象时,glVertexAttribPointer 的最后一个参数应该偏移到您需要的数据。例如,您的 ATTRIB_VERTEX 数组将从偏移量 0 开始,ATTRIB_COLOR 数组从偏移量 sizeof(float) * 3 开始(因为 position 需要三个浮点数),等等...
当您不使用缓冲区对象,而是使用顶点数组时,您必须通过调用将当前绑定的缓冲区对象解除绑定到 GL_ARRAY_BUFFER 目标
glBindBuffer(GL_ARRAY_BUFFER, 0);
【讨论】:
OpenGL 文档说 glVertexAttribPointer 的最后一个参数是指向数组中第一个通用顶点属性的第一个组件的指针。并且 sizeof(float) * 3 只给出从数组开头的偏移量,这不是我需要的。 文档还详细说明:“如果在指定通用顶点属性数组时将非零命名缓冲区对象绑定到 GL_ARRAY_BUFFER 目标,pointer
将被视为缓冲区对象的数据存储。”【参考方案2】:
好的,我使用 glVertexPointer 和 glEnableClientState 函数让它工作了。但是对于 glVertexAttribPointer 和 glEnableVertexAttribArray 由于某种原因仍然没有几何图形渲染。 现在代码如下所示: VBO 初始化:
struct Vertex
GLfloat x, y, z;
GLubyte r, g, b, a;
;
......
const GLsizeiptr data_size = NUMBER_OF_CUBE_VERTICES *sizeof(struct Vertex);
glGenBuffers(1, &cubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, data_size, vertices, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, sizeof(struct Vertex), (GLvoid*)((char*)NULL));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(struct Vertex), (GLvoid*)offsetof(struct Vertex, r));
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
渲染:
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, NUMBER_OF_CUBE_VERTICES);
如果我切换到 glVertexAttribPointer / glEnableVertexAttribArray,我不知道为什么这段代码不起作用。有任何想法吗?也许我需要将指向和启用功能从初始化部分移动到渲染部分?
【讨论】:
顺便说一句,glVertexAttribPointer 函数是否比 glVertexPointer 更好?谢谢。 两者的区别在于 glVertexPointer 用于指定顶点的坐标,而 glVertexAttribPointer 可以为顶点指定任何数据,如颜色、纹理坐标、法线和 ofc、坐标(位置)。不同之处还在于 glVertexAttribPointer (仅!)与顶点和/或片段着色器结合使用,而 glVertexPointer 通常用于固定功能管道。您可以坚持使用 OpenGL 1.1(固定功能)或学习 GLSL 并使用着色器。 我想这是来自 ios OpenGL 模板的代码。所以 ATTRIB_VERTEX 和 ATTRIB_COLOR 只是顶点着色器的输入变量的位置。这些不是 OpenGL 宏。 谢谢,我有照片了以上是关于opengl es VBO用法 - 无几何渲染的主要内容,如果未能解决你的问题,请参考以下文章
Android OpenGL ES 2. 0 VBO 不渲染