我发现一些特殊的 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.glsl 替换为
varying 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 上运行它。它会立即崩溃。
最佳答案
首先,您提到的这 3 款 iPhone 有 3 种不同的 GPU:
- iPhone 5 -> SGX543
- iPhone 5s -> A7
- iPhone 6/Plus -> A8
这意味着它在 iOS 中可能有不同的驱动程序,glsl shader 编译实现也可能不同,但实际上除了 Apple 的人之外没有人知道。在您这边,这意味着您确实需要在真实设备上运行/调试您的应用程序,而不是软模拟器。
另一方面,您的 iPhone 5/5s/6 Plus 是相同的 iOS 版本,对吗? [我想是的,;)]
回到你的问题,我认为你不应该在你的glsl着色器中使用像c这样的全局变量,因为着色器中没有堆栈/堆存储布局,但大多数变量都是寄存器。
这意味着你的 float a;将保留一个寄存器位置,这是 GPU 中的有限资源!我认为不建议在 glsl 中使用全局变量,或者更明确地说,在大多数程序语言中。
您可以尝试使用如下函数调用来检查有关着色器的状态,以获取有关着色器编译失败的更多详细信息:
glGetProgramiv(program, GL_LINK_STATUS, &link_status);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
glGetProgramInfoLog(program, length, NULL, &log[0]);
希望对您有所帮助。
关于ios - GLSL 代码使应用程序在 iPhone 6 Plus 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27307508/