Commit patch from abies that drastically reduce the garbage creation when switching techniques. It also reduce grabage collection for the AbdtractShadowRenderer.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10497 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
0186a20983
commit
723e3c0e30
@ -1,261 +1,260 @@ |
|||||||
/* |
/* |
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
* All rights reserved. |
* All rights reserved. |
||||||
* |
* |
||||||
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
||||||
* modification, are permitted provided that the following conditions are |
* modification, are permitted provided that the following conditions are |
||||||
* met: |
* met: |
||||||
* |
* |
||||||
* * Redistributions of source code must retain the above copyright |
* * Redistributions of source code must retain the above copyright |
||||||
* notice, this list of conditions and the following disclaimer. |
* notice, this list of conditions and the following disclaimer. |
||||||
* |
* |
||||||
* * Redistributions in binary form must reproduce the above copyright |
* * Redistributions in binary form must reproduce the above copyright |
||||||
* notice, this list of conditions and the following disclaimer in the |
* notice, this list of conditions and the following disclaimer in the |
||||||
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
||||||
* |
* |
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
* may be used to endorse or promote products derived from this software |
* may be used to endorse or promote products derived from this software |
||||||
* without specific prior written permission. |
* without specific prior written permission. |
||||||
* |
* |
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
*/ |
*/ |
||||||
package com.jme3.material; |
package com.jme3.material; |
||||||
|
|
||||||
import com.jme3.asset.AssetManager; |
import com.jme3.asset.AssetManager; |
||||||
import com.jme3.renderer.Caps; |
import com.jme3.renderer.Caps; |
||||||
import com.jme3.shader.*; |
import com.jme3.shader.*; |
||||||
import java.util.ArrayList; |
import java.util.ArrayList; |
||||||
import java.util.Collection; |
import java.util.Collection; |
||||||
import java.util.EnumSet; |
import java.util.EnumSet; |
||||||
import java.util.List; |
import java.util.List; |
||||||
import java.util.logging.Logger; |
import java.util.logging.Logger; |
||||||
|
|
||||||
/** |
/** |
||||||
* Represents a technique instance. |
* Represents a technique instance. |
||||||
*/ |
*/ |
||||||
public class Technique /* implements Savable */ { |
public class Technique /* implements Savable */ { |
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Technique.class.getName()); |
private static final Logger logger = Logger.getLogger(Technique.class.getName()); |
||||||
private TechniqueDef def; |
private TechniqueDef def; |
||||||
private Material owner; |
private Material owner; |
||||||
private ArrayList<Uniform> worldBindUniforms; |
private ArrayList<Uniform> worldBindUniforms; |
||||||
private DefineList defines; |
private DefineList defines; |
||||||
private Shader shader; |
private Shader shader; |
||||||
private boolean needReload = true; |
private boolean needReload = true; |
||||||
|
|
||||||
/** |
/** |
||||||
* Creates a new technique instance that implements the given |
* Creates a new technique instance that implements the given |
||||||
* technique definition. |
* technique definition. |
||||||
* |
* |
||||||
* @param owner The material that will own this technique |
* @param owner The material that will own this technique |
||||||
* @param def The technique definition being implemented. |
* @param def The technique definition being implemented. |
||||||
*/ |
*/ |
||||||
public Technique(Material owner, TechniqueDef def) { |
public Technique(Material owner, TechniqueDef def) { |
||||||
this.owner = owner; |
this.owner = owner; |
||||||
this.def = def; |
this.def = def; |
||||||
if (def.isUsingShaders()) { |
if (def.isUsingShaders()) { |
||||||
this.worldBindUniforms = new ArrayList<Uniform>(); |
this.worldBindUniforms = new ArrayList<Uniform>(); |
||||||
this.defines = new DefineList(); |
this.defines = new DefineList(); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Serialization only. Do not use. |
* Serialization only. Do not use. |
||||||
*/ |
*/ |
||||||
public Technique() { |
public Technique() { |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Returns the technique definition that is implemented by this technique |
* Returns the technique definition that is implemented by this technique |
||||||
* instance. |
* instance. |
||||||
* |
* |
||||||
* @return the technique definition that is implemented by this technique |
* @return the technique definition that is implemented by this technique |
||||||
* instance. |
* instance. |
||||||
*/ |
*/ |
||||||
public TechniqueDef getDef() { |
public TechniqueDef getDef() { |
||||||
return def; |
return def; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Returns the shader currently used by this technique instance. |
* Returns the shader currently used by this technique instance. |
||||||
* <p> |
* <p> |
||||||
* Shaders are typically loaded dynamically when the technique is first |
* Shaders are typically loaded dynamically when the technique is first |
||||||
* used, therefore, this variable will most likely be null most of the time. |
* used, therefore, this variable will most likely be null most of the time. |
||||||
* |
* |
||||||
* @return the shader currently used by this technique instance. |
* @return the shader currently used by this technique instance. |
||||||
*/ |
*/ |
||||||
public Shader getShader() { |
public Shader getShader() { |
||||||
return shader; |
return shader; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Returns a list of uniforms that implements the world parameters |
* Returns a list of uniforms that implements the world parameters |
||||||
* that were requested by the material definition. |
* that were requested by the material definition. |
||||||
* |
* |
||||||
* @return a list of uniforms implementing the world parameters. |
* @return a list of uniforms implementing the world parameters. |
||||||
*/ |
*/ |
||||||
public List<Uniform> getWorldBindUniforms() { |
public List<Uniform> getWorldBindUniforms() { |
||||||
return worldBindUniforms; |
return worldBindUniforms; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Called by the material to tell the technique a parameter was modified. |
* Called by the material to tell the technique a parameter was modified. |
||||||
* Specify <code>null</code> for value if the param is to be cleared. |
* Specify <code>null</code> for value if the param is to be cleared. |
||||||
*/ |
*/ |
||||||
void notifyParamChanged(String paramName, VarType type, Object value) { |
void notifyParamChanged(String paramName, VarType type, Object value) { |
||||||
// Check if there's a define binding associated with this
|
// Check if there's a define binding associated with this
|
||||||
// parameter.
|
// parameter.
|
||||||
String defineName = def.getShaderParamDefine(paramName); |
String defineName = def.getShaderParamDefine(paramName); |
||||||
if (defineName != null) { |
if (defineName != null) { |
||||||
// There is a define. Change it on the define list.
|
// There is a define. Change it on the define list.
|
||||||
// The "needReload" variable will determine
|
// The "needReload" variable will determine
|
||||||
// if the shader will be reloaded when the material
|
// if the shader will be reloaded when the material
|
||||||
// is rendered.
|
// is rendered.
|
||||||
|
|
||||||
if (value == null) { |
if (value == null) { |
||||||
// Clear the define.
|
// Clear the define.
|
||||||
needReload = defines.remove(defineName) || needReload; |
needReload = defines.remove(defineName) || needReload; |
||||||
} else { |
} else { |
||||||
// Set the define.
|
// Set the define.
|
||||||
needReload = defines.set(defineName, type, value) || needReload; |
needReload = defines.set(defineName, type, value) || needReload; |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
void updateUniformParam(String paramName, VarType type, Object value) { |
void updateUniformParam(String paramName, VarType type, Object value) { |
||||||
if (paramName == null) { |
if (paramName == null) { |
||||||
throw new IllegalArgumentException(); |
throw new IllegalArgumentException(); |
||||||
} |
} |
||||||
|
|
||||||
Uniform u = shader.getUniform(paramName); |
Uniform u = shader.getUniform(paramName); |
||||||
switch (type) { |
switch (type) { |
||||||
case TextureBuffer: |
case TextureBuffer: |
||||||
case Texture2D: // fall intentional
|
case Texture2D: // fall intentional
|
||||||
case Texture3D: |
case Texture3D: |
||||||
case TextureArray: |
case TextureArray: |
||||||
case TextureCubeMap: |
case TextureCubeMap: |
||||||
case Int: |
case Int: |
||||||
u.setValue(VarType.Int, value); |
u.setValue(VarType.Int, value); |
||||||
break; |
break; |
||||||
default: |
default: |
||||||
u.setValue(type, value); |
u.setValue(type, value); |
||||||
break; |
break; |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Returns true if the technique must be reloaded. |
* Returns true if the technique must be reloaded. |
||||||
* <p> |
* <p> |
||||||
* If a technique needs to reload, then the {@link Material} should |
* If a technique needs to reload, then the {@link Material} should |
||||||
* call {@link #makeCurrent(com.jme3.asset.AssetManager) } on this |
* call {@link #makeCurrent(com.jme3.asset.AssetManager) } on this |
||||||
* technique. |
* technique. |
||||||
* |
* |
||||||
* @return true if the technique must be reloaded. |
* @return true if the technique must be reloaded. |
||||||
*/ |
*/ |
||||||
public boolean isNeedReload() { |
public boolean isNeedReload() { |
||||||
return needReload; |
return needReload; |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Prepares the technique for use by loading the shader and setting |
* Prepares the technique for use by loading the shader and setting |
||||||
* the proper defines based on material parameters. |
* the proper defines based on material parameters. |
||||||
* |
* |
||||||
* @param assetManager The asset manager to use for loading shaders. |
* @param assetManager The asset manager to use for loading shaders. |
||||||
*/ |
*/ |
||||||
public void makeCurrent(AssetManager assetManager, boolean techniqueSwitched, EnumSet<Caps> rendererCaps) { |
public void makeCurrent(AssetManager assetManager, boolean techniqueSwitched, EnumSet<Caps> rendererCaps) { |
||||||
if (!def.isUsingShaders()) { |
if (!def.isUsingShaders()) { |
||||||
// No shaders are used, no processing is neccessary.
|
// No shaders are used, no processing is neccessary.
|
||||||
return; |
return; |
||||||
} |
} |
||||||
|
|
||||||
if (techniqueSwitched) { |
if (techniqueSwitched) { |
||||||
// If the technique was switched, check if the define list changed
|
// If the technique was switched, check if the define list changed
|
||||||
// based on material parameters.
|
// based on material parameters.
|
||||||
DefineList newDefines = new DefineList(); |
|
||||||
Collection<MatParam> params = owner.getParams(); |
Collection<MatParam> params = owner.getParams(); |
||||||
for (MatParam param : params) { |
|
||||||
String defineName = def.getShaderParamDefine(param.getName()); |
if (!defines.equalsParams(params,def)) { |
||||||
if (defineName != null) { |
// Defines were changed, update define list
|
||||||
newDefines.set(defineName, param.getVarType(), param.getValue()); |
defines.clear(); |
||||||
} |
for (MatParam param : params) { |
||||||
} |
String defineName = def.getShaderParamDefine(param.getName()); |
||||||
|
if (defineName != null) { |
||||||
if (!defines.getCompiled().equals(newDefines.getCompiled())) { |
defines.set(defineName, param.getVarType(), param.getValue()); |
||||||
// Defines were changed, update define list
|
} |
||||||
defines.clear(); |
} |
||||||
defines.addFrom(newDefines); |
needReload = true; |
||||||
needReload = true; |
} |
||||||
} |
} |
||||||
} |
|
||||||
|
if (needReload) { |
||||||
if (needReload) { |
loadShader(assetManager,rendererCaps); |
||||||
loadShader(assetManager,rendererCaps); |
} |
||||||
} |
} |
||||||
} |
|
||||||
|
private void loadShader(AssetManager manager,EnumSet<Caps> rendererCaps) { |
||||||
private void loadShader(AssetManager manager,EnumSet<Caps> rendererCaps) { |
|
||||||
|
if (getDef().isUsingShaderNodes()) { |
||||||
if (getDef().isUsingShaderNodes()) { |
shader = manager.getShaderGenerator(rendererCaps).generateShader(this); |
||||||
shader = manager.getShaderGenerator(rendererCaps).generateShader(this); |
} else { |
||||||
} else { |
ShaderKey key = new ShaderKey(def.getVertexShaderName(), |
||||||
ShaderKey key = new ShaderKey(def.getVertexShaderName(), |
def.getFragmentShaderName(), |
||||||
def.getFragmentShaderName(), |
getAllDefines(), |
||||||
getAllDefines(), |
def.getVertexShaderLanguage(), |
||||||
def.getVertexShaderLanguage(), |
def.getFragmentShaderLanguage()); |
||||||
def.getFragmentShaderLanguage()); |
shader = manager.loadShader(key); |
||||||
shader = manager.loadShader(key); |
|
||||||
|
} |
||||||
} |
// register the world bound uniforms
|
||||||
// register the world bound uniforms
|
worldBindUniforms.clear(); |
||||||
worldBindUniforms.clear(); |
if (def.getWorldBindings() != null) { |
||||||
if (def.getWorldBindings() != null) { |
for (UniformBinding binding : def.getWorldBindings()) { |
||||||
for (UniformBinding binding : def.getWorldBindings()) { |
Uniform uniform = shader.getUniform("g_" + binding.name()); |
||||||
Uniform uniform = shader.getUniform("g_" + binding.name()); |
uniform.setBinding(binding); |
||||||
uniform.setBinding(binding); |
if (uniform != null) { |
||||||
if (uniform != null) { |
worldBindUniforms.add(uniform); |
||||||
worldBindUniforms.add(uniform); |
} |
||||||
} |
} |
||||||
} |
} |
||||||
} |
needReload = false; |
||||||
needReload = false; |
} |
||||||
} |
|
||||||
|
/** |
||||||
/** |
* Computes the define list |
||||||
* Computes the define list |
* @return the complete define list |
||||||
* @return the complete define list |
*/ |
||||||
*/ |
public DefineList getAllDefines() { |
||||||
public DefineList getAllDefines() { |
DefineList allDefines = new DefineList(); |
||||||
DefineList allDefines = new DefineList(); |
allDefines.addFrom(def.getShaderPresetDefines()); |
||||||
allDefines.addFrom(def.getShaderPresetDefines()); |
allDefines.addFrom(defines); |
||||||
allDefines.addFrom(defines); |
return allDefines; |
||||||
return allDefines; |
} |
||||||
} |
|
||||||
|
/* |
||||||
/* |
public void write(JmeExporter ex) throws IOException { |
||||||
public void write(JmeExporter ex) throws IOException { |
OutputCapsule oc = ex.getCapsule(this); |
||||||
OutputCapsule oc = ex.getCapsule(this); |
oc.write(def, "def", null); |
||||||
oc.write(def, "def", null); |
oc.writeSavableArrayList(worldBindUniforms, "worldBindUniforms", null); |
||||||
oc.writeSavableArrayList(worldBindUniforms, "worldBindUniforms", null); |
oc.write(defines, "defines", null); |
||||||
oc.write(defines, "defines", null); |
oc.write(shader, "shader", null); |
||||||
oc.write(shader, "shader", null); |
} |
||||||
} |
|
||||||
|
public void read(JmeImporter im) throws IOException { |
||||||
public void read(JmeImporter im) throws IOException { |
InputCapsule ic = im.getCapsule(this); |
||||||
InputCapsule ic = im.getCapsule(this); |
def = (TechniqueDef) ic.readSavable("def", null); |
||||||
def = (TechniqueDef) ic.readSavable("def", null); |
worldBindUniforms = ic.readSavableArrayList("worldBindUniforms", null); |
||||||
worldBindUniforms = ic.readSavableArrayList("worldBindUniforms", null); |
defines = (DefineList) ic.readSavable("defines", null); |
||||||
defines = (DefineList) ic.readSavable("defines", null); |
shader = (Shader) ic.readSavable("shader", null); |
||||||
shader = (Shader) ic.readSavable("shader", null); |
} |
||||||
} |
*/ |
||||||
*/ |
} |
||||||
} |
|
||||||
|
@ -1,203 +1,263 @@ |
|||||||
/* |
/* |
||||||
* Copyright (c) 2009-2012 jMonkeyEngine |
* Copyright (c) 2009-2012 jMonkeyEngine |
||||||
* All rights reserved. |
* All rights reserved. |
||||||
* |
* |
||||||
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
||||||
* modification, are permitted provided that the following conditions are |
* modification, are permitted provided that the following conditions are |
||||||
* met: |
* met: |
||||||
* |
* |
||||||
* * Redistributions of source code must retain the above copyright |
* * Redistributions of source code must retain the above copyright |
||||||
* notice, this list of conditions and the following disclaimer. |
* notice, this list of conditions and the following disclaimer. |
||||||
* |
* |
||||||
* * Redistributions in binary form must reproduce the above copyright |
* * Redistributions in binary form must reproduce the above copyright |
||||||
* notice, this list of conditions and the following disclaimer in the |
* notice, this list of conditions and the following disclaimer in the |
||||||
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
||||||
* |
* |
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
* may be used to endorse or promote products derived from this software |
* may be used to endorse or promote products derived from this software |
||||||
* without specific prior written permission. |
* without specific prior written permission. |
||||||
* |
* |
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
*/ |
*/ |
||||||
package com.jme3.shader; |
package com.jme3.shader; |
||||||
|
|
||||||
import com.jme3.export.*; |
import com.jme3.export.*; |
||||||
import java.io.IOException; |
import com.jme3.material.MatParam; |
||||||
import java.util.Map; |
import com.jme3.material.TechniqueDef; |
||||||
import java.util.TreeMap; |
|
||||||
|
import java.io.IOException; |
||||||
public class DefineList implements Savable, Cloneable { |
import java.util.Collection; |
||||||
|
import java.util.Map; |
||||||
private static final String ONE = "1"; |
import java.util.TreeMap; |
||||||
|
|
||||||
private TreeMap<String, String> defines = new TreeMap<String, String>(); |
public class DefineList implements Savable, Cloneable { |
||||||
private String compiled = null; |
|
||||||
private int cachedHashCode = 0; |
private static final String ONE = "1"; |
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException{ |
private TreeMap<String, String> defines = new TreeMap<String, String>(); |
||||||
OutputCapsule oc = ex.getCapsule(this); |
private String compiled = null; |
||||||
|
private int cachedHashCode = 0; |
||||||
String[] keys = new String[defines.size()]; |
|
||||||
String[] vals = new String[defines.size()]; |
public void write(JmeExporter ex) throws IOException{ |
||||||
|
OutputCapsule oc = ex.getCapsule(this); |
||||||
int i = 0; |
|
||||||
for (Map.Entry<String, String> define : defines.entrySet()){ |
String[] keys = new String[defines.size()]; |
||||||
keys[i] = define.getKey(); |
String[] vals = new String[defines.size()]; |
||||||
vals[i] = define.getValue(); |
|
||||||
i++; |
int i = 0; |
||||||
} |
for (Map.Entry<String, String> define : defines.entrySet()){ |
||||||
|
keys[i] = define.getKey(); |
||||||
oc.write(keys, "keys", null); |
vals[i] = define.getValue(); |
||||||
oc.write(vals, "vals", null); |
i++; |
||||||
} |
} |
||||||
|
|
||||||
public void read(JmeImporter im) throws IOException{ |
oc.write(keys, "keys", null); |
||||||
InputCapsule ic = im.getCapsule(this); |
oc.write(vals, "vals", null); |
||||||
|
} |
||||||
String[] keys = ic.readStringArray("keys", null); |
|
||||||
String[] vals = ic.readStringArray("vals", null); |
public void read(JmeImporter im) throws IOException{ |
||||||
for (int i = 0; i < keys.length; i++){ |
InputCapsule ic = im.getCapsule(this); |
||||||
defines.put(keys[i], vals[i]); |
|
||||||
} |
String[] keys = ic.readStringArray("keys", null); |
||||||
} |
String[] vals = ic.readStringArray("vals", null); |
||||||
|
for (int i = 0; i < keys.length; i++){ |
||||||
public void clear() { |
defines.put(keys[i], vals[i]); |
||||||
defines.clear(); |
} |
||||||
compiled = ""; |
} |
||||||
cachedHashCode = 0; |
|
||||||
} |
public void clear() { |
||||||
|
defines.clear(); |
||||||
public String get(String key){ |
compiled = ""; |
||||||
return defines.get(key); |
cachedHashCode = 0; |
||||||
} |
} |
||||||
|
|
||||||
@Override |
public String get(String key){ |
||||||
public DefineList clone() { |
return defines.get(key); |
||||||
try { |
} |
||||||
DefineList clone = (DefineList) super.clone(); |
|
||||||
clone.cachedHashCode = 0; |
@Override |
||||||
clone.compiled = null; |
public DefineList clone() { |
||||||
clone.defines = (TreeMap<String, String>) defines.clone(); |
try { |
||||||
return clone; |
DefineList clone = (DefineList) super.clone(); |
||||||
} catch (CloneNotSupportedException ex) { |
clone.cachedHashCode = 0; |
||||||
throw new AssertionError(); |
clone.compiled = null; |
||||||
} |
clone.defines = (TreeMap<String, String>) defines.clone(); |
||||||
} |
return clone; |
||||||
|
} catch (CloneNotSupportedException ex) { |
||||||
public boolean set(String key, VarType type, Object val){ |
throw new AssertionError(); |
||||||
if (val == null){ |
} |
||||||
defines.remove(key); |
} |
||||||
compiled = null; |
|
||||||
cachedHashCode = 0; |
public boolean set(String key, VarType type, Object val){ |
||||||
return true; |
if (val == null){ |
||||||
} |
defines.remove(key); |
||||||
|
compiled = null; |
||||||
switch (type){ |
cachedHashCode = 0; |
||||||
case Boolean: |
return true; |
||||||
if (((Boolean) val).booleanValue()) { |
} |
||||||
// same literal, != will work
|
|
||||||
if (defines.put(key, ONE) != ONE) { |
switch (type){ |
||||||
compiled = null; |
case Boolean: |
||||||
cachedHashCode = 0; |
if (((Boolean) val).booleanValue()) { |
||||||
return true; |
// same literal, != will work
|
||||||
} |
if (defines.put(key, ONE) != ONE) { |
||||||
} else if (defines.containsKey(key)) { |
compiled = null; |
||||||
defines.remove(key); |
cachedHashCode = 0; |
||||||
compiled = null; |
return true; |
||||||
cachedHashCode = 0; |
} |
||||||
return true; |
} else if (defines.containsKey(key)) { |
||||||
} |
defines.remove(key); |
||||||
|
compiled = null; |
||||||
break; |
cachedHashCode = 0; |
||||||
case Float: |
return true; |
||||||
case Int: |
} |
||||||
String newValue = val.toString(); |
|
||||||
String original = defines.put(key, newValue); |
break; |
||||||
if (!val.equals(original)) { |
case Float: |
||||||
compiled = null; |
case Int: |
||||||
cachedHashCode = 0; |
String newValue = val.toString(); |
||||||
return true; |
String original = defines.put(key, newValue); |
||||||
} |
if (!val.equals(original)) { |
||||||
break; |
compiled = null; |
||||||
default: |
cachedHashCode = 0; |
||||||
// same literal, != will work
|
return true; |
||||||
if (defines.put(key, ONE) != ONE) { |
} |
||||||
compiled = null; |
break; |
||||||
cachedHashCode = 0; |
default: |
||||||
return true; |
// same literal, != will work
|
||||||
} |
if (defines.put(key, ONE) != ONE) { |
||||||
break; |
compiled = null; |
||||||
} |
cachedHashCode = 0; |
||||||
|
return true; |
||||||
return false; |
} |
||||||
} |
break; |
||||||
|
} |
||||||
public boolean remove(String key){ |
|
||||||
if (defines.remove(key) != null) { |
return false; |
||||||
compiled = null; |
} |
||||||
cachedHashCode = 0; |
|
||||||
return true; |
public boolean remove(String key){ |
||||||
} |
if (defines.remove(key) != null) { |
||||||
return false; |
compiled = null; |
||||||
} |
cachedHashCode = 0; |
||||||
|
return true; |
||||||
public void addFrom(DefineList other){ |
} |
||||||
if (other == null) { |
return false; |
||||||
return; |
} |
||||||
} |
|
||||||
compiled = null; |
public void addFrom(DefineList other){ |
||||||
cachedHashCode = 0; |
if (other == null) { |
||||||
defines.putAll(other.defines); |
return; |
||||||
} |
} |
||||||
|
compiled = null; |
||||||
public String getCompiled(){ |
cachedHashCode = 0; |
||||||
if (compiled == null){ |
defines.putAll(other.defines); |
||||||
StringBuilder sb = new StringBuilder(); |
} |
||||||
for (Map.Entry<String, String> entry : defines.entrySet()){ |
|
||||||
sb.append("#define ").append(entry.getKey()).append(" "); |
public String getCompiled(){ |
||||||
sb.append(entry.getValue()).append('\n'); |
if (compiled == null){ |
||||||
} |
StringBuilder sb = new StringBuilder(); |
||||||
compiled = sb.toString(); |
for (Map.Entry<String, String> entry : defines.entrySet()){ |
||||||
} |
sb.append("#define ").append(entry.getKey()).append(" "); |
||||||
return compiled; |
sb.append(entry.getValue()).append('\n'); |
||||||
} |
} |
||||||
|
compiled = sb.toString(); |
||||||
@Override |
} |
||||||
public boolean equals(Object obj) { |
return compiled; |
||||||
final DefineList other = (DefineList) obj; |
} |
||||||
return defines.equals(other.defines); |
|
||||||
} |
@Override |
||||||
|
public boolean equals(Object obj) { |
||||||
@Override |
final DefineList other = (DefineList) obj; |
||||||
public int hashCode() { |
return defines.equals(other.defines); |
||||||
if (cachedHashCode == 0) { |
} |
||||||
cachedHashCode = defines.hashCode(); |
|
||||||
} |
public boolean equalsParams(Collection<MatParam> params, TechniqueDef def) { |
||||||
return cachedHashCode; |
|
||||||
} |
int size = 0; |
||||||
|
|
||||||
@Override |
for (MatParam param : params) { |
||||||
public String toString(){ |
String key = def.getShaderParamDefine(param.getName()); |
||||||
StringBuilder sb = new StringBuilder(); |
if (key != null) { |
||||||
int i = 0; |
Object val = param.getValue(); |
||||||
for (Map.Entry<String, String> entry : defines.entrySet()) { |
if (val != null) { |
||||||
sb.append(entry.getKey()).append("=").append(entry.getValue()); |
|
||||||
if (i != defines.size() - 1) { |
switch (param.getVarType()) { |
||||||
sb.append(", "); |
case Boolean: { |
||||||
} |
String current = defines.get(key); |
||||||
i++; |
if (((Boolean) val).booleanValue()) { |
||||||
} |
if (current == null || current != ONE) { |
||||||
return sb.toString(); |
return false; |
||||||
} |
} |
||||||
|
size++; |
||||||
} |
} else { |
||||||
|
if (current != null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case Float: |
||||||
|
case Int: { |
||||||
|
String newValue = val.toString(); |
||||||
|
String current = defines.get(key); |
||||||
|
if (!newValue.equals(current)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
size++; |
||||||
|
} |
||||||
|
break; |
||||||
|
default: { |
||||||
|
if (!defines.containsKey(key)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
size++; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (size != defines.size()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
if (cachedHashCode == 0) { |
||||||
|
cachedHashCode = defines.hashCode(); |
||||||
|
} |
||||||
|
return cachedHashCode; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString(){ |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
int i = 0; |
||||||
|
for (Map.Entry<String, String> entry : defines.entrySet()) { |
||||||
|
sb.append(entry.getKey()).append("=").append(entry.getValue()); |
||||||
|
if (i != defines.size() - 1) { |
||||||
|
sb.append(", "); |
||||||
|
} |
||||||
|
i++; |
||||||
|
} |
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue