Package cc.plural.graphics

Source Code of cc.plural.graphics.ShaderProgram

/**
* Copyright (C) 2012 J.W.Marsden <jmarsden@plural.cc>
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package cc.plural.graphics;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL20;

/**
* @deprecated
*/
public class ShaderProgram {

    boolean compiled;

    String vertexShaderSource;

    String fragmentShaderSource;

    int vertexShaderHandle = -1;

    int fragmentShaderHandle = -1;

    int programHandle = -1;

    String[] attributeNames;

    List<ShaderProperty> shaderAttributes;

    String[] uniformNames;

    List<ShaderProperty> shaderUniforms;

    public static final String DEFAULT_VERTEX_SHADER = "#version 120\r\n"
            + "\r\n"
            + "uniform mat4 projectionMatrix;\r\n"
            + "uniform mat4 viewMatrix;\r\n"
            + "uniform mat4 modelMatrix;\r\n"
            + "\r\n"
            + "in vec4 in_Position;\r\n"
            + "in vec4 in_Color;\r\n"
            + "in vec2 in_TextureCoord;\r\n"
            + "\r\n"
            + "out vec4 pass_Color;\r\n"
            + "out vec2 pass_TextureCoord;\r\n"
            + "\r\n"
            + "void main() {\r\n"
            + "  gl_Position = in_Position;\r\n"
            + "  gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_Position;\r\n"
            + "  \r\n"
            + "  pass_Color = in_Color;\r\n"
            + "  pass_TextureCoord = in_TextureCoord;\r\n"
            + "}\r\n";

    public static final String DEFAULT_FRAGMENT_SHADER = "#version 120\r\n"
            + "\r\n"
            + "uniform sampler2D textureDiffuse;\r\n"
            + "\r\n"
            + "in vec4 pass_Color;\r\n"
            + "in vec2 pass_TextureCoord;\r\n"
            + "\r\n"
            + "out vec4 out_Color;\r\n"
            + "\r\n"
            + "void main() {\r\n"
            + "  out_Color = pass_Color;\r\n"
            + "  out_Color = texture2D(textureDiffuse, pass_TextureCoord);\r\n"
            + "}\r\n";

    public ShaderProgram() {
        compiled = false;

        shaderAttributes = null;
        shaderUniforms = null;
    }

    /**
     * @return the programHandle
     */
    public int getProgramHandle() {
        return programHandle;
    }

    public int createShaderProgram(String vertexShaderSource, String fragmentShaderSource) {
        this.vertexShaderSource = vertexShaderSource;
        this.fragmentShaderSource = fragmentShaderSource;

        // TODO: if already made then clean up before remake.
        vertexShaderHandle = compileShader(GL20.GL_VERTEX_SHADER, vertexShaderSource);
        fragmentShaderHandle = compileShader(GL20.GL_FRAGMENT_SHADER, fragmentShaderSource);

        programHandle = GL20.glCreateProgram();
        if(programHandle == 0) {
            throw new NullPointerException("Program Create Error?");
        }

        GL20.glAttachShader(programHandle, vertexShaderHandle);
        GL20.glAttachShader(programHandle, fragmentShaderHandle);
        GL20.glLinkProgram(programHandle);

        ByteBuffer tmp = ByteBuffer.allocateDirect(4);
        tmp.order(ByteOrder.nativeOrder());
        IntBuffer result = tmp.asIntBuffer();

        GL20.glGetProgram(programHandle, GL20.GL_LINK_STATUS, result);
        int linked = result.get(0);
        if(linked == 0) {
            System.out.println("Error with shader Compile:\r\n" + GL20.glGetProgramInfoLog(programHandle, 100));
            return -1;
        }

        compiled = true;

        identifyAttributes();

        identifyUniforms();

        return programHandle;
    }

    public int createDefaultShaderProgram() {
        return createShaderProgram(DEFAULT_VERTEX_SHADER, DEFAULT_FRAGMENT_SHADER);
    }

    private int compileShader(int type, String shader) {

        IntBuffer result = BufferUtils.createIntBuffer(1);

        programHandle = GL20.glCreateShader(type);

        GL20.glShaderSource(programHandle, shader);
        GL20.glCompileShader(programHandle);
        GL20.glGetShader(programHandle, GL20.GL_COMPILE_STATUS, result);

        int compiledResult = result.get(0);
        if(compiledResult == 0) {
            System.out.println("Error with shader Compile:\r\n" + GL20.glGetShaderInfoLog(vertexShaderHandle, 100));
        }

        return programHandle;
    }

