Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package space.engine;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.nio.FloatBuffer;
- import java.nio.IntBuffer;
- import java.util.HashMap;
- import org.lwjgl.opengl.ARBShaderObjects;
- import org.lwjgl.opengl.ARBVertexShader;
- import org.lwjgl.opengl.GL20;
- import org.newdawn.slick.SlickException;
- import org.newdawn.slick.util.ResourceLoader;
- public class ShaderProgram {
- private static boolean strict = true;
- public static void setStrictMode(boolean enabled) {
- strict = enabled;
- }
- public static boolean isStrictMode() {
- return strict;
- }
- // TODO: move to outer level ?
- public static class Shader {
- private String source;
- private int type;
- private int id;
- private String log = "";
- public Shader(int type, String source) {
- if (source==null)
- throw new IllegalArgumentException("shader source code must not be null");
- this.source = source;
- this.type = type;
- id = createShader(type, source);
- }
- public boolean valid() {
- return id!=0;
- }
- private int createShader(int type, String source) {
- int shader = ARBShaderObjects.glCreateShaderObjectARB(type);
- if (shader==0)
- return 0;
- ARBShaderObjects.glShaderSourceARB(shader, source);
- ARBShaderObjects.glCompileShaderARB(shader);
- int comp = ARBShaderObjects.glGetObjectParameteriARB(shader, GL20.GL_COMPILE_STATUS);
- if (comp==0) {
- int len = ARBShaderObjects.glGetObjectParameteriARB(shader, GL20.GL_INFO_LOG_LENGTH);
- log = ARBShaderObjects.glGetInfoLogARB(shader, len);
- return 0;
- }
- return shader;
- }
- public void release() {
- if (id!=0) {
- ARBShaderObjects.glDeleteObjectARB(id);
- id = 0;
- }
- }
- public String getLog() {
- return log;
- }
- public int getID() {
- return id;
- }
- public int getType() {
- return type;
- }
- public String getSource() {
- return source;
- }
- }
- private int program;
- private String log = "";
- protected HashMap<String, Integer> uniforms = new HashMap<String, Integer>();
- protected HashMap<String, Integer> attributes = new HashMap<String, Integer>();
- private Shader vert, frag;
- public static ShaderProgram loadProgram(String vertFile, String fragFile) throws SlickException {
- return new ShaderProgram(loadSource(vertFile), loadSource(fragFile));
- }
- public static String loadSource(String ref) throws SlickException {
- InputStream in = ResourceLoader.getResourceAsStream(ref);
- try { return loadSource(in); }
- catch (SlickException e) {
- throw new SlickException("could not load source file: "+ref);
- }
- }
- public static String loadSource(InputStream in) throws SlickException{
- try {
- BufferedReader br = new BufferedReader(new InputStreamReader(in));
- String line = "";
- String txt = "";
- while ((line=br.readLine()) != null)
- txt += line + "\n";
- br.close();
- return txt.trim();
- } catch (IOException e) {
- throw new SlickException("could not load source file");
- }
- }
- public ShaderProgram(String vertexShader, String fragShader) {
- this(new Shader(GL20.GL_VERTEX_SHADER, vertexShader),
- new Shader(GL20.GL_FRAGMENT_SHADER, fragShader));
- }
- public ShaderProgram(Shader vertexShader, Shader fragShader) {
- if (vertexShader==null || fragShader==null)
- throw new IllegalArgumentException("shaders must be non-null");
- this.vert = vertexShader;
- this.frag = fragShader;
- log += vert.getLog() + frag.getLog();
- this.program = compile();
- if (valid()) {
- fetchUniforms();
- // fetchAttributes();
- }
- }
- private int compile() {
- if (!vert.valid() || !frag.valid())
- return 0;
- int program = ARBShaderObjects.glCreateProgramObjectARB();
- ARBShaderObjects.glAttachObjectARB(program, vert.getID());
- ARBShaderObjects.glAttachObjectARB(program, frag.getID());
- ARBShaderObjects.glLinkProgramARB(program);
- //GL20.glValidateProgram(program);
- int comp = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_LINK_STATUS);
- if (comp==0) {
- int len = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_INFO_LOG_LENGTH);
- log += ARBShaderObjects.glGetInfoLogARB(program, len);
- return 0;
- }
- return program;
- }
- /**
- * Returns the log for this shader program as well as any shaders attached to this program.
- * @return
- */
- public String getLog() {
- return log;
- }
- public void unbind() {
- ARBShaderObjects.glUseProgramObjectARB(0);
- }
- public void bind() {
- if (!valid())
- throw new IllegalStateException("trying to enable a program that is not valid");
- ARBShaderObjects.glUseProgramObjectARB(program);
- }
- public void release() {
- ARBShaderObjects.glDetachObjectARB(program, vert.getID());
- ARBShaderObjects.glDetachObjectARB(program, frag.getID());
- vert.release();
- frag.release();
- ARBShaderObjects.glDeleteObjectARB(program);
- }
- public int getID() {
- return program;
- }
- public boolean valid() {
- return program != 0;
- }
- // protected int findAttributeLocation(String name) {
- // int location = attributes.get(name);
- // if (location!=-1)
- // return location;
- // location = ARBVertexShader.glGetAttribLocationARB(program, name);
- // if (location == -1 && strict)
- // throw new IllegalArgumentException("no active attribute by name '"+name+"'");
- // attributes.put(name, location);
- // return location;
- // }
- protected int findUniformLocation(String name) {
- Integer locI = uniforms.get(name);
- int location = locI==null ? -1 : locI.intValue();
- if (location!=-1)
- return location;
- location = ARBShaderObjects.glGetUniformLocationARB(program, name);
- if (location == -1 && strict)
- throw new IllegalArgumentException("no active uniform by name '"+name+"' (disable strict compiling to suppress warnings)");
- uniforms.put(name, location);
- return location;
- }
- private void fetchUniforms() {
- int len = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_ACTIVE_UNIFORMS);
- //max length of all uniforms stored in program
- int strLen = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_ACTIVE_UNIFORM_MAX_LENGTH);
- for (int i=0; i<len; i++) {
- String name = ARBShaderObjects.glGetActiveUniformARB(program, i, strLen);
- int id = ARBShaderObjects.glGetUniformLocationARB(program, name);
- uniforms.put(name, id);
- }
- }
- // private void fetchAttributes() {
- // int len = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_ACTIVE_ATTRIBUTES);
- // //max length of all uniforms stored in program
- // int strLen = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH);
- // for (int i=0; i<len; i++) {
- // String name = ARBVertexShader.glGetActiveAttribARB(program, i, strLen);
- // int id = ARBVertexShader.glGetAttribLocationARB(program, name);
- // uniforms.put(name, id);
- // }
- // }
- public int getUniformID(String name) {
- return findUniformLocation(name);
- }
- // public int getAttributeID(String name) {
- // return findAttributeLocation(name);
- // }
- // public String[] getAttributes() {
- // return attributes.keySet().toArray(new String[attributes.size()]);
- // }
- public String[] getUniformNames() {
- return uniforms.keySet().toArray(new String[uniforms.size()]);
- }
- public Shader getVertexShader() {
- return vert;
- }
- public Shader getFragmentShader() {
- return frag;
- }
- public boolean getUniform(String name, FloatBuffer buf) {
- int id = getUniformID(name);
- if (id==-1) return false;
- ARBShaderObjects.glGetUniformARB(program, id, buf);
- return true;
- }
- public boolean getUniform(String name, IntBuffer buf) {
- int id = getUniformID(name);
- if (id==-1) return false;
- ARBShaderObjects.glGetUniformARB(program, id, buf);
- return true;
- }
- public boolean hasUniform(String name) {
- return uniforms.containsKey(name);
- }
- public boolean hasAttribute(String name) {
- return attributes.containsKey(name);
- }
- public void setUniform1f(String name, float f) {
- int id = getUniformID(name);
- if (id==-1) return;
- ARBShaderObjects.glUniform1fARB(id, f);
- }
- public void setUniform1i(String name, int i) {
- int id = getUniformID(name);
- if (id==-1) return;
- ARBShaderObjects.glUniform1iARB(id, i);
- }
- public void setUniform2f(String name, float a, float b) {
- int id = getUniformID(name);
- if (id==-1) return;
- ARBShaderObjects.glUniform2fARB(id, a, b);
- }
- public void setUniform3f(String name, float a, float b, float c) {
- int id = getUniformID(name);
- if (id==-1) return;
- ARBShaderObjects.glUniform3fARB(id, a, b, c);
- }
- public void setUniform4f(String name, float a, float b, float c, float d) {
- int id = getUniformID(name);
- if (id==-1) return;
- ARBShaderObjects.glUniform4fARB(id, a, b, c, d);
- }
- // TODO: include more setUniforms/getUniforms
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement