Search code examples
lwjgl

Shaders won't link, but no errors show


Well, the title pretty much says it all, my shaders won't link.

Output:

 [INFO|2016-01-06 18:21:27|Renderer Thread (Test window)] Shader compile status is 1, log: 
 [INFO|2016-01-06 18:21:27|Renderer Thread (Test window)] Shader compile status is 1, log: 
 [INFO|2016-01-06 18:21:27|Renderer Thread (Test window)] Link status: 0
 [INFO|2016-01-06 18:21:27|Renderer Thread (Test window)] Link errors:

Link status 0 obviously means it failed. But why? Obviously the glUseProgram fails with error 1282 because the program failed to link.

Link code:

    int vshId = this.loadShader(this.getClass().getResource("/shaders/blocks.vsh"), GL20.GL_VERTEX_SHADER);
    int fshId = this.loadShader(this.getClass().getResource("/shaders/blocks.fsh"), GL20.GL_FRAGMENT_SHADER);
    int programId = GL20.glCreateProgram();
    GL20.glAttachShader(programId, vshId);
    GL20.glAttachShader(programId, fshId);
    GL20.glLinkProgram(programId);
    GL20.glValidateProgram(programId);
    IntBuffer buf = BufferUtils.createIntBuffer(1);
    GL20.glGetProgramiv(programId, GL20.GL_LINK_STATUS, buf);
    int linkStatus = buf.get();
    Logger.getInstance().logf("Link status: %s", linkStatus);
    Logger.getInstance().logf("Link errors: %s", GL20.glGetProgramInfoLog(programId));

loadShader function:

public int loadShader(URL resource, int type) {
    InputStream stream;
    try {
        stream = resource.openStream();
    } catch (IOException e) {
        e.printStackTrace();
        return -1;
    }

    String s = "";
    byte[] b = new byte[256];
    try {
        while (stream.read(b) > -1) {
            s += new String(b);
        }
    } catch (IOException e) {
        e.printStackTrace();
        return -2;
    }
    String shaderSrc = s;
    int shaderID = GL20.glCreateShader(type);
    GL20.glShaderSource(shaderID, shaderSrc);
    GL20.glCompileShader(shaderID);
    int status = GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS);
    Logger.getInstance().logf("Shader compile status is %s, log: %s", status, GL20.glGetShaderInfoLog(shaderID));
    return shaderID;
}

These two snippets are part of class SpriteManager (https://gitlab.com/MRebhan/RetroEngine/blob/master/src/de/marco_rebhan/retroengine/texture/SpriteManager.java)

Fragment shader:

#version 130

in vec2 tex_coord;
uniform sampler2D tex;

void main(void) {
  gl_FragColor = texture(tex, tex_coord);
}

Vertex shader:

#version 130

in vec2 position;

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

Why is this happening? I don't see any error. And when I put garbage lines into the shader source, it says 0:3(1): error: syntax error, unexpected NEW_IDENTIFIER. I get why that won't compile successfully, but I don't get why the correct shaders don't work... Please help.

Entire project can be viewed at https://gitlab.com/MRebhan/RetroEngine


Solution

  • I feel really dumb now. First, calling glGetProgrami before glValidateProgam made errors appear, namely that out vec2 tex_coord was missing from the vertex shader. Derp. Now it's working. I will put the fixed versions here:

    Vertex shader:

    #version 130
    
    in vec2 position;
    out vec2 tex_coord;
    
    void main(void) {
      gl_Position = vec4(position, 0.0, 1.0);
      tex_coord = position;
    }
    

    Link Shader code:

    int vshId = this.loadShader(this.getClass().getResource("/shaders/blocks.vsh"), GL20.GL_VERTEX_SHADER);
    int fshId = this.loadShader(this.getClass().getResource("/shaders/blocks.fsh"), GL20.GL_FRAGMENT_SHADER);
    int programId = GL20.glCreateProgram();
    GL20.glAttachShader(programId, vshId);
    GL20.glAttachShader(programId, fshId);
    GL20.glLinkProgram(programId);
    int linkStatus = GL20.glGetProgrami(programId, GL20.GL_LINK_STATUS);
    GL20.glValidateProgram(programId);
    Logger.getInstance().logf("Link status: %s", linkStatus);
    Logger.getInstance().logf("Link errors: %s", GL20.glGetProgramInfoLog(programId));