2

編集: このリンクで見つかった Apple による作業コード例: http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html

200 x 200 の正方形の固定グリッドの頂点を作成した後、VBO を使用して頂点を GPU に送信してレンダリングします。頂点の色を更新するにはどうすればよいですか? 何百もの頂点の色が、数フレームごとに頻繁に変化します。

以前、VBO を使用しない問題に取り組みました。頂点と色の配列を作成し、次のコードを使用して頂点をレンダリングしました。配列を更新して頂点の色を変更しましたtriangleColours:

-(void)render {

    glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
    glClear(GL_COLOR_BUFFER_BIT);

    [effect prepareToDraw];

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 2,
                          GL_FLOAT, GL_FALSE, 0, triangleVertices);

    glEnableVertexAttribArray(GLKVertexAttribColor);
    glVertexAttribPointer(GLKVertexAttribColor, 4,
                          GL_FLOAT, GL_FALSE, 0, triangleColours);


    glDrawArrays(GL_TRIANGLES, 0, numTriangleVertices);

    glDisableVertexAttribArray(GLKVertexAttribPosition);
    glDisableVertexAttribArray(GLKVertexAttribColor);
}

上記のコードは機能しましたが、バッテリーを大量に消費したため、現在は VBO で実行しようとしています。頂点の位置は変わらないので、VBO を使用するのが良い選択であることは理解していますが、頂点の色を変更するにはどうすればよいでしょうか。

これは、単一の正方形のみを描画するように簡略化された現在のコードです。

編集:以下のコードを更新して、頂点の色が変更されたときにのみアップロードするようにするにはどうすればよいですか? VBO セットアップ コードと描画コードはどのように変更する必要がありますか? verticesColours の色配列を更新してから glBufferSubData() を呼び出すのはどうですか?

    // Setup vertices and VBO

    // Vertices for a single square

    const Vertex Vertices[] = {

        // position and colour
        {{-20, -20}, {1, 1, 1, 1}},
        {{-20, -20}, {1, 1, 1, 1}},
        {{-20, -20}, {1, 1, 1, 1}},
        {{-20, -20}, {1, 1, 1, 1}},
    };

    const GLubyte Indices[] = {

        0, 1, 2,
        2, 3, 0,
    };

    numIndices = sizeof(Indices)/sizeof(Indices[0]);

    [EAGLContext setCurrentContext:self.context];

    glEnable(GL_CULL_FACE);

    self.effect = [[GLKBaseEffect alloc] init];

    self.effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(-50.0, 50.0,
                                                                 -50.0, 50.0,
                                                                  0.0, 1.0);


    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &_indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);        
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
    glEnableVertexAttribArray(GLKVertexAttribColor);
    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Color));

    glBindVertexArrayOES(0);


// Render

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    [self.effect prepareToDraw];    

    glBindVertexArrayOES(_vertexArray);   
    glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_BYTE, 0);
}
4

1 に答える 1

6

依存します。(素晴らしい言葉ですね。すべての状況に適しています。)

予測不可能な方法で各頂点の色を変更する必要がある場合は、それらを描画するたびに、はい、フレームごとに頂点の色をアップロードする必要があります。頂点位置を独自の (静的) VBO に配置することは良い選択です。これにより、毎回アップロードせずに再利用できるため (システム メモリ <-> GPU メモリ帯域幅は常に貴重な商品です)、変更する必要があるものはすべて、まあ、変わらなければならないでしょう。

ただし、各頂点の色をプログラムで計算できる場合は、頂点シェーダーが役立ちます。(確かに、それらは何のために作られたのでしょう!) 願わくば、各頂点の色は、次のいくつかの組み合わせの関数です。

  1. 頂点ごとの静的データ。これをVBOに一度アップロードして再利用できます。
  2. 配列全体でグローバルな変数データ。これにはシェーダー ユニフォームを使用し、描画ごとに 1 回アップロードするだけです。
  3. プラットフォームがそれをサポートしている場合、おそらく頂点テクスチャですか?

次に、これらの入力から色を計算する頂点シェーダーを作成できます。すべてのフレームで、シェーダーのユニフォームを再指定するだけで済みます。これは通常、合計で 12 程度のフロートです。

したがって、色をどのように変更したいかによって異なります。頂点シェーダーを使用できる場合は、描画ごとにアップロードをスキップできます。頂点シェーダーで実行できない場合、および/または突然変異が複雑すぎるか恣意的である場合は、その CPU 側で実行し、アップロードの弾丸を噛む必要があります。

于 2013-01-29T05:08:16.773 に答える