0

GLKit を使用して、iPhone 用の OpenGL を開始しました。私のプログラミングのバックグラウンドは、10年以上前にC、C++の経験がほとんどなく、JavaとObjective 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 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 の/私のコード) で実際に行われていることは何ですか?
    • 頂点が読み取り専用の場合に vertices[i] を設定できるのはなぜですか?頂点にメモリが割り当てられる場所と方法は?
  • 上記のコード (バッファ作成とバインディングのもの) を Ian の/私のアプローチのどこに置くことができますか? また、バインディングと描画の間に (変数がメソッド呼び出しなどであるという意味で) 接続がないのはなぜですか?
4

1 に答える 1

2
  • 上記のパフォーマンスへの影響はどの程度重要ですか? コードを変更する必要がありますか?

データが絶えず変化している場合、VBO から得られるものはほとんどありません。ただし、ジオメトリが静的である場合は、CPU と GPU の間の貴重な帯域幅を節約して常にコピーしないようにするため、大きな違いが生じます。

  • 上記の最初のコード サンプル (Ian の/私のコード) で実際に行われていることは何ですか?

配列は頂点データで埋められます。次に、OpenGL のポインターがそのデータに設定されます。glDraw… が呼び出されると、ポインターが逆参照され、データがプロセス メモリからレンダリング側にフェッチされ、そこで描画操作で処理されます。

  • 頂点が読み取り専用の場合に vertices[i] を設定できるのはなぜですか?頂点にメモリが割り当てられる場所と方法は?

ポインタだけが読み取り専用だからです。それが指す変数は読み取り/書き込みです

  • 上記のコード(バッファ作成とバインディングのもの)をイアン/私のアプローチのどこに置くことができますか

glGenBuffers と glBufferData は、頂点データの作成に進みます。glVertexPointer はそのままです。glBindBuffer は両方のサイトで使用されます。

そして、バインディングと描画の間に接続がないのはなぜですか (変数を介してメソッド呼び出しまたは何かが行われます)。

私はあなたがその質問で何を意味しているのか確信しています。

于 2011-12-08T12:10:50.457 に答える