testing instancing
							parent
							
								
									8f570e04f0
								
							
						
					
					
						commit
						867d4d7f5d
					
				|  | @ -94,7 +94,7 @@ | |||
|         "env": { | ||||
|           "LD_LIBRARY_PATH": "./lib64", | ||||
|           "DYLD_LIBRARY_PATH": "./osx", | ||||
|           "FNA3D_FORCE_DRIVER": "Vulkan" | ||||
|           "FNA3D_FORCE_DRIVER": "OpenGL" | ||||
|         }, | ||||
|         "cwd": "${workspaceFolder}/KavTest/bin/x64/Debug/net48" | ||||
|       }, | ||||
|  |  | |||
							
								
								
									
										2
									
								
								FNA
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								FNA
								
								
								
								
							|  | @ -1 +1 @@ | |||
| Subproject commit 1df9f588a701eefc4b55a0869cd5871be0124307 | ||||
| Subproject commit 7357a6f297fee33b7a8d5afddaca30480c591ba5 | ||||
							
								
								
									
										2
									
								
								Kav
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								Kav
								
								
								
								
							|  | @ -1 +1 @@ | |||
| Subproject commit 8b43e8f45ee6fa35f5c4d4924a62a3fcafe61301 | ||||
| Subproject commit bb694d3dbe47dcfcee6bfe3fb315587419ba8c0f | ||||
|  | @ -0,0 +1,6 @@ | |||
| using Encompass; | ||||
| 
 | ||||
| namespace KavTest.Components | ||||
| { | ||||
|     public struct InstancedCubeComponent : IComponent { } | ||||
| } | ||||
|  | @ -6,10 +6,12 @@ namespace KavTest.Components | |||
|     public struct ModelComponent : IComponent | ||||
|     { | ||||
|         public Model Model { get; } | ||||
|         public bool Instanced { get; } | ||||
| 
 | ||||
|         public ModelComponent(Model model) | ||||
|         public ModelComponent(Model model, bool instanced) | ||||
|         { | ||||
|             Model = model; | ||||
|             Instanced = instanced; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ namespace KavTest.Spawners | |||
|             var entity = CreateEntity(); | ||||
| 
 | ||||
|             AddComponent(entity, new Transform3DComponent(message.Transform)); | ||||
|             AddComponent(entity, new ModelComponent(RustyBallModel)); | ||||
|             AddComponent(entity, new ModelComponent(RustyBallModel, true)); | ||||
|             AddComponent(entity, new AngularVelocityComponent(message.AngularVelocity)); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ namespace KavTest.Spawners | |||
|             var entity = CreateEntity(); | ||||
| 
 | ||||
|             AddComponent(entity, new Transform3DComponent(message.Transform)); | ||||
|             AddComponent(entity, new ModelComponent(message.Model)); | ||||
|             AddComponent(entity, new ModelComponent(message.Model, true)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,9 @@ | |||
| using Kav; | ||||
| 
 | ||||
| namespace KavTest | ||||
| { | ||||
|     public class InstancedModelContainer | ||||
|     { | ||||
|         public MeshPart CubeModel { get; set; } | ||||
|     } | ||||
| } | ||||
|  | @ -16,6 +16,7 @@ namespace KavTest | |||
|     class KavTestGame : Game | ||||
|     { | ||||
|         GraphicsDeviceManager graphics; | ||||
|         InstancedModelContainer InstancedModelContainer { get; } = new InstancedModelContainer(); | ||||
| 
 | ||||
|         WorldBuilder WorldBuilder { get; } = new WorldBuilder(); | ||||
|         World World { get; set; } | ||||
|  | @ -119,6 +120,10 @@ namespace KavTest | |||
|                 ) | ||||
|             ); | ||||
| 
 | ||||
|             InstancedModelContainer.CubeModel = cubeModel.Meshes[0].MeshParts[0]; | ||||
|             InstancedModelContainer.CubeModel.Albedo = Color.Blue.ToVector3(); | ||||
|             InstancedModelContainer.CubeModel.DisableAlbedoMap = true; | ||||
| 
 | ||||
|             Texture2D.TextureDataFromStreamEXT( | ||||
|                 File.OpenRead("Content/Skybox/front.jpg"), | ||||
|                 out var skyboxSize, | ||||
|  | @ -187,7 +192,7 @@ namespace KavTest | |||
|             WorldBuilder.AddEngine(new StaticModelSpawner()); | ||||
|             WorldBuilder.AddEngine(new DirectionalLightSpawner()); | ||||
|             WorldBuilder.AddEngine(new MeshSpriteSpawner()); | ||||
|             WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice), 0); | ||||
|             WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice, InstancedModelContainer), 0); | ||||
| 
 | ||||
