@@ -16,6 +16,8 @@ public class ShadowRender {
1616 private ArrayList <CascadeShadow > cascadeShadows ;
1717 private ShaderProgram shaderProgram ;
1818 private ShadowBuffer shadowBuffer ;
19+ private int staticDrawCount ;
20+ private int staticRenderBufferHandle ;
1921 private UniformsMap uniformsMap ;
2022
2123 public ShadowRender () {
@@ -34,47 +36,10 @@ public ShadowRender() {
3436 createUniforms ();
3537 }
3638
37- private ByteBuffer buildStaticCommandBuffer (List <Model > modelList , Map <String , Integer > entitiesIdxMap ) {
38- int numMeshes = 0 ;
39- for (Model model : modelList ) {
40- numMeshes += model .getMeshDrawDataList ().size ();
41- }
42-
43- int firstIndex = 0 ;
44- int baseInstance = 0 ;
45- int drawElement = 0 ;
46- ByteBuffer commandBuffer = MemoryUtil .memAlloc (numMeshes * COMMAND_SIZE );
47- for (Model model : modelList ) {
48- List <Entity > entities = model .getEntitiesList ();
49- int numEntities = entities .size ();
50- for (RenderBuffers .MeshDrawData meshDrawData : model .getMeshDrawDataList ()) {
51- // count
52- commandBuffer .putInt (meshDrawData .vertices ());
53- // instanceCount
54- commandBuffer .putInt (numEntities );
55- commandBuffer .putInt (firstIndex );
56- // baseVertex
57- commandBuffer .putInt (meshDrawData .offset ());
58- commandBuffer .putInt (baseInstance );
59-
60- firstIndex += meshDrawData .vertices ();
61- baseInstance += entities .size ();
62-
63- for (Entity entity : entities ) {
64- String name = "drawElements[" + drawElement + "]" ;
65- uniformsMap .setUniform (name + ".modelMatrixIdx" , entitiesIdxMap .get (entity .getId ()));
66- drawElement ++;
67- }
68- }
69- }
70- commandBuffer .flip ();
71-
72- return commandBuffer ;
73- }
74-
7539 public void cleanup () {
7640 shaderProgram .cleanup ();
7741 shadowBuffer .cleanup ();
42+ glDeleteBuffers (staticRenderBufferHandle );
7843 }
7944
8045 private void createUniforms () {
@@ -99,20 +64,18 @@ public ShadowBuffer getShadowBuffer() {
9964 return shadowBuffer ;
10065 }
10166
102- public void render (Scene scene , RenderBuffers globalBuffer ) {
67+ public void render (Scene scene , RenderBuffers renderBuffers ) {
10368 CascadeShadow .updateCascadeShadows (cascadeShadows , scene );
10469
10570 glBindFramebuffer (GL_FRAMEBUFFER , shadowBuffer .getDepthMapFBO ());
10671 glViewport (0 , 0 , ShadowBuffer .SHADOW_MAP_WIDTH , ShadowBuffer .SHADOW_MAP_HEIGHT );
10772
10873 shaderProgram .bind ();
10974
110- Map <String , Integer > entitiesIdxMap = new HashMap <>();
11175 int entityIdx = 0 ;
11276 for (Model model : scene .getModelMap ().values ()) {
11377 List <Entity > entities = model .getEntitiesList ();
11478 for (Entity entity : entities ) {
115- entitiesIdxMap .put (entity .getId (), entityIdx );
11679 uniformsMap .setUniform ("modelMatrices[" + entityIdx + "]" , entity .getModelMatrix ());
11780 entityIdx ++;
11881 }
@@ -123,35 +86,78 @@ public void render(Scene scene, RenderBuffers globalBuffer) {
12386 glClear (GL_DEPTH_BUFFER_BIT );
12487 }
12588
126- renderStaticMeshes (scene , globalBuffer , entitiesIdxMap );
89+ // Static meshes
90+ glBindBuffer (GL_DRAW_INDIRECT_BUFFER , staticRenderBufferHandle );
91+ glBindVertexArray (renderBuffers .getStaticVaoId ());
92+ for (int i = 0 ; i < CascadeShadow .SHADOW_MAP_CASCADE_COUNT ; i ++) {
93+ glFramebufferTexture2D (GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D , shadowBuffer .getDepthMapTexture ().getIds ()[i ], 0 );
94+
95+ CascadeShadow shadowCascade = cascadeShadows .get (i );
96+ uniformsMap .setUniform ("projViewMatrix" , shadowCascade .getProjViewMatrix ());
97+
98+ glMultiDrawElementsIndirect (GL_TRIANGLES , GL_UNSIGNED_INT , 0 , staticDrawCount , 0 );
99+ }
100+ glBindVertexArray (0 );
127101
128102 shaderProgram .unbind ();
129103 glBindFramebuffer (GL_FRAMEBUFFER , 0 );
130104 }
131105
132- private void renderStaticMeshes (Scene scene , RenderBuffers renderBuffers , Map <String , Integer > entitiesIdxMap ) {
133- List <Model > modelList = scene .getModelMap ().values ().stream ().filter (m -> !m .isAnimated ()).toList ();
134-
135- ByteBuffer commandBuffer = buildStaticCommandBuffer (modelList , entitiesIdxMap );
136- int drawCount = commandBuffer .remaining () / COMMAND_SIZE ;
137- int bufferHandle = glGenBuffers ();
138- glBindBuffer (GL_DRAW_INDIRECT_BUFFER , bufferHandle );
139- glBufferData (GL_DRAW_INDIRECT_BUFFER , commandBuffer , GL_DYNAMIC_DRAW );
106+ public void setupData (Scene scene ) {
107+ setupStaticCommandBuffer (scene );
108+ }
140109
141- glBindVertexArray (renderBuffers .getStaticVaoId ());
110+ private void setupStaticCommandBuffer (Scene scene ) {
111+ List <Model > modelList = scene .getModelMap ().values ().stream ().filter (m -> !m .isAnimated ()).toList ();
112+ Map <String , Integer > entitiesIdxMap = new HashMap <>();
113+ int entityIdx = 0 ;
114+ int numMeshes = 0 ;
115+ for (Model model : scene .getModelMap ().values ()) {
116+ List <Entity > entities = model .getEntitiesList ();
117+ numMeshes += model .getMeshDrawDataList ().size ();
118+ for (Entity entity : entities ) {
119+ entitiesIdxMap .put (entity .getId (), entityIdx );
120+ entityIdx ++;
121+ }
122+ }
142123
143- for (int i = 0 ; i < CascadeShadow .SHADOW_MAP_CASCADE_COUNT ; i ++) {
144- glFramebufferTexture2D (GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D , shadowBuffer .getDepthMapTexture ().getIds ()[i ], 0 );
124+ int firstIndex = 0 ;
125+ int baseInstance = 0 ;
126+ int drawElement = 0 ;
127+ shaderProgram .bind ();
128+ ByteBuffer commandBuffer = MemoryUtil .memAlloc (numMeshes * COMMAND_SIZE );
129+ for (Model model : modelList ) {
130+ List <Entity > entities = model .getEntitiesList ();
131+ int numEntities = entities .size ();
132+ for (RenderBuffers .MeshDrawData meshDrawData : model .getMeshDrawDataList ()) {
133+ // count
134+ commandBuffer .putInt (meshDrawData .vertices ());
135+ // instanceCount
136+ commandBuffer .putInt (numEntities );
137+ commandBuffer .putInt (firstIndex );
138+ // baseVertex
139+ commandBuffer .putInt (meshDrawData .offset ());
140+ commandBuffer .putInt (baseInstance );
145141
146- CascadeShadow shadowCascade = cascadeShadows . get ( i );
147- uniformsMap . setUniform ( "projViewMatrix" , shadowCascade . getProjViewMatrix () );
142+ firstIndex += meshDrawData . vertices ( );
143+ baseInstance += entities . size ( );
148144
149- glMultiDrawElementsIndirect (GL_TRIANGLES , GL_UNSIGNED_INT , 0 , drawCount , 0 );
145+ for (Entity entity : entities ) {
146+ String name = "drawElements[" + drawElement + "]" ;
147+ uniformsMap .setUniform (name + ".modelMatrixIdx" , entitiesIdxMap .get (entity .getId ()));
148+ drawElement ++;
149+ }
150+ }
150151 }
152+ commandBuffer .flip ();
153+ shaderProgram .unbind ();
151154
152- glBindVertexArray (0 );
155+ staticDrawCount = commandBuffer .remaining () / COMMAND_SIZE ;
156+
157+ staticRenderBufferHandle = glGenBuffers ();
158+ glBindBuffer (GL_DRAW_INDIRECT_BUFFER , staticRenderBufferHandle );
159+ glBufferData (GL_DRAW_INDIRECT_BUFFER , commandBuffer , GL_DYNAMIC_DRAW );
153160
154161 MemoryUtil .memFree (commandBuffer );
155- glDeleteBuffers (bufferHandle );
156162 }
157163}
0 commit comments