Ver Fonte

initial implementation of MPO (untested!)

Kirill Vainer há 9 anos atrás
pai
commit
cb5c1395b3

+ 42 - 0
jme3-core/src/main/java/com/jme3/material/MatParamOverride.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);
+    }
+
+}

+ 6 - 3
jme3-core/src/main/java/com/jme3/material/Material.java

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

+ 20 - 22
jme3-core/src/main/java/com/jme3/material/Technique.java

@@ -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.
@@ -85,26 +87,8 @@ public final class Technique {
         if (defineId == null) {
             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);
     }
     
     /**

+ 4 - 4
jme3-core/src/main/java/com/jme3/material/TechniqueDef.java

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

+ 24 - 0
jme3-core/src/main/java/com/jme3/scene/Spatial.java

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

+ 37 - 1
jme3-core/src/main/java/com/jme3/shader/DefineList.java

@@ -31,6 +31,7 @@
  */
 package com.jme3.shader;
 
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -41,7 +42,7 @@ import java.util.List;
 public final class DefineList {
 
     public static final int MAX_DEFINES = 64;
-    
+
     private long hash;
     private final int[] vals;
 
@@ -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;
     }