|
@@ -93,7 +93,6 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
private ListMap<String, MatParam> paramValues = new ListMap<String, MatParam>();
|
|
|
private Technique technique;
|
|
|
private HashMap<String, Technique> techniques = new HashMap<String, Technique>();
|
|
|
- private int nextTexUnit = 0;
|
|
|
private RenderState additionalState = null;
|
|
|
private RenderState mergedRenderState = new RenderState();
|
|
|
private boolean transparent = false;
|
|
@@ -264,8 +263,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
// E.g. if user chose custom technique for one material but
|
|
|
// uses default technique for other material, the materials
|
|
|
// are not equal.
|
|
|
- String thisDefName = this.technique != null ? this.technique.getDef().getName() : "Default";
|
|
|
- String otherDefName = other.technique != null ? other.technique.getDef().getName() : "Default";
|
|
|
+ String thisDefName = this.technique != null
|
|
|
+ ? this.technique.getDef().getName()
|
|
|
+ : TechniqueDef.DEFAULT_TECHNIQUE_NAME;
|
|
|
+
|
|
|
+ String otherDefName = other.technique != null
|
|
|
+ ? other.technique.getDef().getName()
|
|
|
+ : TechniqueDef.DEFAULT_TECHNIQUE_NAME;
|
|
|
+
|
|
|
if (!thisDefName.equals(otherDefName)) {
|
|
|
return false;
|
|
|
}
|
|
@@ -510,16 +515,6 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
|
|
|
paramValues.remove(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);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
sortingId = -1;
|
|
|
}
|
|
|
if (technique != null) {
|
|
@@ -562,13 +557,13 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
+ "Linear using texture.getImage.setColorSpace().",
|
|
|
new Object[]{value.getName(), value.getImage().getColorSpace().name(), name});
|
|
|
}
|
|
|
- paramValues.put(name, new MatParamTexture(type, name, value, nextTexUnit++, null));
|
|
|
+ paramValues.put(name, new MatParamTexture(type, name, value, null));
|
|
|
} else {
|
|
|
val.setTextureValue(value);
|
|
|
}
|
|
|
|
|
|
if (technique != null) {
|
|
|
- technique.notifyParamChanged(name, type, nextTexUnit - 1);
|
|
|
+ technique.notifyParamChanged(name, type, value);
|
|
|
}
|
|
|
|
|
|
// need to recompute sort ID
|
|
@@ -704,23 +699,18 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
/**
|
|
|
* Select the technique to use for rendering this material.
|
|
|
* <p>
|
|
|
- * If <code>name</code> is "Default", then one of the
|
|
|
- * {@link MaterialDef#getDefaultTechniques() default techniques}
|
|
|
- * on the material will be selected. Otherwise, the named technique
|
|
|
- * will be found in the material definition.
|
|
|
- * <p>
|
|
|
* Any candidate technique for selection (either default or named)
|
|
|
* must be verified to be compatible with the system, for that, the
|
|
|
* <code>renderManager</code> is queried for capabilities.
|
|
|
*
|
|
|
- * @param name The name of the technique to select, pass "Default" to
|
|
|
- * select one of the default techniques.
|
|
|
+ * @param name The name of the technique to select, pass
|
|
|
+ * {@link TechniqueDef#DEFAULT_TECHNIQUE_NAME} to select one of the default
|
|
|
+ * techniques.
|
|
|
* @param renderManager The {@link RenderManager render manager}
|
|
|
* to query for capabilities.
|
|
|
*
|
|
|
- * @throws IllegalArgumentException If "Default" is passed and no default
|
|
|
- * techniques are available on the material definition, or if a name
|
|
|
- * is passed but there's no technique by that name.
|
|
|
+ * @throws IllegalArgumentException If no technique exists with the given
|
|
|
+ * name.
|
|
|
* @throws UnsupportedOperationException If no candidate technique supports
|
|
|
* the system capabilities.
|
|
|
*/
|
|
@@ -731,46 +721,30 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
// supports all the caps.
|
|
|
if (tech == null) {
|
|
|
EnumSet<Caps> rendererCaps = renderManager.getRenderer().getCaps();
|
|
|
- if (name.equals("Default")) {
|
|
|
- List<TechniqueDef> techDefs = def.getDefaultTechniques();
|
|
|
- if (techDefs == null || techDefs.isEmpty()) {
|
|
|
- throw new IllegalArgumentException("No default techniques are available on material '" + def.getName() + "'");
|
|
|
- }
|
|
|
+ List<TechniqueDef> techDefs = def.getTechniqueDefs(name);
|
|
|
|
|
|
- TechniqueDef lastTech = null;
|
|
|
- for (TechniqueDef techDef : techDefs) {
|
|
|
- if (rendererCaps.containsAll(techDef.getRequiredCaps())) {
|
|
|
- // use the first one that supports all the caps
|
|
|
- tech = new Technique(this, techDef);
|
|
|
- techniques.put(name, tech);
|
|
|
- if(tech.getDef().getLightMode() == renderManager.getPreferredLightMode() ||
|
|
|
- tech.getDef().getLightMode() == LightMode.Disable){
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- lastTech = techDef;
|
|
|
- }
|
|
|
- if (tech == null) {
|
|
|
- throw new UnsupportedOperationException("No default technique on material '" + def.getName() + "'\n"
|
|
|
- + " is supported by the video hardware. The caps "
|
|
|
- + lastTech.getRequiredCaps() + " are required.");
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
- // create "special" technique instance
|
|
|
- TechniqueDef techDef = def.getTechniqueDef(name);
|
|
|
- if (techDef == null) {
|
|
|
- throw new IllegalArgumentException("For material " + def.getName() + ", technique not found: " + name);
|
|
|
- }
|
|
|
+ if (techDefs == null || techDefs.isEmpty()) {
|
|
|
+ throw new IllegalArgumentException(
|
|
|
+ String.format("The requested technique %s is not available on material %s", name, def.getName()));
|
|
|
+ }
|
|
|
|
|
|
- if (!rendererCaps.containsAll(techDef.getRequiredCaps())) {
|
|
|
- throw new UnsupportedOperationException("The explicitly chosen technique '" + name + "' on material '" + def.getName() + "'\n"
|
|
|
- + "requires caps " + techDef.getRequiredCaps() + " which are not "
|
|
|
- + "supported by the video renderer");
|
|
|
+ TechniqueDef lastTech = null;
|
|
|
+ for (TechniqueDef techDef : techDefs) {
|
|
|
+ if (rendererCaps.containsAll(techDef.getRequiredCaps())) {
|
|
|
+ // use the first one that supports all the caps
|
|
|
+ tech = new Technique(this, techDef);
|
|
|
+ techniques.put(name, tech);
|
|
|
+ if (tech.getDef().getLightMode() == renderManager.getPreferredLightMode()
|
|
|
+ || tech.getDef().getLightMode() == LightMode.Disable) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- tech = new Technique(this, techDef);
|
|
|
- techniques.put(name, tech);
|
|
|
+ lastTech = techDef;
|
|
|
+ }
|
|
|
+ if (tech == null) {
|
|
|
+ throw new UnsupportedOperationException("No default technique on material '" + def.getName() + "'\n"
|
|
|
+ + " is supported by the video hardware. The caps "
|
|
|
+ + lastTech.getRequiredCaps() + " are required.");
|
|
|
}
|
|
|
} else if (technique == tech) {
|
|
|
// attempting to switch to an already
|
|
@@ -785,32 +759,43 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
sortingId = -1;
|
|
|
}
|
|
|
|
|
|
- private int updateShaderMaterialParameters(Renderer renderer, Shader shader, List<MatParamOverride> overrides) {
|
|
|
- int unit = 0;
|
|
|
+ private int applyOverrides(Renderer renderer, Shader shader, List<MatParamOverride> overrides, int unit) {
|
|
|
+ for (MatParamOverride override : overrides) {
|
|
|
+ VarType type = override.getVarType();
|
|
|
|
|
|
- if (overrides != null) {
|
|
|
- for (MatParamOverride override : overrides) {
|
|
|
- VarType type = override.getVarType();
|
|
|
+ MatParam paramDef = def.getMaterialParam(override.getName());
|
|
|
|
|
|
- MatParam paramDef = def.getMaterialParam(override.getName());
|
|
|
- if (paramDef == null || paramDef.getVarType() != type || !override.isEnabled()) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (paramDef == null || paramDef.getVarType() != type || !override.isEnabled()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- Uniform uniform = shader.getUniform(override.getPrefixedName());
|
|
|
- if (override.getValue() != null) {
|
|
|
- if (type.isTextureType()) {
|
|
|
- renderer.setTexture(unit, (Texture) override.getValue());
|
|
|
- uniform.setValue(VarType.Int, unit);
|
|
|
- unit++;
|
|
|
- } else {
|
|
|
- uniform.setValue(type, override.getValue());
|
|
|
- }
|
|
|
+ Uniform uniform = shader.getUniform(override.getPrefixedName());
|
|
|
+
|
|
|
+ if (override.getValue() != null) {
|
|
|
+ if (type.isTextureType()) {
|
|
|
+ renderer.setTexture(unit, (Texture) override.getValue());
|
|
|
+ uniform.setValue(VarType.Int, unit);
|
|
|
+ unit++;
|
|
|
} else {
|
|
|
- uniform.clearValue();
|
|
|
+ uniform.setValue(type, override.getValue());
|
|
|
}
|
|
|
+ } else {
|
|
|
+ uniform.clearValue();
|
|
|
}
|
|
|
}
|
|
|
+ return unit;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int updateShaderMaterialParameters(Renderer renderer, Shader shader,
|
|
|
+ List<MatParamOverride> worldOverrides, List<MatParamOverride> forcedOverrides) {
|
|
|
+
|
|
|
+ int unit = 0;
|
|
|
+ if (worldOverrides != null) {
|
|
|
+ unit = applyOverrides(renderer, shader, worldOverrides, unit);
|
|
|
+ }
|
|
|
+ if (forcedOverrides != null) {
|
|
|
+ unit = applyOverrides(renderer, shader, forcedOverrides, unit);
|
|
|
+ }
|
|
|
|
|
|
for (int i = 0; i < paramValues.size(); i++) {
|
|
|
MatParam param = paramValues.getValue(i);
|
|
@@ -857,7 +842,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
*/
|
|
|
public void preload(RenderManager renderManager) {
|
|
|
if (technique == null) {
|
|
|
- selectTechnique("Default", renderManager);
|
|
|
+ selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
|
|
|
}
|
|
|
TechniqueDef techniqueDef = technique.getDef();
|
|
|
Renderer renderer = renderManager.getRenderer();
|
|
@@ -867,8 +852,8 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- Shader shader = technique.makeCurrent(renderManager, null, null, rendererCaps);
|
|
|
- updateShaderMaterialParameters(renderer, shader, null);
|
|
|
+ Shader shader = technique.makeCurrent(renderManager, null, null, null, rendererCaps);
|
|
|
+ updateShaderMaterialParameters(renderer, shader, null, null);
|
|
|
renderManager.getRenderer().setShader(shader);
|
|
|
}
|
|
|
|
|
@@ -957,7 +942,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
*/
|
|
|
public void render(Geometry geometry, LightList lights, RenderManager renderManager) {
|
|
|
if (technique == null) {
|
|
|
- selectTechnique("Default", renderManager);
|
|
|
+ selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
|
|
|
}
|
|
|
|
|
|
TechniqueDef techniqueDef = technique.getDef();
|
|
@@ -975,7 +960,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
List<MatParamOverride> overrides = geometry.getWorldMatParamOverrides();
|
|
|
|
|
|
// Select shader to use
|
|
|
- Shader shader = technique.makeCurrent(renderManager, overrides, lights, rendererCaps);
|
|
|
+ Shader shader = technique.makeCurrent(renderManager, overrides, renderManager.getForcedMatParams(), lights, rendererCaps);
|
|
|
|
|
|
// Begin tracking which uniforms were changed by material.
|
|
|
clearUniformsSetByCurrent(shader);
|
|
@@ -984,9 +969,10 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
renderManager.updateUniformBindings(shader);
|
|
|
|
|
|
// Set material parameters
|
|
|
+
|
|
|
//TODO RRemove the unit when texture units are handled in the Uniform
|
|
|
- int unit = updateShaderMaterialParameters(renderer, shader, geometry.getWorldMatParamOverrides());
|
|
|
-
|
|
|
+ int unit = updateShaderMaterialParameters(renderer, shader, overrides, renderManager.getForcedMatParams());
|
|
|
+
|
|
|
// Clear any uniforms not changed by material.
|
|
|
resetUniformsNotSetByCurrent(shader);
|
|
|
|
|
@@ -1081,11 +1067,6 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|
|
MatParam param = entry.getValue();
|
|
|
if (param instanceof MatParamTexture) {
|
|
|
MatParamTexture texVal = (MatParamTexture) param;
|
|
|
-
|
|
|
- if (nextTexUnit < texVal.getUnit() + 1) {
|
|
|
- nextTexUnit = texVal.getUnit() + 1;
|
|
|
- }
|
|
|
-
|
|
|
// the texture failed to load for this param
|
|
|
// do not add to param values
|
|
|
if (texVal.getTextureValue() == null || texVal.getTextureValue().getImage() == null) {
|