|             // WorldBuilder.SendMessage(new RustyBallSpawnMessage( | ||||
|             //     new Transform3D(new Vector3(0, 0, 0)), | ||||
|  | @ -209,46 +214,51 @@ namespace KavTest | |||
|             //     rustyBallModel | ||||
|             // )); | ||||
| 
 | ||||
|             WorldBuilder.SendMessage(new StaticModelSpawnMessage( | ||||
|                 new Transform3D(new Vector3(0, -3, 0), Quaternion.Identity, new Vector3(10f, 1f, 10f)), | ||||
|                 floorModel | ||||
|             )); | ||||
|             // WorldBuilder.SendMessage(new StaticModelSpawnMessage( | ||||
|             //     new Transform3D(new Vector3(0, -3, 0), Quaternion.Identity, new Vector3(10f, 1f, 10f)), | ||||
|             //     floorModel | ||||
|             // )); | ||||
| 
 | ||||
|             WorldBuilder.SendMessage(new StaticModelSpawnMessage( | ||||
|                 new Transform3D( | ||||
|                     new Vector3(0, 1, 0), | ||||
|                     Quaternion.CreateFromAxisAngle( | ||||
|                         Vector3.Right, | ||||
|                         -Microsoft.Xna.Framework.MathHelper.PiOver2 | ||||
|                     ), | ||||
|                     new Vector3(1f, 1f, 1f) | ||||
|                 ), | ||||
|                 redCylinderModel | ||||
|             )); | ||||
|             // WorldBuilder.SendMessage(new StaticModelSpawnMessage( | ||||
|             //     new Transform3D( | ||||
|             //         new Vector3(0, 1, 0), | ||||
|             //         Quaternion.CreateFromAxisAngle( | ||||
|             //             Vector3.Right, | ||||
|             //             -Microsoft.Xna.Framework.MathHelper.PiOver2 | ||||
|             //         ), | ||||
|             //         new Vector3(1f, 1f, 1f) | ||||
|             //     ), | ||||
|             //     redCylinderModel | ||||
|             // )); | ||||
| 
 | ||||
|             WorldBuilder.SendMessage(new StaticModelSpawnMessage( | ||||
|                 new Transform3D( | ||||
|                     new Vector3(-3, 1, 0), | ||||
|                     Quaternion.CreateFromAxisAngle( | ||||
|                         Vector3.Right, | ||||
|                         -Microsoft.Xna.Framework.MathHelper.PiOver2 | ||||
|                     ), | ||||
|                     new Vector3(1f, 1f, 1f) | ||||
|                 ), | ||||
|                 blueTorusModel | ||||
|             )); | ||||
|             // WorldBuilder.SendMessage(new StaticModelSpawnMessage( | ||||
|             //     new Transform3D( | ||||
|             //         new Vector3(-3, 1, 0), | ||||
|             //         Quaternion.CreateFromAxisAngle( | ||||
|             //             Vector3.Right, | ||||
|             //             -Microsoft.Xna.Framework.MathHelper.PiOver2 | ||||
|             //         ), | ||||
|             //         new Vector3(1f, 1f, 1f) | ||||
|             //     ), | ||||
|             //     blueTorusModel | ||||
|             // )); | ||||
| 
 | ||||
