1
1
/*
2
- * Copyright (c) 2009-2021 jMonkeyEngine
2
+ * Copyright (c) 2009-2024 jMonkeyEngine
3
3
* All rights reserved.
4
4
*
5
5
* Redistribution and use in source and binary forms, with or without
47
47
import com .jme3 .renderer .queue .RenderQueue .Bucket ;
48
48
import com .jme3 .scene .Geometry ;
49
49
import com .jme3 .shader .*;
50
+ import com .jme3 .shader .bufferobject .BufferObject ;
50
51
import com .jme3 .texture .Image ;
51
52
import com .jme3 .texture .Texture ;
52
53
import com .jme3 .texture .image .ColorSpace ;
@@ -87,6 +88,16 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
87
88
private boolean receivesShadows = false ;
88
89
private int sortingId = -1 ;
89
90
91
+ /**
92
+ * Track bind ids for textures and buffers
93
+ * Used internally
94
+ */
95
+ public static class BindUnits {
96
+ public int textureUnit = 0 ;
97
+ public int bufferUnit = 0 ;
98
+ }
99
+ private BindUnits bindUnits = new BindUnits ();
100
+
90
101
public Material (MaterialDef def ) {
91
102
if (def == null ) {
92
103
throw new IllegalArgumentException ("Material definition cannot be null" );
@@ -506,6 +517,18 @@ public void setParam(String name, VarType type, Object value) {
506
517
}
507
518
}
508
519
520
+ /**
521
+ * Pass a parameter to the material shader.
522
+ *
523
+ * @param name the name of the parameter defined in the material definition (j3md)
524
+ * @param value the value of the parameter
525
+ */
526
+ public void setParam (String name , Object value ) {
527
+ MatParam p = getMaterialDef ().getMaterialParam (name );
528
+ setParam (name , p .getVarType (), value );
529
+ }
530
+
531
+
509
532
/**
510
533
* Clear a parameter from this material. The parameter must exist
511
534
* @param name the name of the parameter to clear
@@ -685,8 +708,7 @@ public void setColor(String name, ColorRGBA value) {
685
708
* @param value the buffer object.
686
709
*/
687
710
public void setUniformBufferObject (final String name , final BufferObject value ) {
688
- value .setBufferType (BufferObject .BufferType .UniformBufferObject );
689
- setParam (name , VarType .BufferObject , value );
711
+ setParam (name , VarType .UniformBufferObject , value );
690
712
}
691
713
692
714
/**
@@ -696,8 +718,7 @@ public void setUniformBufferObject(final String name, final BufferObject value)
696
718
* @param value the buffer object.
697
719
*/
698
720
public void setShaderStorageBufferObject (final String name , final BufferObject value ) {
699
- value .setBufferType (BufferObject .BufferType .ShaderStorageBufferObject );
700
- setParam (name , VarType .BufferObject , value );
721
+ setParam (name , VarType .ShaderStorageBufferObject , value );
701
722
}
702
723
703
724
/**
@@ -797,7 +818,7 @@ public void selectTechnique(String name, final RenderManager renderManager) {
797
818
sortingId = -1 ;
798
819
}
799
820
800
- private int applyOverrides (Renderer renderer , Shader shader , SafeArrayList <MatParamOverride > overrides , int unit ) {
821
+ private void applyOverrides (Renderer renderer , Shader shader , SafeArrayList <MatParamOverride > overrides , BindUnits bindUnits ) {
801
822
for (MatParamOverride override : overrides .getArray ()) {
802
823
VarType type = override .getVarType ();
803
824
@@ -810,85 +831,80 @@ private int applyOverrides(Renderer renderer, Shader shader, SafeArrayList<MatPa
810
831
Uniform uniform = shader .getUniform (override .getPrefixedName ());
811
832
812
833
if (override .getValue () != null ) {
813
- if (type .isTextureType ()) {
814
- try {
815
- renderer .setTexture (unit , (Texture ) override .getValue ());
816
- } catch (TextureUnitException exception ) {
817
- int numTexParams = unit + 1 ;
818
- String message = "Too many texture parameters ("
819
- + numTexParams + ") assigned\n to " + toString ();
820
- throw new IllegalStateException (message );
821
- }
822
- uniform .setValue (VarType .Int , unit );
823
- unit ++;
824
- } else {
825
- uniform .setValue (type , override .getValue ());
826
- }
834
+ updateShaderMaterialParameter (renderer , type , shader , override , bindUnits , true );
827
835
} else {
828
836
uniform .clearValue ();
829
837
}
830
838
}
831
- return unit ;
832
839
}
833
840
834
- private int updateShaderMaterialParameters (Renderer renderer , Shader shader ,
835
- SafeArrayList <MatParamOverride > worldOverrides , SafeArrayList <MatParamOverride > forcedOverrides ) {
836
841
837
- int unit = 0 ;
842
+ private void updateShaderMaterialParameter (Renderer renderer , VarType type , Shader shader , MatParam param , BindUnits unit , boolean override ) {
843
+ if (type == VarType .UniformBufferObject || type == VarType .ShaderStorageBufferObject ) {
844
+ ShaderBufferBlock bufferBlock = shader .getBufferBlock (param .getPrefixedName ());
845
+ BufferObject bufferObject = (BufferObject ) param .getValue ();
846
+
847
+ ShaderBufferBlock .BufferType btype ;
848
+ if (type == VarType .ShaderStorageBufferObject ) {
849
+ btype = ShaderBufferBlock .BufferType .ShaderStorageBufferObject ;
850
+ bufferBlock .setBufferObject (btype , bufferObject );
851
+ renderer .setShaderStorageBufferObject (unit .bufferUnit , bufferObject ); // TODO: probably not needed
852
+ } else {
853
+ btype = ShaderBufferBlock .BufferType .UniformBufferObject ;
854
+ bufferBlock .setBufferObject (btype , bufferObject );
855
+ renderer .setUniformBufferObject (unit .bufferUnit , bufferObject ); // TODO: probably not needed
856
+ }
857
+ unit .bufferUnit ++;
858
+ } else {
859
+ Uniform uniform = shader .getUniform (param .getPrefixedName ());
860
+ if (!override && uniform .isSetByCurrentMaterial ()) return ;
861
+
862
+ if (type .isTextureType ()) {
863
+ try {
864
+ renderer .setTexture (unit .textureUnit , (Texture ) param .getValue ());
865
+ } catch (TextureUnitException exception ) {
866
+ int numTexParams = unit .textureUnit + 1 ;
867
+ String message = "Too many texture parameters (" + numTexParams + ") assigned\n to " + toString ();
868
+ throw new IllegalStateException (message );
869
+ }
870
+ uniform .setValue (VarType .Int , unit .textureUnit );
871
+ unit .textureUnit ++;
872
+ } else {
873
+ uniform .setValue (type , param .getValue ());
874
+ }
875
+ }
876
+ }
877
+
878
+
879
+
880
+
881
+ private BindUnits updateShaderMaterialParameters (Renderer renderer , Shader shader , SafeArrayList <MatParamOverride > worldOverrides ,
882
+ SafeArrayList <MatParamOverride > forcedOverrides ) {
883
+
884
+ bindUnits .textureUnit = 0 ;
885
+ bindUnits .bufferUnit = 0 ;
886
+
838
887
if (worldOverrides != null ) {
839
- unit = applyOverrides (renderer , shader , worldOverrides , unit );
888
+ applyOverrides (renderer , shader , worldOverrides , bindUnits );
840
889
}
841
890
if (forcedOverrides != null ) {
842
- unit = applyOverrides (renderer , shader , forcedOverrides , unit );
891
+ applyOverrides (renderer , shader , forcedOverrides , bindUnits );
843
892
}
844
893
845
894
for (int i = 0 ; i < paramValues .size (); i ++) {
846
895
847
896
MatParam param = paramValues .getValue (i );
848
897
VarType type = param .getVarType ();
849
898
850
- if (isBO (type )) {
851
-
852
- final ShaderBufferBlock bufferBlock = shader .getBufferBlock (param .getPrefixedName ());
853
- bufferBlock .setBufferObject ((BufferObject ) param .getValue ());
854
-
855
- } else {
856
-
857
- Uniform uniform = shader .getUniform (param .getPrefixedName ());
858
- if (uniform .isSetByCurrentMaterial ()) {
859
- continue ;
860
- }
861
-
862
- if (type .isTextureType ()) {
863
- try {
864
- renderer .setTexture (unit , (Texture ) param .getValue ());
865
- } catch (TextureUnitException exception ) {
866
- int numTexParams = unit + 1 ;
867
- String message = "Too many texture parameters ("
868
- + numTexParams + ") assigned\n to " + toString ();
869
- throw new IllegalStateException (message );
870
- }
871
- uniform .setValue (VarType .Int , unit );
872
- unit ++;
873
- } else {
874
- uniform .setValue (type , param .getValue ());
875
- }
876
- }
899
+ updateShaderMaterialParameter (renderer , type , shader , param , bindUnits , false );
877
900
}
878
901
879
- //TODO HACKY HACK remove this when texture unit is handled by the uniform.
880
- return unit ;
902
+ // TODO HACKY HACK remove this when texture unit is handled by the
903
+ // uniform.
904
+ return bindUnits ;
881
905
}
882
906
883
- /**
884
- * Returns true if the type is Buffer Object's type.
885
- *
886
- * @param type the material parameter type.
887
- * @return true if the type is Buffer Object's type.
888
- */
889
- private boolean isBO (final VarType type ) {
890
- return type == VarType .BufferObject ;
891
- }
907
+
892
908
893
909
private void updateRenderState (Geometry geometry , RenderManager renderManager , Renderer renderer , TechniqueDef techniqueDef ) {
894
910
if (renderManager .getForcedRenderState () != null ) {
@@ -1064,13 +1080,13 @@ public void render(Geometry geometry, LightList lights, RenderManager renderMana
1064
1080
renderManager .updateUniformBindings (shader );
1065
1081
1066
1082
// Set material parameters
1067
- int unit = updateShaderMaterialParameters (renderer , shader , overrides , renderManager .getForcedMatParams ());
1083
+ BindUnits units = updateShaderMaterialParameters (renderer , shader , overrides , renderManager .getForcedMatParams ());
1068
1084
1069
1085
// Clear any uniforms not changed by material.
1070
1086
resetUniformsNotSetByCurrent (shader );
1071
1087
1072
1088
// Delegate rendering to the technique
1073
- technique .render (renderManager , shader , geometry , lights , unit );
1089
+ technique .render (renderManager , shader , geometry , lights , units );
1074
1090
}
1075
1091
1076
1092
/**
0 commit comments