* 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
3.0
Sha..rd 13 years ago
parent fbf29530f3
commit 7b9b9905ef
  1. 2
      engine/src/core/com/jme3/material/MatParam.java
  2. 2
      engine/src/core/com/jme3/material/MatParamTexture.java
  3. 121
      engine/src/core/com/jme3/material/Material.java
  4. 94
      engine/src/core/com/jme3/material/Technique.java

@ -144,7 +144,7 @@ public class MatParam implements Savable, Cloneable {
void apply(Renderer r, Technique technique) { void apply(Renderer r, Technique technique) {
TechniqueDef techDef = technique.getDef(); TechniqueDef techDef = technique.getDef();
if (techDef.isUsingShaders()) { if (techDef.isUsingShaders()) {
technique.updateUniformParam(getPrefixedName(), getVarType(), getValue(), true); technique.updateUniformParam(getPrefixedName(), getVarType(), getValue());
} }
if (ffBinding != null && r instanceof GL1Renderer) { if (ffBinding != null && r instanceof GL1Renderer) {
((GL1Renderer) r).setFixedFuncBinding(ffBinding, getValue()); ((GL1Renderer) r).setFixedFuncBinding(ffBinding, getValue());

@ -45,7 +45,7 @@ public class MatParamTexture extends MatParam {
TechniqueDef techDef = technique.getDef(); TechniqueDef techDef = technique.getDef();
r.setTexture(getUnit(), getTextureValue()); r.setTexture(getUnit(), getTextureValue());
if (techDef.isUsingShaders()) { if (techDef.isUsingShaders()) {
technique.updateUniformParam(getPrefixedName(), getVarType(), getUnit(), true); technique.updateUniformParam(getPrefixedName(), getVarType(), getUnit());
} }
} }

@ -402,8 +402,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
* @return The MatParam if set, or null if not set. * @return The MatParam if set, or null if not set.
*/ */
public MatParam getParam(String name) { public MatParam getParam(String name) {
MatParam param = paramValues.get(name); return paramValues.get(name);
return param;
} }
/** /**
@ -432,28 +431,20 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
return paramValues.values(); 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); MatParam paramDef = def.getMaterialParam(name);
String newName = name; if (paramDef == null) {
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) {
throw new IllegalArgumentException("Material parameter is not defined: " + name); throw new IllegalArgumentException("Material parameter is not defined: " + name);
} }
if (type != null && paramDef.getVarType() != type) { if (type != null && paramDef.getVarType() != type) {
logger.log(Level.WARNING, "Material parameter being set: {0} with " 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()}); + "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 * @param value the value of the parameter
*/ */
public void setParam(String name, VarType type, Object value) { public void setParam(String name, VarType type, Object value) {
name = checkSetParam(type, name); checkSetParam(type, name);
MatParam val = getParam(name); MatParam val = getParam(name);
if (technique != null) {
technique.notifySetParam(name, type, value);
}
if (val == null) { if (val == null) {
MatParam paramDef = def.getMaterialParam(name); MatParam paramDef = def.getMaterialParam(name);
paramValues.put(name, new MatParam(type, name, value, paramDef.getFixedFuncBinding())); paramValues.put(name, new MatParam(type, name, value, paramDef.getFixedFuncBinding()));
} else { } else {
val.setValue(value); 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 * @param name the name of the parameter to clear
*/ */
public void clearParam(String name) { 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. checkSetParam(null, name);
// name = checkSetParam(null, name);
MatParam matParam = getParam(name); MatParam matParam = getParam(name);
if (matParam != null) { if (matParam == null) {
paramValues.remove(name); return;
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.");
} }
int texUnit = val.getUnit();
paramValues.remove(name); paramValues.remove(name);
nextTexUnit--; if (matParam instanceof MatParamTexture) {
for (MatParam param : paramValues.values()) { int texUnit = ((MatParamTexture) matParam).getUnit();
if (param instanceof MatParamTexture) { nextTexUnit--;
MatParamTexture texParam = (MatParamTexture) param; for (MatParam param : paramValues.values()) {
if (texParam.getUnit() > texUnit) { if (param instanceof MatParamTexture) {
texParam.setUnit(texParam.getUnit() - 1); 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(); throw new IllegalArgumentException();
} }
name = checkSetParam(type, name); checkSetParam(type, name);
MatParamTexture val = getTextureParam(name); MatParamTexture val = getTextureParam(name);
if (val == null) { if (val == null) {
paramValues.put(name, new MatParamTexture(type, name, value, nextTexUnit++)); paramValues.put(name, new MatParamTexture(type, name, value, nextTexUnit++));
@ -556,7 +523,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
} }
if (technique != null) { if (technique != null) {
technique.notifySetParam(name, type, nextTexUnit - 1); technique.notifyParamChanged(name, type, nextTexUnit - 1);
} }
// need to recompute sort ID // need to recompute sort ID
@ -573,7 +540,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
public void setTexture(String name, Texture value) { public void setTexture(String name, Texture value) {
if (value == null) { if (value == null) {
// clear it // clear it
clearTextureParam(name); clearParam(name);
return; return;
} }
@ -950,7 +917,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
} }
technique = tech; technique = tech;
tech.makeCurrent(def.getAssetManager()); tech.makeCurrent(def.getAssetManager(), true);
// shader was changed // shader was changed
sortingId = -1; sortingId = -1;
@ -961,13 +928,13 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
// NOTE: Not really needed anymore since we have technique // NOTE: Not really needed anymore since we have technique
// selection by caps. Rename all "FixedFunc" techniques to "Default" // selection by caps. Rename all "FixedFunc" techniques to "Default"
// and remove this hack. // 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); selectTechnique("FixedFunc", rm);
} else { } else {
selectTechnique("Default", rm); selectTechnique("Default", rm);
} }
} else if (technique.isNeedReload()) { } else {
technique.makeCurrent(def.getAssetManager()); technique.makeCurrent(def.getAssetManager(), false);
} }
} }
@ -996,9 +963,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
continue; continue;
} }
technique.updateUniformParam(param.getName(), technique.updateUniformParam(param.getName(), param.getVarType(), param.getValue());
param.getVarType(),
param.getValue(), true);
} }
} }
@ -1177,7 +1142,13 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
continue; 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); paramValues.put(param.getName(), param);
} }