|             WorldBuilder.SendMessage(new StaticModelSpawnMessage( | ||||
|                 new Transform3D( | ||||
|                     new Vector3(3, 1, 0), | ||||
|                     Quaternion.CreateFromAxisAngle( | ||||
|                         Vector3.Right, | ||||
|                         -Microsoft.Xna.Framework.MathHelper.PiOver2 | ||||
|                     ), | ||||
|                     new Vector3(1f, 1f, 1f) | ||||
|                 ), | ||||
|                 cubeModel | ||||
|             )); | ||||
|             for (int i = -10; i < 10; i++) | ||||
|             { | ||||
|                 for (int j = -10; j < 10; j++) | ||||
|                 { | ||||
|                     for (int k = -10; k < 10; k++) | ||||
|                     { | ||||
|                         var entity = WorldBuilder.CreateEntity(); | ||||
|                         WorldBuilder.SetComponent(entity, new Transform3DComponent( | ||||
|                             new Transform3D( | ||||
|                                 new Vector3(i * 3, j * 3, k * 3) | ||||
|                             ) | ||||
|                         )); | ||||
|                         WorldBuilder.SetComponent(entity, new InstancedCubeComponent()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             WorldBuilder.SendMessage(new MeshSpriteSpawnMessage( | ||||
|                 new Transform3D(new Vector3(3, 0, 11), Quaternion.CreateFromAxisAngle(Vector3.Up, (float)System.Math.PI), Vector3.One), | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ namespace KavTest.Renderers | |||
|     { | ||||
|         private GraphicsDevice GraphicsDevice { get; } | ||||
|         private SpriteBatch SpriteBatch { get; } | ||||
|         private InstancedModelContainer InstancedModelContainer { get; } | ||||
| 
 | ||||
|         private Kav.Renderer Renderer { get; } | ||||
| 
 | ||||
|  | @ -26,6 +27,24 @@ namespace KavTest.Renderers | |||
|         private RenderTarget2D DeferredTarget { get; } | ||||
|         private RenderTarget2D BillboardTarget { get; } | ||||
| 
 | ||||
|         private readonly Dictionary<Kav.MeshPart, List<Matrix>> InstanceMap = new Dictionary<MeshPart, List<Matrix>>(); | ||||
| 
 | ||||
|         private IEnumerable<Matrix> CubeTransforms | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 foreach (var entity in ReadEntitiesAsEnumerable<InstancedCubeComponent>()) | ||||
|                 { | ||||
|                     if (HasComponent<Transform3DComponent>(entity)) | ||||
|                     { | ||||
|                         var transformComponent = GetComponent<Transform3DComponent>(entity); | ||||
| 
 | ||||
|                         yield return transformComponent.Transform.TransformMatrix; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private IEnumerable<(Kav.Model, Matrix)> ModelTransforms | ||||
|         { | ||||
|             get | ||||
|  | @ -117,9 +136,12 @@ namespace KavTest.Renderers | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public SceneRenderer(GraphicsDevice graphicsDevice) | ||||
|         { | ||||
|         public SceneRenderer( | ||||
|             GraphicsDevice graphicsDevice, | ||||
|             InstancedModelContainer instancedModelContainer | ||||
|         ) { | ||||
|             GraphicsDevice = graphicsDevice; | ||||
|             InstancedModelContainer = instancedModelContainer; | ||||
| 
 | ||||
|             var renderDimensionsX = GraphicsDevice.PresentationParameters.BackBufferWidth; | ||||
|             var renderDimensionsY = GraphicsDevice.PresentationParameters.BackBufferHeight; | ||||
|  | @ -220,11 +242,19 @@ namespace KavTest.Renderers | |||
| 
 | ||||
|                 GraphicsDevice.SetRenderTargets(GBuffer); | ||||
|                 GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0); | ||||
|                 GraphicsDevice.DepthStencilState = DepthStencilState.Default; | ||||
| 
 | ||||
|                 Renderer.GBufferRender( | ||||
|                 // Renderer.GBufferRender( | ||||
|                 //     GBuffer, | ||||
|                 //     camera, | ||||
|                 //     ModelTransforms | ||||
|                 // ); | ||||
| 
 | ||||
|                 Renderer.InstancedGBufferRender( | ||||
|                     GBuffer, | ||||
|                     camera, | ||||
|                     ModelTransforms | ||||
|                     InstancedModelContainer.CubeModel, | ||||
|                     CubeTransforms | ||||
|                 ); | ||||
| 
 | ||||
|                 GraphicsDevice.SetRenderTarget(DeferredTarget); | ||||
|  | @ -299,5 +329,39 @@ namespace KavTest.Renderers | |||
|                 SpriteBatch.End(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void CollectInstances() | ||||
|         { | ||||
|             foreach (var list in InstanceMap.Values) | ||||
|             { | ||||
|                 list.Clear(); | ||||
|             } | ||||
| 
 | ||||
|             foreach (var modelEntity in ReadEntities<ModelComponent>()) | ||||
|             { | ||||
|                 if (HasComponent<Transform3DComponent>(modelEntity)) | ||||
|                 { | ||||
|                     var modelComponent = GetComponent<ModelComponent>(modelEntity); | ||||
|                     if (modelComponent.Instanced) | ||||
|                     { | ||||
|                         var transformComponent = GetComponent<Transform3DComponent>(modelEntity); | ||||
| 
 | ||||
|                         foreach (var mesh in modelComponent.Model.Meshes) | ||||
|                         { | ||||
|                             foreach (var meshPart in mesh.MeshParts) | ||||
|                             { | ||||
|                                 if (!InstanceMap.ContainsKey(meshPart)) | ||||
|                                 { | ||||
|                                     InstanceMap.Add(meshPart, new List<Matrix>()); | ||||
|                                 } | ||||
|                                 else | ||||
| 
 | ||||
|                                 InstanceMap[meshPart].Add(transformComponent.Transform.TransformMatrix); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue