iPhone Cheetah 3D OpenGL ES顶点缓冲区对象(VBO)示例
我想使用顶点缓冲区对象(VBO)来改进我在OpenGLES1.1 iPhone游戏中对复杂模型的渲染。在读了一些关于某某和这个的帖子之后(http://playcontrol.net/ewing/jibberjabber/opengl_vertex_buffer_object.html)在本教程中,考虑到我的Cheetah 3D导出模型格式,我仍然难以理解VBO以及如何实现它们。有人可以给我一个例子,实现一个VBO,并使用它来绘制我的顶点与给定的数据结构,并解释语法?我非常感谢任何帮助iPhone Cheetah 3D OpenGL ES顶点缓冲区对象(VBO)示例,iphone,opengl-es,vbo,vertex-buffer,Iphone,Opengl Es,Vbo,Vertex Buffer,我想使用顶点缓冲区对象(VBO)来改进我在OpenGLES1.1 iPhone游戏中对复杂模型的渲染。在读了一些关于某某和这个的帖子之后(http://playcontrol.net/ewing/jibberjabber/opengl_vertex_buffer_object.html)在本教程中,考虑到我的Cheetah 3D导出模型格式,我仍然难以理解VBO以及如何实现它们。有人可以给我一个例子,实现一个VBO,并使用它来绘制我的顶点与给定的数据结构,并解释语法?我非常感谢任何帮助 #def
#define body_vertexcount 434
#define body_polygoncount 780
// The vertex data is saved in the following format:
// u0,v0,normalx0,normaly0,normalz0,x0,y0,z0
float body_vertex[body_vertexcount][8]={
{0.03333, 0.00000, -0.68652, -0.51763, 0.51063, 0.40972, -0.25028, -1.31418},
{...},
{...}
}
GLushort body_index[body_polygoncount][3]={
{0, 1, 2},
{2, 3, 0}
}
我在Pro OpenGL ES(Appress)第9章的帮助下编写了以下代码。我正在使用paurelements命令获得EXC\u BAD\u访问权限,我不知道为什么。谁能帮我弄点光吗?谢谢-
// First thing we do is create / setup the index buffer
glGenBuffers(1, &bodyIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO);
// For constrast, instead of glBufferSubData and glMapBuffer,
// we can directly supply the data in one-shot
glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*sizeof(GLubyte), body_index, GL_STATIC_DRAW);
// Define our data structure
int numXYZElements = 3;
int numNormalElements = 3;
int numTextureCoordElements = 2;
long totalXYZBytes;
long totalNormalBytes;
long totalTexCoordinateBytes;
int numBytesPerVertex;
// Allocate a new buffer
glGenBuffers(1, &bodyVBO);
// Bind the buffer object to use
glBindBuffer(GL_ARRAY_BUFFER, bodyVBO);
// Tally up the size of the data components
numBytesPerVertex = numXYZElements;
numBytesPerVertex += numNormalElements;
numBytesPerVertex += numTextureCoordElements;
numBytesPerVertex *= sizeof(GLfloat);
// Actually allocate memory on the GPU ( Data is static here )
glBufferData(GL_ARRAY_BUFFER, numBytesPerVertex * body_vertexcount, 0, GL_STATIC_DRAW);
// Upload data to the cache ( memory mapping )
GLubyte *vboBuffer = (GLubyte *)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
// Caclulate the total number of bytes for each data type
totalXYZBytes = numXYZElements * body_vertexcount * sizeof(GLfloat);
totalNormalBytes = numNormalElements * body_vertexcount * sizeof(GLfloat);
totalTexCoordinateBytes = numTextureCoordElements * body_vertexcount * sizeof(GLfloat);
// Set the total bytes property for the body
self.bodyTotalBytes = totalXYZBytes + totalNormalBytes + totalTexCoordinateBytes;
// Setup the copy of the buffer(s) using memcpy()
memcpy(vboBuffer, body_vertex, self.bodyTotalBytes);
// Perform the actual copy
glUnmapBufferOES(GL_ARRAY_BUFFER);
以下是我得到异常的绘图命令:
// Activate the VBOs to draw
glBindBuffer(GL_ARRAY_BUFFER, bodyVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO);
// Setup drawing
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glClientActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,lightGreyInt);
// Setup pointers
glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0 );
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 12 );
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 24 );
// Now draw the body
glDrawElements(GL_TRIANGLES, body_polygoncount,GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL));
//glDrawElements(GL_TRIANGLES, body_polygoncount, GL_UNSIGNED_SHORT, nil);
//glDrawElements(GL_TRIANGLES,body_polygoncount*3,GL_UNSIGNED_SHORT,body_index);
首先,你的索引缓冲区太小了,你不仅仅有
body\u polygoncount
索引,还有body\u polygoncount*3
。您还弄乱了类型,因为它们很短,所以您需要GLushort
而不是GLubyte
,所以应该是这样
glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*3*sizeof(GLushort),
body_index, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 20 ); //3rd, after 5*4 byte
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0 ); //1st
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 8 ); //2nd, after 2*4 bytes
glDrawElements(GL_TRIANGLES, body_polygoncount*3,
GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL));
然后,你搞乱了属性的偏移,因为你的数据首先包含纹理坐标,然后是法线,然后是每个顶点的位置,它应该是
glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*3*sizeof(GLushort),
body_index, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 20 ); //3rd, after 5*4 byte
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0 ); //1st
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 8 ); //2nd, after 2*4 bytes
glDrawElements(GL_TRIANGLES, body_polygoncount*3,
GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL));
最后,在一个glpaurements
调用中,您没有给出三角形的数量,而是给出元素(索引)的数量,所以应该是
glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*3*sizeof(GLushort),
body_index, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 20 ); //3rd, after 5*4 byte
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0 ); //1st
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 8 ); //2nd, after 2*4 bytes
glDrawElements(GL_TRIANGLES, body_polygoncount*3,
GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL));
否则您的代码看起来是合理的(当然,映射是毫无意义的,您可以再次使用glBufferData
,但我猜您这样做是为了学习),如果您了解它所做的一切,那么就没有更多了
但我想知道,如果您只使用没有VBOs的客户端顶点数组,那么所有这些错误也会发生,我认为OpenGL ES 1.1没有立即模式
glBegin/glEnd
。因此,如果您不知道这些错误,我想知道为什么您的游戏以前在没有VBOs的情况下运行。我无法相信,如果您已经知道顶点数组和OpenGL的其他部分是如何工作的(您提到的OpenGL ES 1.1游戏表明了这一点),那么找不到任何学习资源可以很好地解释这一点。你也可以看一下,但是你问题中的链接教程看起来很合理(不过我只是浏览了一下)。你在哪方面有问题?我们不仅仅是为您编写代码。您不了解的数据结构和语法是什么?请尽可能明确,以便我们能够制定合理的答案。我已经粘贴了我的代码,尤其是在使用GLDrawerElements调用呈现交错数据时遇到了问题。我的EXC\u访问权限不好,我非常感谢您的帮助-谢谢-我看到了我的错误。。现在它有意义了。我以前画的是://Draw the Gun-Render and Texture procedure for gunX//glBindTexture(GL_Texture_2D,lightGreyInt);glVertexPointer(3,GL_FLOAT,sizeof(vertexStruct)和插值Verticesgun[0][5]);glTexCoordPointer(2,GL_浮点,sizeof(vertexStruct)和插值VerticesGun[0][0]);glNormalPointer(GL_FLOAT、sizeof(vertexStruct)和插值Verticesgun[0][2]);GLD元素(GL_三角形、gun2_多边形计数*3、GL_无符号_短、gun2_索引);