2011-10-10 128 views
3

我試圖找出爲什麼下面GLSL代碼不起作用:GLSL預處理

#ifndef VertexPositionType 
#define VertexPositionType vec3 
#endif 

in StandardVertexShaderInputs { 
    VertexPositionType ds_VertexPosition; 
}; 

vec4 ProjectVertexPosition(in vec4 v); 

vec4 ProjectVertexPosition(in vec3 v); 

void main() { 
    gl_Position = ProjectVertexPosition(ds_VertexPosition); 
} 

着色器拒絕編譯。該信息登錄狀態:

錯誤C1008:未定義的變量「ProjectVertexPosition」

即使它不發出警告的預處理,我得到了預處理符號VertexPositionType不被替換。如果我刪除預處理器定義,一切都很好。現在

,說明書說:

的#define和#undef功能被定義爲是用於具有和不具有宏 參數宏定義C++預處理器的標準。

也許下面這行是不是一個有效的預處理線?

#define VertexPositionType vec3 
+0

你嘗試在多臺機器/驅動程序版本GLSL支持通常比HLSL更酥,你可能已經打了一個壞的驅動程序? – Anteru

+0

編號實際上編譯NVidia 280.26,着色器版本150 ... – Luca

+6

定義「不起作用」 - 無法編譯,無法鏈接,鏈接正常但不運行,還有其他嗎?看看實際的編譯器錯誤(如果有的話)是什麼? –

回答

1

你聲明的重載函數調用ProjectVertexPosition,但是你從來沒有定義的,所以當你去鏈接程序,你會得到不確定的錯誤。這個錯誤可能更有意義的是說'未定義的函數'而不是'未定義的變量'(因爲你聲明它是一個函數),但我猜測鏈接器沒有足夠的信息來知道函數符號和一個可變符號。

這個錯誤可能是從LinkProgram調用,不CompileShader電話來了,無關與預處理或VertexPositionType

+0

不要告訴我的箱子上發生了什麼。你不相信我的分析嗎?它不夠嗎?如果你願意的話,我可以公開所有的步驟來斷言這個問題是關於預處理器的... – Luca

+0

...只是指出它,函數是在另一個着色器對象中定義的,並且錯誤是從CompileShader信息日誌。 – Luca

+4

既然你沒有提供任何有關正在發生的事情的信息,我不得不猜測。你沒有提供足夠的信息來重現這個問題,你所看到的東西似乎與預處理器無關。 –

5

着色器是非法的。 NVIDIA的編譯器可能不會隨地吐痰了正確的錯誤,但你的着色是做了錯誤的事(當然,除了這個事實,你沒有提供#version聲明。我認爲#version 330,但它總是好的是明確約GLSL版本) 。

我只能假設這是一個頂點着色器,因爲你寫gl_Position。輸入接口塊在頂點着色器中爲非法,就像輸出接口塊在片段着色器中非法。 AMD的編譯器是相當更加明確這一點:

ERROR: 0:5: error(#328) interface block should not apply in 'Vertex Shader in'. 
ERROR: 0:14: error(#143) Undeclared identifier ds_VertexPosition 
ERROR: 0:14: error(#202) No matching overloaded function found ProjectVertexPosition 
ERROR: 0:14: error(#160) Cannot convert from 'const float' to 'Position 4-component vector of float' 
ERROR: error(#273) 4 compilation errors. No code generated 

當我刪除的接口塊定義,把它當作只是in VertexPositionType ds_VertexPosition;,它編譯罰款。

如果我刪除了預處理器定義,一切都很好。

然後恭喜你:你找到了一個N​​VIDIA驅動程序的bug。您應該將它報告給它們,因爲頂點着色器中不允許輸入接口塊。

0

你的計劃有兩個主要問題。 #define不是你的問題。第一個問題是您從不提供vec4 ProjectVertexPosition(in vec# v)函數的實現。您需要提供的聲明,例如

vec4 ProjectVertexPosition(in vec3 v) { 
    return normalize(vec4(v, 1.0)); 
} 

,也爲in vec4 v版本。去掉define的原因是修復了你的問題,這是因爲它使着色器忽略了輸入塊,而輸入塊是無效的。在頂點着色器中,你不能使用in塊。相反,使用佈局和結構或制服和結構。對於頂點着色器,您只需使用制服或佈局,而不是純粹的in s。如果你想使用的佈局,做到以下幾點:

layout(location = 0) in VertexPositionType ds_VertexPosition; 

對於C/C++方面,做了以下(其中pointCount是點在你的VAO和點的數量是一個GLfloat *包含以點X1,Y1,Z1,X2,Y2,Z2,X3 ...:

GLfloat* points = (GLfloat*) malloc(pointCount * 3 * sizeof(GLfloat)); 
// Set your points however you want here 

GLuint vao; 
glGenVertexArrays(1, &vao); 
glBindVertexArray(vao); 

GLuint vbo; 
glGenBuffers(1, &vbo); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, 3 * pointCount * sizeof(GLfloat), points, GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 
glEnableVertexAttribArray(0); 
free(points); 

// Now to draw (use whatever programId is returned when you link the program) 
glUseProgram(programId); 
glBindVertexArray(vao); 
glDrawArrays(GL_TRIANGLES, 0, pointCount); 
glUseProgram(0);