2012-01-07 50 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