com.redthirddivision.quad.rendering.shaders.Shader.java Source code

Java tutorial

Introduction

Here is the source code for com.redthirddivision.quad.rendering.shaders.Shader.java

Source

/*   Copyright 2014 Matthew Rogers "BossLetsPlays"
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package com.redthirddivision.quad.rendering.shaders;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;

/**
 * <strong>Project:</strong> QuadEngine <br>
 * <strong>File:</strong> Shader.java
 *
 * @author <a href = "http://redthirddivision.com/team/blp"> Matthew Rogers</a>
 */
public abstract class Shader {

    private static final FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);

    private int programID;
    private int vertexID;
    private int fragmentID;

    public Shader(String file) {
        this.vertexID = loadVertex(file);
        this.fragmentID = loadFragment(file);
        this.programID = GL20.glCreateProgram();
        GL20.glAttachShader(programID, vertexID);
        GL20.glAttachShader(programID, fragmentID);

        bindAttributes();

        GL20.glLinkProgram(programID);
        GL20.glValidateProgram(programID);

        addUniforms();
    }

    public void start() {
        GL20.glUseProgram(programID);
    }

    public void stop() {
        GL20.glUseProgram(0);
    }

    public void cleanUp() {
        stop();
        GL20.glDetachShader(programID, vertexID);
        GL20.glDetachShader(programID, fragmentID);
        GL20.glDeleteShader(vertexID);
        GL20.glDeleteShader(fragmentID);
        GL20.glDeleteProgram(programID);
    }

    //TODO: Make shaders more generic

    protected abstract void bindAttributes();

    protected abstract void addUniforms();

    protected void bindAttribute(int attribute, String name) {
        GL20.glBindAttribLocation(programID, attribute, name);
    }

    public void setUniform(int location, float value) {
        GL20.glUniform1f(location, value);
    }

    public void setUniform(int location, int value) {
        GL20.glUniform1i(location, value);
    }

    public void setUniform(int location, boolean value) {
        float load = 0;
        if (value)
            load = 1;
        setUniform(location, load);
    }

    public void setUniform(int location, Vector2f value) {
        GL20.glUniform2f(location, value.x, value.y);
    }

    public void setUniform(int location, Vector3f value) {
        GL20.glUniform3f(location, value.x, value.y, value.z);
    }

    public void setUniform(int location, Matrix4f value) {
        value.store(matrixBuffer);
        matrixBuffer.flip();
        GL20.glUniformMatrix4(location, false, matrixBuffer);
    }

    protected int getUniformLocation(String name) {
        if (name.equals("yes"))
            System.out.println(GL20.glGetUniformLocation(programID, name));
        return GL20.glGetUniformLocation(programID, name);
    }

    private int loadVertex(String file) {
        return loadShader("source/com/redthirddivision/quad/rendering/shaders/" + file + "_vert.glsl",
                GL20.GL_VERTEX_SHADER);
    }

    private int loadFragment(String file) {
        return loadShader("source/com/redthirddivision/quad/rendering/shaders/" + file + "_frag.glsl",
                GL20.GL_FRAGMENT_SHADER);
    }

    private int loadShader(String file, int type) {
        System.out.println("Loading shader <" + file + ">");
        StringBuilder source = new StringBuilder();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String line = null;
            while ((line = reader.readLine()) != null)
                source.append(line).append("\n");
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("Error: Could not read shader file: " + file);
            System.exit(1);
        } finally {
            if (reader != null)
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

        int shaderID = GL20.glCreateShader(type);
        GL20.glShaderSource(shaderID, source);
        GL20.glCompileShader(shaderID);
        if (GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
            System.err.println("Error: Could not comple shader");
            System.err.println(GL20.glGetShaderInfoLog(shaderID, 500));
            System.exit(1);
        }

        return shaderID;
    }

}