【问题标题】:OpenGL sending vertex pointers or generating buffersOpenGL 发送顶点指针或生成缓冲区
【发布时间】:2011-12-08 11:15:25
【问题描述】:

我刚刚使用 GLKit 为 iPhone 启动了 OpenGL。我的编程背景几乎只是java和objective c,十多年前对C、C++的经验很少。剩下的只是关于我如何与指针斗争的遥远记忆——我认为我失败了。

现在好像一切都回到了我的身边......

我参加了great, great tutorial series of 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 Guide 中偶然发现了以下内容:

[...],但效率低下。每次调用 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/我的方法中我可以将上面的代码(缓冲区创建和绑定的东西)放在哪里,为什么绑定和绘图之间没有连接(变量是方法调用或其他东西)?

【问题讨论】:

    标签: iphone performance opengl-es buffer glkit


    【解决方案1】:
    • 上述性能影响有多大?需要改代码吗?

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

    • 上面的第一个代码示例(Ian 的/我的代码)中真正发生了什么?

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

    • 如果顶点是只读的,为什么可以设置顶点[i] 以及为顶点分配内存的位置和方式?

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

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

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

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

    我知道你这个问题是什么意思。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      相关资源
      最近更新 更多