对于这样的简单对象我会做一个大的VBO说200个对象* NrVerticesPerCube,把所有的数据交错的顶点,正常,UV,顶点,正常,UV等
我做的一个关键帧类似在我的游戏海狸的动画,我开始是这样的:
glGenBuffers(1, &vboObjects[vboGroupBeaver]);
glBindBuffer(GL_ARRAY_BUFFER, vboObjects[vboGroupBeaver]);
glBufferData(GL_ARRAY_BUFFER, beaverVerts*8*sizeof(GLfloat), 0, GL_STATIC_DRAW);
vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
NSString *path;
path = [[NSBundle mainBundle] pathForResource:@"beaver01" ofType:@"bin"];
NSFileHandle *model = [NSFileHandle fileHandleForReadingAtPath:path];
float vertice[8];
int counter = 0;
while (read([model fileDescriptor], &vertice, 8*sizeof(float))) {
memcpy(vbo_buffer, vertice, 8*sizeof(GLfloat)); // 0
vbo_buffer += 8*sizeof(GLfloat);
counter++;
}
glUnmapBufferOES(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
这将创建一个具有正确大小我VBO缓冲区(在这种情况下,8 *的sizeof(GLfloat)至极是3绿党,3个法线和2UV ),并将第一个关键帧复制到缓冲区中,您可以对初始对象位置执行相同的操作,或者保留原来的对象位置并计算后者...
然后在每帧中我做2个关键帧之间插入我的海狸的每个顶点,只是做一个绘制调用,这是非常快的4029顶我的海狸,并在60FPS的作品在我的iPhone 3G。
对于你只是做gltranslates它会更简单,只是X,Y,Z值添加到每个立方体的每个顶点。
你会更新它是这样的:
glBindBuffer(GL_ARRAY_BUFFER, vboObjects[vboGroupBeaver]);
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
绑定VBO缓存和mapit地图到缓冲区变种。 计算您想要的临时变量的东西。
memcpy(vbo_buffer, currentVert, 6*sizeof(GLfloat)); // 0
vbo_buffer += 8*sizeof(GLfloat);
复制它和更新缓冲区来下一个对象,重复,直到所有对象更新中... 你也可以做的所有更新在一个单独的阵列和复制整个数组,但你会被复制的额外信息通常不会改变(法线和UV)。或者你可以不使用交错数据和复制...
glUnmapBufferOES(GL_ARRAY_BUFFER);
映射到该VBO缓冲
glVertexPointer(3, GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL));
glNormalPointer(GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
glTexCoordPointer(2, GL_FLOAT,8*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, beaverVerts);
设置你的绘图调用,并绘制了一切......
如果您需要要旋转的对象,而不仅仅是gltranslate他们,你将需要添加一些矩阵乘法沿途...
编辑**
好的,用手做gltranste其实很简单(旋转等等有点棘手)。
我使用的是使用TRIANGLE_STRIP而不是三角形绘制的交错平面,但原理是相同的。
float beltInter[] = {
0.0, 0.0, 0.0, // vertices[0]
0.0, 0.0, 1.0, // Normals [0]
6.0, 1.0, // UV [0]
0.0, 480, 0.0, // vertices[1]
0.0, 0.0, 1.0, // Normals [1]
0.0, 1.0, // UV [1]
320.0, 0.0, 0.0, // vertices[2]
0.0, 0.0, 1.0, // Normals [2]
6.0, 0.0, // UV [2]
320.0, 480, 0.0, // vertices[3]
0.0, 0.0, 1.0, // Normals [3]
0.0, 0.0 // UV [3]
};
所以这是交错的顶点,你有顶点,然后再法线紫外线,如果你不使用纹理代替UV颜色。
最简单的方法是将所有对象都放在一个数组中(如果所有对象都是相同的大小,则容易),并在绘制后更新位置(而不是在opengl框架的中间),更好的是做一个单独的线程,创建2个驻国际中心组织更新他们中的一个,而从其他拉丝,这样的事情:
- 线程1的OpenGL DrawFrom VBO0
- 线程2游戏更新,内部阵列上更新位置,并复制到VBO1 ,设置Var表示VBO1是准备好的(因此,当所有更新完成时,线程1仅从绘图变为VBO1)。
- 线程1的OpenGL DrawFrom VBO1
- 线程2游戏更新,同样的事情,但更新VBO0
- 继续使用相同的逻辑
这就是所谓的双缓冲,你有时用它来garanty稳定,没有这个您的游戏逻辑会在显卡需要时更新VBO,并且显卡将不得不等待,从而导致更低的FPS。
无论如何,回到主题
使相当于的glTranslatef(10,20,30)只是做:
int maxvertices = 4;
float x = 10;
float y = 20;
float z = 30;
int counter = 0;
int stride = 8; // stride is 8 = 3 x vertice + 3 x normal + 2 x UV change to 3 x color or 4 x color depending on your needs
glBindBuffer(GL_ARRAY_BUFFER, vboObjects[myObjects]);
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
while (counter < (maxVertices*8)) {
beltInter[counter] += x; // just sum the corresponding values to each
beltInter[counter+1] += y;
beltInter[counter+2] += z;
memcpy(vbo_buffer, currentVert, 3*sizeof(GLfloat)); // again only copy what you need, in this case only copying the vertices, if your're updating all the data, you can just do a single memcpy at the end instead of these partial ones
vbo_buffer += stride*sizeof(GLfloat); // forward the buffer
counter += stride; // only update the vertex, but you could update everything
}
glUnmapBufferOES(GL_ARRAY_BUFFER);
glVertexPointer(3, GL_FLOAT, stride*sizeof(GLfloat), (GLvoid*)((char*)NULL));
glNormalPointer(GL_FLOAT, stride*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
glTexCoordPointer(2, GL_FLOAT,stride*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, maxVertices);
当然的更新值不必是相同的所有的对象,事实上使用这样的基础数组,你可以随时更新所有信息,只需要将例程在需要时复制到VBO。所有这一切
从上飞记忆写的,所以有可能小龙:-)
希望有所帮助。
感谢您的回答,但它仍然让我感到困惑。我将不得不计算并更新我的游戏对象循环中的VBO,对吗?我应该指出,我的'通用立方体'是一个由72个顶点组成的数组(类似于“1.0,0.0,0.0,...”) - 为了在一个数组中更新VBO,我需要计算基于立方体位置的每个立方体的每个顶点将会是glTranslate偏移量,对吧?我将如何能够存储颜色数据? – ttarik 2012-01-29 03:38:37
是的,你会更新游戏循环中的VBO,每个立方体有72个顶点,所以你看14400个顶点?这对我的4029个顶点来说有点不利,但是我的主要游戏在3G上绘制了更多的顶点,它仍然可以工作。是的,但要做一个翻译,所有你需要做的就是将数值加到每个顶点,这非常快,我在我的插值中使用这种插值要差很多。颜色数据应该交错,我使用的纹理,你会coulou数据,而不是UV映射,并调用适当的glcolorpointer ... – led42 2012-01-29 12:02:19
再次感谢。希望我的最后一个问题,我设置了这一点,并看着我的立方体顶点(http://puu.sh/f3Yz)和呃..我怎么会'总结值到每个顶点',以设置正确的位置?例如,如果我想翻译X +5和Z +10,那么每个顶点必须更改哪些内容? – ttarik 2012-01-30 03:01:46