From 7b9b9905efbe98bb5d5c005ecf5e4dd4b3c56d04 Mon Sep 17 00:00:00 2001 From: "Sha..rd" Date: Thu, 14 Jun 2012 00:21:50 +0000 Subject: [PATCH] * Removed workarounds for setting material parameter with m_ prefix. From now on it will only be supported when loading really old J3O files. * Small optimization: if technique is already loaded, define list will not be reconstructed on define change git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9491 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../src/core/com/jme3/material/MatParam.java | 2 +- .../com/jme3/material/MatParamTexture.java | 2 +- .../src/core/com/jme3/material/Material.java | 121 +++++++----------- .../src/core/com/jme3/material/Technique.java | 94 ++++++-------- 4 files changed, 86 insertions(+), 133 deletions(-) diff --git a/engine/src/core/com/jme3/material/MatParam.java b/engine/src/core/com/jme3/material/MatParam.java index c363f7588..5a63fc11d 100644 --- a/engine/src/core/com/jme3/material/MatParam.java +++ b/engine/src/core/com/jme3/material/MatParam.java @@ -144,7 +144,7 @@ public class MatParam implements Savable, Cloneable { void apply(Renderer r, Technique technique) { TechniqueDef techDef = technique.getDef(); if (techDef.isUsingShaders()) { - technique.updateUniformParam(getPrefixedName(), getVarType(), getValue(), true); + technique.updateUniformParam(getPrefixedName(), getVarType(), getValue()); } if (ffBinding != null && r instanceof GL1Renderer) { ((GL1Renderer) r).setFixedFuncBinding(ffBinding, getValue()); diff --git a/engine/src/core/com/jme3/material/MatParamTexture.java b/engine/src/core/com/jme3/material/MatParamTexture.java index fc8b4697e..2ec6356c9 100644 --- a/engine/src/core/com/jme3/material/MatParamTexture.java +++ b/engine/src/core/com/jme3/material/MatParamTexture.java @@ -45,7 +45,7 @@ public class MatParamTexture extends MatParam { TechniqueDef techDef = technique.getDef(); r.setTexture(getUnit(), getTextureValue()); if (techDef.isUsingShaders()) { - technique.updateUniformParam(getPrefixedName(), getVarType(), getUnit(), true); + technique.updateUniformParam(getPrefixedName(), getVarType(), getUnit()); } } diff --git a/engine/src/core/com/jme3/material/Material.java b/engine/src/core/com/jme3/material/Material.java index 5a840eedc..82e970293 100644 --- a/engine/src/core/com/jme3/material/Material.java +++ b/engine/src/core/com/jme3/material/Material.java @@ -402,8 +402,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { * @return The MatParam if set, or null if not set. */ public MatParam getParam(String name) { - MatParam param = paramValues.get(name); - return param; + return paramValues.get(name); } /** @@ -432,28 +431,20 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { return paramValues.values(); } - private String checkSetParam(VarType type, String name) { + /** + * Check if setting the parameter given the type and name is allowed. + * @param type The type that the "set" function is designed to set + * @param name The name of the parameter + */ + private void checkSetParam(VarType type, String name) { MatParam paramDef = def.getMaterialParam(name); - String newName = name; - - if (paramDef == null && name.startsWith("m_")) { - newName = name.substring(2); - paramDef = def.getMaterialParam(newName); - if (paramDef == null) { - throw new IllegalArgumentException("Material parameter is not defined: " + name); - } else { - logger.log(Level.WARNING, "Material parameter {0} uses a deprecated naming convention use {1} instead ", new Object[]{name, newName}); - } - } else if (paramDef == null) { + if (paramDef == null) { throw new IllegalArgumentException("Material parameter is not defined: " + name); } - if (type != null && paramDef.getVarType() != type) { logger.log(Level.WARNING, "Material parameter being set: {0} with " + "type {1} doesn''t match definition types {2}", new Object[]{name, type.name(), paramDef.getVarType()}); } - - return newName; } /** @@ -464,18 +455,19 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { * @param value the value of the parameter */ public void setParam(String name, VarType type, Object value) { - name = checkSetParam(type, name); - + checkSetParam(type, name); + MatParam val = getParam(name); - if (technique != null) { - technique.notifySetParam(name, type, value); - } if (val == null) { MatParam paramDef = def.getMaterialParam(name); paramValues.put(name, new MatParam(type, name, value, paramDef.getFixedFuncBinding())); } else { val.setValue(value); } + + if (technique != null) { + technique.notifyParamChanged(name, type, value); + } } /** @@ -483,54 +475,29 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { * @param name the name of the parameter to clear */ public void clearParam(String name) { - //On removal, we don't check if the param exists in the paramDef, and just go on with the process. - // name = checkSetParam(null, name); - + checkSetParam(null, name); MatParam matParam = getParam(name); - if (matParam != null) { - paramValues.remove(name); - if (technique != null) { - technique.notifyClearParam(name); - } - if (matParam instanceof MatParamTexture) { - int texUnit = ((MatParamTexture) matParam).getUnit(); - nextTexUnit--; - for (MatParam param : paramValues.values()) { - if (param instanceof MatParamTexture) { - MatParamTexture texParam = (MatParamTexture) param; - if (texParam.getUnit() > texUnit) { - texParam.setUnit(texParam.getUnit() - 1); - } - } - } - } - } -// else { -// throw new IllegalArgumentException("The given parameter is not set."); -// } - } - - private void clearTextureParam(String name) { - name = checkSetParam(null, name); - - MatParamTexture val = getTextureParam(name); - if (val == null) { - throw new IllegalArgumentException("The given texture for parameter \"" + name + "\" is null."); + if (matParam == null) { + return; } - - int texUnit = val.getUnit(); + paramValues.remove(name); - nextTexUnit--; - for (MatParam param : paramValues.values()) { - if (param instanceof MatParamTexture) { - MatParamTexture texParam = (MatParamTexture) param; - if (texParam.getUnit() > texUnit) { - texParam.setUnit(texParam.getUnit() - 1); + if (matParam instanceof MatParamTexture) { + int texUnit = ((MatParamTexture) matParam).getUnit(); + nextTexUnit--; + for (MatParam param : paramValues.values()) { + if (param instanceof MatParamTexture) { + MatParamTexture texParam = (MatParamTexture) param; + if (texParam.getUnit() > texUnit) { + texParam.setUnit(texParam.getUnit() - 1); + } } } + sortingId = -1; + } + if (technique != null) { + technique.notifyParamChanged(name, null, null); } - - sortingId = -1; } /** @@ -547,7 +514,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { throw new IllegalArgumentException(); } - name = checkSetParam(type, name); + checkSetParam(type, name); MatParamTexture val = getTextureParam(name); if (val == null) { paramValues.put(name, new MatParamTexture(type, name, value, nextTexUnit++)); @@ -556,7 +523,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { } if (technique != null) { - technique.notifySetParam(name, type, nextTexUnit - 1); + technique.notifyParamChanged(name, type, nextTexUnit - 1); } // need to recompute sort ID @@ -573,7 +540,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { public void setTexture(String name, Texture value) { if (value == null) { // clear it - clearTextureParam(name); + clearParam(name); return; } @@ -950,7 +917,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { } technique = tech; - tech.makeCurrent(def.getAssetManager()); + tech.makeCurrent(def.getAssetManager(), true); // shader was changed sortingId = -1; @@ -961,13 +928,13 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { // NOTE: Not really needed anymore since we have technique // selection by caps. Rename all "FixedFunc" techniques to "Default" // and remove this hack. - if (!rm.getRenderer().getCaps().contains(Caps.GLSL100)) { + if (def.getTechniqueDef("FixedFunc") != null && !rm.getRenderer().getCaps().contains(Caps.GLSL100)) { selectTechnique("FixedFunc", rm); } else { selectTechnique("Default", rm); } - } else if (technique.isNeedReload()) { - technique.makeCurrent(def.getAssetManager()); + } else { + technique.makeCurrent(def.getAssetManager(), false); } } @@ -996,9 +963,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { continue; } - technique.updateUniformParam(param.getName(), - param.getVarType(), - param.getValue(), true); + technique.updateUniformParam(param.getName(), param.getVarType(), param.getValue()); } } @@ -1177,7 +1142,13 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { continue; } } - param.setName(checkSetParam(param.getVarType(), param.getName())); + + if (im.getFormatVersion() == 0 && param.getName().startsWith("m_")) { + // Ancient version of jME3 ... + param.setName(param.getName().substring(2)); + } + + checkSetParam(param.getVarType(), param.getName()); paramValues.put(param.getName(), param); } diff --git a/engine/src/core/com/jme3/material/Technique.java b/engine/src/core/com/jme3/material/Technique.java index 5ae20a50e..44f473295 100644 --- a/engine/src/core/com/jme3/material/Technique.java +++ b/engine/src/core/com/jme3/material/Technique.java @@ -109,41 +109,33 @@ public class Technique implements Savable { } /** - * 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 null for value if the param is to be cleared. */ - void notifySetParam(String paramName, VarType type, Object value) { + void notifyParamChanged(String paramName, VarType type, Object value) { + // Check if there's a define binding associated with this + // parameter. String defineName = def.getShaderParamDefine(paramName); if (defineName != null) { - needReload = defines.set(defineName, type, value); - } - if (shader != null) { - updateUniformParam(paramName, type, value); - } - } - - /** - * Called by the material to tell the technique a parameter was cleared - */ - void notifyClearParam(String paramName) { - String defineName = def.getShaderParamDefine(paramName); - if (defineName != null) { - needReload = defines.remove(defineName); - } - if (shader != null) { - if (!paramName.startsWith("m_")) { - paramName = "m_" + paramName; + // There is a define. Change it on the define list. + // The "needReload" variable will determine + // if the shader will be reloaded when the material + // is rendered. + + if (value == null) { + // Clear the define. + needReload = defines.remove(defineName); + } else { + // Set the define. + needReload = defines.set(defineName, type, value); } - shader.removeUniform(paramName); } } - void updateUniformParam(String paramName, VarType type, Object value, boolean ifNotOwner) { + void updateUniformParam(String paramName, VarType type, Object value) { Uniform u = shader.getUniform(paramName); - -// if (ifNotOwner && u.getLastChanger() == owner) -// return; - switch (type) { + case TextureBuffer: case Texture2D: // fall intentional case Texture3D: case TextureArray: @@ -155,11 +147,6 @@ public class Technique implements Savable { u.setValue(type, value); break; } -// u.setLastChanger(owner); - } - - void updateUniformParam(String paramName, VarType type, Object value) { - updateUniformParam(paramName, type, value, false); } /** @@ -181,9 +168,15 @@ public class Technique implements Savable { * * @param assetManager The asset manager to use for loading shaders. */ - public void makeCurrent(AssetManager assetManager) { - // check if reload is needed.. - if (def.isUsingShaders()) { + public void makeCurrent(AssetManager assetManager, boolean techniqueSwitched) { + if (!def.isUsingShaders()) { + // No shaders are used, no processing is neccessary. + return; + } + + if (techniqueSwitched) { + // If the technique was switched, check if the define list changed + // based on material parameters. DefineList newDefines = new DefineList(); Collection params = owner.getParams(); for (MatParam param : params) { @@ -192,17 +185,18 @@ public class Technique implements Savable { newDefines.set(defineName, param.getVarType(), param.getValue()); } } - - if (!needReload && defines.getCompiled().equals(newDefines.getCompiled())) { - newDefines = null; - // defines have not been changed.. - } else { + + if (!defines.getCompiled().equals(newDefines.getCompiled())) { + // Defines were changed, update define list defines.clear(); defines.addFrom(newDefines); - // defines changed, recompile needed - loadShader(assetManager); + needReload = true; } } + + if (needReload) { + loadShader(assetManager); + } } private void loadShader(AssetManager manager) { @@ -212,17 +206,10 @@ public class Technique implements Savable { allDefines.addFrom(defines); ShaderKey key = new ShaderKey(def.getVertexShaderName(), - def.getFragmentShaderName(), - allDefines, - def.getShaderLanguage()); + def.getFragmentShaderName(), + allDefines, + def.getShaderLanguage()); shader = manager.loadShader(key); - if (shader == null) { - logger.warning("Failed to reload shader!"); - return; - } - - // refresh the uniform links - //owner.updateUniformLinks(); // register the world bound uniforms worldBindUniforms.clear(); @@ -235,15 +222,12 @@ public class Technique implements Savable { } } } - needReload = false; } public void write(JmeExporter ex) throws IOException { OutputCapsule oc = ex.getCapsule(this); oc.write(def, "def", null); - // TODO: - // oc.write(owner, "owner", null); oc.writeSavableArrayList(worldBindUniforms, "worldBindUniforms", null); oc.write(defines, "defines", null); oc.write(shader, "shader", null); @@ -255,7 +239,5 @@ public class Technique implements Savable { worldBindUniforms = ic.readSavableArrayList("worldBindUniforms", null); defines = (DefineList) ic.readSavable("defines", null); shader = (Shader) ic.readSavable("shader", null); - //if (shader != null) - // owner.updateUniformLinks(); } }