2014-03-27 72 views
2

我有点沮丧。我即将使用mac(OS X mavericks)来编写代码。Opengl es 2.0在使用const时,OSX上的GLSL编译失败

我的着色器在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' 

片断着色段:

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)"+ 
.... 

我已经红透的OpenGL规格并没有发现使用const或声明的主变量的一些问题。

感谢您的帮助

+0

确定,即“常量”就是这个道理或这只是一个假设吗? – Springrbua

+1

它在我看来,问题是线'const vec3 light = normalize(vec3(-0.5,-0.8,-1.0));',在那里你设置一个常数值一个函数的结果,着色器编译器可能不知道将其减少到一个常量值,所以你可以用实际的向量归一化它的结果吗? –

+0

是的,你在哪里,这是正常化调用。 Thx很多,你做了我的da年。有趣的是,android GL驱动程序正在处理的不仅仅是桌面系统的驱动程序。请将您的解决方案作为答案发布。 – fky

回答

3

我会在这里重新发布我的意见,使这可能被关闭了,但现在看来,在OS X上的GLSL编译器不喜欢这一行:

const vec3 light = normalize(vec3(-0.5,-0.8,-1.0)); 

计算值被分配给一个常量。它可能不会优化那些其他编译器所做的工作。用它产生的结束向量替换规范化应该解决这个问题。

如果您认为这是一个错误,我建议在http://bugreport.apple.com处提交,因为我知道苹果的OpenGL驱动程序团队确实注意到这样的情况并在过去修复过这些情况。

0

如果您尝试重新分配变量,那么“const”在这里购买的唯一一件编译器错误。作为一种解决方法,你可以删除“const”,而不会引起任何后果。你也可以将这些声明移到main之外。

4

大约凌晨4点不眠,这让我很唠叨,我终于明白了为什么。行为是正确的,并且您可能希望为桌面着色器使用#version 120.解释如下:

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

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

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

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

从Apple编译器相关的错误不幸夹到否则OP的水平滚动我可能会得出这样的结论迟早:(

"ERROR: 0:13: Initializer not allowed”