Advertisement
Guest User

Untitled

a guest
Mar 19th, 2012
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.94 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement