sketchwars.graphics.Shader.java Source code

Java tutorial

Introduction

Here is the source code for sketchwars.graphics.Shader.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package sketchwars.graphics;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GL11;

/**
 *
 * @author Najash Najimudeen <najash.najm@gmail.com>
 */
public class Shader {
    private int program = -1;

    public Shader(String vertexShaderFile, String fragmentShaderFile) throws Exception {
        if (vertexShaderFile == null || vertexShaderFile.length() < 1) {
            throw new Exception("Invalid vertex shader file path.");
        } else if (fragmentShaderFile == null || fragmentShaderFile.length() < 1) {
            throw new Exception("Invalid fragment shader file path.");
        }

        loadShader(vertexShaderFile, fragmentShaderFile);
    }

    private void loadShader(String vertexShaderFile, String fragmentShaderFile) throws Exception {
        int vertShader = createShaderFromFile(vertexShaderFile, ARBVertexShader.GL_VERTEX_SHADER_ARB);
        int fragShader = createShaderFromFile(fragmentShaderFile, ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);

        int shaderProgram = ARBShaderObjects.glCreateProgramObjectARB();

        if (shaderProgram == 0) {
            throw new Exception("Error Creating shader program object.");
        }

        ARBShaderObjects.glAttachObjectARB(shaderProgram, vertShader);
        ARBShaderObjects.glAttachObjectARB(shaderProgram, fragShader);

        ARBShaderObjects.glLinkProgramARB(shaderProgram);
        if (ARBShaderObjects.glGetObjectParameteriARB(shaderProgram,
                ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) {
            throw new Exception(getLogInfo(shaderProgram));
        }

        ARBShaderObjects.glValidateProgramARB(shaderProgram);
        if (ARBShaderObjects.glGetObjectParameteriARB(shaderProgram,
                ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE) {
            throw new Exception(getLogInfo(shaderProgram));
        }

        program = shaderProgram;
    }

    private int createShaderFromString(String shaderString, int shaderType) throws Exception {
        int shader = 0;
        try {
            shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType);

            if (shader == 0)
                return 0;

            if (shaderString != null) {
                ARBShaderObjects.glShaderSourceARB(shader, shaderString);
                ARBShaderObjects.glCompileShaderARB(shader);

                if (ARBShaderObjects.glGetObjectParameteriARB(shader,
                        ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE) {
                    throw new RuntimeException("Error creating shader: " + getLogInfo(shader));
                }
                return shader;
            }
        } catch (Exception exc) {
            ARBShaderObjects.glDeleteObjectARB(shader);
            throw exc;
        }
        return -1;
    }

    private int createShaderFromFile(String filename, int shaderType) throws Exception {
        String shaderFileStr = readFileAsString(filename);

        if (shaderFileStr != null) {
            return createShaderFromString(shaderFileStr, shaderType);
        }
        return -1;
    }

    private String readFileAsString(String filename) {
        StringBuilder source = new StringBuilder();
        BufferedReader reader = null;
        FileInputStream in = null;

        try {
            in = new FileInputStream(filename);
            reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));

            String line;
            while ((line = reader.readLine()) != null) {
                source.append(line).append('\n');
            }
        } catch (FileNotFoundException | UnsupportedEncodingException ex) {
            System.err.println("Shader:readFileAsString(): " + ex);
            return null;
        } catch (IOException ex) {
            System.err.println("Shader:readFileAsString(): " + ex);
            return null;
        } finally {
            try {
                if (reader != null)
                    reader.close();

                if (in != null)
                    in.close();
            } catch (Exception ex) {
                System.err.println("Shader:readFileAsString(): " + ex);
                return null;
            }
        }

        return source.toString();
    }

    private static String getLogInfo(int obj) {
        return ARBShaderObjects.glGetInfoLogARB(obj,
                ARBShaderObjects.glGetObjectParameteriARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB));
    }

    public int getProgram() {
        return program;
    }

    public boolean isValid() {
        return program != -1;
    }

    public void begin() {
        if (program != -1) {
            ARBShaderObjects.glUseProgramObjectARB(program);
        }
    }

    public void end() {
        if (program != -1) {
            ARBShaderObjects.glUseProgramObjectARB(0);
        }
    }
}