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