2015-10-04 69 views
1

我使用OpenGL在几个不同的对象中绘制数组。每个对象都绘制不同的数据,但对于每个对象,数据的容器/位置在程序的整个生命周期内保持不变。 OpenGL的告诉我,我有很多冗余状态的呼叫:冗余状态调用OpenGL

  • glBindFramebuffer
  • glUniformMatrix4fv
  • glUniform4fv
  • glBindRenderbuffer
的这些,我只显式调用glUniformMatrix4fv和glUniform4fv

。看到这个之后,我试着移动它们,以便在OpenGL的设置过程中只调用它们,但是数组并没有被绘制。

这是目前的每次重绘什么时间获取调用示例:

glBindVertexArrayOES(_vertexArray); 
glUseProgram(_program); 
glUniformMatrix4fv(_mvpMatrixHandle,1,0,_mvpMatrix.m); 
glUniform4fv(_colorHandle,1,colors); 
glDrawArrays(GL_TRIANGLE_FAN,0,4); 




问题

  1. 由于变量的容器和位置我我传递给这些函数,每次为给定对象绘制数组或者在开始时只绘制一次数组时,是否需要调用这些函数该节目的宁?如果是这样,我该怎么做?

  2. 如何消除这些我没有明确调用的其他冗余状态调用?

回答

1

如果该值没有变化,则传递给着色器的任何数据都只能传递一次。虽然完全有可能,但我会建议你不要仅仅因为这样的代码难以维护而这样做。如果在某些时候你选择改变矩阵,那么它会给你重组带来麻烦。所以,只有在非常晚期的发展状态下才会这样做,而只有在需要获得业绩的时候(不过这并不会造成很大的差别)。还有其他的方法来处理这些东西,但冷杉...

如果移动矩阵调用时不绘制对象,然后矩阵不正确设置或更多可能的情况是你忘记使用着色器程序之前电话。 (glUseProgram(_program);

既然你说你自己没有绑定缓冲区,仍然可以使用一些更高级别的工具,比如GLKView(控制器),它可以在内部为你做。你将无法失去这些警告,我建议你根本不要使用这些工具。从GLKit中唯一有用的是我的经验中的矩阵和一些矢量操作。

那么关于你的多余通话和“其他方式”。有些人做的是检查发送到着色器的当前状态,并比较新值是否与当前值不同。这并不像看起来那么容易,因为一些值应该是每着色器和一些每个上下文。例如,如果启用alpha混合,它将影响所有着色器,您应该检查并分配上下文对象的值。另一方面,如果您要设置矩阵等制服,则应该检查并将其分配到正在使用的着色器上。这需要一些工作,但值得它来获得一个漂亮的干净的代码:您应该为着色器对象和上下文对象创建包装。这些也应该分配前进行的某些参数的状态,他们被分配时,检查新值:

- (void)setMatrix:(GLKMatrix4)matrix 
{ 
    if(memcmp(currentMatrix.m, matrix.m, sizeof(matrix.m)) != 0) { // will return 0 if they are the same 
     memcpy(currentMatrix.m, matrix.m, sizeof(matrix.m)); // copy the new data 
     glUniformMatrix4fv(_mvpMatrixHandle, 1, 0, matrix.m); // send data to shader 
    } 
} 

这应该那么对你正在使用的所有调用来完成。即使每次调用它都会阻止任何多余的调用,但由于内存比较,会在CPU上产生小的开销。这仍然是非常小的开销。

+0

太棒了,谢谢。这是一个很好的解释。 –