0

我刚刚使用 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/我的方法中,为什么绑定和绘图之间没有连接(变量是方法调用或其他东西)?
4

1 回答 1

2
  • 上述性能影响有多大?有必要改代码吗?

如果数据不断变化,那么 VBO 几乎没有什么好处。然而,如果几何图形是静态的,它会产生巨大的差异,因为它节省了 CPU 和 GPU 之间的宝贵带宽,而不是一直复制它。

  • 在上面的第一个代码示例(Ian 的/我的代码)中……到底发生了什么?

用顶点数据填充数组。然后将 OpenGL 中的指针设置为该数据。当 glDraw… 被调用时,指针被取消引用,数据从进程内存到渲染端,在绘图操作中处理。

  • 如果顶点是只读的,为什么可以设置顶点[i],以及在哪里以及如何为顶点分配内存?

因为只有指针是只读的。它指向的变量是读/写

  • 我在哪里可以将上面的代码(缓冲区创建和绑定的东西)放在 Ian/我的方法中

glGenBuffers 和 glBufferData 去创建顶点数据。glVertexPointer 保持在原来的位置。并且 glBindBuffer 在两个站点都使用。

为什么绑定和绘图之间没有联系(变量是方法调用或其他东西)?

我很清楚你这个问题是什么意思。

于 2011-12-08T12:10:50.457 回答