Guest User

AbstractShader

a guest
Oct 18th, 2018
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.29 KB | None | 0 0
  1. package Engine.GraphicsEngine;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.FileReader;
  5. import java.io.IOException;
  6. import java.nio.FloatBuffer;
  7.  
  8. import org.lwjgl.BufferUtils;
  9. import org.lwjgl.opengl.GL11;
  10. import org.lwjgl.opengl.GL20;
  11. import org.lwjglx.util.vector.Matrix4f;
  12. import org.lwjglx.util.vector.Vector3f;
  13.  
  14. import Engine.Exceptions.ExceptionThrower;
  15. import Engine.Exceptions.InternalErrorException;
  16. import Engine.Exceptions.ShaderIncompatableException;
  17. import Engine.OptionManager.EngineOptions;
  18. import Engine.OptionManager.OptionHandler;
  19. /** A generic shader program class which can be etended to create by other shaders.
  20.  *
  21.  * @author Bram Steenbergen
  22.  * @version 1.0
  23.  * @since 1.0
  24.  *
  25.  */
  26. public abstract class AbstractShader {
  27.    
  28.     /** The ID of the shader program.
  29.      */
  30.     private int programID;
  31.    
  32.     /** The ID of the vertes shader.
  33.      */
  34.     private int vertexShaderID;
  35.     /** The ID of the fragment shader.
  36.      */
  37.     private int fragmentShaderID;
  38.    
  39.     /* Filename of the shader.
  40.      */
  41.     private String vertexFile;
  42.    
  43.     /* Filename of the shader.
  44.      */
  45.     private String fragmentFile;
  46.     private static FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
  47.    
  48.     /** Create a nrw GenericSsaderProfram for the given vertex- and fragmentshader's
  49.      *  filename. (Shader files should be placed in the RESShaderFiles folder)
  50.      *
  51.      * @param vertexFile The filename of the vertex shader.
  52.      * @param fragmentFile The filename of the fragment SHader
  53.      */
  54.     public AbstractShader(String vertexFile, String fragmentFile) {
  55.         this.vertexFile = vertexFile;
  56.         this.fragmentFile = fragmentFile;
  57.  
  58.     }
  59.    
  60.     /** Loads the shader in openGL so it can be used.
  61.      */
  62.     public void setupShader() {
  63.         //Get the ID's
  64.         if(!getFileExtention(vertexFile).equals("vs")) {
  65.             ExceptionThrower.throwException(new ShaderIncompatableException(vertexFile));
  66.         }
  67.         if(!getFileExtention(fragmentFile).equals("fs")) {
  68.             ExceptionThrower.throwException(new ShaderIncompatableException(fragmentFile));
  69.         }
  70.         vertexShaderID = loadShader(this.vertexFile, GL20.GL_VERTEX_SHADER);
  71.         fragmentShaderID = loadShader(this.fragmentFile, GL20.GL_FRAGMENT_SHADER);
  72.         programID = GL20.glCreateProgram();
  73.         // attach shaders to program
  74.         GL20.glAttachShader(programID, vertexShaderID);
  75.         GL20.glAttachShader(programID, fragmentShaderID);
  76.         // Link the program.
  77.         bindAttributes();
  78.         GL20.glLinkProgram(programID);
  79.         // Validate the program.
  80.         GL20.glValidateProgram(programID);
  81.         getAllUniformLocations();
  82.     }
  83.    
  84.     /** Get the file extention as a string from a given filepath string (without the dot).
  85.      *
  86.      * @param path The filepath.
  87.      * @return The extention.
  88.      */
  89.     private String getFileExtention(String path) {
  90.         String extension = "";
  91.  
  92.         int i = path.lastIndexOf('.');
  93.         int p = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
  94.  
  95.         if (i >= p) {
  96.             extension = path.substring(i+1);
  97.         }
  98.         return extension;
  99.     }
  100.    
  101.     /** Load a shader from a shader file
  102.      *
  103.      * @param file the filename of the shader
  104.      * @param type the type of the shader
  105.      * @return the ID of the shader
  106.      */
  107.     private static int loadShader(String file, int type){
  108.         //create a string builder.
  109.         StringBuilder shaderSource = new StringBuilder();
  110.         //read the file and store in shaderSource.
  111.         try{
  112.             BufferedReader reader = new BufferedReader(new FileReader(OptionHandler.getProperty(EngineOptions.PATHSHADERFILES_KEY, OptionHandler.ENGINE_OPTION_ID) + file));
  113.             String line;
  114.             while((line = reader.readLine())!=null){
  115.                 shaderSource.append(line).append("//\n");
  116.             }
  117.             reader.close();
  118.         }catch(IOException e){
  119.             System.out.println(file);
  120.             ExceptionThrower.throwException(new InternalErrorException());
  121.         }
  122.         //get shader ID.
  123.         int shaderID = GL20.glCreateShader(type);
  124.         //create shader from source.
  125.         GL20.glShaderSource(shaderID, shaderSource);
  126.         //compile shader.
  127.         GL20.glCompileShader(shaderID);
  128.         //check for errors.
  129.         if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS )== GL11.GL_FALSE){
  130.             System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
  131.             System.err.println("[ERROR]: Could not compile shader!");
  132.             ExceptionThrower.throwException(new InternalErrorException());
  133.         }
  134.         //Return shader ID.
  135.         return shaderID;
  136.     }
  137.    
  138.     /** Start the shader.
  139.      */
  140.     public void start(){
  141.         GL20.glUseProgram(programID);
  142.     }
  143.    
  144.     /** Stop the shader.
  145.      */
  146.     public void stop(){
  147.         GL20.glUseProgram(0);
  148.     }
  149.    
  150.     /** Remove the shader.
  151.      */
  152.     public void cleanUp(){
  153.         // Stop shader before cleanup.
  154.         stop();
  155.         // Detach shaders from program.
  156.         GL20.glDetachShader(programID, vertexShaderID);
  157.         GL20.glDetachShader(programID, fragmentShaderID);
  158.         // Delete shaders.
  159.         GL20.glDeleteShader(vertexShaderID);
  160.         GL20.glDeleteShader(fragmentShaderID);
  161.         // Delete program.
  162.         GL20.glDeleteProgram(programID);
  163.     }
  164.    
  165.     /** Get a uniform variable's location.
  166.      *
  167.      * @param uniformName the name of the uniformVariable.
  168.      * @return the location of the uniform variable.
  169.      */
  170.     protected int getUniformLocation(String uniformName) {
  171.         return GL20.glGetUniformLocation(programID, uniformName);
  172.     }
  173.     /** Get all uniform variables
  174.      */
  175.     protected abstract void getAllUniformLocations();
  176.    
  177.     /** Load a float uniform variable.
  178.      *
  179.      * @param Location the location to load the variable.
  180.      * @param Value the value of the variable.
  181.      */
  182.     protected void loadFloat(int location, float value) {
  183.         GL20.glUniform1f(location, value);
  184.     }
  185.    
  186.    
  187.     /** Load a Vector3f uniform variable.
  188.      *
  189.      * @param Location the location to load the variable.
  190.      * @param Value the value of the variable.
  191.      */
  192.     protected void loadVector(int location, Vector3f value) {
  193.         GL20.glUniform3f(location, value.x, value.y, value.z);
  194.     }
  195.    
  196.    
  197.     /** Load a boolean uniform variable.
  198.      *
  199.      * @param Location the location to load the variable.
  200.      * @param Value the value of the variable.
  201.      */
  202.     protected void loadBoolean(int location, boolean value) {
  203.         float toLoad = 0;
  204.         if(value) {
  205.             toLoad = 1;
  206.         }
  207.         GL20.glUniform1f(location, toLoad);
  208.     }
  209.    
  210.    
  211.     /** Load a Matrix4f uniform variable.
  212.      *
  213.      * @param Location the location to load the variable.
  214.      * @param Value the value of the variable.
  215.      */
  216.     protected void loadMatrix(int location, Matrix4f matrix) {
  217.         matrix.store(buffer);
  218.         buffer.flip();
  219.         GL20.glUniformMatrix4fv(location, false, buffer);
  220.     }
  221.    
  222.     /** Method to override for attibute binding.
  223.      */
  224.     protected abstract void bindAttributes();
  225.    
  226.     /** Bind a single attribute
  227.      */
  228.     protected void bindAttribute(int attribute, String variableName){
  229.         GL20.glBindAttribLocation(programID, attribute, variableName);
  230.     }
  231.  
  232.     @Override
  233.     /** generate a string with shader details.
  234.      *
  235.      * @return The shader details as a string.
  236.      */
  237.     public String toString() {
  238.         return "  [vertexFile=" + vertexFile + ", fragmentFile=" + fragmentFile + "]";
  239.     }
  240. }
Add Comment
Please, Sign In to add comment