159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved. 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met: 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer. 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer in the 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * documentation and/or other materials provided with the distribution. 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * may be used to endorse or promote products derived from this software 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * without specific prior written permission. 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.shader; 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.*; 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.renderer.Renderer; 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer; 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.IntMap; 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.IntMap.Entry; 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.ListMap; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.NativeObject; 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Collection; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.HashMap; 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic final class Shader extends NativeObject implements Savable { 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private String language; 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * True if the shader is fully compiled & linked. 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * (e.g no GL error will be invoked if used). 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private boolean usable = false; 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * A list of all shaders currently attached. 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private ArrayList<ShaderSource> shaderList; 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Maps uniform name to the uniform variable. 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// private HashMap<String, Uniform> uniforms; 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private ListMap<String, Uniform> uniforms; 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Maps attribute name to the location of the attribute in the shader. 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private IntMap<Attribute> attribs; 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Type of shader. The shader will control the pipeline of it's type. 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static enum ShaderType { 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Control fragment rasterization. (e.g color of pixel). 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Fragment, 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Control vertex processing. (e.g transform of model to clip space) 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vertex, 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Control geometry assembly. (e.g compile a triangle list from input data) 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Geometry; 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Shader source describes a shader object in OpenGL. Each shader source 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * is assigned a certain pipeline which it controls (described by it's type). 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static class ShaderSource extends NativeObject implements Savable { 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ShaderType shaderType; 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta boolean usable = false; 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta String name = null; 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta String source = null; 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta String defines = null; 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public ShaderSource(ShaderType type){ 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(ShaderSource.class); 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.shaderType = type; 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (type == null) 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new NullPointerException("The shader type must be specified"); 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected ShaderSource(ShaderSource ss){ 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(ShaderSource.class, ss.id); 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.shaderType = ss.shaderType; 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta usable = false; 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta name = ss.name; 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // forget source & defines 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public ShaderSource(){ 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(ShaderSource.class); 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter ex) throws IOException{ 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta OutputCapsule oc = ex.getCapsule(this); 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(shaderType, "shaderType", null); 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(name, "name", null); 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(source, "source", null); 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(defines, "defines", null); 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter im) throws IOException{ 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta InputCapsule ic = im.getCapsule(this); 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shaderType = ic.readEnum("shaderType", ShaderType.class, null); 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta name = ic.readString("name", null); 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta source = ic.readString("source", null); 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta defines = ic.readString("defines", null); 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setName(String name){ 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.name = name; 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public String getName(){ 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return name; 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public ShaderType getType() { 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return shaderType; 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setSource(String source){ 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (source == null) 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new NullPointerException("Shader source cannot be null"); 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.source = source; 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setUpdateNeeded(); 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setDefines(String defines){ 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (defines == null) 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new NullPointerException("Shader defines cannot be null"); 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.defines = defines; 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setUpdateNeeded(); 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public String getSource(){ 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return source; 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public String getDefines(){ 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return defines; 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean isUsable(){ 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return usable; 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setUsable(boolean usable){ 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.usable = usable; 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public String toString(){ 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta String nameTxt = ""; 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (name != null) 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nameTxt = "name="+name+", "; 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (defines != null) 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nameTxt += "defines, "; 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return getClass().getSimpleName() + "["+nameTxt+"type=" 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + shaderType.name()+"]"; 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void resetObject(){ 19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta id = -1; 20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta usable = false; 20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setUpdateNeeded(); 20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void deleteObject(Object rendererObject){ 20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ((Renderer)rendererObject).deleteShaderSource(ShaderSource.this); 20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public NativeObject createDestructableClone(){ 20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return new ShaderSource(ShaderSource.this); 21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Create an empty shader. 21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Shader(String language){ 21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(Shader.class); 21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.language = language; 21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shaderList = new ArrayList<ShaderSource>(); 22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// uniforms = new HashMap<String, Uniform>(); 22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta uniforms = new ListMap<String, Uniform>(); 22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta attribs = new IntMap<Attribute>(); 22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Do not use this constructor. Serialization purposes only. 22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Shader(){ 22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(Shader.class); 23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Shader(Shader s){ 23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(Shader.class, s.id); 23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shaderList = new ArrayList<ShaderSource>(); 23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //uniforms = new ListMap<String, Uniform>(); 23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //attribs = new IntMap<Attribute>(); 23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // NOTE: Because ShaderSources are registered separately with 23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // the GLObjectManager 24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (ShaderSource source : s.shaderList){ 24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shaderList.add( (ShaderSource)source.createDestructableClone() ); 24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter ex) throws IOException{ 24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta OutputCapsule oc = ex.getCapsule(this); 24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.write(language, "language", null); 24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.writeSavableArrayList(shaderList, "shaderList", null); 24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.writeIntSavableMap(attribs, "attribs", null); 25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta oc.writeStringSavableMap(uniforms, "uniforms", null); 25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter im) throws IOException{ 25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta InputCapsule ic = im.getCapsule(this); 25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta language = ic.readString("language", null); 25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shaderList = ic.readSavableArrayList("shaderList", null); 25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta attribs = (IntMap<Attribute>) ic.readIntSavableMap("attribs", null); 25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta HashMap<String, Uniform> uniMap = (HashMap<String, Uniform>) ic.readStringSavableMap("uniforms", null); 26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta uniforms = new ListMap<String, Uniform>(uniMap); 26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Creates a deep clone of the shader, where the sources are available 26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * but have not been compiled yet. Does not copy the uniforms or attribs. 26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return 26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// public Shader createDeepClone(String defines){ 26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Shader newShader = new Shader(language); 27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// for (ShaderSource source : shaderList){ 27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// if (!source.getDefines().equals(defines)){ 27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// // need to clone the shadersource so 27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// // the correct defines can be placed 27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// ShaderSource newSource = new ShaderSource(source.getType()); 27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// newSource.setSource(source.getSource()); 27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// newSource.setDefines(defines); 27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// newShader.addSource(newSource); 27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// }else{ 27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// // no need to clone source, also saves 28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// // having to compile the shadersource 28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// newShader.addSource(source); 28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return newShader; 28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Adds source code to a certain pipeline. 28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param type The pipeline to control 29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param source The shader source code (in GLSL). 29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void addSource(ShaderType type, String name, String source, String defines){ 29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ShaderSource shader = new ShaderSource(type); 29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shader.setSource(source); 29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shader.setName(name); 29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (defines != null) 29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shader.setDefines(defines); 29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shaderList.add(shader); 30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setUpdateNeeded(); 30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void addSource(ShaderType type, String source, String defines){ 30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta addSource(type, null, source, defines); 30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void addSource(ShaderType type, String source){ 30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta addSource(type, source, null); 31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Adds an existing shader source to this shader. 31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param source 31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private void addSource(ShaderSource source){ 31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shaderList.add(source); 31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setUpdateNeeded(); 31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Uniform getUniform(String name){ 32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Uniform uniform = uniforms.get(name); 32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (uniform == null){ 32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta uniform = new Uniform(); 32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta uniform.name = name; 32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta uniforms.put(name, uniform); 32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return uniform; 32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void removeUniform(String name){ 33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta uniforms.remove(name); 33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Attribute getAttribute(VertexBuffer.Type attribType){ 33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int ordinal = attribType.ordinal(); 33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Attribute attrib = attribs.get(ordinal); 33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (attrib == null){ 33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta attrib = new Attribute(); 34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta attrib.name = attribType.name(); 34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta attribs.put(ordinal, attrib); 34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return attrib; 34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// public Collection<Uniform> getUniforms(){ 34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return uniforms.values(); 34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public ListMap<String, Uniform> getUniformMap(){ 35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return uniforms; 35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// public Collection<Attribute> getAttributes() { 35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// return attribs. 35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// } 35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Collection<ShaderSource> getSources(){ 35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return shaderList; 36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public String getLanguage(){ 36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return language; 36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public String toString(){ 36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return getClass().getSimpleName() + "[language="+language 36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + ", numSources="+shaderList.size() 37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + ", numUniforms="+uniforms.size() 37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta + ", shaderSources="+getSources()+"]"; 37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Clears all sources. Assuming that they have already been detached and 37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * removed on the GL side. 37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void resetSources(){ 37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta shaderList.clear(); 38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Returns true if this program and all it's shaders have been compiled, 38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * linked and validated successfuly. 38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean isUsable(){ 38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return usable; 38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Sets if the program can be used. Should only be called by the Renderer. 39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param usable 39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setUsable(boolean usable){ 39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.usable = usable; 39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Usually called when the shader itself changes or during any 40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * time when the var locations need to be refreshed. 40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void resetLocations(){ 40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // NOTE: Shader sources will be reset seperately from the shader itself. 40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (Uniform uniform : uniforms.values()){ 40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta uniform.reset(); // fixes issue with re-initialization 40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (Entry<Attribute> entry : attribs){ 40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta entry.getValue().location = -2; 40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setUpdateNeeded(){ 41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.setUpdateNeeded(); 41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta resetLocations(); 41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Called by the object manager to reset all object IDs. This causes 42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the shader to be reuploaded to the GPU incase the display was restarted. 42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void resetObject() { 42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.id = -1; 42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.usable = false; 42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (ShaderSource source : shaderList){ 42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta source.resetObject(); 42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta setUpdateNeeded(); 43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void deleteObject(Object rendererObject) { 43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ((Renderer)rendererObject).deleteShader(this); 43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public NativeObject createDestructableClone(){ 44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return new Shader(this); 44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 444