我发现一些特殊的GLSL写作风格会让iPhone 6 Plus崩溃而没有任何日志。
例如,如果您编写类似下面的代码的GLSL,它将在glLinkProgram崩溃。
float testFun(float co) {
return co;
}
float a = testFun(0.1);
void main()
{
// your code here
}
但是如果你移动" a"的定义进入一个函数,然后它将正常工作。
这不会发生在iPhone5或5s中。
您可以通过
下载示例项目来重现此错误http://www.raywenderlich.com/3664/opengl-tutorial-for-ios-opengl-es-2-0
然后用
替换SimpleFragment.glslvarying lowp vec4 DestinationColor;
varying lowp vec2 TexCoordOut; // New
uniform sampler2D Texture; // New
precision highp float;
float testFun(float co) {
return co;
}
float a = testFun(0.1);
void main()
{
gl_FragColor = vec4(0.7, 0.5, 0.3, 1.0);
}
并在iPhone 6 Plus上运行它。它会立即崩溃。
答案 0 :(得分:1)
首先,你提到的这3款iPhone有3种不同的GPU:
- iPhone 5 - > SGX543
- iPhone 5s - > A7
- iPhone 6 / Plus - > A8
这意味着它在iOS中可能有不同的驱动程序,glsl着色器编译工具也可能会有所不同,但没有人真正知道除了Apple的人。在您这边,这意味着您真的需要在真实设备上运行/调试您的应用程序,而不是软模拟器。
另一方面,你的iPhone 5 / 5s / 6 Plus在同一个iOS版本上,对吧? [我假设是的,;)]
回到你的问题,我认为你不应该在你的glsl着色器中使用像c这样的全局变量,因为着色器中没有堆栈/堆存储布局,但大多数变量都是寄存器。
这意味着你的浮动a;将有一个注册地点,这是GPU中有限的资源!我认为不建议在glsl中使用全局变量,或者在大多数程序语言中使用更清晰的变量。
您可以尝试使用下面的函数调用检查着色器的状态,以获取有关着色器编译失败的详细说明:
glGetProgramiv(程序,GL_LINK_STATUS和& link_status);
glGetProgramiv(program,GL_INFO_LOG_LENGTH,& length);
glGetProgramInfoLog(program,length,NULL,& log [0]);
希望它有所帮助。
答案 1 :(得分:0)
您的着色器代码包含错误。这一行无效:
float a = testFun(0.1);
在ES 2.0 GLSL规范中," 4.3存储限定符"第29页说(重点补充):
没有存储限定符或仅使用const限定符的全局变量声明可能包含初始值设定项,在这种情况下,它们将在执行main()的第一行之前初始化。 此类初始值设定项必须是常量表达式。
现在问题变成testFun(0.1)
是一个常量表达式。 Section" 5.10常量表达式"第49页澄清:
以下内容不得用于常量表达式:
- 用户定义的功能
着色器编译器崩溃的事实看起来像Apple bug。用它们归档。