@ -29,6 +29,7 @@
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
* /
package com.jme3.shader ;
package com.jme3.shader ;
import com.jme3.export.JmeExporter ;
import com.jme3.export.JmeExporter ;
@ -41,7 +42,6 @@ import com.jme3.math.Matrix4f;
import com.jme3.math.Quaternion ;
import com.jme3.math.Quaternion ;
import com.jme3.math.Vector2f ;
import com.jme3.math.Vector2f ;
import com.jme3.math.Vector3f ;
import com.jme3.math.Vector3f ;
import com.jme3.math.Vector4f ;
import com.jme3.util.BufferUtils ;
import com.jme3.util.BufferUtils ;
import java.io.IOException ;
import java.io.IOException ;
import java.nio.FloatBuffer ;
import java.nio.FloatBuffer ;
@ -50,77 +50,81 @@ public class Uniform extends ShaderVariable {
private static final Integer ZERO_INT = Integer . valueOf ( 0 ) ;
private static final Integer ZERO_INT = Integer . valueOf ( 0 ) ;
private static final Float ZERO_FLT = Float . valueOf ( 0 ) ;
private static final Float ZERO_FLT = Float . valueOf ( 0 ) ;
private static final FloatBuffer ZERO_BUF = BufferUtils . createFloatBuffer ( 4 * 4 ) ;
private static final FloatBuffer ZERO_BUF = BufferUtils . createFloatBuffer ( 4 * 4 ) ;
/ * *
/ * *
* Currently set value of the uniform .
* Currently set value of the uniform .
* /
* /
protected Object value = null ;
protected Object value = null ;
protected FloatBuffer multiData = null ;
protected FloatBuffer multiData = null ;
/ * *
/ * *
* Type of uniform
* Type of uniform
* /
* /
protected VarType varType ;
protected VarType varType ;
/ * *
/ * *
* Binding to a renderer value , or null if user - defined uniform
* Binding to a renderer value , or null if user - defined uniform
* /
* /
protected UniformBinding binding ;
protected UniformBinding binding ;
protected boolean setByCurrentMaterial = false ;
protected boolean setByCurrentMaterial = false ;
// protected Object lastChanger = null;
// protected Object lastChanger = null;
@Override
@Override
public void write ( JmeExporter ex ) throws IOException {
public void write ( JmeExporter ex ) throws IOException {
super . write ( ex ) ;
super . write ( ex ) ;
OutputCapsule oc = ex . getCapsule ( this ) ;
OutputCapsule oc = ex . getCapsule ( this ) ;
oc . write ( varType , "varType" , null ) ;
oc . write ( varType , "varType" , null ) ;
oc . write ( binding , "binding" , null ) ;
oc . write ( binding , "binding" , null ) ;
switch ( varType ) {
switch ( varType ) {
case Boolean :
case Boolean :
oc . write ( ( ( Boolean ) value ) . booleanValue ( ) , "valueBoolean" , false ) ;
oc . write ( ( ( Boolean ) value ) . booleanValue ( ) , "valueBoolean" , false ) ;
break ;
break ;
case Float :
case Float :
oc . write ( ( ( Float ) value ) . floatValue ( ) , "valueFloat" , 0 ) ;
oc . write ( ( ( Float ) value ) . floatValue ( ) , "valueFloat" , 0 ) ;
break ;
break ;
case FloatArray :
case FloatArray :
oc . write ( ( FloatBuffer ) value , "valueFloatArray" , null ) ;
oc . write ( ( FloatBuffer ) value , "valueFloatArray" , null ) ;
break ;
break ;
case Int :
case Int :
oc . write ( ( ( Integer ) value ) . intValue ( ) , "valueInt" , 0 ) ;
oc . write ( ( ( Integer ) value ) . intValue ( ) , "valueInt" , 0 ) ;
break ;
break ;
case Matrix3 :
case Matrix3 :
oc . write ( ( Matrix3f ) value , "valueMatrix3" , null ) ;
oc . write ( ( Matrix3f ) value , "valueMatrix3" , null ) ;
break ;
break ;
case Matrix3Array :
case Matrix3Array :
case Matrix4Array :
case Matrix4Array :
case Vector2Array :
case Vector2Array :
throw new UnsupportedOperationException ( "Come again?" ) ;
throw new UnsupportedOperationException ( "Come again?" ) ;
case Matrix4 :
case Matrix4 :
oc . write ( ( Matrix4f ) value , "valueMatrix4" , null ) ;
oc . write ( ( Matrix4f ) value , "valueMatrix4" , null ) ;
break ;
break ;
case Vector2 :
case Vector2 :
oc . write ( ( Vector2f ) value , "valueVector2" , null ) ;
oc . write ( ( Vector2f ) value , "valueVector2" , null ) ;
break ;
break ;
case Vector3 :
case Vector3 :
oc . write ( ( Vector3f ) value , "valueVector3" , null ) ;
oc . write ( ( Vector3f ) value , "valueVector3" , null ) ;
break ;
break ;
case Vector3Array :
case Vector3Array :
oc . write ( ( FloatBuffer ) value , "valueVector3Array" , null ) ;
oc . write ( ( FloatBuffer ) value , "valueVector3Array" , null ) ;
break ;
break ;
case Vector4 :
case Vector4 :
oc . write ( ( ColorRGBA ) value , "valueVector4" , null ) ;
oc . write ( ( ColorRGBA ) value , "valueVector4" , null ) ;
break ;
break ;
case Vector4Array :
case Vector4Array :
oc . write ( ( FloatBuffer ) value , "valueVector4Array" , null ) ;
oc . write ( ( FloatBuffer ) value , "valueVector4Array" , null ) ;
break ;
break ;
}
}
}
}
@Override
@Override
public void read ( JmeImporter im ) throws IOException {
public void read ( JmeImporter im ) throws IOException {
super . read ( im ) ;
super . read ( im ) ;
InputCapsule ic = im . getCapsule ( this ) ;
InputCapsule ic = im . getCapsule ( this ) ;
varType = ic . readEnum ( "varType" , VarType . class , null ) ;
varType = ic . readEnum ( "varType" , VarType . class , null ) ;
binding = ic . readEnum ( "binding" , UniformBinding . class , null ) ;
binding = ic . readEnum ( "binding" , UniformBinding . class , null ) ;
switch ( varType ) {
switch ( varType ) {
case Boolean :
case Boolean :
value = ic . readBoolean ( "valueBoolean" , false ) ;
value = ic . readBoolean ( "valueBoolean" , false ) ;
break ;
break ;
@ -160,17 +164,17 @@ public class Uniform extends ShaderVariable {
}
}
@Override
@Override
public String toString ( ) {
public String toString ( ) {
StringBuilder sb = new StringBuilder ( ) ;
StringBuilder sb = new StringBuilder ( ) ;
if ( name ! = null ) {
if ( name ! = null ) {
sb . append ( "Uniform[name=" ) ;
sb . append ( "Uniform[name=" ) ;
sb . append ( name ) ;
sb . append ( name ) ;
if ( varType ! = null ) {
if ( varType ! = null ) {
sb . append ( ", type=" ) ;
sb . append ( ", type=" ) ;
sb . append ( varType ) ;
sb . append ( varType ) ;
sb . append ( ", value=" ) ;
sb . append ( ", value=" ) ;
sb . append ( value ) ;
sb . append ( value ) ;
} else {
} else {
sb . append ( ", value=<not set>" ) ;
sb . append ( ", value=<not set>" ) ;
}
}
}
}
@ -178,11 +182,11 @@ public class Uniform extends ShaderVariable {
return sb . toString ( ) ;
return sb . toString ( ) ;
}
}
public void setBinding ( UniformBinding binding ) {
public void setBinding ( UniformBinding binding ) {
this . binding = binding ;
this . binding = binding ;
}
}
public UniformBinding getBinding ( ) {
public UniformBinding getBinding ( ) {
return binding ;
return binding ;
}
}
@ -190,7 +194,7 @@ public class Uniform extends ShaderVariable {
return varType ;
return varType ;
}
}
public Object getValue ( ) {
public Object getValue ( ) {
return value ;
return value ;
}
}
@ -198,7 +202,7 @@ public class Uniform extends ShaderVariable {
return setByCurrentMaterial ;
return setByCurrentMaterial ;
}
}
public void clearSetByCurrentMaterial ( ) {
public void clearSetByCurrentMaterial ( ) {
setByCurrentMaterial = false ;
setByCurrentMaterial = false ;
}
}
@ -209,15 +213,16 @@ public class Uniform extends ShaderVariable {
// public Object getLastChanger(){
// public Object getLastChanger(){
// return lastChanger;
// return lastChanger;
// }
// }
public void clearValue ( ) {
public void clearValue ( ) {
updateNeeded = true ;
updateNeeded = true ;
if ( multiData ! = null ) {
if ( multiData ! = null ) {
ZERO_BUF . clear ( ) ;
ZERO_BUF . clear ( ) ;
multiData . clear ( ) ;
multiData . clear ( ) ;
while ( multiData . remaining ( ) > 0 ) {
while ( multiData . remaining ( ) > 0 ) {
ZERO_BUF . limit ( Math . min ( multiData . remaining ( ) , 16 ) ) ;
ZERO_BUF . limit ( Math . min ( multiData . remaining ( ) , 16 ) ) ;
multiData . put ( ZERO_BUF ) ;
multiData . put ( ZERO_BUF ) ;
}
}
@ -226,11 +231,10 @@ public class Uniform extends ShaderVariable {
return ;
return ;
}
}
if ( varType = = null ) {
if ( varType = = null )
return ;
return ;
}
switch ( varType ) {
switch ( varType ) {
case Int :
case Int :
this . value = ZERO_INT ;
this . value = ZERO_INT ;
break ;
break ;
@ -238,153 +242,140 @@ public class Uniform extends ShaderVariable {
this . value = Boolean . FALSE ;
this . value = Boolean . FALSE ;
break ;
break ;
case Float :
case Float :
this . value = ZERO_FLT ;
this . value = ZERO_FLT ;
break ;
break ;
case Vector2 :
case Vector2 :
( ( Vector2f ) this . value ) . set ( Vector2f . ZERO ) ;
this . value = Vector2f . ZERO ;
break ;
break ;
case Vector3 :
case Vector3 :
( ( Vector3f ) this . value ) . set ( Vector3f . ZERO ) ;
this . value = Vector3f . ZERO ;
break ;
break ;
case Vector4 :
case Vector4 :
if ( this . value instanceof ColorRGBA ) {
if ( this . value instanceof ColorRGBA ) {
( ( ColorRGBA ) this . value ) . set ( ColorRGBA . BlackNoAlpha ) ;
this . value = ColorRGBA . BlackNoAlpha ;
} else if ( this . value instanceof Quaternion ) {
} else {
( ( Quaternion ) this . value ) . set ( Quaternion . ZERO ) ;
this . value = Quaternion . ZERO ;
} else {
( ( Vector4f ) this . value ) . set ( Vector4f . ZERO ) ;
}
}
break ;
break ;
default :
default :
break ; // won't happen because those are either textures
break ; // won't happen because those are either textures
// or multidata types
// or multidata types
}
}
}
}
public void setValue ( VarType type , Object value ) {
public void setValue ( VarType type , Object value ) {
if ( location = = - 1 ) {
if ( location = = - 1 )
return ;
return ;
}
if ( varType ! = null & & varType ! = type ) {
if ( varType ! = null & & varType ! = type )
throw new IllegalArgumentException ( "Expected a " + varType . name ( ) + " value!" ) ;
throw new IllegalArgumentException ( "Expected a " + varType . name ( ) + " value!" ) ;
}
if ( value = = null ) {
if ( value = = null )
throw new NullPointerException ( ) ;
throw new NullPointerException ( ) ;
}
setByCurrentMaterial = true ;
setByCurrentMaterial = true ;
switch ( type ) {
switch ( type ) {
case Matrix3 :
case Matrix3 :
Matrix3f m3 = ( Matrix3f ) value ;
Matrix3f m3 = ( Matrix3f ) value ;
if ( multiData = = null ) {
if ( multiData = = null )
multiData = BufferUtils . createFloatBuffer ( 9 ) ;
multiData = BufferUtils . createFloatBuffer ( 9 ) ;
}
m3 . fillFloatBuffer ( multiData , true ) ;
m3 . fillFloatBuffer ( multiData , true ) ;
multiData . clear ( ) ;
multiData . clear ( ) ;
break ;
break ;
case Matrix4 :
case Matrix4 :
Matrix4f m4 = ( Matrix4f ) value ;
Matrix4f m4 = ( Matrix4f ) value ;
if ( multiData = = null ) {
if ( multiData = = null )
multiData = BufferUtils . createFloatBuffer ( 16 ) ;
multiData = BufferUtils . createFloatBuffer ( 16 ) ;
}
m4 . fillFloatBuffer ( multiData , true ) ;
m4 . fillFloatBuffer ( multiData , true ) ;
multiData . clear ( ) ;
multiData . clear ( ) ;
break ;
break ;
case FloatArray :
case FloatArray :
float [ ] fa = ( float [ ] ) value ;
float [ ] fa = ( float [ ] ) value ;
if ( multiData = = null ) {
if ( multiData = = null ) {
multiData = BufferUtils . createFloatBuffer ( fa ) ;
multiData = BufferUtils . createFloatBuffer ( fa ) ;
} else {
} else {
multiData = BufferUtils . ensureLargeEnough ( multiData , fa . length ) ;
multiData = BufferUtils . ensureLargeEnough ( multiData , fa . length ) ;
}
}
multiData . put ( fa ) ;
multiData . put ( fa ) ;
multiData . clear ( ) ;
multiData . clear ( ) ;
break ;
break ;
case Vector2Array :
case Vector2Array :
Vector2f [ ] v2a = ( Vector2f [ ] ) value ;
Vector2f [ ] v2a = ( Vector2f [ ] ) value ;
if ( multiData = = null ) {
if ( multiData = = null ) {
multiData = BufferUtils . createFloatBuffer ( v2a ) ;
multiData = BufferUtils . createFloatBuffer ( v2a ) ;
} else {
} else {
multiData = BufferUtils . ensureLargeEnough ( multiData , v2a . length * 2 ) ;
multiData = BufferUtils . ensureLargeEnough ( multiData , v2a . length * 2 ) ;
}
}
for ( int i = 0 ; i < v2a . length ; i + + ) {
for ( int i = 0 ; i < v2a . length ; i + + )
BufferUtils . setInBuffer ( v2a [ i ] , multiData , i ) ;
BufferUtils . setInBuffer ( v2a [ i ] , multiData , i ) ;
}
multiData . clear ( ) ;
multiData . clear ( ) ;
break ;
break ;
case Vector3Array :
case Vector3Array :
Vector3f [ ] v3a = ( Vector3f [ ] ) value ;
Vector3f [ ] v3a = ( Vector3f [ ] ) value ;
if ( multiData = = null ) {
if ( multiData = = null ) {
multiData = BufferUtils . createFloatBuffer ( v3a ) ;
multiData = BufferUtils . createFloatBuffer ( v3a ) ;
} else {
} else {
multiData = BufferUtils . ensureLargeEnough ( multiData , v3a . length * 3 ) ;
multiData = BufferUtils . ensureLargeEnough ( multiData , v3a . length * 3 ) ;
}
}
for ( int i = 0 ; i < v3a . length ; i + + ) {
for ( int i = 0 ; i < v3a . length ; i + + )
BufferUtils . setInBuffer ( v3a [ i ] , multiData , i ) ;
BufferUtils . setInBuffer ( v3a [ i ] , multiData , i ) ;
}
multiData . clear ( ) ;
multiData . clear ( ) ;
break ;
break ;
case Vector4Array :
case Vector4Array :
Quaternion [ ] v4a = ( Quaternion [ ] ) value ;
Quaternion [ ] v4a = ( Quaternion [ ] ) value ;
if ( multiData = = null ) {
if ( multiData = = null ) {
multiData = BufferUtils . createFloatBuffer ( v4a ) ;
multiData = BufferUtils . createFloatBuffer ( v4a ) ;
} else {
} else {
multiData = BufferUtils . ensureLargeEnough ( multiData , v4a . length * 4 ) ;
multiData = BufferUtils . ensureLargeEnough ( multiData , v4a . length * 4 ) ;
}
}
for ( int i = 0 ; i < v4a . length ; i + + ) {
for ( int i = 0 ; i < v4a . length ; i + + )
BufferUtils . setInBuffer ( v4a [ i ] , multiData , i ) ;
BufferUtils . setInBuffer ( v4a [ i ] , multiData , i ) ;
}
multiData . clear ( ) ;
multiData . clear ( ) ;
break ;
break ;
case Matrix3Array :
case Matrix3Array :
Matrix3f [ ] m3a = ( Matrix3f [ ] ) value ;
Matrix3f [ ] m3a = ( Matrix3f [ ] ) value ;
if ( multiData = = null ) {
if ( multiData = = null )
multiData = BufferUtils . createFloatBuffer ( m3a . length * 9 ) ;
multiData = BufferUtils . createFloatBuffer ( m3a . length * 9 ) ;
} else {
else {
multiData = BufferUtils . ensureLargeEnough ( multiData , m3a . length * 9 ) ;
multiData = BufferUtils . ensureLargeEnough ( multiData , m3a . length * 9 ) ;
}
}
for ( int i = 0 ; i < m3a . length ; i + + ) {
for ( int i = 0 ; i < m3a . length ; i + + )
m3a [ i ] . fillFloatBuffer ( multiData , true ) ;
m3a [ i ] . fillFloatBuffer ( multiData , true ) ;
}
multiData . clear ( ) ;
multiData . clear ( ) ;
break ;
break ;
case Matrix4Array :
case Matrix4Array :
Matrix4f [ ] m4a = ( Matrix4f [ ] ) value ;
Matrix4f [ ] m4a = ( Matrix4f [ ] ) value ;
if ( multiData = = null ) {
if ( multiData = = null )
multiData = BufferUtils . createFloatBuffer ( m4a . length * 16 ) ;
multiData = BufferUtils . createFloatBuffer ( m4a . length * 16 ) ;
} else {
else {
multiData = BufferUtils . ensureLargeEnough ( multiData , m4a . length * 16 ) ;
multiData = BufferUtils . ensureLargeEnough ( multiData , m4a . length * 16 ) ;
}
}
for ( int i = 0 ; i < m4a . length ; i + + ) {
for ( int i = 0 ; i < m4a . length ; i + + )
m4a [ i ] . fillFloatBuffer ( multiData , true ) ;
m4a [ i ] . fillFloatBuffer ( multiData , true ) ;
}
multiData . clear ( ) ;
multiData . clear ( ) ;
break ;
break ;
// Only use check if equals optimization for primitive values
// Only use check if equals optimization for primitive values
case Int :
case Int :
case Float :
case Float :
case Boolean :
case Boolean :
if ( this . value ! = null & & this . value . equals ( value ) ) {
if ( this . value ! = null & & this . value . equals ( value ) )
return ;
return ;
}
this . value = value ;
this . value = value ;
break ;
break ;
@ -393,21 +384,19 @@ public class Uniform extends ShaderVariable {
break ;
break ;
}
}
if ( multiData ! = null ) {
if ( multiData ! = null )
this . value = multiData ;
this . value = multiData ;
}
varType = type ;
varType = type ;
updateNeeded = true ;
updateNeeded = true ;
}
}
public void setVector4Length ( int length ) {
public void setVector4Length ( int length ) {
if ( location = = - 1 ) {
if ( location = = - 1 )
return ;
return ;
}
FloatBuffer fb = ( FloatBuffer ) value ;
FloatBuffer fb = ( FloatBuffer ) value ;
if ( fb = = null | | fb . capacity ( ) < length ) {
if ( fb = = null | | fb . capacity ( ) < length ) {
value = BufferUtils . createFloatBuffer ( length * 4 ) ;
value = BufferUtils . createFloatBuffer ( length * 4 ) ;
}
}
@ -416,14 +405,12 @@ public class Uniform extends ShaderVariable {
setByCurrentMaterial = true ;
setByCurrentMaterial = true ;
}
}
public void setVector4InArray ( float x , float y , float z , float w , int index ) {
public void setVector4InArray ( float x , float y , float z , float w , int index ) {
if ( location = = - 1 ) {
if ( location = = - 1 )
return ;
return ;
}
if ( varType ! = null & & varType ! = VarType . Vector4Array ) {
if ( varType ! = null & & varType ! = VarType . Vector4Array )
throw new IllegalArgumentException ( "Expected a " + varType . name ( ) + " value!" ) ;
throw new IllegalArgumentException ( "Expected a " + varType . name ( ) + " value!" ) ;
}
FloatBuffer fb = ( FloatBuffer ) value ;
FloatBuffer fb = ( FloatBuffer ) value ;
fb . position ( index * 4 ) ;
fb . position ( index * 4 ) ;
@ -432,18 +419,19 @@ public class Uniform extends ShaderVariable {
updateNeeded = true ;
updateNeeded = true ;
setByCurrentMaterial = true ;
setByCurrentMaterial = true ;
}
}
public boolean isUpdateNeeded ( ) {
public boolean isUpdateNeeded ( ) {
return updateNeeded ;
return updateNeeded ;
}
}
public void clearUpdateNeeded ( ) {
public void clearUpdateNeeded ( ) {
updateNeeded = false ;
updateNeeded = false ;
}
}
public void reset ( ) {
public void reset ( ) {
setByCurrentMaterial = false ;
setByCurrentMaterial = false ;
location = - 2 ;
location = - 2 ;
updateNeeded = true ;
updateNeeded = true ;
}
}
}
}