【发布时间】:2013-11-15 18:17:08
【问题描述】:
在 iOS 上的 OpenGL ES 2.0 程序中,我按如下方式编译着色器:
setShaderState(state);//enables or disables GL_BLEND
GLuint vertexShader = compileShaderPart(vertexShader, GL_VERTEX_SHADER, state);
GLuint fragmentShader = compileShaderPart(fragmentShader, GL_FRAGMENT_SHADER, state);
//linking
GLuint programHandle = glCreateProgram();
Assert(programHandle != 0, "Program handle 0");
for(auto shaderAttribute : shaderAttributeList){
if(isVertexAttribute(shaderAttribute.attribute())){
glBindAttribLocation(programHandle, shaderAttribute.attribute(), shaderAttribute.attributeName(1).c_str());
}
}
glAttachShader(programHandle, vertexShader);
glAttachShader(programHandle, fragmentShader);
glLinkProgram(programHandle);
Assert(glGetError() == GL_NO_ERROR, "Could not link program");
GLint linkSuccess;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
if (linkSuccess == GL_FALSE) {
GLchar messages[256];
glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);
ELog << messages;
Assert(0, "Error compiling shader");
}
ShaderUniformHandleMap shaderUniformMap;
Shader *shader = new Shader(programHandle, availableShader.name, shaderUniformMap, state);
glUseProgram(programHandle);
auto mesh = Mesh::load("quad");
shader->bindMesh(mesh);
auto temp_texture = Texture2D::load("checker");
for(auto uniform : shader->texture){
glUniform1i(uniform.handle, shader->bindTexture(temp_texture->textureId()));
}
glDrawElements(GL_TRIANGLES, mesh->indexDataSize(), GL_UNSIGNED_SHORT, 0);
为了便于阅读,我将统一读取部分留了出来,而 compileShaderPart 函数尽可能简单明了。
在仪器中的 openGL ES Analyzer 中运行应用程序会导致数百次出现“在预热阶段之外编译的着色器”问题。 glDrawElements 调用不应该解决这个问题吗?
我了解到像 GL_Blend 这样的更改状态会产生这种影响,因此我编译了两次相同的着色器,一次启用 GL_Blend,一次禁用,但没有任何区别。
这里有什么问题?我还发现很难找到有关这些预热内容的信息,到目前为止,我已经收集到着色器只是在第一次绘制调用之后才真正编译,这就是我最后绘制那个四边形的原因。
【问题讨论】:
-
据我所知,预热是指提前设置渲染管道。对于 GLSL 着色器,如果实现将编译推迟到第一次使用,那么您可能希望使用着色器绘制场景,但实际上并不显示结果。
-
我们遇到了同样的问题。我们的着色器在主循环之外编译/链接。我们没有在主循环中发生任何着色器编译/链接,但在游戏期间,我们每帧都会看到数百个这样的警告。不知道发生了什么。你找到了吗?
标签: ios compilation opengl-es-2.0 shader instruments