    private void identifyAttributes() {
        IntBuffer result = BufferUtils.createIntBuffer(1);
        IntBuffer type = BufferUtils.createIntBuffer(2);

        GL20.glGetProgram(programHandle, GL20.GL_ACTIVE_ATTRIBUTES, result);
        int numAttributes = result.get(0);

        attributeNames = new String[numAttributes];
        shaderAttributes = new ArrayList<ShaderProperty>(numAttributes);

        for(int i = 0; i < numAttributes; i++) {
            //result.clear();
            //result.put(0, 256);
            type.clear();
            String name = GL20.glGetActiveAttrib(programHandle, i, 100, type);
            int location = GL20.glGetAttribLocation(programHandle, name);
            ShaderProperty attribute = new ShaderProperty(location, type.get(0), name);
            shaderAttributes.add(attribute);
            attributeNames[i] = name;
        }
    }

    private void identifyUniforms() {
        IntBuffer result = BufferUtils.createIntBuffer(1);
        IntBuffer type = BufferUtils.createIntBuffer(2);

        GL20.glGetProgram(programHandle, GL20.GL_ACTIVE_UNIFORMS, result);
        int numUniforms = result.get(0);


        uniformNames = new String[numUniforms];
        shaderUniforms = new ArrayList<ShaderProperty>(numUniforms);

        for(int i = 0; i < numUniforms; i++) {

            type.clear();
            String name = GL20.glGetActiveUniform(programHandle, i, 100, type);
            int location = GL20.glGetUniformLocation(programHandle, name);

            ShaderProperty attribute = new ShaderProperty(location, type.get(0), name);
            shaderUniforms.add(attribute);
            uniformNames[i] = name;
        }
    }

    public boolean hasUnform(String name) {
        boolean found = false;
        for(int i = 0; i < uniformNames.length; i++) {
            if(uniformNames[i].equals(name)) {
                found = true;
                break;
            }
        }
        return found;
    }

    public int getUnformLocation(String name) {
        int location = -1;
        for(int i = 0; i < uniformNames.length; i++) {
            if(uniformNames[i].equals(name)) {
                location = i;
                break;
            }
        }
        return location;
    }

    public void setUniformMatrix4f(String name, boolean transpose, FloatBuffer bufferMatrix) {
        if(!hasUnform(name)) {
            throw new RuntimeException("No Uniform " + name);
        }
        GL20.glUniformMatrix4(getUnformLocation(name), transpose, bufferMatrix);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("ShaderProgram:\r\n");
        builder.append("=== Vertex Shader Begin ===\r\n\t");
        builder.append(vertexShaderSource.replace("\n", "\n\t"));
        builder.append("\r\n=== Vertex Shader End ===\r\n");
        builder.append("=== Fragment Shader Begin ===\r\n\t");
        builder.append(fragmentShaderSource.replace("\n", "\n\t"));
        builder.append("\r\n=== Fragment Shader End ===\r\n");

        builder.append("=== Vertex Attributes ===\r\n");

        if(shaderAttributes != null) {
            for(ShaderProperty prop : shaderAttributes) {
                builder.append("\t").append(prop).append("\r\n");
            }
        }

        builder.append("=== Uniforms ===\r\n");
        if(shaderUniforms != null) {
            for(ShaderProperty prop : shaderUniforms) {
                builder.append("\t").append(prop).append("\r\n");
            }
        }

        return builder.toString();
    }

    /**
     * Disposes all resources associated with this shader. Must be called when the shader is no longer used.
     */
    public void dispose() {
        /*
         * GL20 gl = Gdx.graphics.getGL20();
         * gl.glUseProgram(0);
         * gl.glDeleteShader(vertexShaderHandle);
         * gl.glDeleteShader(fragmentShaderHandle);
         * gl.glDeleteProgram(program);
         * if (shaders.get(Gdx.app) != null) shaders.get(Gdx.app).remove(this);
         */
    }
}
TOP

Related Classes of cc.plural.graphics.ShaderProgram

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.