package de.gamezock.metacraft.ui; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.AbstractMap; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.media.opengl.GL2; public class ShaderLoader { private static Map, Integer> programs = new HashMap, Integer>(); static private void printInfoLog(GL2 gl, int object) { IntBuffer lengthBuffer = IntBuffer.allocate(1); gl.glGetObjectParameterivARB(object, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, lengthBuffer); int length = lengthBuffer.get(0); if(length > 0) { ByteBuffer log = ByteBuffer.allocate(length); IntBuffer foo = IntBuffer.allocate(1); gl.glGetInfoLogARB(object, length, foo, log); System.err.println(new String(log.array())); } } static private String readStream(InputStream stream) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); String ret = "", line; while ((line = reader.readLine()) != null) { ret += line + "\n"; } return ret; } static private int loadShader(GL2 gl, String name, int type) { int shader = gl.glCreateShaderObjectARB(type); try { InputStream stream = ShaderLoader.class.getResourceAsStream("/de/gamezock/metacraft/resources/shaders/" + name); String source = readStream(stream); gl.glShaderSourceARB(shader, 1, new String[] {source}, null); gl.glCompileShaderARB(shader); printInfoLog(gl, shader); return shader; } catch (IOException e) { } if(shader != 0) gl.glDeleteObjectARB(shader); return 0; } static public boolean load(GL2 gl, String vsName, String fsName) { Integer savedProg = programs.get(new AbstractMap.SimpleEntry(vsName, fsName)); if(savedProg != null) { gl.glUseProgram(savedProg); return true; } int vs = loadShader(gl, vsName, GL2.GL_VERTEX_SHADER); int fs = loadShader(gl, fsName, GL2.GL_FRAGMENT_SHADER); if(vs != 0 && fs != 0) { int program = gl.glCreateProgramObjectARB(); gl.glAttachObjectARB(program, vs); gl.glAttachObjectARB(program, fs); gl.glLinkProgramARB(program); printInfoLog(gl, program); gl.glUseProgramObjectARB(program); programs.put(new AbstractMap.SimpleEntry(vsName, fsName), program); return true; } return false; } }