2014-03-27 112 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」