2

I'm trying to compile simple shader on my linux machine with Radeon HD 5470 video card and fglrx AMD driver.

My vertex shader code

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;

void main()
{

    gl_Position.xyz = vertexPosition_modelspace;
    gl_Position.w = 1.0;

}

Read code from file

void Shader::load_from_file(const std::string& file)
{
    std::ifstream is(file, std::ios_base::in);
    if (is.is_open()) {
        std::string line{""};
        while(std::getline(is, line)) {
            // program_code_ is a std::string member
            program_code_ += "\n" + line; 
        }

        is.close();
    } else {
         throw Exception("Could not open shader source code file");
    }       
}

Try to compile

void Shader::build_shader()
{   
    const GLchar* tmp = program_code_.c_str();    
    const GLint tmplen = program_code_.length();

    std::cout << "Shader code: " << tmp << std::endl;

    glShaderSource(shader_handler_, 1, &tmp, &tmplen);
    CHECK_ERR();

    glCompileShader(shader_handler_);
    CHECK_ERR();
    //...
}

And have error from glGetShaderInfoLog

Exception caught: Vertex shader failed to compile with the following errors:
ERROR: 0:1: error(#132) Syntax error: "<" parse error
ERROR: error(#273) 1 compilation errors.  No code generated

But before I calling glShaderSource, I print to stdout value of tmp pointer and it seems to valid shader code:

Shader code: 
#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;

void main()
{

    gl_Position.xyz = vertexPosition_modelspace;
    gl_Position.w = 1.0;

}

My code doesn't read garbage from memory, but I can't understand what's wrong.

Also

 % glxinfo | grep vertex_program
 % GL_ARB_vertex_program
genpfault
  • 47,669
  • 9
  • 68
  • 119
kaludis
  • 21
  • 2
  • You should append `line + "\n"` instead of `"\n" + line`. (It probably won't fix the error though.) – leemes May 26 '15 at 22:30
  • 2
    Also, why do you even read it line by line? You can [read the whole file at once](http://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring). – leemes May 26 '15 at 22:33
  • 2
    Another possible issue is the fact that you only ever append to the string member variable, but don't clear it. Might it be the case that `load_from_file` is called multiple times, or some other reason why the member might contain data before the call? – leemes May 26 '15 at 22:34
  • How is `program_code_` defined? – MicroVirus May 26 '15 at 23:29
  • Try passing null for the lengths array. I have seen many drivers behave badly when using this parameter, instead of letting it calculate the length itself. – MuertoExcobito May 27 '15 at 01:52
  • Are you sure that `strlen(tmp) == tmplen` ? – Amadeus May 27 '15 at 02:13
  • @leemes Reading file whole at once fixed problem. Thnx for your replies. – kaludis May 27 '15 at 09:01
  • I wrote it as an answer, also giving you some code snippet which should work pretty smooth and fast. – leemes May 27 '15 at 10:31

1 Answers1

1

Reading the file line by line, and concatenating these lines, seems to be the problem.

I don't know how this introduces an error which matches the error message you got from the shader compiler, but as suggested in the comments, reading the whole file at once solves the problem.

The following lines reads from a file stream is by utilizing the function rdbuf and a stringstream (you need to #include <sstream>):

std::ostringstream contents;
contents << is.rdbuf();
program_code_ = contents.str();

For more information about this method, and a comparison to other methods, see http://insanecoding.blogspot.de/2011/11/how-to-read-in-file-in-c.html.

leemes
  • 42,229
  • 18
  • 115
  • 172