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();
}
}