Ste*_*nov 0 opengl performance
目前,每次我想切换着色器时,我都会调用此函数(简化):
void switchToShader(ShaderProgram* newProg, Mesh& mesh) {
if(m_currentProg != nullptr) {
m_currentProg->disableAttributeArray("aPos");
}
newProg->enableAttributeArray("aPos");
mesh.vertexPosBuffer()->bind();
glVertexAttribPointer(newProg->attributeLocation("aPos"), 2, GL_FLOAT, false, 0, 0);
newProg->bind();
mesh.indexBuffer()->bind();
m_currentProg = newProg;
}
Run Code Online (Sandbox Code Playgroud)
尽管如此,这似乎是不必要的低效率.
请注意,此功能仅用于支持在具有相同属性数组集的程序之间切换.
理想情况下,我的代码看起来更像这样:
ShaderProgram::ShaderProgram() {
// ...
enableAttributeArray("aPos");
glVertexAttribPointer(newProg->attributeLocation("aPos"), 2, GL_FLOAT, false, 0, 0);
}
void switchToShader(ShaderProgram* newProg, Mesh& mesh) {
mesh.vertexPosBuffer()->bind();
newProg->bind();
mesh.indexBuffer()->bind();
}
Run Code Online (Sandbox Code Playgroud)
但由于显而易见的原因,这不起作用.
请注意,我的类ShaderProgram派生自Qt的QOpenGLShaderProgram.
任何提示如何使我的代码更有效?
我知道我可以使用glBindAttribLocation强制atder数组aPos,在着色器程序初始化时,使用例如位置1,对于我的所有着色器程序,这意味着我enableAttributeArray每帧只能做一次并且可以跳过disableAttributeArray.但这有点不优雅,因为它意味着编写一些额外的代码并通过我任意选择的attrib位置.
我目前正在调查VAO.
编辑:使用glBindAttribLocation和VAO后,我的问题解决了.我的代码现在看起来像这样:
void switchToShader(ShaderProgram* newProg, Mesh& mesh) {
newProg->bind();
mesh.vao()->bind();
m_currentProg = newProg;
}
Run Code Online (Sandbox Code Playgroud)
我甚至可以在此功能之外将着色器程序和VAO彼此独立地绑定.
但这有点不优雅,因为它意味着要编写一些额外的代码
然后把它放在你的着色器中layout(location = #).那不是"不优雅"; 他说"把信息放在哪里".
并通过我任意选择的attrib位置.
然而,你没有"通过我的任意选择属性名称 "的问题.从代码的角度来看,"aPos"和1之间没有区别.您必须为VAO获取该属性的某种标识符.在这两种情况下,您都可以将其硬编码为特定值; 无论是字符串文字还是整数字面意思都没有.
只是如果使用整数,则在更改程序时不必不断重新创建VAO.
QT将VAO命令放入着色器对象的API是错误的,现在您可以看到确切的原因.程序不应负责启用哪些属性或来自哪些属性.
你知道如何解决你的问题.所以解决它.