2012-06-20 101 views
3

我想添加着色器GLFW/GLEW。OpenGL着色器沒有鏈接着色器程序

我得到的是,着色器加載錯誤,但他們沒有有效的目標代碼。

這是我的代碼有裝載着色器:

class SHADER { 
public: 

void LoadShaders(const char *vertexFile, const char *fragmentFile); 

char *vertexShader; 
char *fragmentShader; 

private: 

int Load(const char *filename, char*&shaderSource); 
fstream file; 
}; 

int SHADER::Load(const char *filename, char *&shaderSource) { 
file.open(filename, ios::in); 
if(file.is_open()) { 
    file.tellg(); 
    file.seekg(0,ios::end); 
    unsigned long len = file.tellg(); 
    file.seekg(ios::beg); 

    if(len == 0) { 
     return -2; 
    } else { 
     shaderSource = new char[len + 1]; 
     file.read(shaderSource,len); 
     file.close(); 
     printf("%s\n",shaderSource); 
    } 
} else { 
    return -1; 
} 
return 0; 
} 

void SHADER::LoadShaders(const char *vertexFile, const char *fragmentFile) { 
int resultVertex = this->Load(vertexFile, vertexShader); 
int resultFragment = this->Load(fragmentFile, fragmentShader); 
if(resultVertex ==0 && resultFragment ==0) { 
    printf("Shaders loaded succesfully.\n"); 
} 
if(resultVertex == -2) { 
    printf("VertexShader is empty!\n"); 
} 
if(resultFragment == -2) { 
    printf("FragmentShader is empty!\n"); 
} 
if(resultVertex == -1) { 
    printf("Unable to load VertexShader!\n"); 
} 
if(resultFragment == -1) { 
    printf("Unable to load FragmentShader!\n"); 
} 
} 

這是初始化着色器代碼:

SHADER Shaders; 
GLhandleARB vertexShader, fragmentShader, shaderProgram; 

Shaders.LoadShaders("vertexShader.vert","fragmentShader.frag"); 

const char* vertTemp = Shaders.vertexShader; 
vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); 
glShaderSourceARB(vertexShader, 1, &vertTemp, NULL); 
glCompileShaderARB(vertexShader); 
traceShaderInfoLog(vertexShader); 

const char* fragTemp = Shaders.fragmentShader; 
fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); 
glShaderSourceARB(fragmentShader, 1, &fragTemp, NULL); 
glCompileShaderARB(fragmentShader); 
traceShaderInfoLog(fragmentShader); 

delete[] Shaders.vertexShader; 
delete[] Shaders.fragmentShader; 

shaderProgram = glCreateProgramObjectARB(); 
glAttachObjectARB(shaderProgram,vertexShader); 
glAttachObjectARB(shaderProgram,fragmentShader); 
glLinkProgramARB(shaderProgram); 
traceProgramInfoLog(shaderProgram); 

glUseProgramObjectARB(shaderProgram); 

這是vertexShader.vert和fragmentShader.frag:

void main(){ 
gl_Position = ftransform(); 
} 
void main(){ 
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
} 

這是當我打印日誌我的錯誤,我得到這個非常奇怪的符號在電子第二是每次腳本我重新編譯其他符號:

void main(){ 
    //gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
    gl_Position = ftransform(); 
}┘ 
void main(){ 
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
}♣ 
Shaders loaded succesfully. 
Vertex shader was successfully compiled to run on hardware. 

Fragment shader failed to compile with the following errors: 
ERROR: 0:3: error(#132) Syntax error: '<' parse error 
ERROR: error(#273) 1 compilation errors. No code generated 

Fragment shader(s) were not successfully compiled before glLinkProgram() was called. 
Link failed. 
+0

怪異的性格來源於未能追加NUL(你離開房間,但從來沒有寫過最後一個字符)。在'Shader :: LOAD'中,設置'shaderSource [len] = 0;'。 –

+0

當我設置'shaderSource [len] = 0;' – tversteeg

回答

4

你的負擔的功能是最有可能的問題:簽名應該速戰速決讀

int SHADER::Load(const char *filename, char *&shaderSource) // Note the & 

。你在這個函數中分配內存並重新指定指針 - 你只能將源代碼加載到那個地址 - 但是它永遠不會離開函數。

編譯器最有可能得到一個空字符串由於內存被初始化爲零(你在調試運行呢?),並不會失敗,因爲這是有時沒關係。但鏈接器注意到沒有任何代碼可以鏈接!

+0

另外,你不應該釋放()你新建的內存,但你應該刪除它。並且SHADER類的析構函數將會在何處執行 - 還要在構造函數中初始化這些指針。或者更好:使用std :: string或任何體面的字符串類。 – ltjax

+0

謝謝,但現在我得到了這個錯誤:'着色器加載成功。 頂點着色器已成功編譯爲在硬件上運行。 片段着色失敗,出現以下的錯誤進行編譯: ERROR:0:3:錯誤(#132)語法錯誤: '<' 解析錯誤 ERROR:錯誤(#273)1個編譯錯誤。未生成代碼 片段着色器在調用glLinkProgram()之前未成功編譯。 鏈接失敗.' – tversteeg

+2

您是否按照Ben Voigt的建議添加了零終止字符?打印源代碼時,你還有那些奇怪的字符嗎?在讀取像這樣的文件時,你應該添加std :: ios :: binary標誌來打開(),這樣tellg就可以像你期望的那樣工作。 – ltjax

0

當它失敗鏈接,檢索鏈接錯誤日誌,其中可能有更多的線索。

glGetProgramInfoLog

+0

我使用glGetProgramInfoLog,並導致錯誤:錯誤(#280)不是所有着色器都有有效的對象代碼 錯誤:錯誤(#280 )不是所有的着色器都有有效的目標代碼 ' – tversteeg