RM: add ability to force mat param
This commit is contained in:
parent
d0035b0bc6
commit
83259061d3
@ -774,31 +774,42 @@ 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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
} else {
|
||||
uniform.clearValue();
|
||||
}
|
||||
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());
|
||||
}
|
||||
} 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++) {
|
||||
@ -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…
x
Reference in New Issue
Block a user