Search code examples
javashaderjoglfragment-shadervertex-shader

My ShaderProgram doesn't work


My primary language is French, I will try to do my best.

I try to learn about shader, but I'm not able to find why my shader doesn't work. I draw using VAO with 2 VBO. One for Vertices an the other for indices. My object render fine but my shader seems to have no effects.

My svn project eclipse ; http://sourceforge.net/projects/mad-game-engine

My vao setup;
VAO
--VBO 0 Vertices
--VBO 1 Indices

My ShaderProgram;

package fr.mad.engine.shader;

import java.io.BufferedReader;
import java.io.FileReader;

import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GL4;

import fr.mad.engine.LOG;

public abstract class ShaderProgram {
    private int programID;
    private int vertexShaderID;
    private int fragmentShaerID;
    private LOG log;

    public ShaderProgram(String vertexFile, String fragmentFile, LOG log, GL2 gl) {
        this.log = new LOG(log, "shader");
        vertexShaderID = loadShader(vertexFile, GL2ES2.GL_VERTEX_SHADER, gl.getGL2());
        fragmentShaerID = loadShader(fragmentFile, GL2ES2.GL_FRAGMENT_SHADER, gl.getGL2());
        programID = gl.glCreateProgram();
        gl.glAttachShader(programID, vertexShaderID);
        gl.glAttachShader(programID, fragmentShaerID);
        bindAttributes(gl);
        gl.glLinkProgram(programID);
        gl.glValidateProgram(programID);
        checkProgram(gl, programID);
    }

    public void start(GL2 gl) {
        gl.glUseProgram(programID);
    }

    public void stop(GL2 gl) {
        gl.glUseProgram(0);
    }

    public void clenUp(GL2 gl) {
        stop(gl);
        gl.glDetachShader(programID, vertexShaderID);
        gl.glDetachShader(programID, fragmentShaerID);
        gl.glDeleteShader(vertexShaderID);
        gl.glDeleteShader(this.fragmentShaerID);
        gl.glDeleteProgram(programID);
    }

    protected abstract void bindAttributes(GL2 gl);

    protected void bindAttribute(GL2 gl, int i, String t) {
        gl.glBindAttribLocation(programID, i, t);
    }

    private int loadShader(String file, int type, GL2 gl) {
        log.log("Loading " + (GL2ES2.GL_VERTEX_SHADER == type ? "Vertex" : "Fragment") + " Shader");
        StringBuilder shaderSource = new StringBuilder();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line;
            while ((line = reader.readLine()) != null) {
                shaderSource.append(line).append("\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        int shaderID = gl.glCreateShader(type);
        gl.glShaderSource(shaderID, 1, new String[] { shaderSource.toString() }, new int[] { shaderSource.toString().length() }, 0);
        gl.glCompileShader(shaderID);

        checkShader(gl, shaderID);

        log.log("");

        return shaderID;
    }

    private void checkProgram(GL2 gl, int handle) {

        int[] buffer = new int[1];

        gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_LINK_STATUS_ARB, buffer, 0);
        if (buffer[0] == GL.GL_FALSE) // 1 or 0
            warning("error linking program ");

        gl.glValidateProgramARB(handle);
        gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_VALIDATE_STATUS_ARB, buffer, 0);
        if (buffer[0] == GL.GL_FALSE)
            warning("program not validate");

        gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, buffer, 0);
        byte[] log = new byte[buffer[0]];
        gl.glGetInfoLogARB(handle, buffer[0], buffer, 0, log, 0);

        if (log[0] != 0)
            warning("linker info log:\n" + new String(log));
    }

    private void checkShader(GL2 gl, int handle) {

        int[] buffer = new int[1];
        gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_COMPILE_STATUS_ARB, buffer, 0);
        if (buffer[0] == GL.GL_FALSE) {
            warning("error compiling shader");
        }

        gl.glGetObjectParameterivARB(handle, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, buffer, 0);
        byte[] log = new byte[buffer[0]];
        gl.glGetInfoLogARB(handle, buffer[0], buffer, 0, log, 0);

        if (log[0] != 0)
            warning("compiler info log:\n" + new String(log, 0, log.length - 1));
    }

    private void warning(String string) {
        log.log(string);
    }

}

Vertex shader;

#version 400 core

in vec3 position;

out vec3 colour;

void main(void){

    gl_Position = vec4(position.xyz,1.0);
    colour = sin(vec3(0,1,0));
}

Fragment shadder;

#version 400 core

in vec3 colour;

out vec4 out_Color;

void main(void){
    out_Color = vec4(colour,1.0);
    gl_FragColor = vec4(colour,1.0);
}

My Drawing Methode;

shader.start(gl);
gl.glBindVertexArray(vaoid);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbovertid);
gl.glEnableVertexAttribArray(0);
gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, vboindexid);
gl.glEnableVertexAttribArray(1);
gl.glColor3f(1f, 0, 0);
gl.glDrawElements(GL.GL_TRIANGLES, this.indices.length, GL.GL_UNSIGNED_INT, 0);
gl.glEnableVertexAttribArray(1);
gl.glEnableVertexAttribArray(0);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
gl.glBindVertexArray(0);
shader.stop(gl);

With theses method in shaderprogram;

private void checkProgram(GL2 gl, int handle) {

        int[] buffer = new int[1];

        gl.glGetProgramiv(handle, GL2ES2.GL_LINK_STATUS, buffer, 0);
        if (buffer[0] == GL.GL_FALSE) // 1 or 0
            warning("error linking program ");

        gl.glValidateProgram(handle);
        gl.glGetProgramiv(handle, GL2.GL_VALIDATE_STATUS, buffer, 0);
        if (buffer[0] == GL.GL_FALSE)
            warning("program not validate");

        gl.glGetProgramiv(handle, GL2.GL_INFO_LOG_LENGTH, buffer, 0);
        byte[] log = new byte[buffer[0]];
        gl.glGetProgramInfoLog(handle, buffer[0], buffer, 0, log, 0);

        if (log[0] != 0)
            warning("linker info log:\n" + new String(log));
    }

    private void checkShader(GL2 gl, int handle) {

        int[] buffer = new int[1];
        gl.glGetProgramiv(handle, GL2.GL_COMPILE_STATUS, buffer, 0);
        if (buffer[0] == GL.GL_FALSE) {
            warning("error compiling shader");
        }

        gl.glGetProgramiv(handle, GL2.GL_INFO_LOG_LENGTH, buffer, 0);
        byte[] log = new byte[buffer[0]];
        if(log.length>0)
        gl.glGetShaderInfoLog(handle, buffer[0], buffer, 0, log, 0);

        if(log.length>0)
        if (log[0] != 0)
            warning("compiler info log:\n" + new String(log, 0, log.length - 1));
    }

I obtain this log;

Loading Vertex Shader
error compiling shader

Loading Fragment Shader
error compiling shader

error linking program 
program not validate

Solution

  • as I wrote before your log is not GLSL compilation/link log you have messed it up somewhere. When I put your shaders into mine engine here is the log for nVidia Environment:

    [Vertex]
    OK
    
    [Fragment]
    OK
    0(9) : warning C7533: global variable gl_FragColor is deprecated after version 120
    
    [Program]
    Linker error
    Fragment info
    -------------
    0(9) : warning C7533: global variable gl_FragColor is deprecated after version 120
    error:  user-defined fragment shader outputs may not be used with gl_FragColor or gl_FragData
    

    So change the fragment shader to this:

    #version 400 core
    
    in vec3 colour;
    
    out vec4 out_Color;
    
    void main(void){
        out_Color = vec4(colour,1.0);
    }
    

    by removing the gl_FragColor = vec4(colour,1.0); because you already set the output color. You can do that just once ... if you still need old style variable then use compatibility profile instead of core

    Check this: glGetShaderInfoLog

    My bet is that you are calling different glGetShaderInfoLog provided by any of the gl based libs you linked to your program. That is why you have those weird messages instead compilation/link log. Try to use the original gl one which returns the log directly from gfx driver ...