Material: allow multiple named techniques

cleanup_build_scripts
Kirill Vainer 9 years ago
parent 83259061d3
commit e4f7916301
  1. 58
      jme3-core/src/main/java/com/jme3/material/Material.java
  2. 43
      jme3-core/src/main/java/com/jme3/material/MaterialDef.java
  3. 2
      jme3-core/src/main/java/com/jme3/material/TechniqueDef.java
  4. 3
      jme3-core/src/main/java/com/jme3/renderer/RenderManager.java
  5. 2
      jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java
  6. 2
      jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java
  7. 13
      jme3-core/src/test/java/com/jme3/material/plugins/J3MLoaderTest.java
  8. 2
      jme3-core/src/tools/java/jme3tools/shadercheck/ShaderCheck.java

@ -720,46 +720,30 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
// supports all the caps. // supports all the caps.
if (tech == null) { if (tech == null) {
EnumSet<Caps> rendererCaps = renderManager.getRenderer().getCaps(); EnumSet<Caps> rendererCaps = renderManager.getRenderer().getCaps();
if (name.equals("Default")) { List<TechniqueDef> techDefs = def.getTechniqueDefs(name);
List<TechniqueDef> techDefs = def.getDefaultTechniques();
if (techDefs == null || techDefs.isEmpty()) {
throw new IllegalArgumentException("No default techniques are available on material '" + def.getName() + "'");
}
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 { if (techDefs == null || techDefs.isEmpty()) {
// create "special" technique instance throw new IllegalArgumentException(
TechniqueDef techDef = def.getTechniqueDef(name); String.format("The requested technique %s is not available on material %s", name, def.getName()));
if (techDef == null) { }
throw new IllegalArgumentException("For material " + def.getName() + ", technique not found: " + name);
}
if (!rendererCaps.containsAll(techDef.getRequiredCaps())) { TechniqueDef lastTech = null;
throw new UnsupportedOperationException("The explicitly chosen technique '" + name + "' on material '" + def.getName() + "'\n" for (TechniqueDef techDef : techDefs) {
+ "requires caps " + techDef.getRequiredCaps() + " which are not " if (rendererCaps.containsAll(techDef.getRequiredCaps())) {
+ "supported by the video renderer"); // 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;
tech = new Technique(this, techDef); }
techniques.put(name, tech); 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) { } else if (technique == tech) {
// attempting to switch to an already // attempting to switch to an already

@ -32,6 +32,7 @@
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.shader.VarType; import com.jme3.shader.VarType;
import com.jme3.texture.image.ColorSpace; import com.jme3.texture.image.ColorSpace;
import java.util.*; import java.util.*;
@ -51,8 +52,7 @@ public class MaterialDef {
private String assetName; private String assetName;
private AssetManager assetManager; private AssetManager assetManager;
private List<TechniqueDef> defaultTechs; private Map<String, List<TechniqueDef>> techniques;
private Map<String, TechniqueDef> techniques;
private Map<String, MatParam> matParams; private Map<String, MatParam> matParams;
/** /**
@ -70,9 +70,8 @@ public class MaterialDef {
public MaterialDef(AssetManager assetManager, String name){ public MaterialDef(AssetManager assetManager, String name){
this.assetManager = assetManager; this.assetManager = assetManager;
this.name = name; this.name = name;
techniques = new HashMap<String, TechniqueDef>(); techniques = new HashMap<String, List<TechniqueDef>>();
matParams = new HashMap<String, MatParam>(); matParams = new HashMap<String, MatParam>();
defaultTechs = new ArrayList<TechniqueDef>();
logger.log(Level.FINE, "Loaded material definition: {0}", name); logger.log(Level.FINE, "Loaded material definition: {0}", name);
} }
@ -164,40 +163,26 @@ public class MaterialDef {
/** /**
* Adds a new technique definition to this material definition. * Adds a new technique definition to this material definition.
* <p>
* If the technique name is "Default", it will be added
* to the list of {@link MaterialDef#getDefaultTechniques() default techniques}.
* *
* @param technique The technique definition to add. * @param technique The technique definition to add.
*/ */
public void addTechniqueDef(TechniqueDef technique) { public void addTechniqueDef(TechniqueDef technique) {
if (technique.getName().equals("Default")) { List<TechniqueDef> list = techniques.get(technique.getName());
defaultTechs.add(technique); if (list == null) {
} else { list = new ArrayList<>();
techniques.put(technique.getName(), technique); techniques.put(technique.getName(), list);
} }
list.add(technique);
} }
/** /**
* Returns a list of all default techniques. * Returns technique definitions with the given name.
* *
* @return a list of all default techniques. * @param name The name of the technique definitions to find
*
* @return The technique definitions, or null if cannot be found.
*/ */
public List<TechniqueDef> getDefaultTechniques(){ public List<TechniqueDef> getTechniqueDefs(String name) {
return defaultTechs;
}
/**
* Returns a technique definition with the given name.
* This does not include default techniques which can be
* retrieved via {@link MaterialDef#getDefaultTechniques() }.
*
* @param name The name of the technique definition to find
*
* @return The technique definition, or null if cannot be found.
*/
public TechniqueDef getTechniqueDef(String name) {
return techniques.get(name); return techniques.get(name);
} }
} }

@ -94,7 +94,7 @@ public class TechniqueDef implements Savable {
PostPass, PostPass,
} }
private EnumSet<Caps> requiredCaps = EnumSet.noneOf(Caps.class); private final EnumSet<Caps> requiredCaps = EnumSet.noneOf(Caps.class);
private String name; private String name;
private int sortId; private int sortId;

@ -580,7 +580,8 @@ public class RenderManager {
//if it does not exists in the mat def, we check for forcedMaterial and render the geom if not null //if it does not exists in the mat def, we check for forcedMaterial and render the geom if not null
//else the geom is not rendered //else the geom is not rendered
if (forcedTechnique != null) { if (forcedTechnique != null) {
if (g.getMaterial().getMaterialDef().getTechniqueDef(forcedTechnique) != null) { MaterialDef matDef = g.getMaterial().getMaterialDef();
if (matDef.getTechniqueDefs(forcedTechnique) != null) {
tmpTech = g.getMaterial().getActiveTechnique() != null ? g.getMaterial().getActiveTechnique().getDef().getName() : "Default"; tmpTech = g.getMaterial().getActiveTechnique() != null ? g.getMaterial().getActiveTechnique().getDef().getName() : "Default";
g.getMaterial().selectTechnique(forcedTechnique, this); g.getMaterial().selectTechnique(forcedTechnique, this);
//saving forcedRenderState for future calls //saving forcedRenderState for future calls

@ -587,7 +587,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
for (int i = 0; i < l.size(); i++) { for (int i = 0; i < l.size(); i++) {
Material mat = l.get(i).getMaterial(); Material mat = l.get(i).getMaterial();
//checking if the material has the post technique and adding it to the material cache //checking if the material has the post technique and adding it to the material cache
if (mat.getMaterialDef().getTechniqueDef(postTechniqueName) != null) { if (mat.getMaterialDef().getTechniqueDefs(postTechniqueName) != null) {
if (!matCache.contains(mat)) { if (!matCache.contains(mat)) {
matCache.add(mat); matCache.add(mat);
} }

@ -533,7 +533,7 @@ public class PssmShadowRenderer implements SceneProcessor {
for (int i = 0; i < l.size(); i++) { for (int i = 0; i < l.size(); i++) {
Material mat = l.get(i).getMaterial(); Material mat = l.get(i).getMaterial();
//checking if the material has the post technique and adding it to the material cache //checking if the material has the post technique and adding it to the material cache
if (mat.getMaterialDef().getTechniqueDef(postTechniqueName) != null) { if (mat.getMaterialDef().getTechniqueDefs(postTechniqueName) != null) {
if (!matCache.contains(mat)) { if (!matCache.contains(mat)) {
matCache.add(mat); matCache.add(mat);
} }

@ -7,8 +7,11 @@ import com.jme3.asset.TextureKey;
import com.jme3.material.MatParamTexture; import com.jme3.material.MatParamTexture;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.MaterialDef; import com.jme3.material.MaterialDef;
import com.jme3.renderer.Caps;
import com.jme3.shader.VarType; import com.jme3.shader.VarType;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import java.io.IOException;
import java.util.EnumSet;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -18,6 +21,7 @@ import org.mockito.runners.MockitoJUnitRunner;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
/** /**
@ -51,6 +55,15 @@ public class J3MLoaderTest {
j3MLoader = new J3MLoader(); j3MLoader = new J3MLoader();
} }
@Test
public void multipleSameNamedTechniques_shouldBeSupported() throws IOException {
when(assetInfo.openStream()).thenReturn(J3MLoader.class.getResourceAsStream("/same-name-technique.j3md"));
MaterialDef def = (MaterialDef) j3MLoader.load(assetInfo);
assertEquals(2, def.getTechniqueDefs("Test").size());
assertEquals(EnumSet.of(Caps.GLSL150), def.getTechniqueDefs("Test").get(0).getRequiredCaps());
assertEquals(EnumSet.of(Caps.GLSL100), def.getTechniqueDefs("Test").get(1).getRequiredCaps());
}
@Test @Test
public void oldStyleTextureParameters_shouldBeSupported() throws Exception { public void oldStyleTextureParameters_shouldBeSupported() throws Exception {
when(assetInfo.openStream()).thenReturn(J3MLoader.class.getResourceAsStream("/texture-parameters-oldstyle.j3m")); when(assetInfo.openStream()).thenReturn(J3MLoader.class.getResourceAsStream("/texture-parameters-oldstyle.j3m"));

@ -38,7 +38,7 @@ public class ShaderCheck {
MaterialDef def = (MaterialDef) assetManager.loadAsset(matdefName); MaterialDef def = (MaterialDef) assetManager.loadAsset(matdefName);
EnumSet<Caps> rendererCaps = EnumSet.noneOf(Caps.class); EnumSet<Caps> rendererCaps = EnumSet.noneOf(Caps.class);
rendererCaps.add(Caps.GLSL100); rendererCaps.add(Caps.GLSL100);
for (TechniqueDef techDef : def.getDefaultTechniques()) { for (TechniqueDef techDef : def.getTechniqueDefs("Default")) {
DefineList defines = techDef.createDefineList(); DefineList defines = techDef.createDefineList();
Shader shader = techDef.getShader(assetManager, rendererCaps, defines); Shader shader = techDef.getShader(assetManager, rendererCaps, defines);
for (Validator validator : validators) { for (Validator validator : validators) {

Loading…
Cancel
Save