SHARE
TWEET

Untitled

a guest Mar 19th, 2012 34 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package space.engine;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.InputStreamReader;
  7. import java.nio.FloatBuffer;
  8. import java.nio.IntBuffer;
  9. import java.util.HashMap;
  10.  
  11. import org.lwjgl.opengl.ARBShaderObjects;
  12. import org.lwjgl.opengl.ARBVertexShader;
  13. import org.lwjgl.opengl.GL20;
  14. import org.newdawn.slick.SlickException;
  15. import org.newdawn.slick.util.ResourceLoader;
  16.  
  17. public class ShaderProgram {
  18.  
  19.         private static boolean strict = true;
  20.        
  21.         public static void setStrictMode(boolean enabled) {
  22.                 strict = enabled;
  23.         }
  24.        
  25.         public static boolean isStrictMode() {
  26.                 return strict;
  27.         }
  28.        
  29.         // TODO: move to outer level ?
  30.         public static class Shader {
  31.                
  32.                 private String source;
  33.                 private int type;
  34.                 private int id;
  35.                 private String log = "";
  36.                
  37.                 public Shader(int type, String source) {
  38.                         if (source==null)
  39.                                 throw new IllegalArgumentException("shader source code must not be null");
  40.                         this.source = source;
  41.                         this.type = type;
  42.                         id = createShader(type, source);
  43.                 }
  44.  
  45.                 public boolean valid() {
  46.                         return id!=0;
  47.                 }
  48.                
  49.                 private int createShader(int type, String source) {
  50.                         int shader = ARBShaderObjects.glCreateShaderObjectARB(type);
  51.                         if (shader==0)
  52.                                 return 0;
  53.                        
  54.                         ARBShaderObjects.glShaderSourceARB(shader, source);
  55.                         ARBShaderObjects.glCompileShaderARB(shader);
  56.                         int comp = ARBShaderObjects.glGetObjectParameteriARB(shader, GL20.GL_COMPILE_STATUS);
  57.                         if (comp==0) {
  58.                                 int len = ARBShaderObjects.glGetObjectParameteriARB(shader, GL20.GL_INFO_LOG_LENGTH);
  59.                                 log = ARBShaderObjects.glGetInfoLogARB(shader, len);
  60.                                 return 0;
  61.                         }
  62.                         return shader;
  63.                 }
  64.                
  65.                 public void release() {
  66.                         if (id!=0) {
  67.                                 ARBShaderObjects.glDeleteObjectARB(id);
  68.                                 id = 0;
  69.                         }
  70.                 }
  71.                
  72.                 public String getLog() {
  73.                         return log;
  74.                 }
  75.                
  76.                 public int getID() {
  77.                         return id;
  78.                 }
  79.                
  80.                 public int getType() {
  81.                         return type;
  82.                 }
  83.                
  84.                 public String getSource() {
  85.                         return source;
  86.                 }
  87.         }
  88.        
  89.         private int program;
  90.        
  91.         private String log = "";
  92.        
  93.         protected HashMap<String, Integer> uniforms = new HashMap<String, Integer>();
  94.         protected HashMap<String, Integer> attributes = new HashMap<String, Integer>();
  95.        
  96.        
  97.         private Shader vert, frag;
  98.        
  99.         public static ShaderProgram loadProgram(String vertFile, String fragFile) throws SlickException {
  100.                 return new ShaderProgram(loadSource(vertFile), loadSource(fragFile));
  101.         }
  102.        
  103.         public static String loadSource(String ref) throws SlickException {
  104.                 InputStream in = ResourceLoader.getResourceAsStream(ref);
  105.                 try { return loadSource(in); }
  106.                 catch (SlickException e) {
  107.                         throw new SlickException("could not load source file: "+ref);
  108.                 }
  109.         }
  110.        
  111.     public static String loadSource(InputStream in) throws SlickException{
  112.         try {
  113.                 BufferedReader br = new BufferedReader(new InputStreamReader(in));
  114.                 String line = "";
  115.                 String txt = "";
  116.                 while ((line=br.readLine()) != null)
  117.                         txt += line + "\n";
  118.                 br.close();
  119.                 return txt.trim();
  120.         } catch (IOException e) {
  121.                 throw new SlickException("could not load source file");
  122.         }
  123.     }
  124.        
  125.     public ShaderProgram(String vertexShader, String fragShader) {
  126.         this(new Shader(GL20.GL_VERTEX_SHADER, vertexShader),
  127.                  new Shader(GL20.GL_FRAGMENT_SHADER, fragShader));
  128.     }
  129.    
  130.         public ShaderProgram(Shader vertexShader, Shader fragShader) {
  131.                 if (vertexShader==null || fragShader==null)
  132.                         throw new IllegalArgumentException("shaders must be non-null");
  133.                 this.vert = vertexShader;
  134.                 this.frag = fragShader;
  135.                 log += vert.getLog() + frag.getLog();
  136.                 this.program = compile();
  137.                 if (valid()) {
  138.                         fetchUniforms();
  139. //                      fetchAttributes();
  140.                 }
  141.         }
  142.        
  143.         private int compile() {
  144.                 if (!vert.valid() || !frag.valid())
  145.                         return 0;
  146.                 int program = ARBShaderObjects.glCreateProgramObjectARB();
  147.         ARBShaderObjects.glAttachObjectARB(program, vert.getID());
  148.         ARBShaderObjects.glAttachObjectARB(program, frag.getID());
  149.         ARBShaderObjects.glLinkProgramARB(program);
  150.         //GL20.glValidateProgram(program);
  151.         int comp = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_LINK_STATUS);
  152.         if (comp==0) {
  153.                 int len = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_INFO_LOG_LENGTH);
  154.                         log += ARBShaderObjects.glGetInfoLogARB(program, len);
  155.                         return 0;
  156.         }
  157.         return program;
  158.         }
  159.        
  160.        
  161.        
  162.         /**
  163.          * Returns the log for this shader program as well as any shaders attached to this program.
  164.          * @return
  165.          */
  166.         public String getLog() {
  167.                 return log;
  168.         }
  169.        
  170.         public void unbind() {
  171.                 ARBShaderObjects.glUseProgramObjectARB(0);
  172.         }
  173.        
  174.         public void bind() {
  175.                 if (!valid())
  176.                         throw new IllegalStateException("trying to enable a program that is not valid");
  177.                 ARBShaderObjects.glUseProgramObjectARB(program);
  178.         }
  179.        
  180.         public void release() {
  181.                 ARBShaderObjects.glDetachObjectARB(program, vert.getID());
  182.                 ARBShaderObjects.glDetachObjectARB(program, frag.getID());
  183.                 vert.release();
  184.                 frag.release();
  185.                 ARBShaderObjects.glDeleteObjectARB(program);
  186.         }
  187.        
  188.         public int getID() {
  189.                 return program;
  190.         }
  191.        
  192.         public boolean valid() {
  193.                 return program != 0;
  194.         }
  195.        
  196. //      protected int findAttributeLocation(String name) {
  197. //              int location = attributes.get(name);
  198. //              if (location!=-1)
  199. //                      return location;
  200. //              location = ARBVertexShader.glGetAttribLocationARB(program, name);
  201. //              if (location == -1 && strict)
  202. //                      throw new IllegalArgumentException("no active attribute by name '"+name+"'");
  203. //              attributes.put(name, location);
  204. //              return location;
  205. //      }
  206.        
  207.         protected int findUniformLocation(String name) {
  208.                 Integer locI = uniforms.get(name);
  209.                 int location = locI==null ? -1 : locI.intValue();
  210.                 if (location!=-1)
  211.                         return location;
  212.                 location = ARBShaderObjects.glGetUniformLocationARB(program, name);
  213.                 if (location == -1 && strict)
  214.                         throw new IllegalArgumentException("no active uniform by name '"+name+"' (disable strict compiling to suppress warnings)");
  215.                 uniforms.put(name, location);
  216.                 return location;
  217.         }
  218.        
  219.         private void fetchUniforms() {
  220.                 int len = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_ACTIVE_UNIFORMS);
  221.                 //max length of all uniforms stored in program
  222.                 int strLen = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_ACTIVE_UNIFORM_MAX_LENGTH);
  223.                
  224.                 for (int i=0; i<len; i++) {
  225.                         String name = ARBShaderObjects.glGetActiveUniformARB(program, i, strLen);
  226.                         int id = ARBShaderObjects.glGetUniformLocationARB(program, name);
  227.                         uniforms.put(name, id);
  228.                 }
  229.         }
  230.        
  231. //      private void fetchAttributes() {
  232. //              int len = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_ACTIVE_ATTRIBUTES);
  233. //              //max length of all uniforms stored in program
  234. //              int strLen = ARBShaderObjects.glGetObjectParameteriARB(program, GL20.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH);
  235. //              for (int i=0; i<len; i++) {
  236. //                      String name = ARBVertexShader.glGetActiveAttribARB(program, i, strLen);
  237. //                      int id = ARBVertexShader.glGetAttribLocationARB(program, name);
  238. //                      uniforms.put(name, id);
  239. //              }
  240. //      }
  241.        
  242.         public int getUniformID(String name) {
  243.                 return findUniformLocation(name);
  244.         }
  245.        
  246. //      public int getAttributeID(String name) {
  247. //              return findAttributeLocation(name);
  248. //      }
  249.        
  250. //      public String[] getAttributes() {
  251. //              return attributes.keySet().toArray(new String[attributes.size()]);
  252. //      }
  253.        
  254.         public String[] getUniformNames() {
  255.                 return uniforms.keySet().toArray(new String[uniforms.size()]);
  256.         }
  257.        
  258.         public Shader getVertexShader() {
  259.                 return vert;
  260.         }
  261.        
  262.         public Shader getFragmentShader() {
  263.                 return frag;
  264.         }
  265.  
  266.         public boolean getUniform(String name, FloatBuffer buf) {
  267.                 int id = getUniformID(name);
  268.                 if (id==-1) return false;
  269.                 ARBShaderObjects.glGetUniformARB(program, id, buf);
  270.                 return true;
  271.         }
  272.        
  273.         public boolean getUniform(String name, IntBuffer buf) {
  274.                 int id = getUniformID(name);
  275.                 if (id==-1) return false;
  276.                 ARBShaderObjects.glGetUniformARB(program, id, buf);
  277.                 return true;
  278.         }
  279.        
  280.         public boolean hasUniform(String name) {
  281.                 return uniforms.containsKey(name);
  282.         }
  283.        
  284.         public boolean hasAttribute(String name) {
  285.                 return attributes.containsKey(name);
  286.         }
  287.  
  288.         public void setUniform1f(String name, float f) {
  289.                 int id = getUniformID(name);
  290.                 if (id==-1) return;
  291.                 ARBShaderObjects.glUniform1fARB(id, f);
  292.         }
  293.        
  294.         public void setUniform1i(String name, int i) {
  295.                 int id = getUniformID(name);
  296.                 if (id==-1) return;
  297.                 ARBShaderObjects.glUniform1iARB(id, i);
  298.         }
  299.        
  300.         public void setUniform2f(String name, float a, float b) {
  301.                 int id = getUniformID(name);
  302.                 if (id==-1) return;
  303.                 ARBShaderObjects.glUniform2fARB(id, a, b);
  304.         }
  305.        
  306.         public void setUniform3f(String name, float a, float b, float c) {
  307.                 int id = getUniformID(name);
  308.                 if (id==-1) return;
  309.                 ARBShaderObjects.glUniform3fARB(id, a, b, c);
  310.         }
  311.        
  312.         public void setUniform4f(String name, float a, float b, float c, float d) {
  313.                 int id = getUniformID(name);
  314.                 if (id==-1) return;
  315.                 ARBShaderObjects.glUniform4fARB(id, a, b, c, d);
  316.         }
  317.        
  318.        
  319.         // TODO: include more setUniforms/getUniforms
  320. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top