我刚刚使用 GLKit 为 iPhone 启动了 OpenGL。我的编程背景几乎只是 Java 和 Objective C,十多年前几乎没有 C、C++ 经验。剩下的只是我如何与指针斗争的遥远记忆——我认为我失败了。
现在似乎一切都回到了我身边......
我参加了Ian Terrel 的一些非常棒的教程系列的迭代,这真的帮助了我(谢谢!!!)。
这个问题是关于代码的以下部分(主要直接取自教程):
@interface AAAShape : NSObject
{
NSMutableData *vertexData;
// ...
}
@property(readonly) int vertexCount;
@property(readonly) GLKVector2 *vertices;
//...
@end
@implementation AAAShape
//...
-(GLKVector2 *)vertices
{
if(!vertexData)
{
vertexData = [NSMutableData dataWithLength:sizeof(GLKVector2)*self.vertexCount];
}
return [vertexData mutableBytes];
}
-(void)renderInScene:(AAAScene *)scene
{
//... Effect Stuff
//...
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, self.vertices);
//...
}
//...
@end
//Using the Shape:
//(AATriangle is of AAAShape and implements the vertextCount with "return 3;")
AAATriangle *triangle = [[AAATriangle alloc]init];
triangle.vertices[0] = GLKVector2Make(2., .0);
triangle.vertices[1] = GLKVector2Make(-2., .0);
triangle.vertices[2] = GLKVector2Make(.0, -3.);
//...
所有这些工作都很好,但后来我在 Apple 的OpenGl 指南中偶然发现了以下内容:
[...],但效率低下。每次调用 DrawModel 时,索引和顶点数据都会复制到 OpenGL ES,然后传输到图形硬件。[...] 会影响性能。[...]您的应用程序应将其顶点数据存储在顶点缓冲区对象 (VBO) 中。[...]
那里建议的代码示例(其他来源显示几乎相同)如下所示:
GLuint vertexBuffer;
void CreateVertexBuffers()
{
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}
后来用:
void DrawModelUsingVertexBuffers()
{
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(vertexStruct), (void*)offsetof(vertexStruct,position));
glEnableVertexAttribArray(ATTRIB_POSITION);
//...
}
我有几个问题:
- 上述性能影响有多大?有必要改代码吗?
- 在上面的第一个代码示例(Ian 的/我的代码)中……到底发生了什么?
- 如果顶点是只读的,为什么可以设置顶点[i],以及在哪里以及如何为顶点分配内存?
- 我可以在哪里将上面的代码(缓冲区创建和绑定的东西)放在 Ian/我的方法中,为什么绑定和绘图之间没有连接(变量是方法调用或其他东西)?