RM: add ability to force mat param

cleanup_build_scripts
Kirill Vainer 9 years ago
parent d0035b0bc6
commit 83259061d3
  1. 57
      jme3-core/src/main/java/com/jme3/material/Material.java
  2. 34
      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,32 +774,43 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
sortingId = -1;
}
private void 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 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++) {
MatParam param = paramValues.getValue(i);
@ -854,8 +865,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);
}
@ -962,7 +973,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);
@ -971,7 +982,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
renderManager.updateUniformBindings(shader);
// Set material parameters
updateShaderMaterialParameters(renderer, shader, geometry.getWorldMatParamOverrides());
updateShaderMaterialParameters(renderer, shader, overrides, renderManager.getForcedMatParams());
// Clear any uniforms not changed by material.
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.
*
@ -120,7 +134,8 @@ public final class Technique {
* @param rendererCaps The renderer capabilities which the shader should support.
* @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) {
TechniqueDefLogic logic = def.getLogic();
AssetManager assetManager = owner.getMaterialDef().getAssetManager();
@ -128,18 +143,11 @@ public final class Technique {
dynamicDefines.clear();
dynamicDefines.setAll(paramDefines);
if (overrides != null) {
for (MatParamOverride override : overrides) {
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 (worldOverrides != null) {
applyOverrides(dynamicDefines, worldOverrides);
}
if (forcedOverrides != null) {
applyOverrides(dynamicDefines, forcedOverrides);
}
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.LightFilter;
import com.jme3.light.LightList;
import com.jme3.material.MatParamOverride;
import com.jme3.material.Material;
import com.jme3.material.MaterialDef;
import com.jme3.material.RenderState;
@ -82,6 +83,7 @@ public class RenderManager {
private Material forcedMaterial = null;
private String forcedTechnique = null;
private RenderState forcedRenderState = null;
private final List<MatParamOverride> forcedOverrides = new ArrayList<>();
private int viewX, viewY, viewWidth, viewHeight;
private Matrix4f orthoMatrix = new Matrix4f();
private LightList filteredLightList = new LightList(null);
@ -92,6 +94,7 @@ public class RenderManager {
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
private int singlePassLightBatchSize = 1;
/**
* Create a high-level rendering interface over the
* low-level rendering interface.
@ -426,6 +429,44 @@ public class RenderManager {
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.
* <p>

@ -53,6 +53,7 @@ import com.jme3.system.TestUtil;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
@ -126,6 +127,22 @@ public class MaterialMatParamOverrideTest {
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");
@ -439,10 +456,22 @@ public class MaterialMatParamOverrideTest {
root.updateGeometricState();
}
private void inputFpo(MatParamOverride... overrides) {
if (evaluated) {
throw new IllegalStateException();
}
for (MatParamOverride override : overrides) {
renderManager.addForcedMatParam(override);
}
}
private void reset() {
evaluated = false;
usedShader = null;
Arrays.fill(usedTextures, null);
for (MatParamOverride override : new ArrayList<>(renderManager.getForcedMatParams())) {
renderManager.removeForcedMatParam(override);
}
}
private Define def(String name, VarType type, Object value) {

Loading…
Cancel
Save