Bladeren bron

* Fixed issue 590 (Uniform.setVector4Length() re-allocating buffer even when not needed)

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10544 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Sha..om 12 jaren geleden
bovenliggende
commit
3195940994
1 gewijzigde bestanden met toevoegingen van 350 en 350 verwijderingen
  1. 350 350
      engine/src/core/com/jme3/shader/Uniform.java

+ 350 - 350
engine/src/core/com/jme3/shader/Uniform.java

@@ -1,350 +1,350 @@
-/*
- * Copyright (c) 2009-2012 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.shader;
-
-import com.jme3.math.*;
-import com.jme3.util.BufferUtils;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-
-public class Uniform extends ShaderVariable {
-
-    private static final Integer ZERO_INT = Integer.valueOf(0);
-    private static final Float ZERO_FLT = Float.valueOf(0);
-    private static final FloatBuffer ZERO_BUF = BufferUtils.createFloatBuffer(4*4);
-
-    /**
-     * Currently set value of the uniform.
-     */
-    protected Object value = null;
-    
-    /**
-     * For arrays or matrices, efficient format
-     * that can be sent to GL faster.
-     */
-    protected FloatBuffer multiData = null;
-
-    /**
-     * Type of uniform
-     */
-    protected VarType varType;
-
-    /**
-     * Binding to a renderer value, or null if user-defined uniform
-     */
-    protected UniformBinding binding;
-
-    /**
-     * Used to track which uniforms to clear to avoid
-     * values leaking from other materials that use that shader.
-     */
-    protected boolean setByCurrentMaterial = false;
-
-    @Override
-    public String toString(){
-        StringBuilder sb = new StringBuilder();
-        sb.append("Uniform[name=");
-        sb.append(name);
-        if (varType != null){
-            sb.append(", type=");
-            sb.append(varType);
-            sb.append(", value=");
-            sb.append(value);
-        }else{
-            sb.append(", value=<not set>");
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    public void setBinding(UniformBinding binding){
-        this.binding = binding;
-    }
-
-    public UniformBinding getBinding(){
-        return binding;
-    }
-
-    public VarType getVarType() {
-        return varType;
-    }
-
-    public Object getValue(){
-        return value;
-    }
-
-    public boolean isSetByCurrentMaterial() {
-        return setByCurrentMaterial;
-    }
-
-    public void clearSetByCurrentMaterial(){
-        setByCurrentMaterial = false;
-    }
-
-    private static void setVector4(Vector4f vec, Object value) {
-        if (value instanceof ColorRGBA) {
-            ColorRGBA color = (ColorRGBA) value;
-            vec.set(color.r, color.g, color.b, color.a);
-        } else if (value instanceof Quaternion) {
-            Quaternion quat = (Quaternion) value;
-            vec.set(quat.getX(), quat.getY(), quat.getZ(), quat.getW());
-        } else if (value instanceof Vector4f) {
-            Vector4f vec4 = (Vector4f) value;
-            vec.set(vec4);
-        } else{
-            throw new IllegalArgumentException();
-        }
-    }
-    
-    public void clearValue(){
-        updateNeeded = true;
-
-        if (multiData != null){           
-            multiData.clear();
-
-            while (multiData.remaining() > 0){
-                ZERO_BUF.clear();
-                ZERO_BUF.limit( Math.min(multiData.remaining(), 16) );
-                multiData.put(ZERO_BUF);
-            }
-
-            multiData.clear();
-
-            return;
-        }
-
-        if (varType == null) {
-            return;
-        }
-            
-        switch (varType){
-            case Int:
-                this.value = ZERO_INT;
-                break;
-            case Boolean:
-                this.value = Boolean.FALSE;
-                break;
-            case Float:
-                this.value = ZERO_FLT; 
-                break;
-            case Vector2:
-                this.value = Vector2f.ZERO;
-                break;
-            case Vector3:
-                this.value = Vector3f.ZERO;
-                break;
-            case Vector4:
-                this.value = Vector4f.ZERO;
-                break;
-            default:
-                // won't happen because those are either textures
-                // or multidata types
-        }
-    }
-    
-    public void setValue(VarType type, Object value){
-        if (location == LOC_NOT_DEFINED) {
-            return;
-        }
-
-        if (varType != null && varType != type) {
-            throw new IllegalArgumentException("Expected a " + varType.name() + " value!");
-        }
-
-        if (value == null) {
-            throw new NullPointerException();
-        }
-
-        setByCurrentMaterial = true;
-
-        switch (type){
-            case Matrix3:
-                Matrix3f m3 = (Matrix3f) value;
-                if (multiData == null) {
-                    multiData = BufferUtils.createFloatBuffer(9);
-                }
-                m3.fillFloatBuffer(multiData, true);
-                multiData.clear();
-                break;
-            case Matrix4:
-                Matrix4f m4 = (Matrix4f) value;
-                if (multiData == null) {
-                    multiData = BufferUtils.createFloatBuffer(16);
-                }
-                m4.fillFloatBuffer(multiData, true);
-                multiData.clear();
-                break;
-            case IntArray:
-                int[] ia = (int[]) value;
-                if (this.value == null) {
-                    this.value = BufferUtils.createIntBuffer(ia);
-                } else {
-                    this.value = BufferUtils.ensureLargeEnough((IntBuffer)this.value, ia.length);
-                }
-                ((IntBuffer)this.value).clear();
-                break;
-            case FloatArray:
-                float[] fa = (float[]) value;
-                if (multiData == null) {
-                    multiData = BufferUtils.createFloatBuffer(fa);
-                } else {
-                    multiData = BufferUtils.ensureLargeEnough(multiData, fa.length);
-                }
-                multiData.put(fa);
-                multiData.clear();
-                break;
-            case Vector2Array:
-                Vector2f[] v2a = (Vector2f[]) value;
-                if (multiData == null) {
-                    multiData = BufferUtils.createFloatBuffer(v2a);
-                } else {
-                    multiData = BufferUtils.ensureLargeEnough(multiData, v2a.length * 2);
-                }
-                for (int i = 0; i < v2a.length; i++) {
-                    BufferUtils.setInBuffer(v2a[i], multiData, i);
-                }
-                multiData.clear();
-                break;
-            case Vector3Array:
-                Vector3f[] v3a = (Vector3f[]) value;
-                if (multiData == null) {
-                    multiData = BufferUtils.createFloatBuffer(v3a);
-                } else {
-                    multiData = BufferUtils.ensureLargeEnough(multiData, v3a.length * 3);
-                }
-                for (int i = 0; i < v3a.length; i++) {
-                    BufferUtils.setInBuffer(v3a[i], multiData, i);
-                }
-                multiData.clear();
-                break;
-            case Vector4Array:
-                Vector4f[] v4a = (Vector4f[]) value;
-                if (multiData == null) {
-                    multiData = BufferUtils.createFloatBuffer(v4a);
-                } else {
-                    multiData = BufferUtils.ensureLargeEnough(multiData, v4a.length * 4);
-                }
-                for (int i = 0; i < v4a.length; i++) {
-                    BufferUtils.setInBuffer(v4a[i], multiData, i);
-                }
-                multiData.clear();
-                break;
-            case Matrix3Array:
-                Matrix3f[] m3a = (Matrix3f[]) value;
-                if (multiData == null) {
-                    multiData = BufferUtils.createFloatBuffer(m3a.length * 9);
-                } else {
-                    multiData = BufferUtils.ensureLargeEnough(multiData, m3a.length * 9);
-                }
-                for (int i = 0; i < m3a.length; i++) {
-                    m3a[i].fillFloatBuffer(multiData, true);
-                }
-                multiData.clear();
-                break;
-            case Matrix4Array:
-                Matrix4f[] m4a = (Matrix4f[]) value;
-                if (multiData == null) {
-                    multiData = BufferUtils.createFloatBuffer(m4a.length * 16);
-                } else {
-                    multiData = BufferUtils.ensureLargeEnough(multiData, m4a.length * 16);
-                }
-                for (int i = 0; i < m4a.length; i++) {
-                    m4a[i].fillFloatBuffer(multiData, true);
-                }
-                multiData.clear();
-                break;
-                // Only use check if equals optimization for primitive values
-            case Int:
-            case Float:
-            case Boolean:
-                if (this.value != null && this.value.equals(value)) {
-                    return;
-                }
-                this.value = value;
-                break;
-            default:
-                this.value = value;
-                break;
-        }
-
-        if (multiData != null) {
-            this.value = multiData;
-        }
-
-        varType = type;
-        updateNeeded = true;
-    }
-
-    public void setVector4Length(int length){
-        if (location == -1)
-            return;
-
-        FloatBuffer fb = (FloatBuffer) value;
-        if (fb == null || fb.capacity() < length) {
-            value = BufferUtils.createFloatBuffer(length * 4);
-        }
-
-        varType = VarType.Vector4Array;
-        updateNeeded = true;
-        setByCurrentMaterial = true;
-    }
-
-    public void setVector4InArray(float x, float y, float z, float w, int index){
-        if (location == -1)
-            return;
-
-        if (varType != null && varType != VarType.Vector4Array)
-            throw new IllegalArgumentException("Expected a "+varType.name()+" value!");
-
-        FloatBuffer fb = (FloatBuffer) value;
-        fb.position(index * 4);
-        fb.put(x).put(y).put(z).put(w);
-        fb.rewind();
-        updateNeeded = true;
-        setByCurrentMaterial = true;
-    }
-    
-    public boolean isUpdateNeeded(){
-        return updateNeeded;
-    }
-
-    public void clearUpdateNeeded(){
-        updateNeeded = false;
-    }
-
-    public void reset(){
-        setByCurrentMaterial = false;
-        location = -2;
-        updateNeeded = true;
-    }
-
-}
+/*
+ * Copyright (c) 2009-2012 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.shader;
+
+import com.jme3.math.*;
+import com.jme3.util.BufferUtils;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+public class Uniform extends ShaderVariable {
+
+    private static final Integer ZERO_INT = Integer.valueOf(0);
+    private static final Float ZERO_FLT = Float.valueOf(0);
+    private static final FloatBuffer ZERO_BUF = BufferUtils.createFloatBuffer(4*4);
+
+    /**
+     * Currently set value of the uniform.
+     */
+    protected Object value = null;
+    
+    /**
+     * For arrays or matrices, efficient format
+     * that can be sent to GL faster.
+     */
+    protected FloatBuffer multiData = null;
+
+    /**
+     * Type of uniform
+     */
+    protected VarType varType;
+
+    /**
+     * Binding to a renderer value, or null if user-defined uniform
+     */
+    protected UniformBinding binding;
+
+    /**
+     * Used to track which uniforms to clear to avoid
+     * values leaking from other materials that use that shader.
+     */
+    protected boolean setByCurrentMaterial = false;
+
+    @Override
+    public String toString(){
+        StringBuilder sb = new StringBuilder();
+        sb.append("Uniform[name=");
+        sb.append(name);
+        if (varType != null){
+            sb.append(", type=");
+            sb.append(varType);
+            sb.append(", value=");
+            sb.append(value);
+        }else{
+            sb.append(", value=<not set>");
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public void setBinding(UniformBinding binding){
+        this.binding = binding;
+    }
+
+    public UniformBinding getBinding(){
+        return binding;
+    }
+
+    public VarType getVarType() {
+        return varType;
+    }
+
+    public Object getValue(){
+        return value;
+    }
+
+    public boolean isSetByCurrentMaterial() {
+        return setByCurrentMaterial;
+    }
+
+    public void clearSetByCurrentMaterial(){
+        setByCurrentMaterial = false;
+    }
+
+    private static void setVector4(Vector4f vec, Object value) {
+        if (value instanceof ColorRGBA) {
+            ColorRGBA color = (ColorRGBA) value;
+            vec.set(color.r, color.g, color.b, color.a);
+        } else if (value instanceof Quaternion) {
+            Quaternion quat = (Quaternion) value;
+            vec.set(quat.getX(), quat.getY(), quat.getZ(), quat.getW());
+        } else if (value instanceof Vector4f) {
+            Vector4f vec4 = (Vector4f) value;
+            vec.set(vec4);
+        } else{
+            throw new IllegalArgumentException();
+        }
+    }
+    
+    public void clearValue(){
+        updateNeeded = true;
+
+        if (multiData != null){           
+            multiData.clear();
+
+            while (multiData.remaining() > 0){
+                ZERO_BUF.clear();
+                ZERO_BUF.limit( Math.min(multiData.remaining(), 16) );
+                multiData.put(ZERO_BUF);
+            }
+
+            multiData.clear();
+
+            return;
+        }
+
+        if (varType == null) {
+            return;
+        }
+            
+        switch (varType){
+            case Int:
+                this.value = ZERO_INT;
+                break;
+            case Boolean:
+                this.value = Boolean.FALSE;
+                break;
+            case Float:
+                this.value = ZERO_FLT; 
+                break;
+            case Vector2:
+                this.value = Vector2f.ZERO;
+                break;
+            case Vector3:
+                this.value = Vector3f.ZERO;
+                break;
+            case Vector4:
+                this.value = Vector4f.ZERO;
+                break;
+            default:
+                // won't happen because those are either textures
+                // or multidata types
+        }
+    }
+    
+    public void setValue(VarType type, Object value){
+        if (location == LOC_NOT_DEFINED) {
+            return;
+        }
+
+        if (varType != null && varType != type) {
+            throw new IllegalArgumentException("Expected a " + varType.name() + " value!");
+        }
+
+        if (value == null) {
+            throw new NullPointerException();
+        }
+
+        setByCurrentMaterial = true;
+
+        switch (type){
+            case Matrix3:
+                Matrix3f m3 = (Matrix3f) value;
+                if (multiData == null) {
+                    multiData = BufferUtils.createFloatBuffer(9);
+                }
+                m3.fillFloatBuffer(multiData, true);
+                multiData.clear();
+                break;
+            case Matrix4:
+                Matrix4f m4 = (Matrix4f) value;
+                if (multiData == null) {
+                    multiData = BufferUtils.createFloatBuffer(16);
+                }
+                m4.fillFloatBuffer(multiData, true);
+                multiData.clear();
+                break;
+            case IntArray:
+                int[] ia = (int[]) value;
+                if (this.value == null) {
+                    this.value = BufferUtils.createIntBuffer(ia);
+                } else {
+                    this.value = BufferUtils.ensureLargeEnough((IntBuffer)this.value, ia.length);
+                }
+                ((IntBuffer)this.value).clear();
+                break;
+            case FloatArray:
+                float[] fa = (float[]) value;
+                if (multiData == null) {
+                    multiData = BufferUtils.createFloatBuffer(fa);
+                } else {
+                    multiData = BufferUtils.ensureLargeEnough(multiData, fa.length);
+                }
+                multiData.put(fa);
+                multiData.clear();
+                break;
+            case Vector2Array:
+                Vector2f[] v2a = (Vector2f[]) value;
+                if (multiData == null) {
+                    multiData = BufferUtils.createFloatBuffer(v2a);
+                } else {
+                    multiData = BufferUtils.ensureLargeEnough(multiData, v2a.length * 2);
+                }
+                for (int i = 0; i < v2a.length; i++) {
+                    BufferUtils.setInBuffer(v2a[i], multiData, i);
+                }
+                multiData.clear();
+                break;
+            case Vector3Array:
+                Vector3f[] v3a = (Vector3f[]) value;
+                if (multiData == null) {
+                    multiData = BufferUtils.createFloatBuffer(v3a);
+                } else {
+                    multiData = BufferUtils.ensureLargeEnough(multiData, v3a.length * 3);
+                }
+                for (int i = 0; i < v3a.length; i++) {
+                    BufferUtils.setInBuffer(v3a[i], multiData, i);
+                }
+                multiData.clear();
+                break;
+            case Vector4Array:
+                Vector4f[] v4a = (Vector4f[]) value;
+                if (multiData == null) {
+                    multiData = BufferUtils.createFloatBuffer(v4a);
+                } else {
+                    multiData = BufferUtils.ensureLargeEnough(multiData, v4a.length * 4);
+                }
+                for (int i = 0; i < v4a.length; i++) {
+                    BufferUtils.setInBuffer(v4a[i], multiData, i);
+                }
+                multiData.clear();
+                break;
+            case Matrix3Array:
+                Matrix3f[] m3a = (Matrix3f[]) value;
+                if (multiData == null) {
+                    multiData = BufferUtils.createFloatBuffer(m3a.length * 9);
+                } else {
+                    multiData = BufferUtils.ensureLargeEnough(multiData, m3a.length * 9);
+                }
+                for (int i = 0; i < m3a.length; i++) {
+                    m3a[i].fillFloatBuffer(multiData, true);
+                }
+                multiData.clear();
+                break;
+            case Matrix4Array:
+                Matrix4f[] m4a = (Matrix4f[]) value;
+                if (multiData == null) {
+                    multiData = BufferUtils.createFloatBuffer(m4a.length * 16);
+                } else {
+                    multiData = BufferUtils.ensureLargeEnough(multiData, m4a.length * 16);
+                }
+                for (int i = 0; i < m4a.length; i++) {
+                    m4a[i].fillFloatBuffer(multiData, true);
+                }
+                multiData.clear();
+                break;
+                // Only use check if equals optimization for primitive values
+            case Int:
+            case Float:
+            case Boolean:
+                if (this.value != null && this.value.equals(value)) {
+                    return;
+                }
+                this.value = value;
+                break;
+            default:
+                this.value = value;
+                break;
+        }
+
+        if (multiData != null) {
+            this.value = multiData;
+        }
+
+        varType = type;
+        updateNeeded = true;
+    }
+
+    public void setVector4Length(int length){
+        if (location == -1)
+            return;
+
+        FloatBuffer fb = (FloatBuffer) value;
+        if (fb == null || fb.capacity() < length * 4) {
+            value = BufferUtils.createFloatBuffer(length * 4);
+        }
+
+        varType = VarType.Vector4Array;
+        updateNeeded = true;
+        setByCurrentMaterial = true;
+    }
+
+    public void setVector4InArray(float x, float y, float z, float w, int index){
+        if (location == -1)
+            return;
+
+        if (varType != null && varType != VarType.Vector4Array)
+            throw new IllegalArgumentException("Expected a "+varType.name()+" value!");
+
+        FloatBuffer fb = (FloatBuffer) value;
+        fb.position(index * 4);
+        fb.put(x).put(y).put(z).put(w);
+        fb.rewind();
+        updateNeeded = true;
+        setByCurrentMaterial = true;
+    }
+    
+    public boolean isUpdateNeeded(){
+        return updateNeeded;
+    }
+
+    public void clearUpdateNeeded(){
+        updateNeeded = false;
+    }
+
+    public void reset(){
+        setByCurrentMaterial = false;
+        location = -2;
+        updateNeeded = true;
+    }
+
+}