initial implementation of MPO (untested!)

experimental^2^2
Kirill Vainer 9 years ago
parent 239524c85b
commit cb5c1395b3
  1. 42
      jme3-core/src/main/java/com/jme3/material/MatParamOverride.java
  2. 9
      jme3-core/src/main/java/com/jme3/material/Material.java
  3. 40
      jme3-core/src/main/java/com/jme3/material/Technique.java
  4. 8
      jme3-core/src/main/java/com/jme3/material/TechniqueDef.java
  5. 24
      jme3-core/src/main/java/com/jme3/scene/Spatial.java
  6. 36
      jme3-core/src/main/java/com/jme3/shader/DefineList.java

@ -0,0 +1,42 @@
/*
* Copyright (c) 2009-2016 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.material;
import com.jme3.shader.VarType;
public final class MatParamOverride extends MatParam {
public MatParamOverride(VarType type, String name, Object value) {
super(type, name, value);
}
}

@ -820,7 +820,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
* used for rendering, there won't be any delay since the material has
* been already been setup for rendering.
*
* @param rm The render manager to preload for
* @param renderManager The render manager to preload for
*/
public void preload(RenderManager renderManager) {
if (technique == null) {
@ -834,7 +834,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
return;
}
Shader shader = technique.makeCurrent(renderManager, null, rendererCaps);
Shader shader = technique.makeCurrent(renderManager, null, null, rendererCaps);
updateShaderMaterialParameters(renderer, shader);
renderManager.getRenderer().setShader(shader);
}
@ -938,8 +938,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
// Apply render state
updateRenderState(renderManager, renderer, techniqueDef);
// Get world overrides
ArrayList<MatParamOverride> overrides = geometry.getWorldOverrides();
// Select shader to use
Shader shader = technique.makeCurrent(renderManager, lights, rendererCaps);
Shader shader = technique.makeCurrent(renderManager, overrides, lights, rendererCaps);
// Begin tracking which uniforms were changed by material.
clearUniformsSetByCurrent(shader);

@ -41,7 +41,9 @@ import com.jme3.shader.DefineList;
import com.jme3.shader.Shader;
import com.jme3.shader.VarType;
import com.jme3.util.ListMap;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
/**
* Represents a technique instance.
@ -86,25 +88,7 @@ public final class Technique {
return;
}
if (value == null) {
dynamicDefines.set(defineId, 0);
return;
}
switch (type) {
case Int:
dynamicDefines.set(defineId, (Integer) value);
break;
case Float:
dynamicDefines.set(defineId, (Float) value);
break;
case Boolean:
dynamicDefines.set(defineId, ((Boolean)value));
break;
default:
dynamicDefines.set(defineId, 1);
break;
}
dynamicDefines.set(defineId, type, value);
}
/**
@ -115,6 +99,7 @@ public final class Technique {
*/
void notifyTechniqueSwitched() {
ListMap<String, MatParam> paramMap = owner.getParamsMap();
dynamicDefines.clear();
for (int i = 0; i < paramMap.size(); i++) {
MatParam param = paramMap.getValue(i);
notifyParamChanged(param.getName(), param.getVarType(), param.getValue());
@ -131,10 +116,23 @@ public final class Technique {
* @param rendererCaps The renderer capabilities which the shader should support.
* @return A compatible shader.
*/
Shader makeCurrent(RenderManager renderManager, LightList lights, EnumSet<Caps> rendererCaps) {
Shader makeCurrent(RenderManager renderManager, ArrayList<MatParamOverride> overrides,
LightList lights, EnumSet<Caps> rendererCaps) {
TechniqueDefLogic logic = def.getLogic();
AssetManager assetManager = owner.getMaterialDef().getAssetManager();
return logic.makeCurrent(assetManager, renderManager, rendererCaps, lights, dynamicDefines);
// TODO: remove allocation
DefineList combinedDefines = def.createDefineList();
combinedDefines.setAll(dynamicDefines);
for (MatParamOverride override : overrides) {
Integer defineId = def.getShaderParamDefineId(override.name);
if (defineId != null) {
combinedDefines.set(defineId, override.type, override.value);
}
}
return logic.makeCurrent(assetManager, renderManager, rendererCaps, lights, combinedDefines);
}
/**

@ -330,13 +330,13 @@ public class TechniqueDef implements Savable {
}
/**
* Get the define ID for a given define name.
* Get the define ID for a given material parameter.
*
* @param defineName The define name to lookup
* @param paramName The parameter name to look up
* @return The define ID, or null if not found.
*/
public Integer getShaderParamDefineId(String defineName) {
return paramToDefineId.get(defineName);
public Integer getShaderParamDefineId(String paramName) {
return paramToDefineId.get(paramName);
}

@ -38,6 +38,7 @@ import com.jme3.collision.Collidable;
import com.jme3.export.*;
import com.jme3.light.Light;
import com.jme3.light.LightList;
import com.jme3.material.MatParamOverride;
import com.jme3.material.Material;
import com.jme3.math.*;
import com.jme3.renderer.Camera;
@ -424,6 +425,29 @@ public abstract class Spatial implements Savable, Cloneable, Collidable, Cloneab
return worldLights;
}
/**
* Get the local material parameter overrides.
*
* @return The list of local material parameter overrides.
*/
public ArrayList<MatParamOverride> getLocalOverrides() {
return null;
}
/**
* Get the world material parameter overrides.
*
* Note that this list is only updated on a call to
* {@link #updateGeometricState()}. After update, the world overrides list
* will contain the {@link #getParent() parent's} world overrides combined
* with this spatial's {@link #getLocalOverrides() local overrides}.
*
* @return The list of world material parameter overrides.
*/
public ArrayList<MatParamOverride> getWorldOverrides() {
return null;
}
/**
* <code>getWorldRotation</code> retrieves the absolute rotation of the
* Spatial.

@ -31,6 +31,7 @@
*/
package com.jme3.shader;
import java.util.Arrays;
import java.util.List;
/**
@ -76,6 +77,41 @@ public final class DefineList {
set(id, val ? 1 : 0);
}
public void set(int id, VarType type, Object value) {
if (value == null) {
set(id, 0);
return;
}
switch (type) {
case Int:
set(id, (Integer) value);
break;
case Float:
set(id, (Float) value);
break;
case Boolean:
set(id, ((Boolean) value));
break;
default:
set(id, 1);
break;
}
}
public void setAll(DefineList other) {
for (int i = 0; i < other.vals.length; i++) {
if (other.vals[i] != 0) {
vals[i] = other.vals[i];
}
}
}
public void clear() {
hash = 0;
Arrays.fill(vals, 0);
}
public boolean getBoolean(int id) {
return vals[id] != 0;
}

Loading…
Cancel
Save