使用 const 时,OSX 上的 Opengl es 2.0 GLSL 编译失败

fky*_*fky 2 macos opengl-es glsl libgdx osx-mavericks

我有点沮丧。我即将使用 mac(OS X 小牛)进行编码。

我的着色器在 windows 7 和 android 下运行良好。当我在 OS X 下运行我的应用程序时,我在运行时遇到以下编译器错误。

Exception in thread "LWJGL Application" java.lang.IllegalStateException: ERROR: 0:6: Initializer not allowed
ERROR: 0:6: Use of undeclared identifier 'light'
ERROR: 0:6: Use of undeclared identifier 'spec'
ERROR: 0:6: Use of undeclared identifier 'spec'
ERROR: 0:6: Use of undeclared identifier 'spec'
Run Code Online (Sandbox Code Playgroud)

片段着色器片段:

 String fragmentShader =   
                "#ifdef GL_ES\n" +
                "precision mediump float;\n" +
                "#endif\n" +
                "uniform sampler2D cubeMap;\n"+
                "uniform sampler2D normalMap;"+                 
                "varying vec2 v_TexCoords;"+

                "void main() {\n"+

                "   const vec4 ambientColor = vec4(1.0, 1.0, 1.0, 1.0);" +
                "   const vec4 diffuseColor = vec4(1.0, 1.0, 1.0, 1.0);"+
                "   const vec3 light =  normalize(vec3(-0.5,-0.8,-1.0));"+

                "   vec3 camDir = normalize(vec3(v_TexCoords,0) - vec3(0.5,0.5,10.0));"+ 
                "   vec4 normalPxl = texture2D(normalMap,v_TexCoords);" +
                "   vec3 normal = normalize(normalPxl.xyz - vec3(0.5,0.5,0.5));"+ 


                "   vec3 reflectDir = reflect(camDir,normal);"+   

                "   float spec = pow(max(0.0,dot(camDir,reflect(light,normal))),4.0);"+
                "   gl_FragColor = vec4(texture2D(cubeMap, reflectDir.xy * 0.5+0.5).xyz,normalPxl.w-0.1)"+
....
Run Code Online (Sandbox Code Playgroud)

我已经通过 OpenGL Specs 发现了使用 const 或在 main 中声明一些变量没有任何问题。

感谢你的帮助

Bra*_*son 5

我将在这里重新发布我的评论,以便可以将其关闭,但 OS X 上的 GLSL 编译器似乎不喜欢这一行:

const vec3 light =  normalize(vec3(-0.5,-0.8,-1.0));
Run Code Online (Sandbox Code Playgroud)

其中计算值被分配给常量。它可能不会像其他编译器那样优化它。用它产生的结束向量替换标准化应该可以解决这个问题。

如果您认为这是一个错误,我建议您将其提交到http://bugreport.apple.com,因为我知道 Apple 的 OpenGL 驱动程序团队确实关注此类情况,并且过去已经修复了它们。


小智 5

凌晨 4 点左右失眠,这一直困扰着我,我终于明白了原因。长话短说:这种行为是正确的,您可能希望将#version 120 用于桌面着色器。解释如下...

这里有两个 GLSL 语言标准,ES 100 和 Desktop 110。与版本号相反,100 在 110 之后被标准化,并且包含 Desktop 120 的一些(但不是全部)功能。

这里有两个语义特征,一个是标记为 const 的局部变量的初始化,另一个是应用于常量参数的内置函数的常量性。因此,我们需要查看两个不同特性的两个不同规范以了解行为。

100 和 110 都只允许使用常量表达式初始化 const 局部变量(100 §4.3.2“const 声明的初始化器必须是一个常量表达式”和 110 §4.3.2“const 声明的初始化器必须由文字值构成,其他 const 变量(不包括函数调用参数 [原文如此]),或这些变量的表达式。”)。GLSL 420 中放宽了此限制。

100 和 110 的不同在于它们是否允许内置函数参与常量表达式。110 没有(第 4.3.3 节,“操作数是整型常量表达式的表达式,包括构造函数,但不包括函数调用。”)但 100 没有(第 5.10 节,“[...] 一个内置函数调用,其参数都是常量表达式,纹理查找函数除外。”)。此限制在 GLSL 120 中的桌面上放宽。

不幸的是,来自 Apple 编译器的相关错误夹在 OP 的水平滚动中,否则我可能会更快得出这个结论:(

"ERROR: 0:13: Initializer not allowed”
Run Code Online (Sandbox Code Playgroud)