Search code examples
openglshaderrenderlwjgl

lwjgl 3 Black Screen width multiple shaders


The problem i think is in the hud shader program. I don't know why game can't render, return black screen.

ShaderProgram

private int programID;
private int vertexShaderID;
private int fragmentShaderID;

private final Map<String, Integer> uniforms;

public ShaderProgram() {

    uniforms = new HashMap<>();
}

public void createProgram() throws Exception {

    programID = glCreateProgram();

    if(programID == 0) {
        throw new Exception("Failed to create Program");
    }
}

public void createUniforms(String uniform) throws Exception {

    int location = glGetUniformLocation(programID, uniform);

    if(location < 0) {
        throw new Exception("Can't find uniform: " + uniform);
    }

    uniforms.put(uniform, location);
}

public void setUniform(String uniform, int value) {
    glUniform1i(uniforms.get(uniform), value);
}

public void setUniform(String uniform, Matrix4f value) {

    FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
    value.get(buffer);

    glUniformMatrix4fv(uniforms.get(uniform), false, buffer);
}

public void setUniform(String uniformName, Vector3f value) {
    glUniform3f(uniforms.get(uniformName), value.x, value.y, value.z);
}

public void setUniform(String uniformName, float value) {
    glUniform1f(uniforms.get(uniformName), value);
}

public void createVertexShader(String vertexShader) throws Exception {
    vertexShaderID = createShaders(vertexShader, GL_VERTEX_SHADER);
}

public void createFragmentShader(String fragmentShader) throws Exception {
    fragmentShaderID = createShaders(fragmentShader, GL_FRAGMENT_SHADER);
}

public int createShaders(String shader, int type) throws Exception {

    int shaderID = glCreateShader(type);

    glShaderSource(shaderID, shader);

    glCompileShader(shaderID);
    if(glGetShaderi(shaderID, GL_COMPILE_STATUS) == 0) {
        throw new Exception("Failed to compile shader: " + glGetShaderInfoLog(shaderID, 1024));
    }

    glAttachShader(programID, shaderID);

    return shaderID;
}

public void link() throws Exception {

    glLinkProgram(programID);
    if(glGetProgrami(programID, GL_LINK_STATUS) == 0) {
        throw new Exception("Failed to link program: " + glGetProgramInfoLog(programID, 1024));
    }

    glValidateProgram(programID);
    if(glGetProgrami(programID, GL_VALIDATE_STATUS) == 0) {
        System.err.println("Error by validate program: " + glGetProgramInfoLog(programID, 1024));
    }
}

public void bind() {
    glUseProgram(programID);
}

public void unbind() {
    glUseProgram(0);
}

public void cleanUp() {

    unbind();

    if(programID != 0) {
        if(vertexShaderID != 0) {
            glDetachShader(programID, vertexShaderID);
        }
        if(fragmentShaderID != 0) {
            glDetachShader(programID, fragmentShaderID);
        }

        glDeleteProgram(programID);
    }
}

MasterShaders extends ShaderProgram

private Texture texture;
private TransformationMatrix transformation;

private float FOV = (float) Math.toRadians(60.0f);
private float Z_NEAR = 0.01f;
private float Z_FAR = 1000.0f;

private String VERTEX_SHADER = "/com/ms/resources/shaders/vertexShader.glsl";
private String FRAGMENT_SHADER = "/com/ms/resources/shaders/fragmentShader.glsl";
private String FONT_VERTEX_SHADER = "/com/ms/resources/shaders/fontVertexShader.glsl";
private String FONT_FRAGMENT_SHADER = "/com/ms/resources/shaders/fontFragmentShader.glsl";

public MasterShaders() {
    super();

    texture = new Texture();
    transformation = new TransformationMatrix();
}

public void shadersLoader() throws Exception {

    super.createProgram();
    super.createVertexShader(FileLoader.loadResources(VERTEX_SHADER));
    super.createFragmentShader(FileLoader.loadResources(FRAGMENT_SHADER));
    super.link();

    getUniforms();
}

