首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最基本的vbo工作示例

最基本的vbo工作示例
EN

Stack Overflow用户
提问于 2011-02-23 21:31:24
回答 4查看 27.4K关注 0票数 19

我想知道在OpenGL中使用vbo的最简单的方法...我试着运行了一些有效的示例,但被所有其他信息所遮蔽,这真的让我感到困惑……目前这就是我所拥有的

代码语言:javascript
复制
GLuint vboId = 0;
const int trisize = (m_tris.size()/2)*3;//m_tris is an index array for verts and normals
GLfloat* vertices = new GLfloat[trisize];
GLfloat* normals = new GLfloat[trisize];

int j=0;
for (int i=0; i<m_tris.size(); i+=2) {

    normals[j] = m_normals[m_tris[i+1]*3];
    vertices[j++] = m_vertices[m_tris[i]*3];
    normals[j] = m_normals[m_tris[i+1]*3+1];
    vertices[j++] = m_vertices[m_tris[i]*3+1];
    normals[j] = m_normals[m_tris[i+1]*3+2];
    vertices[j++] = m_vertices[m_tris[i]*3+2];
} //im pretty sure this loop is right as its what i used before to display mesh correctly without vbo's using glVertex3f

glGenBuffersARB(1, &vboId);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices)+sizeof(normals), 0, GL_STATIC_DRAW_ARB);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices), vertices);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices), sizeof(normals), normals);

glVertexPointer(sizeof(vertices), GL_FLOAT, 3, 0);
glNormalPointer(GL_FLOAT, 3, (void*)sizeof(vertices));

在render方法中,我有

代码语言:javascript
复制
glDrawArrays(GL_TRIANGLES, 0, this->getTriNum()); //0 is the vboId?

我还有一个运行一次的方法..。

代码语言:javascript
复制
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

当我尝试运行我的代码时,我得到"EXC_BAD_ACCESS“

关于我做错了什么有什么建议吗?或者一个非常简单的vbo实现会非常有帮助

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-23 22:26:41

你所做的看起来是正确的,除了sizeof(顶点)给你的是地址的大小,而不是数组的大小。因此,当您调用glBufferData时,您将分配8个字节,而当您调用glBufferSubData时,您将用顶点数组的前四个字节填充这8个字节,然后使用normals数组的前四个字节填充这8个字节。然后,当您调用glDrawArrays时,第一个索引会导致数组索引越界异常(因此是EXC_BAD_ACCESS)。

代码语言:javascript
复制
// Data
GLuint geometry_array = 0;
GLuint indice_array = 0;

GLfloat *geometry;
GLuint *indices;

您可以以不同的方式执行此初始化,但我将所有数据交错放入一个32字节的顶点数组中。只要正确使用glVertexPointer、glNormalPointer和glTexCoordPointer,您选择的任何设置数组的方法都可以工作。

代码语言:javascript
复制
// Initialize

geometry = new GLfloat[8*num_geometry];
indices = new GLuint[num_indices];

/* Fill geometry: 0, 1, 2 = vertex_xyz 
 *                3, 4, 5 = normal_xyz
 *                6, 7 = tex_coord_uv
 */

glGenBuffers(1, &geometry_array);
glBindBuffer(GL_ARRAY_BUFFER, geometry_array);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*8*num_geometry, NULL, GL_DYNAMIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat)*8*num_geometry, geometry);

glGenBuffers(1, &indice_array);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indice_array);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*num_indices, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(GLuint)*num_indices, indices);

渲染函数分为五个步骤。首先,绑定缓冲区,以便OpenGL知道在哪里可以找到几何体和索引数据。其次,为每种类型的数据启用各种客户端状态。如果省略了其中一个,则不会呈现该类型数据,如果省略了所有数据,则不会呈现整个对象。第三,您必须告诉OpenGL每种类型的数据在您的数组中包含的位置。在这种情况下,32字节的几何数据以12字节的顶点数据开始,因此起始偏移量应为零或NULL。由于每个顶点-法线-纹理坐标组合都是32字节,这就是步长。"sizeof(GLfloat)8“表示距离偏移量为NULL的32个字节,将会有另一个顶点xyz组。在法线的情况下,每个正常的xyz组在顶点xyz组的偏移量之后12个字节,因此"(float)(sizeof(GLfloat)*3)“作为起始偏移量。同样,步长是32字节。第四,你必须告诉它绘制所有与索引数组相关的三角形。最后,您应该禁用客户端状态,以防您希望使用不同的呈现方法。

代码语言:javascript
复制
//Render
// Step 1
glBindBuffer(GL_ARRAY_BUFFER, geometry_array);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indice_array);

// Step 2
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);

// Step 3
glTexCoordPointer(3, GL_FLOAT, sizeof(GLfloat)*8, (float*)(sizeof(GLfloat)*5));
glNormalPointer(GL_FLOAT, sizeof(GLfloat)*8, (float*)(sizeof(GLfloat)*3));
glVertexPointer(3, GL_FLOAT, sizeof(GLfloat)*8, NULL);

// Step 4
glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_INT, NULL);

// Step 5
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
票数 24
EN

Stack Overflow用户

发布于 2011-02-23 21:37:04

This is a VBO tutorial with an working example。这个例子看起来很简单,所以你可以把它作为参考。

票数 3
EN

Stack Overflow用户

发布于 2016-10-11 19:18:43

OpenGL - VBO, Shader, VAO有一个简单的例子,它展示了基于VBO的渲染所需的API调用的基本序列。该示例从传统的即时模式过渡到基于着色器的现代渲染。

示例代码可以在Github project OpenGl-Render上访问,并且可以在Windows和Linux上运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5091570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档