Merge branch 'master' into PBRisComing
# Conflicts: # jme3-core/src/main/java/com/jme3/material/Material.java
This commit is contained in:
commit
6a9c655be3
@ -35,7 +35,6 @@ import com.jme3.export.InputCapsule;
|
|||||||
import com.jme3.export.JmeExporter;
|
import com.jme3.export.JmeExporter;
|
||||||
import com.jme3.export.JmeImporter;
|
import com.jme3.export.JmeImporter;
|
||||||
import com.jme3.export.OutputCapsule;
|
import com.jme3.export.OutputCapsule;
|
||||||
import com.jme3.renderer.Renderer;
|
|
||||||
import com.jme3.shader.VarType;
|
import com.jme3.shader.VarType;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.image.ColorSpace;
|
import com.jme3.texture.image.ColorSpace;
|
||||||
@ -44,13 +43,11 @@ import java.io.IOException;
|
|||||||
public class MatParamTexture extends MatParam {
|
public class MatParamTexture extends MatParam {
|
||||||
|
|
||||||
private Texture texture;
|
private Texture texture;
|
||||||
private int unit;
|
|
||||||
private ColorSpace colorSpace;
|
private ColorSpace colorSpace;
|
||||||
|
|
||||||
public MatParamTexture(VarType type, String name, Texture texture, int unit, ColorSpace colorSpace) {
|
public MatParamTexture(VarType type, String name, Texture texture, ColorSpace colorSpace) {
|
||||||
super(type, name, texture);
|
super(type, name, texture);
|
||||||
this.texture = texture;
|
this.texture = texture;
|
||||||
this.unit = unit;
|
|
||||||
this.colorSpace = colorSpace;
|
this.colorSpace = colorSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,31 +89,18 @@ public class MatParamTexture extends MatParam {
|
|||||||
this.colorSpace = colorSpace;
|
this.colorSpace = colorSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnit(int unit) {
|
|
||||||
this.unit = unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUnit() {
|
|
||||||
return unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
super.write(ex);
|
super.write(ex);
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(unit, "texture_unit", -1);
|
oc.write(0, "texture_unit", -1);
|
||||||
|
oc.write(texture, "texture", null); // For backwards compatibility
|
||||||
// For backwards compat
|
|
||||||
oc.write(texture, "texture", null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(JmeImporter im) throws IOException {
|
public void read(JmeImporter im) throws IOException {
|
||||||
super.read(im);
|
super.read(im);
|
||||||
InputCapsule ic = im.getCapsule(this);
|
InputCapsule ic = im.getCapsule(this);
|
||||||
unit = ic.readInt("texture_unit", -1);
|
|
||||||
texture = (Texture) value;
|
texture = (Texture) value;
|
||||||
//texture = (Texture) ic.readSavable("texture", null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -93,7 +93,6 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
private ListMap<String, MatParam> paramValues = new ListMap<String, MatParam>();
|
private ListMap<String, MatParam> paramValues = new ListMap<String, MatParam>();
|
||||||
private Technique technique;
|
private Technique technique;
|
||||||
private HashMap<String, Technique> techniques = new HashMap<String, Technique>();
|
private HashMap<String, Technique> techniques = new HashMap<String, Technique>();
|
||||||
private int nextTexUnit = 0;
|
|
||||||
private RenderState additionalState = null;
|
private RenderState additionalState = null;
|
||||||
private RenderState mergedRenderState = new RenderState();
|
private RenderState mergedRenderState = new RenderState();
|
||||||
private boolean transparent = false;
|
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
|
// E.g. if user chose custom technique for one material but
|
||||||
// uses default technique for other material, the materials
|
// uses default technique for other material, the materials
|
||||||
// are not equal.
|
// are not equal.
|
||||||
String thisDefName = this.technique != null ? this.technique.getDef().getName() : "Default";
|
String thisDefName = this.technique != null
|
||||||
String otherDefName = other.technique != null ? other.technique.getDef().getName() : "Default";
|
? 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)) {
|
if (!thisDefName.equals(otherDefName)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -510,16 +515,6 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
|
|
||||||
paramValues.remove(name);
|
paramValues.remove(name);
|
||||||
if (matParam instanceof MatParamTexture) {
|
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;
|
sortingId = -1;
|
||||||
}
|
}
|
||||||
if (technique != null) {
|
if (technique != null) {
|
||||||
@ -562,13 +557,13 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
+ "Linear using texture.getImage.setColorSpace().",
|
+ "Linear using texture.getImage.setColorSpace().",
|
||||||
new Object[]{value.getName(), value.getImage().getColorSpace().name(), name});
|
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 {
|
} else {
|
||||||
val.setTextureValue(value);
|
val.setTextureValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (technique != null) {
|
if (technique != null) {
|
||||||
technique.notifyParamChanged(name, type, nextTexUnit - 1);
|
technique.notifyParamChanged(name, type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to recompute sort ID
|
// 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.
|
* Select the technique to use for rendering this material.
|
||||||
* <p>
|
* <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)
|
* Any candidate technique for selection (either default or named)
|
||||||
* must be verified to be compatible with the system, for that, the
|
* must be verified to be compatible with the system, for that, the
|
||||||
* <code>renderManager</code> is queried for capabilities.
|
* <code>renderManager</code> is queried for capabilities.
|
||||||
*
|
*
|
||||||
* @param name The name of the technique to select, pass "Default" to
|
* @param name The name of the technique to select, pass
|
||||||
* select one of the default techniques.
|
* {@link TechniqueDef#DEFAULT_TECHNIQUE_NAME} to select one of the default
|
||||||
|
* techniques.
|
||||||
* @param renderManager The {@link RenderManager render manager}
|
* @param renderManager The {@link RenderManager render manager}
|
||||||
* to query for capabilities.
|
* to query for capabilities.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException If "Default" is passed and no default
|
* @throws IllegalArgumentException If no technique exists with the given
|
||||||
* techniques are available on the material definition, or if a name
|
* name.
|
||||||
* is passed but there's no technique by that name.
|
|
||||||
* @throws UnsupportedOperationException If no candidate technique supports
|
* @throws UnsupportedOperationException If no candidate technique supports
|
||||||
* the system capabilities.
|
* the system capabilities.
|
||||||
*/
|
*/
|
||||||
@ -731,10 +721,11 @@ 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()) {
|
if (techDefs == null || techDefs.isEmpty()) {
|
||||||
throw new IllegalArgumentException("No default techniques are available on material '" + def.getName() + "'");
|
throw new IllegalArgumentException(
|
||||||
|
String.format("The requested technique %s is not available on material %s", name, def.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TechniqueDef lastTech = null;
|
TechniqueDef lastTech = null;
|
||||||
@ -743,8 +734,8 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
// use the first one that supports all the caps
|
// use the first one that supports all the caps
|
||||||
tech = new Technique(this, techDef);
|
tech = new Technique(this, techDef);
|
||||||
techniques.put(name, tech);
|
techniques.put(name, tech);
|
||||||
if(tech.getDef().getLightMode() == renderManager.getPreferredLightMode() ||
|
if (tech.getDef().getLightMode() == renderManager.getPreferredLightMode()
|
||||||
tech.getDef().getLightMode() == LightMode.Disable){
|
|| tech.getDef().getLightMode() == LightMode.Disable) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -755,23 +746,6 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
+ " is supported by the video hardware. The caps "
|
+ " is supported by the video hardware. The caps "
|
||||||
+ lastTech.getRequiredCaps() + " are required.");
|
+ 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 (!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");
|
|
||||||
}
|
|
||||||
|
|
||||||
tech = new Technique(this, techDef);
|
|
||||||
techniques.put(name, tech);
|
|
||||||
}
|
|
||||||
} else if (technique == tech) {
|
} else if (technique == tech) {
|
||||||
// attempting to switch to an already
|
// attempting to switch to an already
|
||||||
// active technique.
|
// active technique.
|
||||||
@ -785,19 +759,18 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
sortingId = -1;
|
sortingId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int updateShaderMaterialParameters(Renderer renderer, Shader shader, List<MatParamOverride> overrides) {
|
private int applyOverrides(Renderer renderer, Shader shader, List<MatParamOverride> overrides, int unit) {
|
||||||
int unit = 0;
|
|
||||||
|
|
||||||
if (overrides != null) {
|
|
||||||
for (MatParamOverride override : overrides) {
|
for (MatParamOverride override : overrides) {
|
||||||
VarType type = override.getVarType();
|
VarType type = override.getVarType();
|
||||||
|
|
||||||
MatParam paramDef = def.getMaterialParam(override.getName());
|
MatParam paramDef = def.getMaterialParam(override.getName());
|
||||||
|
|
||||||
if (paramDef == null || paramDef.getVarType() != type || !override.isEnabled()) {
|
if (paramDef == null || paramDef.getVarType() != type || !override.isEnabled()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uniform uniform = shader.getUniform(override.getPrefixedName());
|
Uniform uniform = shader.getUniform(override.getPrefixedName());
|
||||||
|
|
||||||
if (override.getValue() != null) {
|
if (override.getValue() != null) {
|
||||||
if (type.isTextureType()) {
|
if (type.isTextureType()) {
|
||||||
renderer.setTexture(unit, (Texture) override.getValue());
|
renderer.setTexture(unit, (Texture) override.getValue());
|
||||||
@ -810,6 +783,18 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
uniform.clearValue();
|
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++) {
|
for (int i = 0; i < paramValues.size(); i++) {
|
||||||
@ -857,7 +842,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
*/
|
*/
|
||||||
public void preload(RenderManager renderManager) {
|
public void preload(RenderManager renderManager) {
|
||||||
if (technique == null) {
|
if (technique == null) {
|
||||||
selectTechnique("Default", renderManager);
|
selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
|
||||||
}
|
}
|
||||||
TechniqueDef techniqueDef = technique.getDef();
|
TechniqueDef techniqueDef = technique.getDef();
|
||||||
Renderer renderer = renderManager.getRenderer();
|
Renderer renderer = renderManager.getRenderer();
|
||||||
@ -867,8 +852,8 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader shader = technique.makeCurrent(renderManager, null, null, rendererCaps);
|
Shader shader = technique.makeCurrent(renderManager, null, null, null, rendererCaps);
|
||||||
updateShaderMaterialParameters(renderer, shader, null);
|
updateShaderMaterialParameters(renderer, shader, null, null);
|
||||||
renderManager.getRenderer().setShader(shader);
|
renderManager.getRenderer().setShader(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,7 +942,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
*/
|
*/
|
||||||
public void render(Geometry geometry, LightList lights, RenderManager renderManager) {
|
public void render(Geometry geometry, LightList lights, RenderManager renderManager) {
|
||||||
if (technique == null) {
|
if (technique == null) {
|
||||||
selectTechnique("Default", renderManager);
|
selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
TechniqueDef techniqueDef = technique.getDef();
|
TechniqueDef techniqueDef = technique.getDef();
|
||||||
@ -975,7 +960,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
List<MatParamOverride> overrides = geometry.getWorldMatParamOverrides();
|
List<MatParamOverride> overrides = geometry.getWorldMatParamOverrides();
|
||||||
|
|
||||||
// Select shader to use
|
// 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.
|
// Begin tracking which uniforms were changed by material.
|
||||||
clearUniformsSetByCurrent(shader);
|
clearUniformsSetByCurrent(shader);
|
||||||
@ -984,8 +969,9 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
renderManager.updateUniformBindings(shader);
|
renderManager.updateUniformBindings(shader);
|
||||||
|
|
||||||
// Set material parameters
|
// Set material parameters
|
||||||
|
|
||||||
//TODO RRemove the unit when texture units are handled in the Uniform
|
//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.
|
// Clear any uniforms not changed by material.
|
||||||
resetUniformsNotSetByCurrent(shader);
|
resetUniformsNotSetByCurrent(shader);
|
||||||
@ -1081,11 +1067,6 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
MatParam param = entry.getValue();
|
MatParam param = entry.getValue();
|
||||||
if (param instanceof MatParamTexture) {
|
if (param instanceof MatParamTexture) {
|
||||||
MatParamTexture texVal = (MatParamTexture) param;
|
MatParamTexture texVal = (MatParamTexture) param;
|
||||||
|
|
||||||
if (nextTexUnit < texVal.getUnit() + 1) {
|
|
||||||
nextTexUnit = texVal.getUnit() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the texture failed to load for this param
|
// the texture failed to load for this param
|
||||||
// do not add to param values
|
// do not add to param values
|
||||||
if (texVal.getTextureValue() == null || texVal.getTextureValue().getImage() == null) {
|
if (texVal.getTextureValue() == null || texVal.getTextureValue().getImage() == null) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +134,7 @@ public class MaterialDef {
|
|||||||
* @see ColorSpace
|
* @see ColorSpace
|
||||||
*/
|
*/
|
||||||
public void addMaterialParamTexture(VarType type, String name, ColorSpace colorSpace) {
|
public void addMaterialParamTexture(VarType type, String name, ColorSpace colorSpace) {
|
||||||
matParams.put(name, new MatParamTexture(type, name, null , 0, colorSpace));
|
matParams.put(name, new MatParamTexture(type, name, null, colorSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,20 @@ public final class Technique {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyOverrides(DefineList defineList, List<MatParamOverride> overrides) {
|
||||||
|
for (MatParamOverride override : overrides) {
|
||||||
|
if (!override.isEnabled()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Integer defineId = def.getShaderParamDefineId(override.name);
|
||||||
|
if (defineId != null) {
|
||||||
|
if (def.getDefineIdType(defineId) == override.type) {
|
||||||
|
defineList.set(defineId, override.type, override.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the material to determine which shader to use for rendering.
|
* Called by the material to determine which shader to use for rendering.
|
||||||
*
|
*
|
||||||
@ -120,7 +134,8 @@ public final class Technique {
|
|||||||
* @param rendererCaps The renderer capabilities which the shader should support.
|
* @param rendererCaps The renderer capabilities which the shader should support.
|
||||||
* @return A compatible shader.
|
* @return A compatible shader.
|
||||||
*/
|
*/
|
||||||
Shader makeCurrent(RenderManager renderManager, List<MatParamOverride> overrides,
|
Shader makeCurrent(RenderManager renderManager, List<MatParamOverride> worldOverrides,
|
||||||
|
List<MatParamOverride> forcedOverrides,
|
||||||
LightList lights, EnumSet<Caps> rendererCaps) {
|
LightList lights, EnumSet<Caps> rendererCaps) {
|
||||||
TechniqueDefLogic logic = def.getLogic();
|
TechniqueDefLogic logic = def.getLogic();
|
||||||
AssetManager assetManager = owner.getMaterialDef().getAssetManager();
|
AssetManager assetManager = owner.getMaterialDef().getAssetManager();
|
||||||
@ -128,18 +143,11 @@ public final class Technique {
|
|||||||
dynamicDefines.clear();
|
dynamicDefines.clear();
|
||||||
dynamicDefines.setAll(paramDefines);
|
dynamicDefines.setAll(paramDefines);
|
||||||
|
|
||||||
if (overrides != null) {
|
if (worldOverrides != null) {
|
||||||
for (MatParamOverride override : overrides) {
|
applyOverrides(dynamicDefines, worldOverrides);
|
||||||
if (!override.isEnabled()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Integer defineId = def.getShaderParamDefineId(override.name);
|
|
||||||
if (defineId != null) {
|
|
||||||
if (def.getDefineIdType(defineId) == override.type) {
|
|
||||||
dynamicDefines.set(defineId, override.type, override.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (forcedOverrides != null) {
|
||||||
|
applyOverrides(dynamicDefines, forcedOverrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
return logic.makeCurrent(assetManager, renderManager, rendererCaps, lights, dynamicDefines);
|
return logic.makeCurrent(assetManager, renderManager, rendererCaps, lights, dynamicDefines);
|
||||||
|
@ -53,6 +53,14 @@ public class TechniqueDef implements Savable {
|
|||||||
*/
|
*/
|
||||||
public static final int SAVABLE_VERSION = 1;
|
public static final int SAVABLE_VERSION = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default technique name.
|
||||||
|
*
|
||||||
|
* The technique with this name is selected if no specific technique is
|
||||||
|
* requested by the user. Currently set to "Default".
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_TECHNIQUE_NAME = "Default";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes light rendering mode.
|
* Describes light rendering mode.
|
||||||
*/
|
*/
|
||||||
@ -113,7 +121,7 @@ public class TechniqueDef implements Savable {
|
|||||||
Legacy
|
Legacy
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -153,7 +161,7 @@ public class TechniqueDef implements Savable {
|
|||||||
public TechniqueDef(String name, int sortId){
|
public TechniqueDef(String name, int sortId){
|
||||||
this();
|
this();
|
||||||
this.sortId = sortId;
|
this.sortId = sortId;
|
||||||
this.name = name == null ? "Default" : name;
|
this.name = name == null ? TechniqueDef.DEFAULT_TECHNIQUE_NAME : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -178,7 +186,8 @@ public class TechniqueDef implements Savable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of this technique as specified in the J3MD file.
|
* Returns the name of this technique as specified in the J3MD file.
|
||||||
* Default techniques have the name "Default".
|
* Default
|
||||||
|
* techniques have the name {@link #DEFAULT_TECHNIQUE_NAME}.
|
||||||
*
|
*
|
||||||
* @return the name of this technique
|
* @return the name of this technique
|
||||||
*/
|
*/
|
||||||
|
@ -34,6 +34,7 @@ package com.jme3.renderer;
|
|||||||
import com.jme3.light.DefaultLightFilter;
|
import com.jme3.light.DefaultLightFilter;
|
||||||
import com.jme3.light.LightFilter;
|
import com.jme3.light.LightFilter;
|
||||||
import com.jme3.light.LightList;
|
import com.jme3.light.LightList;
|
||||||
|
import com.jme3.material.MatParamOverride;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.material.MaterialDef;
|
import com.jme3.material.MaterialDef;
|
||||||
import com.jme3.material.RenderState;
|
import com.jme3.material.RenderState;
|
||||||
@ -82,6 +83,7 @@ public class RenderManager {
|
|||||||
private Material forcedMaterial = null;
|
private Material forcedMaterial = null;
|
||||||
private String forcedTechnique = null;
|
private String forcedTechnique = null;
|
||||||
private RenderState forcedRenderState = null;
|
private RenderState forcedRenderState = null;
|
||||||
|
private final List<MatParamOverride> forcedOverrides = new ArrayList<>();
|
||||||
private int viewX, viewY, viewWidth, viewHeight;
|
private int viewX, viewY, viewWidth, viewHeight;
|
||||||
private Matrix4f orthoMatrix = new Matrix4f();
|
private Matrix4f orthoMatrix = new Matrix4f();
|
||||||
private LightList filteredLightList = new LightList(null);
|
private LightList filteredLightList = new LightList(null);
|
||||||
@ -92,6 +94,7 @@ public class RenderManager {
|
|||||||
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
|
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
|
||||||
private int singlePassLightBatchSize = 1;
|
private int singlePassLightBatchSize = 1;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a high-level rendering interface over the
|
* Create a high-level rendering interface over the
|
||||||
* low-level rendering interface.
|
* low-level rendering interface.
|
||||||
@ -426,6 +429,44 @@ public class RenderManager {
|
|||||||
this.forcedTechnique = forcedTechnique;
|
this.forcedTechnique = forcedTechnique;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a forced material parameter to use when rendering geometries.
|
||||||
|
* <p>
|
||||||
|
* The provided parameter takes precedence over parameters set on the
|
||||||
|
* material or any overrides that exist in the scene graph that have the
|
||||||
|
* same name.
|
||||||
|
*
|
||||||
|
* @param override The override to add
|
||||||
|
* @see MatParamOverride
|
||||||
|
* @see #removeForcedMatParam(com.jme3.material.MatParamOverride)
|
||||||
|
*/
|
||||||
|
public void addForcedMatParam(MatParamOverride override) {
|
||||||
|
forcedOverrides.add(override);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a forced material parameter previously added.
|
||||||
|
*
|
||||||
|
* @param override The override to remove.
|
||||||
|
* @see #addForcedMatParam(com.jme3.material.MatParamOverride)
|
||||||
|
*/
|
||||||
|
public void removeForcedMatParam(MatParamOverride override) {
|
||||||
|
forcedOverrides.remove(override);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the forced material parameters applied to rendered geometries.
|
||||||
|
* <p>
|
||||||
|
* Forced parameters can be added via
|
||||||
|
* {@link #addForcedMatParam(com.jme3.material.MatParamOverride)} or removed
|
||||||
|
* via {@link #removeForcedMatParam(com.jme3.material.MatParamOverride)}.
|
||||||
|
*
|
||||||
|
* @return The forced material parameters.
|
||||||
|
*/
|
||||||
|
public List<MatParamOverride> getForcedMatParams() {
|
||||||
|
return forcedOverrides;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable or disable alpha-to-coverage.
|
* Enable or disable alpha-to-coverage.
|
||||||
* <p>
|
* <p>
|
||||||
@ -539,8 +580,11 @@ 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();
|
||||||
tmpTech = g.getMaterial().getActiveTechnique() != null ? g.getMaterial().getActiveTechnique().getDef().getName() : "Default";
|
if (matDef.getTechniqueDefs(forcedTechnique) != null) {
|
||||||
|
tmpTech = g.getMaterial().getActiveTechnique() != null
|
||||||
|
? g.getMaterial().getActiveTechnique().getDef().getName()
|
||||||
|
: TechniqueDef.DEFAULT_TECHNIQUE_NAME;
|
||||||
g.getMaterial().selectTechnique(forcedTechnique, this);
|
g.getMaterial().selectTechnique(forcedTechnique, this);
|
||||||
//saving forcedRenderState for future calls
|
//saving forcedRenderState for future calls
|
||||||
RenderState tmpRs = forcedRenderState;
|
RenderState tmpRs = forcedRenderState;
|
||||||
|
@ -593,8 +593,8 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
|
|||||||
worldOverrides.addAll(localOverrides);
|
worldOverrides.addAll(localOverrides);
|
||||||
} else {
|
} else {
|
||||||
assert (parent.refreshFlags & RF_MATPARAM_OVERRIDE) == 0;
|
assert (parent.refreshFlags & RF_MATPARAM_OVERRIDE) == 0;
|
||||||
worldOverrides.addAll(localOverrides);
|
|
||||||
worldOverrides.addAll(parent.worldOverrides);
|
worldOverrides.addAll(parent.worldOverrides);
|
||||||
|
worldOverrides.addAll(localOverrides);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -46,14 +46,17 @@ import org.junit.Assert;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static com.jme3.scene.MPOTestUtils.*;
|
import static com.jme3.scene.MPOTestUtils.*;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
import com.jme3.shader.DefineList;
|
import com.jme3.shader.DefineList;
|
||||||
import com.jme3.system.NullRenderer;
|
import com.jme3.system.NullRenderer;
|
||||||
import com.jme3.system.TestUtil;
|
import com.jme3.system.TestUtil;
|
||||||
import com.jme3.texture.Image.Format;
|
import com.jme3.texture.Image.Format;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.Texture2D;
|
import com.jme3.texture.Texture2D;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates how {@link MatParamOverride MPOs} work on the material level.
|
* Validates how {@link MatParamOverride MPOs} work on the material level.
|
||||||
@ -124,6 +127,33 @@ public class MaterialMatParamOverrideTest {
|
|||||||
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 2.79f));
|
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 2.79f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testForcedOverride() {
|
||||||
|
material("Common/MatDefs/Light/Lighting.j3md");
|
||||||
|
inputMp(mpoFloat("AlphaDiscardThreshold", 3.12f));
|
||||||
|
inputMpo(mpoFloat("AlphaDiscardThreshold", 2.79f));
|
||||||
|
inputFpo(mpoFloat("AlphaDiscardThreshold", 1.23f));
|
||||||
|
outDefines(def("DISCARD_ALPHA", VarType.Float, 1.23f));
|
||||||
|
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 1.23f));
|
||||||
|
|
||||||
|
reset();
|
||||||
|
root.clearMatParamOverrides();
|
||||||
|
root.updateGeometricState();
|
||||||
|
outDefines(def("DISCARD_ALPHA", VarType.Float, 2.79f));
|
||||||
|
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 2.79f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChildOverridesParent() {
|
||||||
|
material("Common/MatDefs/Light/Lighting.j3md");
|
||||||
|
|
||||||
|
inputParentMpo(mpoFloat("AlphaDiscardThreshold", 3.12f));
|
||||||
|
inputMpo(mpoFloat("AlphaDiscardThreshold", 2.79f));
|
||||||
|
|
||||||
|
outUniforms(uniform("AlphaDiscardThreshold", VarType.Float, 2.79f));
|
||||||
|
outDefines(def("DISCARD_ALPHA", VarType.Float, 2.79f));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMpoDisable() {
|
public void testMpoDisable() {
|
||||||
material("Common/MatDefs/Light/Lighting.j3md");
|
material("Common/MatDefs/Light/Lighting.j3md");
|
||||||
@ -222,7 +252,7 @@ public class MaterialMatParamOverrideTest {
|
|||||||
|
|
||||||
reset();
|
reset();
|
||||||
geometry.clearMatParamOverrides();
|
geometry.clearMatParamOverrides();
|
||||||
geometry.updateGeometricState();
|
root.updateGeometricState();
|
||||||
outDefines(def("NUM_BONES", VarType.Int, 1234));
|
outDefines(def("NUM_BONES", VarType.Int, 1234));
|
||||||
outUniforms(uniform("NumberOfBones", VarType.Int, 1234));
|
outUniforms(uniform("NumberOfBones", VarType.Int, 1234));
|
||||||
|
|
||||||
@ -272,7 +302,7 @@ public class MaterialMatParamOverrideTest {
|
|||||||
|
|
||||||
reset();
|
reset();
|
||||||
geometry.clearMatParamOverrides();
|
geometry.clearMatParamOverrides();
|
||||||
geometry.updateGeometricState();
|
root.updateGeometricState();
|
||||||
outDefines();
|
outDefines();
|
||||||
outUniforms();
|
outUniforms();
|
||||||
}
|
}
|
||||||
@ -315,7 +345,7 @@ public class MaterialMatParamOverrideTest {
|
|||||||
|
|
||||||
reset();
|
reset();
|
||||||
geometry.clearMatParamOverrides();
|
geometry.clearMatParamOverrides();
|
||||||
geometry.updateGeometricState();
|
root.updateGeometricState();
|
||||||
outDefines();
|
outDefines();
|
||||||
outUniforms();
|
outUniforms();
|
||||||
outTextures();
|
outTextures();
|
||||||
@ -341,7 +371,7 @@ public class MaterialMatParamOverrideTest {
|
|||||||
|
|
||||||
reset();
|
reset();
|
||||||
geometry.clearMatParamOverrides();
|
geometry.clearMatParamOverrides();
|
||||||
geometry.updateGeometricState();
|
root.updateGeometricState();
|
||||||
outDefines(def("DIFFUSEMAP", VarType.Texture2D, tex1));
|
outDefines(def("DIFFUSEMAP", VarType.Texture2D, tex1));
|
||||||
outUniforms(uniform("DiffuseMap", VarType.Int, 0));
|
outUniforms(uniform("DiffuseMap", VarType.Int, 0));
|
||||||
outTextures(tex1);
|
outTextures(tex1);
|
||||||
@ -369,9 +399,15 @@ public class MaterialMatParamOverrideTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Geometry geometry = new Geometry("geometry", new Box(1, 1, 1));
|
private final Geometry geometry = new Geometry("Geometry", new Box(1, 1, 1));
|
||||||
|
private final Node root = new Node("Root Node");
|
||||||
private final LightList lightList = new LightList(geometry);
|
private final LightList lightList = new LightList(geometry);
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
root.attachChild(geometry);
|
||||||
|
}
|
||||||
|
|
||||||
private final NullRenderer renderer = new NullRenderer() {
|
private final NullRenderer renderer = new NullRenderer() {
|
||||||
@Override
|
@Override
|
||||||
public void setShader(Shader shader) {
|
public void setShader(Shader shader) {
|
||||||
@ -407,13 +443,35 @@ public class MaterialMatParamOverrideTest {
|
|||||||
for (MatParamOverride override : overrides) {
|
for (MatParamOverride override : overrides) {
|
||||||
geometry.addMatParamOverride(override);
|
geometry.addMatParamOverride(override);
|
||||||
}
|
}
|
||||||
geometry.updateGeometricState();
|
root.updateGeometricState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inputParentMpo(MatParamOverride... overrides) {
|
||||||
|
if (evaluated) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
for (MatParamOverride override : overrides) {
|
||||||
|
root.addMatParamOverride(override);
|
||||||
|
}
|
||||||
|
root.updateGeometricState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inputFpo(MatParamOverride... overrides) {
|
||||||
|
if (evaluated) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
for (MatParamOverride override : overrides) {
|
||||||
|
renderManager.addForcedMatParam(override);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reset() {
|
private void reset() {
|
||||||
evaluated = false;
|
evaluated = false;
|
||||||
usedShader = null;
|
usedShader = null;
|
||||||
Arrays.fill(usedTextures, null);
|
Arrays.fill(usedTextures, null);
|
||||||
|
for (MatParamOverride override : new ArrayList<>(renderManager.getForcedMatParams())) {
|
||||||
|
renderManager.removeForcedMatParam(override);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Define def(String name, VarType type, Object value) {
|
private Define def(String name, VarType type, Object value) {
|
||||||
@ -520,6 +578,10 @@ public class MaterialMatParamOverrideTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void outUniforms(Uniform... uniforms) {
|
private void outUniforms(Uniform... uniforms) {
|
||||||
|
if (!evaluated) {
|
||||||
|
evaluateTechniqueDef();
|
||||||
|
}
|
||||||
|
|
||||||
HashSet<Uniform> actualUniforms = new HashSet<>();
|
HashSet<Uniform> actualUniforms = new HashSet<>();
|
||||||
|
|
||||||
for (Uniform uniform : usedShader.getUniformMap().values()) {
|
for (Uniform uniform : usedShader.getUniformMap().values()) {
|
||||||
|
@ -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"));
|
||||||
@ -107,7 +120,7 @@ public class J3MLoaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TextureKey setupMockForTexture(final String paramName, final String path, final boolean flipY, final Texture texture) {
|
private TextureKey setupMockForTexture(final String paramName, final String path, final boolean flipY, final Texture texture) {
|
||||||
when(materialDef.getMaterialParam(paramName)).thenReturn(new MatParamTexture(VarType.Texture2D, paramName, texture, 0, null));
|
when(materialDef.getMaterialParam(paramName)).thenReturn(new MatParamTexture(VarType.Texture2D, paramName, texture, null));
|
||||||
|
|
||||||
final TextureKey textureKey = new TextureKey(path, flipY);
|
final TextureKey textureKey = new TextureKey(path, flipY);
|
||||||
textureKey.setGenerateMips(true);
|
textureKey.setGenerateMips(true);
|
||||||
|
@ -33,6 +33,7 @@ package com.jme3.renderer;
|
|||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.TechniqueDef;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.renderer.queue.GeometryList;
|
import com.jme3.renderer.queue.GeometryList;
|
||||||
import com.jme3.renderer.queue.OpaqueComparator;
|
import com.jme3.renderer.queue.OpaqueComparator;
|
||||||
@ -92,7 +93,7 @@ public class OpaqueComparatorTest {
|
|||||||
String techniqueName = materials[i].getActiveTechnique().getDef().getName();
|
String techniqueName = materials[i].getActiveTechnique().getDef().getName();
|
||||||
clonedMaterial.selectTechnique(techniqueName, renderManager);
|
clonedMaterial.selectTechnique(techniqueName, renderManager);
|
||||||
} else {
|
} else {
|
||||||
clonedMaterial.selectTechnique("Default", renderManager);
|
clonedMaterial.selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
geom.setMaterial(clonedMaterial);
|
geom.setMaterial(clonedMaterial);
|
||||||
@ -156,7 +157,7 @@ public class OpaqueComparatorTest {
|
|||||||
Material lightingMatGlow = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
|
Material lightingMatGlow = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
|
||||||
|
|
||||||
lightingMatDefault.setName("TechDefault");
|
lightingMatDefault.setName("TechDefault");
|
||||||
lightingMatDefault.selectTechnique("Default", renderManager);
|
lightingMatDefault.selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
|
||||||
|
|
||||||
lightingPostShadow.setName("TechPostShad");
|
lightingPostShadow.setName("TechPostShad");
|
||||||
lightingPostShadow.selectTechnique("PostShadow", renderManager);
|
lightingPostShadow.selectTechnique("PostShadow", renderManager);
|
||||||
@ -272,7 +273,7 @@ public class OpaqueComparatorTest {
|
|||||||
tex2.getImage().setId(3);
|
tex2.getImage().setId(3);
|
||||||
|
|
||||||
matBase1.setName("BASE");
|
matBase1.setName("BASE");
|
||||||
matBase1.selectTechnique("Default", renderManager);
|
matBase1.selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
|
||||||
matBase1.setBoolean("UseVertexColor", true);
|
matBase1.setBoolean("UseVertexColor", true);
|
||||||
matBase1.setTexture("DiffuseMap", texBase);
|
matBase1.setTexture("DiffuseMap", texBase);
|
||||||
|
|
||||||
|
10
jme3-core/src/test/resources/same-name-technique.j3md
Normal file
10
jme3-core/src/test/resources/same-name-technique.j3md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
MaterialDef Test Material {
|
||||||
|
Technique Test {
|
||||||
|
VertexShader GLSL150 : test150.vert
|
||||||
|
FragmentShader GLSL150 : test150.frag
|
||||||
|
}
|
||||||
|
Technique Test {
|
||||||
|
VertexShader GLSL100 : test.vert
|
||||||
|
FragmentShader GLSL100 : test.frag
|
||||||
|
}
|
||||||
|
}
|
@ -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(TechniqueDef.DEFAULT_TECHNIQUE_NAME)) {
|
||||||
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) {
|
||||||
|
@ -3,6 +3,7 @@ package jme3test.material;
|
|||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.material.Technique;
|
import com.jme3.material.Technique;
|
||||||
|
import com.jme3.material.TechniqueDef;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.shape.Box;
|
import com.jme3.scene.shape.Box;
|
||||||
@ -27,7 +28,7 @@ public class TestShaderNodes extends SimpleApplication {
|
|||||||
Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
|
Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
|
||||||
|
|
||||||
Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md");
|
Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md");
|
||||||
mat.selectTechnique("Default", renderManager);
|
mat.selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
|
||||||
Technique t = mat.getActiveTechnique();
|
Technique t = mat.getActiveTechnique();
|
||||||
|
|
||||||
// for (Shader.ShaderSource shaderSource : t.getShader().getSources()) {
|
// for (Shader.ShaderSource shaderSource : t.getShader().getSources()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user