flash.display.Shader.java Source code

Java tutorial

Introduction

Here is the source code for flash.display.Shader.java

Source

/*
 * This file is part of Apparat.
 *
 * Copyright (C) 2010 Joa Ebert
 * http://www.joa-ebert.com/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package flash.display;

import apparat.pbj.Pbj;
import flash.utils.ByteArray;
import jitb.lang.annotations.Element;
import jitb.lang.annotations.Metadata;
import jitb.util.ShaderUtil;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;

/**
 * @author Joa Ebert
 */
@Metadata({ @Element(name = "Version", keys = { "" }, values = { "10" }) })
public class Shader extends jitb.lang.Object {
    private ByteArray _byteCode;
    private Pbj _pbj;

    private ShaderData _data;

    private int _vertexShaderId = -1;
    private int _fragmentShaderId = -1;
    private int _programId = -1;

    public Shader() {
    }

    public Shader(final ByteArray byteCode) {
        byteCode(byteCode);
    }

    public ByteArray byteCode() {
        return _byteCode;
    }

    public void byteCode(final ByteArray value) {
        _byteCode = value;

        if (null != _pbj) {
            _pbj = null;
            _data = null;
        }

        if (-1 != _programId) {
            //cleanup ...
        }

        pbj();
    }

    public ShaderData data() {
        return _data;
    }

    public void data(final ShaderData value) {
        _data = value;
    }

    public final void JITB$bind(double x, double y, double width, double height) {
        JITB$bind(x, y, width, height, true);
    }

    public void JITB$bind(double x, double y, double width, double height, boolean flipY) {
        if (ShaderUtil.shaderSupport()) {
            ARBShaderObjects.glUseProgramObjectARB(programId());

            final int location = ARBShaderObjects.glGetUniformLocationARB(programId(), "PB_OFFSET");

            if (flipY) {
                ARBShaderObjects.glUniform4fARB(location, (float) x, (float) y, (float) height, -1.0f);
            } else {
                ARBShaderObjects.glUniform4fARB(location, (float) x, (float) y, 0.0f, 1.0f);
            }

            if (null != data()) {
                data().JITB$applyParameters(programId());
            }
        } else {
            throw new RuntimeException("Sorry, no shaders supported on your system.");
        }
    }

    public void JITB$unbind() {
        ARBShaderObjects.glUseProgramObjectARB(0);
        if (null != data()) {
            data().JITB$unapplyParameters();
        }
    }

    private Pbj pbj() {
        if (null == _pbj && null != _byteCode) {
            _pbj = ShaderUtil.getPbj(_byteCode);
            _data = new ShaderData(_pbj);
        }

        return _pbj;
    }

    protected int programId() {
        if (-1 == _programId) {
            compileShader();
        }

        return _programId;
    }

    protected String vertexShader() {
        return pbj().toVertexShader();
    }

    protected String fragmentShader() {
        return pbj().toFragmentShader();
    }

    protected void compileShader() {
        System.out.println("Compiling shader ...");
        final String vertexShader = vertexShader();
        final String fragmentShader = fragmentShader();

        System.out.println("Vertex shader:");
        System.out.println(vertexShader);
        System.out.println("Fragment shader:");
        System.out.println(fragmentShader);

        _vertexShaderId = ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
        ARBShaderObjects.glShaderSourceARB(_vertexShaderId, vertexShader);
        ARBShaderObjects.glCompileShaderARB(_vertexShaderId);
        System.out.println("VertexShader Info: " + ARBShaderObjects.glGetInfoLogARB(_vertexShaderId, 8192));

        _fragmentShaderId = ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
        ARBShaderObjects.glShaderSourceARB(_fragmentShaderId, fragmentShader);
        ARBShaderObjects.glCompileShaderARB(_fragmentShaderId);
        System.out.println("FragmentShader Info: " + ARBShaderObjects.glGetInfoLogARB(_fragmentShaderId, 8192));

        _programId = ARBShaderObjects.glCreateProgramObjectARB();
        ARBShaderObjects.glAttachObjectARB(_programId, _vertexShaderId);
        ARBShaderObjects.glAttachObjectARB(_programId, _fragmentShaderId);
        ARBShaderObjects.glLinkProgramARB(_programId);
        System.out.println("Program Info: " + ARBShaderObjects.glGetInfoLogARB(_programId, 8192));
    }
}