2012-01-07 47 views
3

我遇到了着色器加載代碼的問題。讓我感到困惑的奇怪之處在於,它可能會在5次之內運行一次,但後來只有一些作品。例如,它會加載碎片着色器,但紋理將無法正常工作(它會在幾何圖形上畫出紋理的奇怪外觀)。我認爲問題出在加載代碼,所以這就是我的問題。任何人都可以發現我在下面的代碼中找不到的錯誤?OpenGL着色器加載失敗

char* vs, * fs; 

vertexShaderHandle = glCreateShader(GL_VERTEX_SHADER); 
fragmentShaderHandle = glCreateShader(GL_FRAGMENT_SHADER); 

long sizeOfVShaderFile = getSizeOfFile(VERTEX_SHADER_FILE_NAME); 
long sizeOfFShaderFile = getSizeOfFile(FRAGMENT_SHADER_FILE_NAME); 

if(sizeOfVShaderFile == -1) 
{ 
    cerr << VERTEX_SHADER_FILE_NAME<<" is null! Exiting..." << endl; 
    return; 
} 
if(sizeOfFShaderFile == -1) 
{ 
    cerr << FRAGMENT_SHADER_FILE_NAME<<" is null! Exiting..." << endl; 
    return; 
} 

vs = readFile(VERTEX_SHADER_FILE_NAME); 
fs = readFile(FRAGMENT_SHADER_FILE_NAME); 

const char* vv = vs, *ff = fs; 

glShaderSource(vertexShaderHandle , 1, &vv, NULL); 

cout << "DEBUGGING SHADERS" << endl; 
cout << "VERTEX SHADER: "; 
printShaderInfoLog(vertexShaderHandle); 
cout << endl; 

glShaderSource(fragmentShaderHandle, 1, &ff, NULL); 

cout << "FRAGMENT SHADER: "; 
printShaderInfoLog(fragmentShaderHandle); 
cout << endl; 


glCompileShader(vertexShaderHandle); 

cout << "VERTEX SHADER: "; 
printShaderInfoLog(vertexShaderHandle); 
cout << endl; 

glCompileShader(fragmentShaderHandle); 

cout << "FRAGMENT SHADER: "; 
printShaderInfoLog(fragmentShaderHandle); 
cout << endl; 


programHandle = glCreateProgram(); 

cout << "DEBUGGING PROGRAM" << endl; 

glAttachShader(programHandle, vertexShaderHandle); 

printProgramInfoLog(programHandle); 

glAttachShader(programHandle, fragmentShaderHandle); 

printProgramInfoLog(programHandle); 


glLinkProgram(programHandle); 

printProgramInfoLog(programHandle); 

glUseProgram(programHandle); 

printProgramInfoLog(programHandle); 


delete[] vs; delete[] fs; 

這裏的READFILE功能:

char* readFile(const char* path) 
{ 
    unsigned int fileSize = getSizeOfFile(path); 

    char* file_data = new char[fileSize]; 

    ifstream input_stream; 

    input_stream.open(path, ios::binary); 

    input_stream.read(file_data, fileSize); 

    input_stream.close(); 
    //this is deleted at the end of the shader code 
    return file_data; 
} 

下面所有的消息是來自完全相同的可執行文件(不重建)。

這裏的第一種可能的錯誤消息:

BallGLWidget::initializeGL called 
DEBUGGING SHADERS 
VERTEX SHADER: 
FRAGMENT SHADER: 
VERTEX SHADER: ERROR: 0:17: '<' : syntax error syntax error 


FRAGMENT SHADER: 
DEBUGGING PROGRAM 
ERROR: One or more attached shaders not successfully compiled 

ERROR: One or more attached shaders not successfully compiled 

glGetError enum value: GL_NO_ERROR 

另一種可能的錯誤消息:

BallGLWidget::initializeGL called 
DEBUGGING SHADERS 
VERTEX SHADER: 
FRAGMENT SHADER: 
VERTEX SHADER: ERROR: 0:17: 'tt' : syntax error syntax error 


FRAGMENT SHADER: ERROR: 0:33: '?' : syntax error syntax error 


DEBUGGING PROGRAM 
ERROR: One or more attached shaders not successfully compiled 

ERROR: One or more attached shaders not successfully compiled 

這裏的輸出時,它的工作原理(在5或6次也許1)

BallGLWidget::initializeGL called 
DEBUGGING SHADERS 
VERTEX SHADER: 
FRAGMENT SHADER: 
VERTEX SHADER: 
FRAGMENT SHADER: 
DEBUGGING PROGRAM 
Image format is GL_RGB 
Checking textures... 
glGetError enum value: GL_NO_ERROR 

我認真地懷疑它的着色器本身,因爲他們有時候會這樣做......並且報告的錯誤是垃圾。

如果有更多的信息會有幫助,我會很樂意提供。

編輯:這裏的着色器

頂點着色器:

attribute vec2 a_v_position; 
attribute vec2 a_tex_position; 

varying vec2 tex_coord_output; 


void main() 
{ 
    tex_coord_output = a_tex_position; 

    gl_Position = vec4(a_v_position, 0.0, 1.0); 
} 

片段着色器:

varying vec2 tex_coord_output; 

uniform sampler2D ballsampler; 


void main() 
{ 
     gl_FragColor = texture2D(ballsampler, tex_coord_output); 
} 
+1

我們可以看看實際的着色器嗎? – 2012-01-07 09:36:48

+0

當然,我將它們發佈在編輯中 – Prime 2012-01-07 09:51:11

+0

您可以檢查ifstream.read()調用的返回值以確保您正在閱讀的數據是實際數據,並且由於某種原因它不會失敗?您的初始化似乎一目瞭然,錯誤似乎表明它可能正在讀取流中的垃圾數據(如果在這種假設下,我的錯誤會再次檢查您的代碼) – 2012-01-07 09:54:56

回答

2

您正在閱讀的文件,但據我可以看你是不是零終止文本。嘗試分配文件大小+ 1並將最後一個字符設置爲零。

+0

謝謝!就是這樣!太好了,我從來沒有想到這一點。 – Prime 2012-01-07 10:30:25

+0

零終止,或提供glShaderSource與數據的長度。 – datenwolf 2012-01-07 12:39:51

4

你的問題的Getting garbage chars when reading GLSL files重複,這裏是我的answer它:


您使用C++,所以我建議你利用這一點。而不是讀成自分配的字符數組,我建議你讀入的std :: string:

#include <string> 
#include <fstream> 

std::string loadFileToString(char const * const fname) 
{ 
    std::ifstream ifile(fname); 
    std::string filetext; 

    while(ifile.good()) { 
     std::string line; 
     std::getline(ifile, line); 
     filetext.append(line + "\n"); 
    } 

    return filetext; 
} 

,可自動完成所有的內存分配和適當界定的 - 關鍵詞是RAII:資源分配初始化。稍後你可以上傳着色器源代碼,如

void glcppShaderSource(GLuint shader, std::string const &shader_string) 
{ 
    GLchar const *shader_source = shader_string.c_str(); 
    GLint const shader_length = shader_string.size(); 

    glShaderSource(shader, 1, &shader_source, &shader_length); 
} 

void load_shader(GLuint shaderobject, char * const shadersourcefilename) 
{ 
    glcppShaderSource(shaderobject, loadFileToString(shadersourcefilename)); 
} 
+0

非常感謝你的代碼片段!爲我節省了大量的工作! – newprogrammer 2012-02-27 07:35:14