public void fontShadersLoader() throws Exception {

    super.createProgram();
    super.createVertexShader(FileLoader.loadResources(FONT_VERTEX_SHADER));
    super.createFragmentShader(FileLoader.loadResources(FONT_FRAGMENT_SHADER));
    super.link();

    getFontUniforms();
}

public void renderShaders(ObjectModifier[] object, Camera camera, Light light) {

    super.bind();

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    createProjectionMatrix();
    createTransformationMatrix(object);
    createViewMatrix(camera);
    createLight(light, texture.getShineDamper(), texture.getReflectivity());

    super.unbind();
}

public void renderHud(IHud hud) {

    super.bind();

    createHud(hud);

    super.unbind();
}

public void getUniforms() throws Exception {

    super.createUniforms("projectionMatrix");
    super.createUniforms("viewMatrix");
    super.createUniforms("transformationMatrix");
    super.createUniforms("textureSampler");
    super.createUniforms("lightPosition");
    super.createUniforms("lightColour");
    super.createUniforms("shineDamper");
    super.createUniforms("reflectivity");
}

public void getFontUniforms() throws Exception {

    super.createUniforms("projModelMatrix");
    super.createUniforms("color");
}

public Matrix4f createProjectionMatrix() {

    Matrix4f projectionMatrix = new Matrix4f();

    projectionMatrix = transformation.getProjectionMatrix(
            FOV, 
            Display.getWidth(), 
            Display.getHeight(), 
            Z_NEAR, 
            Z_FAR);

    super.setUniform("projectionMatrix", projectionMatrix);

    return projectionMatrix;
}

public Matrix4f createTransformationMatrix(ObjectModifier[] object) {

    Matrix4f transformationMatrix = new Matrix4f();

    for(ObjectModifier objects : object) {

        transformationMatrix = transformation.getTransformationMatrix(objects);
        super.setUniform("transformationMatrix", transformationMatrix); 

        objects.getMesh().renderMesh();
    }

    super.setUniform("textureSampler", 0);

    return transformationMatrix;
}

public Matrix4f createViewMatrix(Camera camera) {

    Matrix4f viewMatrix = new Matrix4f();
    viewMatrix = transformation.getViewMatrix(camera);

    super.setUniform("viewMatrix", viewMatrix);

    return viewMatrix;
}

public void createLight(Light light, float damper, float reflectivity) {

    super.setUniform("lightPosition", light.getPosition());
    super.setUniform("lightColour", light.getColor());
    super.setUniform("shineDamper", damper);
    super.setUniform("reflectivity", reflectivity);
}

public void createHud(IHud hud) {

    Matrix4f ortho = transformation.getOrthoProjectionMatrix(0, Display.getWidth(), Display.getHeight(), 0);

    for(ObjectModifier objects : hud.getObjects()) {

        Mesh mesh = objects.getMesh();

        Matrix4f projModelMatrix = transformation.getOrtoProjModelMatrix(objects, ortho);
        super.setUniform("projModelMatrix", projModelMatrix);
        super.setUniform("color", objects.getMesh().getLight().getColor());

        mesh.renderMesh();
    }
}

public void cleanUp() {

    cleanUp();
}

Renderer

private Mesh mesh;
private MasterShaders shaders;

public Renderer() throws Exception {

    mesh = new Mesh();
    shaders = new MasterShaders();
}

public void init() throws Exception {

    shaders.shadersLoader();
    shaders.fontShadersLoader();
}

public void render(ObjectModifier[] object, Camera camera, Light light, IHud hud) {

    clear();

    shaders.renderShaders(object, camera, light);
    shaders.renderHud(hud);
}

public void clear() {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

public void cleanUp() {

    mesh.cleanUp();
    shaders.cleanUp();
}

If in the init() method and in the render() method of the renderer class i remove:

- shaders.fontShadersLoader();

- shaders.renderHud(hud);

my game render the object.

The console don't return any error. Some idea?


Solution

  • It seems you are creating a new program id twice in the same object, the fontloader one overwriting the shaderloader one, then you bind that id with super.bind() (in this case the fontloader shader program id) for both drawing calls, renderShaders() and renderHud().

    Solution: You need to store 2 different program ids and call glUseProgram(programid) for each in the appropriate method.