Advertisement
Guest User

Untitled

a guest
Jul 24th, 2014
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.38 KB | None | 0 0
  1. package ecumene.opengl;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.File;
  5. import java.io.FileReader;
  6. import java.nio.FloatBuffer;
  7. import java.nio.IntBuffer;
  8. import java.util.HashMap;
  9.  
  10. import org.lwjgl.BufferUtils;
  11. import org.lwjgl.opengl.GL11;
  12. import org.lwjgl.opengl.GL20;
  13. import org.lwjgl.opengl.Util;
  14.  
  15. import ecumene.EcuException;
  16.  
  17. /**
  18.  * Used for loading GLSL shader program sources from
  19.  * files then loading them into OpenGL with their
  20.  * correct custom, and primitive GLSL syntax.
  21.  *
  22.  * @author Ecumene
  23.  */
  24. public class Shader {
  25.     /**Shader program pointer*/
  26.     private int programID;
  27.    
  28.     /** Holds the shader sources*/
  29.     private HashMap<File, Integer> shaderSources;
  30.    
  31.     /**Initializes a shader with empty parameters*/
  32.     public Shader(){
  33.         programID = GL20.glCreateProgram();
  34.         shaderSources = new HashMap<>();
  35.     }
  36.    
  37.     /**
  38.      * Attach a shader source for linking
  39.      *
  40.      * @param file The file name of the shader source
  41.      * @param type The shader type
  42.      * @see Shader#link();
  43.      */
  44.     public void attachShaderSource(File file, int type){
  45.         String shaderSource = sourceFromFile(file);
  46.         int shader;
  47.        
  48.         shader = GL20.glCreateShader(type);
  49.         GL20.glShaderSource(shader, shaderSource);
  50.        
  51.         GL20.glCompileShader(shader);
  52.        
  53.         if (GL20.glGetShaderi(shader, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE)
  54.         {
  55.             System.err.println("Unable to compile shader:");
  56.             System.err.println(GL20.glGetShaderInfoLog(shader, GL20.glGetShaderi(shader, GL20.GL_INFO_LOG_LENGTH)));
  57.            
  58.             dispose();
  59.             throw new EcuException("Unable to compile shader, GLSL error");
  60.         }
  61.        
  62.         GL20.glAttachShader(programID, shader);
  63.         Util.checkGLError();
  64.         shaderSources.put(file, shader);
  65.     }
  66.    
  67.     /**
  68.      * Links the shader program
  69.      * @see Shader#attachShaderSource(File file, int type);
  70.      */
  71.     public void link(){
  72.         GL20.glLinkProgram(programID);
  73.         GL20.glValidateProgram(programID);
  74.        
  75.         if (GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS) == GL11.GL_FALSE)
  76.         {
  77.             dispose();
  78.             throw new EcuException("Unable to link shader program.");
  79.         }
  80.        
  81.         Util.checkGLError();
  82.     }
  83.    
  84.     /**
  85.      * Binds the shader program
  86.      */
  87.     public void bind(){
  88.         GL20.glUseProgram(programID);
  89.     }
  90.    
  91.     /**
  92.      * Unbinds the shader program
  93.      */
  94.     public static void unbind(){
  95.         GL20.glUseProgram(0);
  96.     }
  97.    
  98.     /**
  99.      * Removes the shader program from the ram, and unbinds it
  100.      */
  101.     public void dispose()
  102.     {
  103.         unbind();
  104.  
  105.         for(Integer i : shaderSources.values()){
  106.             GL20.glDetachShader(programID, i);
  107.             GL20.glDeleteShader(i);
  108.         }
  109.        
  110.         GL20.glDeleteProgram(programID);
  111.     }
  112.    
  113.     /**
  114.      * Sets a uniform float
  115.      * @param name The uniform's name
  116.      * @param values The uniforms values
  117.      */
  118.     public void setUniformf(String name, float ... values){
  119.         if(values.length > 4){
  120.             throw new EcuException("Too many variables! (x>4)");
  121.         }
  122.        
  123.         FloatBuffer floats = BufferUtils.createFloatBuffer(values.length);
  124.         floats.put(values);
  125.         floats.flip();
  126.        
  127.         int location = GL20.glGetUniformLocation(programID, name);
  128.        
  129.         switch(values.length){
  130.             case 1: GL20.glUniform1(location, floats);
  131.             case 2: GL20.glUniform2(location, floats);
  132.             case 3: GL20.glUniform3(location, floats);
  133.             case 4: GL20.glUniform4(location, floats);
  134.         }
  135.     }
  136.    
  137.     /**
  138.      * Sets a uniform integer
  139.      * @param name The uniform's name
  140.      * @param values The uniforms values
  141.      */
  142.     public void setUniformi(String name, int ... values){
  143.         if(values.length > 4){
  144.             throw new EcuException("Too many variables! (x>4)");
  145.         }
  146.        
  147.         IntBuffer ints = BufferUtils.createIntBuffer(values.length);
  148.         ints.put(values);
  149.         ints.flip();
  150.        
  151.         int location = GL20.glGetUniformLocation(programID, name);
  152.        
  153.         switch(values.length){
  154.             case 1: GL20.glUniform1(location, ints);
  155.             case 2: GL20.glUniform2(location, ints);
  156.             case 3: GL20.glUniform3(location, ints);
  157.             case 4: GL20.glUniform4(location, ints);
  158.         }
  159.     }
  160.    
  161.     /**
  162.      * Binds a vertex attribute to a ID
  163.      * @param name The attribute's name
  164.      * @param id The attributre's ID
  165.      */
  166.     public void bindAttribute(int id, String name){
  167.         GL20.glBindAttribLocation(programID, id, name);
  168.     }
  169.    
  170.     /**
  171.      * <a href="https://github.com/BennyQBD/3DGameEngine/blob/master/src/com/base/engine/rendering/Shader.java">Special thanks to TheBennyBox (BennyQBD)</a>
  172.      * Loads text from a file and parses for a '#include', then matches it with the correct included file
  173.      */
  174.     private static String sourceFromFile(File file)
  175.     {
  176.         StringBuilder shaderSource = new StringBuilder();
  177.         BufferedReader shaderReader = null;
  178.         final String INCLUDE_DIRECTIVE = "#include";
  179.  
  180.         try
  181.         {
  182.             shaderReader = new BufferedReader(new FileReader(file));
  183.             String line;
  184.  
  185.             while((line = shaderReader.readLine()) != null)
  186.             {
  187.                 if(line.startsWith(INCLUDE_DIRECTIVE))
  188.                 {
  189.                     shaderSource.append(sourceFromFile(new File(line.substring(INCLUDE_DIRECTIVE.length() + 2, line.length() - 1))));
  190.                 }
  191.                 else
  192.                     shaderSource.append(line).append("\n");
  193.             }
  194.  
  195.             shaderReader.close();
  196.         }
  197.         catch(Exception e)
  198.         {
  199.             e.printStackTrace();
  200.             System.exit(1);
  201.         }
  202.  
  203.  
  204.         return shaderSource.toString();
  205.     }
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement