2

複数のオブジェクト (約 200 個のオブジェクト、一度に 15 個のオブジェクトが表示され、それぞれに独自の頂点とインデックス バッファーがある) に対して VAO (頂点配列オブジェクト) を使用すると、混乱が生じます。以下は私のレンダリング関数です

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

glClearColor(0.50f, 0.50f, 0.50f, 1.0f);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

[super drawLines];


for(int i=0; i< self.numberofBars; i++) //numberofBars

{

    // Render the object

    [self.barShaderProg use];

    iVBarNode *temp = [theBars objectAtIndex:i];

    _modelViewProjectionMatrix = GLKMatrix4Multiply(ProjectionView, modelMatrix);
    _modelViewProjectionMatrix =  GLKMatrix4Multiply(_modelViewProjectionMatrix, temp.modelMatrix);
    GLKMatrix4 modeltotalMatrix = GLKMatrix4Multiply(modelMatrix, temp.modelMatrix);
    GLKMatrix4 modelViewMatrix = GLKMatrix4Multiply(ViewMatrix, modeltotalMatrix);

    _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);


    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0,_normalMatrix.m);//
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEW_MATRIX], 1, 0, modelViewMatrix.m);

    glUniform4f(uniforms[COLOR_VECTOR], temp.barColor.r, temp.barColor.g, temp.barColor.b, temp.barColor.a);

    //bind corresponding buffer before drawing
    glBindBuffer(GL_ARRAY_BUFFER, [temp getVertexID]);


    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(12));


    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, [temp getIndexID]);
    glDrawElements(GL_TRIANGLES, [temp.bar getIndicesSize], GL_UNSIGNED_SHORT, (void*)0); 
}


if(self.translation>0)
{
    self.paused = NO;

}
else{
    self.paused = YES;
} 
}

これは完全に正常に機能します。OpenGLES アナライザーで私のコードを分析した後、glVertexAttribPointer 呼び出しが冗長であったため (すべて同じ)、VAO を使用してそれらの恩恵を受けることが示されました。しかし、それらを異なる頂点バッファオブジェクトで使用できるかどうかはわかりません。私がインターネットで見つけたほとんどの例は、1 つまたは 2 つの VBO でそれらを使用しており、2 番目の VBO は同じ属性ではなく別の属性を定義しています。単一のVAOを使用しましたが、以下のように機能しませんでした

-(void) configureVertexArrayObject

{

// Create and bind the vertex array object.

glGenVertexArraysOES(1,&vertexArrayObject);

glBindVertexArrayOES(vertexArrayObject);

for(int i=0;i<self.numberofBars;i++)
{
    iVBarNode *myNode = [theBars objectAtIndex:i];

 glBindBuffer(GL_ARRAY_BUFFER, [myNode getVertexID]);
// Configure the attributes in the VAO
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(12));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, [myNode getIndexID]);

}

// Bind back to the default state.

glBindBuffer(GL_ARRAY_BUFFER,0);

glBindVertexArrayOES(0);

}

これが私がレンダリングする方法です

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

glClearColor(0.50f, 0.50f, 0.50f, 1.0f);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

[super drawLines];

glBindVertexArrayOES(vertexArrayObject);

for(int i=0; i< self.numberofBars; i++) //numberofBars

{

    // Render the object

    [self.barShaderProg use];

    iVBarNode *temp = [theBars objectAtIndex:i];

    _modelViewProjectionMatrix = GLKMatrix4Multiply(ProjectionView, modelMatrix);
    _modelViewProjectionMatrix =  GLKMatrix4Multiply(_modelViewProjectionMatrix, temp.modelMatrix);
    GLKMatrix4 modeltotalMatrix = GLKMatrix4Multiply(modelMatrix, temp.modelMatrix);
    GLKMatrix4 modelViewMatrix = GLKMatrix4Multiply(ViewMatrix, modeltotalMatrix);

    _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);


    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0,_normalMatrix.m);//
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEW_MATRIX], 1, 0, modelViewMatrix.m);

    glUniform4f(uniforms[COLOR_VECTOR], temp.barColor.r, temp.barColor.g, temp.barColor.b, temp.barColor.a);

    //all buffer associated with VAO now

    glDrawElements(GL_TRIANGLES, [temp.bar getIndicesSize], GL_UNSIGNED_SHORT, (void*)0); 
}

  glBindVertexArrayOES(0);

 if(self.translation>0)
 {
     self.paused = NO;


 }
  else{
    self.paused = YES;

 }


}

2 回目の試みでは、頂点と法線に glVertexAttribPointer() を使用して (VBO ID と IBO ID を指定せずに)、レイアウトだけを VAO に指定して、VAO なしで行っていたようにレンダリングしようとしました (上記の最初のレンダリング コード)。すでにVAOに言及しているので、 glVertexAttribPointer() を使用して頂点レイアウトを指定していませんでした(実際、これはVAOを使用する全体のポイントでした)。これらのアプローチの両方で、同じサイズのオブジェクトが得られました何らかの形で VAO がすべてのオブジェクトのジオメトリを複製していると思わせます。私のすべてのオブジェクトのジオメトリは同じですが、高さが異なります。今私が持っている 1 つのオプションは、単一の頂点とインデックス バッファー オブジェクトを持つことであり、高さに沿ってスケーリングし、必要に応じてオブジェクトを配置できます。それでも、VAOが実際に何を保持し、何を保持しないのか、そしてそれを機能させる方法があるかどうかを知りたい.

4

1 に答える 1

3

OpenGLES アナライザーで私のコードを分析した後、glVertexAttribPointer 呼び出しが冗長であったため (すべて同じ)、VAO を使用してそれらの恩恵を受けることが示されました。

glBindBufferあなたの呼び出しが毎回同じバッファをバインドしていない限り、この推論は疑わしいと思います.

すべてのオブジェクトを同じバッファーにパックし、描画時に bind+glVertexAttribPointer 呼び出しを 1 回実行することで、より多くのことを得ることができます。すべてのオブジェクトが同じ頂点フォーマットを持っているため、それができない理由はないようです。頂点インデックスを調整して、現在大きくなったバッファーで適切な位置を選択する必要がありますが、それほど難しくありません。

于 2012-11-14T23:57:16.030 に答える