Java tutorial
/* 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; } }