2012-07-03 3 views
4

Проблема:OpenGL шейдер (s) отказывается связывать

изо всех сил, чтобы получить код для загрузки внешних шейдеры и он не работает. Независимо от того, как я переписываю код и повторю попытку, я получаю одну и ту же ошибку каждый раз.

Шейдеры компилируются, но не свяжутся, есть ли что-нибудь, что я делаю неправильно в этой функции? Блокировки ошибок работают отлично.

Fragment shader(s) failed to link, vertex shader(s) failed to link. 
ERROR: error(#280) Not all shaders have valid object code. 
ERROR: error(#280) Not all shaders have valid object code. 

Я использую freeglut, x64 окна 7 и MinGW (и я не используется IDE)

Использование:

В моей основной цикл у меня GLuint programId = loadShader("vertex.shader", "frag.shader"); затем включить его с glUseProgram();

GLuint loadShader(const char * vertex_file_path, const char * fragment_file_path) { 

    GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER); 
    GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); 
    GLuint programId = glCreateProgram(); 

    GLint status = GL_FALSE; 
    int infoLogLength; 
    std::string line = ""; 

    //read in and compile 
    std::string vertexShaderCode = ""; 
    std::ifstream vifs(vertex_file_path); 
    if(!vifs.is_open()) { 

     while(getline(vifs, line)) 
      vertexShaderCode += line +"\n"; 
     vifs.close(); 
    } 

    const char * vertexStream = vertexShaderCode.c_str(); 

    std::string fragmentShaderCode = ""; 
    std::ifstream fifs(fragment_file_path); 
    if(!fifs.is_open()) { 

     while(getline(fifs, line)) 
      fragmentShaderCode += line +"\n"; 
     fifs.close(); 
    } 

    const GLchar * fragmentStream = fragmentShaderCode.c_str(); 

    glShaderSource(vertexShaderId, 1, &vertexStream, NULL); 
    glCompileShader(vertexShaderId); 

    glShaderSource(fragmentShaderId, 1, &fragmentStream, NULL); 
    glCompileShader(fragmentShaderId);  

    glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &status); 
    glGetShaderiv(vertexShaderId, GL_INFO_LOG_LENGTH, &infoLogLength); 
    std::vector<char> vertexShaderErrorMessage(infoLogLength); 
    glGetShaderInfoLog(vertexShaderId, infoLogLength, NULL, &vertexShaderErrorMessage[0]); 
    fprintf(stdout, "%s\n", &vertexShaderErrorMessage[0]); 

    glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &status); 
    glGetShaderiv(fragmentShaderId, GL_INFO_LOG_LENGTH, &infoLogLength); 
    std::vector<char> fragmentShaderErrorMessage(infoLogLength); 
    glGetShaderInfoLog(fragmentShaderId, infoLogLength, NULL, &fragmentShaderErrorMessage[0]); 
    fprintf(stdout, "%s\n", &fragmentShaderErrorMessage[0]); 

    glAttachShader(programId, vertexShaderId); 
    glAttachShader(programId, fragmentShaderId); 
    glLinkProgram(programId); 
    glUseProgram(programId); 

    glGetProgramiv(programId, GL_LINK_STATUS, &status); 
    glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLogLength); 
    std::vector<char> programErrorMessage(std::max(infoLogLength, int(1))); 
    glGetProgramInfoLog(programId, infoLogLength, NULL, &programErrorMessage[0]); 
    fprintf(stdout, "%s\n", &programErrorMessage[0]); 

    glDeleteShader(vertexShaderId); 
    glDeleteShader(fragmentShaderId); 

    return programId; 
    } 

[vertex.shader]

#version 400 

layout(location=0) in vec4 in_Position; 
layout(location=1) in vec4 in_Color; 
out vec4 ex_Color; 

void main(void) { 
    gl_Position = in_Position; 
    ex_Color = in_Color; 
} 

frag.shader

#version 400 

in vec4 ex_Color; 
out vec4 out_Color; 

void main(void) { 
    out_Color = ex_Color; 
} 
+0

Тест с более простым шейдером, как и найденные [здесь] (http://stackoverflow.com/questions/11122815/opengl-shaders-dont-link-with-shader-program), чтобы выяснить, является ли проблема это шейдер или код загрузки. –

+0

проблема не в шейдере, они отлично работают внутри. просто не когда я пытаюсь загрузить их, и этот пост не был разрешен (он исправил ошибку и получил другую, я не хочу этого), поэтому я создал эту. – iKlsR

ответ

3

Вы только читать файлы, если они не удалось открыть. Прямо сейчас вы передаете пустые строки до glShaderSource.

Измените тест is_open (еще лучше, проверьте good() вместо is_open()), и все будет работать.

Изменить

std::ifstream vifs(vertex_file_path); 
if(!vifs.is_open()) { // <<=== BACKWARDS! 

    while (getline(vifs, line)) 
     vertexShaderCode += line + "\n"; 
    vifs.close(); 
} 

в

{ 
    std::ifstream vifs(vertex_file_path); 
    while(getline(vifs, line)) 
     vertexShaderCode += line +"\n"; 
} 

Поскольку вы пытаетесь прочитать весь файл, посмотрите на некоторые лучшие способы в this question.

+0

Я пробовал оба метода и по-прежнему ту же ошибку, однако я работаю над пустой идеей. Благодарю. – iKlsR

+1

@iKlsR: Что значит «оба» мои методы? Первый - ваш * неправильный * код. В моей, нет никакого теста 'if' вообще, цикл while заботится об этом. –

+0

вы сказали изменить тест is_open() на good() .. я попробовал это, тогда я попробовал опробовать тест if. такая же ошибка. :( – iKlsR