@ -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 <code>null</code> 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); String defineName = def.getShaderParamDefine(paramName);
if (defineName != null) { if (defineName != null) {
needReload = defines.set(defineName, type, value); // There is a define. Change it on the define list.
} // The "needReload" variable will determine
if (shader != null) { // if the shader will be reloaded when the material
updateUniformParam(paramName, type, value); // is rendered.
}
} if (value == null) {
// Clear the define.
/** needReload = defines.remove(defineName);
* Called by the material to tell the technique a parameter was cleared } else {
*/ // Set the define.
void notifyClearParam(String paramName) { needReload = defines.set(defineName, type, value);
String defineName = def.getShaderParamDefine(paramName);
if (defineName != null) {
needReload = defines.remove(defineName);
}
if (shader != null) {
if (!paramName.startsWith("m_")) {
paramName = "m_" + paramName;
} }
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); Uniform u = shader.getUniform(paramName);
// if (ifNotOwner && u.getLastChanger() == owner)
// return;
switch (type) { switch (type) {
case TextureBuffer:
case Texture2D: // fall intentional case Texture2D: // fall intentional
case Texture3D: case Texture3D:
case TextureArray: case TextureArray:
@ -155,11 +147,6 @@ public class Technique implements Savable {
u.setValue(type, value); u.setValue(type, value);
break; 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. * @param assetManager The asset manager to use for loading shaders.
*/ */
public void makeCurrent(AssetManager assetManager) { public void makeCurrent(AssetManager assetManager, boolean techniqueSwitched) {
// check if reload is needed.. if (!def.isUsingShaders()) {
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(); DefineList newDefines = new DefineList();
Collection<MatParam> params = owner.getParams(); Collection<MatParam> params = owner.getParams();
for (MatParam param : params) { for (MatParam param : params) {
@ -192,17 +185,18 @@ public class Technique implements Savable {
newDefines.set(defineName, param.getVarType(), param.getValue()); newDefines.set(defineName, param.getVarType(), param.getValue());
} }
} }
if (!needReload && defines.getCompiled().equals(newDefines.getCompiled())) { if (!defines.getCompiled().equals(newDefines.getCompiled())) {
newDefines = null; // Defines were changed, update define list
// defines have not been changed..
} else {
defines.clear(); defines.clear();
defines.addFrom(newDefines); defines.addFrom(newDefines);
// defines changed, recompile needed needReload = true;
loadShader(assetManager);
} }
} }
if (needReload) {
loadShader(assetManager);
}
} }
private void loadShader(AssetManager manager) { private void loadShader(AssetManager manager) {
@ -212,17 +206,10 @@ public class Technique implements Savable {
allDefines.addFrom(defines); allDefines.addFrom(defines);
ShaderKey key = new ShaderKey(def.getVertexShaderName(), ShaderKey key = new ShaderKey(def.getVertexShaderName(),
def.getFragmentShaderName(), def.getFragmentShaderName(),
allDefines, allDefines,
def.getShaderLanguage()); def.getShaderLanguage());
shader = manager.loadShader(key); 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 // register the world bound uniforms
worldBindUniforms.clear(); worldBindUniforms.clear();
@ -235,15 +222,12 @@ public class Technique implements Savable {
} }
} }
} }
needReload = false; needReload = false;
} }
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);
// TODO:
// oc.write(owner, "owner", 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);
@ -255,7 +239,5 @@ public class Technique implements Savable {
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);
//if (shader != null)
// owner.updateUniformLinks();
} }
} }

Loading…
Cancel
Save