2014-07-10 36 views
0

我开发了一个使用OpenGL和GLSL的小型3D引擎。简单地对使用OpenGL和GLSL的性能好奇

这里的渲染代码的一部分:

void video::RenderBatch::Render(void) 
{ 
    type::EffectPtr pShaderEffect = EffectManager::GetSingleton() 
     .FindEffectByName(this->m_pMaterial->GetAssocEffectName()); 

    pShaderEffect->Bind(); 
    { 
     ///VERTEX ATTRIBUTES LOCATIONS. 
     { 
      pShaderEffect->BindAttribLocation(scene::VERTEX_POSITION, "VertexPosition"); 
      pShaderEffect->BindAttribLocation(scene::VERTEX_TEXTURE, "VertexTexture"); 
      pShaderEffect->BindAttribLocation(scene::VERTEX_NORMAL, "VertexNormal"); 
     } 
     //SEND MATRIX UNIFORMS. 
     { 
      glm::mat3 normalMatrix = glm::mat3(glm::vec3(this->m_ModelViewMatrix[0]), 
       glm::vec3(this->m_ModelViewMatrix[1]), glm::vec3(this->m_ModelViewMatrix[2])); 

      pShaderEffect->SetUniform("ModelViewProjMatrix", this->m_ModelViewProjMatrix); 
      pShaderEffect->SetUniform("ModelViewMatrix", this->m_ModelViewMatrix); 
      pShaderEffect->SetUniform("NormalMatrix", normalMatrix); 
     } 
     this->SendLightUniforms(pShaderEffect); //LIGHT MATERIALS TO BE SENT JUST ONCE */ 

     pShaderEffect->SendMaterialUniforms(//SEND MATERIALS IF CHANGED 
      this->m_pMaterial->GetName()); 

     this->m_pVertexArray->Lock(); 
     { 
      this->m_pIndexBuffer->Lock(); 
      { 
       RenderData renderData = this->GetVisibleGeometryData(); 
       { 
        glMultiDrawElements(GL_TRIANGLES, (GLsizei*)&renderData.count[0], GL_UNSIGNED_INT, 
         (const GLvoid **)&renderData.indices[0], renderData.count.size()); 
       } 
      } 
      this->m_pIndexBuffer->Unlock(); 
     } 
     this->m_pVertexArray->Unlock(); 
    } 
    pShaderEffect->Release(); 
} 

我发现功能“SetUniform”的调用创建FPS(超过1000 FPS的巨大损失,而不使其+ - 65 FPS吧! )。只需一个简单的调用这个函数就足够了!

这里的功能“这个 - > SetUniform”(矩阵4×4)的代码:

void video::IEffectBase::SetUniform(char const *pName, glm::mat4 mat) 
{ 
    int location = glGetUniformLocation(this->m_Handle, pName); 
    if (location >= 0) 
     glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(mat)); 
} 

在现实中只是功能“glGetUniformLocation”或函数“glUniformMatrix4fv”我只想有一个号召FPS的这种损失。使用此功能的独特呼叫超过1000 FPS到65 FPS是否正常?然而,缓冲区绑定或着色器程序绑定没有这样的效果! (如果我评论所有'SetUniform'调用,即使使用所有绑定(状态更改),我仍然拥有超过1000个FPS!)。所以,为了总结这种情况,我需要将统一的信息发送到着色器程序(矩阵和材料数据等等)的所有功能似乎对帧速率有巨大的影响。然而在这个例子中,我的场景只由一个独特的立方体网格组成!没有什么可怕的渲染GPU!

但我不认为这个问题来自于GPU,因为我的程序就可以了影响仅仅是可笑的(根据“GPUShark”):

enter image description here

,只有6%!但只是显示窗口(没有几何图形)就足以达到6%!所以我的魔方渲染对GPU几乎没有任何影响。所以我认为这个问题来自于CPU/GPU数据传输......我认为使用这些功能损失性能是正常的,但是从1000 FPS到65 FPS却是不可思议!而只是画一个简单的几何图形!

使用这种发送数据的方法,有没有一种方法可以获得更好的性能,或者是否有这种FPS丢失的正常情况?

您对此有何看法?

非常感谢您的帮助!

回答

2

每次您需要设置制服的价值时,请勿拨打glGetUniformLocation。对于给定的着色器,统一的位置不会改变(除非您重新编译它),因此在编译着色器后查找制服一次,并保存用于Render函数的位置值。

+0

哦,确实有效,编译后我会保存一次。这只是因为函数'glGetUniformLocation'的调用。函数glUniformXXX的影响非常小(我仍然有超过1000个FPS使用它们)。非常感谢您的帮助!再见。 – user1364743

+1

你也可以去掉'BindAtttribLocation()'调用。他们在这里没有任何效果。在链接着色器程序以产生任何效果之前,需要调用glBindAttribLocation()。 –