RM: add ability to force mat param

cleanup_build_scripts
Kirill Vainer 9 years ago
parent d0035b0bc6
commit 83259061d3
  1. 27
      jme3-core/src/main/java/com/jme3/material/Material.java
  2. 32
      jme3-core/src/main/java/com/jme3/material/Technique.java
  3. 41
      jme3-core/src/main/java/com/jme3/renderer/RenderManager.java
  4. 29
      jme3-core/src/test/java/com/jme3/material/MaterialMatParamOverrideTest.java

@ -774,19 +774,18 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
sortingId = -1; sortingId = -1;
} }
private void 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());
@ -799,6 +798,18 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
uniform.clearValue(); uniform.clearValue();
} }
} }
return unit;
}
private void 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++) {
@ -854,8 +865,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);
} }
@ -962,7 +973,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);
@ -971,7 +982,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
renderManager.updateUniformBindings(shader); renderManager.updateUniformBindings(shader);
// Set material parameters // Set material parameters
updateShaderMaterialParameters(renderer, shader, geometry.getWorldMatParamOverrides()); updateShaderMaterialParameters(renderer, shader, overrides, renderManager.getForcedMatParams());
// Clear any uniforms not changed by material. // Clear any uniforms not changed by material.
resetUniformsNotSetByCurrent(shader); resetUniformsNotSetByCurrent(shader);

@ -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);

@ -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>

@ -53,6 +53,7 @@ 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; import org.junit.Before;
@ -126,6 +127,22 @@ 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 @Test
public void testChildOverridesParent() { public void testChildOverridesParent() {
material("Common/MatDefs/Light/Lighting.j3md"); material("Common/MatDefs/Light/Lighting.j3md");
@ -439,10 +456,22 @@ public class MaterialMatParamOverrideTest {
root.updateGeometricState(); 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) {

Loading…
Cancel
Save