Package cc.plural.ecs.provider

Source Code of cc.plural.ecs.provider.StringLWJGLShader

/**
* Copyright (C) 2013 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.ecs.provider;

import cc.plural.ecs.renderer.Shader;
import cc.plural.ecs.renderer.ShaderAttribute;
import cc.plural.ecs.renderer.Uniform;
import cc.plural.math.Matrix4f;
import cc.plural.utils.MatrixPrinter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL20;

public class StringLWJGLShader extends Shader {

    private static final int NO_SHADER = 0;
    public boolean inError;
    public String vertexCompileError;
    public String fragmentCompileError;
    public String linkError;
    public boolean compiled;
    public ShaderAttribute[] attributes;
    public Uniform[] uniforms;

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

        this.compiled = false;
        this.uniforms = null;

        inError = false;
    }

    public StringLWJGLShader(URL vertexURL, URL fragmentURL) {

        StringBuilder vertexSource = new StringBuilder();
        StringBuilder fragmentSource = new StringBuilder();
        try {
            InputStreamReader streamReader = new InputStreamReader(vertexURL.openStream());
            BufferedReader reader = new BufferedReader(streamReader);
            String line;
            while ((line = reader.readLine()) != null) {
                vertexSource.append(line).append("\n");
            }
            reader.close();

            streamReader = new InputStreamReader(fragmentURL.openStream());
            reader = new BufferedReader(streamReader);

            while ((line = reader.readLine()) != null) {
                fragmentSource.append(line).append("\n");
            }
            reader.close();

        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("Could not read file.");
        }

        this.vertexShaderSource = vertexSource.toString();
        this.fragmentShaderSource = fragmentSource.toString();

        this.compiled = false;
        this.uniforms = null;

        inError = false;

    }

    public boolean inError() {
        return inError;
    }

    public String getVertexCompileError() {
        return vertexCompileError;
    }

    public String getFragmentCompileError() {
        return fragmentCompileError;
    }

    public String getLinkError() {
        return linkError;
    }

    public boolean isInitialized() {
        return vertexShaderSource != null && fragmentShaderSource != null;
    }

    public void init() {
    }

    public boolean isLoaded() {
        return compiled;
    }

    public void load() {
        if (compiled) {
            return;
        }
        vertexShaderHandle = compileShader(GL20.GL_VERTEX_SHADER, vertexShaderSource);
        fragmentShaderHandle = compileShader(GL20.GL_FRAGMENT_SHADER, fragmentShaderSource);

        programHandle = GL20.glCreateProgram();
        if (programHandle == NO_SHADER) {
            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(NO_SHADER);
        if (linked == NO_SHADER) {
            linkError = GL20.glGetProgramInfoLog(programHandle, 1000);
            System.err.println("Shader Link Error: \"" + linkError + "\"");
            inError = true;
        } else {
            compiled = true;
        }
    }

    public void unLoad() {
        if (programHandle != -1) {
            GL20.glDeleteProgram(programHandle);
            programHandle = -1;
        }
        if (fragmentShaderHandle != -1) {
            GL20.glDeleteShader(fragmentShaderHandle);
            fragmentShaderHandle = -1;
        }
        if (vertexShaderHandle != -1) {
            GL20.glDeleteShader(vertexShaderHandle);
            vertexShaderHandle = -1;
        }
        attributes = null;
        uniforms = null;
        compiled = false;
    }

    public void release() {
        this.vertexShaderSource = null;
        this.fragmentShaderSource = null;
    }

    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(NO_SHADER);
        if (compiledResult == NO_SHADER) {
            if (type == GL20.GL_VERTEX_SHADER) {
                vertexCompileError = GL20.glGetShaderInfoLog(programHandle, 1000);
                System.err.println("Vertex Shader Compile Error: \"" + vertexCompileError + "\"");
                inError = true;
            } else if (type == GL20.GL_FRAGMENT_SHADER) {
                fragmentCompileError = GL20.glGetShaderInfoLog(programHandle, 1000);
                System.err.println("Fragment Shader Compile Error: \"" + fragmentCompileError + "\"");
                inError = true;
            } else {
                System.out.println("Something Wrong Here With Compile:" + shader);
            }
        }

        return programHandle;
    }

    @Override
    public Uniform[] getUniforms() {
        if (uniforms != null) {
            return uniforms;
        }
        IntBuffer result = BufferUtils.createIntBuffer(1);
        IntBuffer type = BufferUtils.createIntBuffer(2);

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

        uniforms = new LWJGLUniform[numUniforms];

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

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

            Uniform uniform = new LWJGLUniform();
            uniform.name = name;
            uniform.location = location;
            uniform.type = typeValue;

            uniforms[i] = uniform;
        }
        return uniforms;
    }

    @Override
    public ShaderAttribute[] getAttributes() {
        if (attributes != null) {
            return attributes;
        }
        IntBuffer result = BufferUtils.createIntBuffer(1);
        IntBuffer type = BufferUtils.createIntBuffer(2);

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

        attributes = new ShaderAttribute[numAttributes];

        for (int i = NO_SHADER; i < numAttributes; i++) {
            type.clear();
            String name = GL20.glGetActiveAttrib(programHandle, i, 100, type);
            int location = GL20.glGetAttribLocation(programHandle, name);
            int typeValue = type.get(NO_SHADER);

            ShaderAttribute attribute = new LWJGLShaderAttribute();
            attribute.name = name;
            attribute.location = location;
            attribute.type = typeValue;

            attributes[i] = attribute;
        }
        return attributes;
    }

    @Override
    public boolean hasAttribute(String name) {
        if (attributes == null) {
            getAttributes();
        }
        for (ShaderAttribute attribute : attributes) {
            if (attribute.name != null && attribute.name.equals(name)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean hasAttribute(int location) {
        if (attributes == null) {
            getAttributes();
        }
        for (ShaderAttribute attribute : attributes) {
            if (attribute.location == location) {
                return true;
            }
        }
        return false;
    }

    @Override
    public ShaderAttribute getAttribute(String name) {
        if (attributes == null) {
            getAttributes();
        }
        for (ShaderAttribute attribute : attributes) {
            if (attribute.name != null && attribute.name.equals(name)) {
                return attribute;
            }
        }
        return null;
    }

    @Override
    public int getAttributeLocation(String name) {
        if (attributes == null) {
            getAttributes();
        }
        for (ShaderAttribute attribute : attributes) {
            if (attribute.name != null && attribute.name.equals(name)) {
                return attribute.location;
            }
        }
        return -1;
    }

    @Override
    public ShaderAttribute getAttribute(int location) {
        if (attributes == null) {
            getAttributes();
        }
        for (ShaderAttribute attribute : attributes) {
            if (attribute.location == location) {
                return attribute;
            }
        }
        return null;
    }

    @Override
    public boolean hasUniform(String name) {
        for (Uniform uniform : getUniforms()) {
            if (uniform.name != null && uniform.name.equals(name)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean hasUniform(int location) {
        for (Uniform uniform : getUniforms()) {
            if (uniform.location == location) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Uniform getUniform(String name) {
        for (Uniform uniform : getUniforms()) {
            if (uniform.name != null && uniform.name.equals(name)) {
                return uniform;
            }
        }
        return null;
    }

    @Override
    public Uniform getUniform(int location) {
        for (Uniform uniform : getUniforms()) {
            if (uniform.location == location) {
                return uniform;
            }
        }
        return null;
    }

    @Override
    public int getUniformLocation(String name) {
        for (Uniform uniform : getUniforms()) {
            if (uniform.name != null && uniform.name.equals(name)) {
                return uniform.location;
            }
        }
        return -1;
    }

    @Override
    public void enable() {
        if (!isInitialized()) {
            init();
        }
        if (!isLoaded()) {
            load();
        }
        GL20.glUseProgram(programHandle);
    }

    @Override
    public void disable() {
        GL20.glUseProgram(NO_SHADER);
    }

    @Override
    public void setUniform(String name, Matrix4f matrix) {
        if (!hasUniform(name)) {
            return;
        }
        int location = getUniformLocation(name);
        setUniform(location, matrix);
    }

    @Override
    public void setUniform(int location, Matrix4f matrix) {
        if (!hasUniform(location)) {
            return;
        }
        FloatBuffer matrix44Buffer = BufferUtils.createFloatBuffer(16);
        matrix.loadColumnMajor(matrix44Buffer);
        matrix44Buffer.flip();
        GL20.glUniformMatrix4(location, false, matrix44Buffer);
    }

}
TOP

Related Classes of cc.plural.ecs.provider.StringLWJGLShader

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.