public void RenderAllStages(GraphicsDevice gd, CommandList cl, GraphicsSystem sc) { if (ThreadedRendering) { RenderAllMultiThreaded(gd, cl, sc); } else { RenderAllSingleThread(gd, cl, sc); } }
public void CreateAllDeviceObjects(GraphicsDevice gd, CommandList cl, GraphicsSystem sc) { _cullableStage[0].Clear(); _octree.GetAllContainedObjects(_cullableStage[0]); foreach (ICullRenderable cr in _cullableStage[0]) { cr.CreateDeviceObjects(gd, cl, sc); } foreach (IRenderable r in _freeRenderables) { r.CreateDeviceObjects(gd, cl, sc); } _resourceUpdateCL = gd.ResourceFactory.CreateCommandList(); _resourceUpdateCL.Name = "Scene Resource Update Command List"; }
public virtual void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, GraphicsSystem sc) { ResourceFactory factory = gd.ResourceFactory; ProjectionMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); ViewMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightViewProjectionBuffer0 = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightViewProjectionBuffer0.Name = "LightViewProjectionBuffer0"; LightViewProjectionBuffer1 = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightViewProjectionBuffer1.Name = "LightViewProjectionBuffer1"; LightViewProjectionBuffer2 = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightViewProjectionBuffer2.Name = "LightViewProjectionBuffer2"; DepthLimitsBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <DepthCascadeLimits>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightInfoBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <DirectionalLightInfo>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); CameraInfoBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <CameraInfo>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); if (Camera != null) { UpdateCameraBuffers(cl); } PointLightsBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <PointLightsInfo.Blittable>(), BufferUsage.UniformBuffer)); PointLightsInfo pli = new PointLightsInfo(); pli.NumActiveLights = 4; pli.PointLights = new PointLightInfo[4] { new PointLightInfo { Color = new Vector3(1f, 1f, 1f), Position = new Vector3(-50, 5, 0), Range = 75f }, new PointLightInfo { Color = new Vector3(1f, .75f, .9f), Position = new Vector3(0, 5, 0), Range = 100f }, new PointLightInfo { Color = new Vector3(1f, 1f, 0.6f), Position = new Vector3(50, 5, 0), Range = 40f }, new PointLightInfo { Color = new Vector3(0.75f, 0.75f, 1f), Position = new Vector3(25, 5, 45), Range = 150f }, }; cl.UpdateBuffer(PointLightsBuffer, 0, pli.GetBlittable()); TextureSamplerResourceLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("SourceTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("SourceSampler", ResourceKind.Sampler, ShaderStages.Fragment))); uint ReflectionMapSize = 2048; ReflectionColorTexture = factory.CreateTexture(TextureDescription.Texture2D(ReflectionMapSize, ReflectionMapSize, 12, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.RenderTarget | TextureUsage.Sampled | TextureUsage.GenerateMipmaps)); ReflectionDepthTexture = factory.CreateTexture(TextureDescription.Texture2D(ReflectionMapSize, ReflectionMapSize, 1, 1, PixelFormat.R32_Float, TextureUsage.DepthStencil)); ReflectionColorView = factory.CreateTextureView(ReflectionColorTexture); ReflectionFramebuffer = factory.CreateFramebuffer(new FramebufferDescription(ReflectionDepthTexture, ReflectionColorTexture)); ReflectionViewProjBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); MirrorClipPlaneBuffer = factory.CreateBuffer(new BufferDescription(32, BufferUsage.UniformBuffer)); gd.UpdateBuffer(MirrorClipPlaneBuffer, 0, new ClipPlaneInfo(MirrorMesh.Plane, true)); NoClipPlaneBuffer = factory.CreateBuffer(new BufferDescription(32, BufferUsage.UniformBuffer)); gd.UpdateBuffer(NoClipPlaneBuffer, 0, new ClipPlaneInfo()); RecreateWindowSizedResources(gd, cl); ShadowMaps.CreateDeviceResources(gd); }
public void Render( GraphicsDevice gd, CommandList rc, GraphicsSystem sc, RenderPasses pass, BoundingFrustum frustum, Vector3 viewPosition, RenderQueue renderQueue, List <ICullRenderable> ICullRenderableList, List <IRenderable> renderableList, Comparer <RenderItemIndex> comparer, bool threaded) { renderQueue.Clear(); ICullRenderableList.Clear(); CollectVisibleObjects(ref frustum, pass, ICullRenderableList); renderQueue.AddRange(ICullRenderableList, viewPosition); renderableList.Clear(); CollectFreeObjects(pass, renderableList); renderQueue.AddRange(renderableList, viewPosition); if (comparer == null) { renderQueue.Sort(); } else { renderQueue.Sort(comparer); } foreach (IRenderable renderable in renderQueue) { renderable.Render(gd, rc, sc, pass); } if (threaded) { lock (_allPerFrameRenderablesSet) { foreach (ICullRenderable thing in ICullRenderableList) { _allPerFrameRenderablesSet.Add(thing); } foreach (IRenderable thing in renderableList) { _allPerFrameRenderablesSet.Add(thing); } } } else { foreach (ICullRenderable thing in ICullRenderableList) { _allPerFrameRenderablesSet.Add(thing); } foreach (IRenderable thing in renderableList) { _allPerFrameRenderablesSet.Add(thing); } } }
private Matrix4x4 UpdateDirectionalLightMatrices( bool useReverseDepth, GraphicsSystem sc, float near, float far, uint shadowMapWidth, out BoundingFrustum lightFrustum) { Vector3 lightDir = sc.DirectionalLight.Direction; Vector3 viewDir = sc.Camera.LookDirection; Vector3 viewPos = sc.Camera.Position; Vector3 unitY = Vector3.UnitY; FrustumCorners cameraCorners; if (useReverseDepth) { FrustumHelpers.ComputePerspectiveFrustumCorners( ref viewPos, ref viewDir, ref unitY, sc.Camera.FieldOfView, far, near, sc.Camera.AspectRatio, out cameraCorners); } else { FrustumHelpers.ComputePerspectiveFrustumCorners( ref viewPos, ref viewDir, ref unitY, sc.Camera.FieldOfView, near, far, sc.Camera.AspectRatio, out cameraCorners); } // Approach used: http://alextardif.com/ShadowMapping.html Vector3 frustumCenter = Vector3.Zero; frustumCenter += cameraCorners.NearTopLeft; frustumCenter += cameraCorners.NearTopRight; frustumCenter += cameraCorners.NearBottomLeft; frustumCenter += cameraCorners.NearBottomRight; frustumCenter += cameraCorners.FarTopLeft; frustumCenter += cameraCorners.FarTopRight; frustumCenter += cameraCorners.FarBottomLeft; frustumCenter += cameraCorners.FarBottomRight; frustumCenter /= 8f; float radius = (cameraCorners.NearTopLeft - cameraCorners.FarBottomRight).Length() / 2.0f; float texelsPerUnit = shadowMapWidth / (radius * 2.0f); Matrix4x4 scalar = Matrix4x4.CreateScale(texelsPerUnit, texelsPerUnit, texelsPerUnit); Vector3 baseLookAt = -lightDir; Matrix4x4 lookat = Matrix4x4.CreateLookAt(Vector3.Zero, baseLookAt, Vector3.UnitY); lookat = scalar * lookat; Matrix4x4.Invert(lookat, out Matrix4x4 lookatInv); frustumCenter = Vector3.Transform(frustumCenter, lookat); frustumCenter.X = (int)frustumCenter.X; frustumCenter.Y = (int)frustumCenter.Y; frustumCenter = Vector3.Transform(frustumCenter, lookatInv); Vector3 lightPos = frustumCenter - (lightDir * radius * 2f); Matrix4x4 lightView = Matrix4x4.CreateLookAt(lightPos, frustumCenter, Vector3.UnitY); Matrix4x4 lightProjection; if (useReverseDepth) { lightProjection = Matrix4x4.CreateOrthographicOffCenter( -radius * _lScale, radius * _rScale, -radius * _bScale, radius * _tScale, radius * _fScale, -radius * _nScale); } else { lightProjection = Matrix4x4.CreateOrthographicOffCenter( -radius * _lScale, radius * _rScale, -radius * _bScale, radius * _tScale, -radius * _nScale, radius * _fScale); } Matrix4x4 viewProjectionMatrix = lightView * lightProjection; lightFrustum = new BoundingFrustum(viewProjectionMatrix); return(viewProjectionMatrix); }
private void RenderAllMultiThreaded(GraphicsDevice gd, CommandList cl, GraphicsSystem sc) { float depthClear = gd.IsDepthRangeZeroToOne ? 0f : 1f; Matrix4x4 cameraProj = Camera.ProjectionMatrix; Vector4 nearLimitCS = Vector4.Transform(new Vector3(0, 0, -_nearCascadeLimit), cameraProj); Vector4 midLimitCS = Vector4.Transform(new Vector3(0, 0, -_midCascadeLimit), cameraProj); Vector4 farLimitCS = Vector4.Transform(new Vector3(0, 0, -_farCascadeLimit), cameraProj); Vector3 lightPos = sc.DirectionalLight.Transform.Position - sc.DirectionalLight.Direction * 1000f; _resourceUpdateCL.Begin(); CommandList[] cls = new CommandList[5]; for (int i = 0; i < cls.Length; i++) { cls[i] = gd.ResourceFactory.CreateCommandList(); cls[i].Begin(); } _resourceUpdateCL.UpdateBuffer(sc.DepthLimitsBuffer, 0, new DepthCascadeLimits { NearLimit = nearLimitCS.Z, MidLimit = midLimitCS.Z, FarLimit = farLimitCS.Z }); _resourceUpdateCL.UpdateBuffer(sc.LightInfoBuffer, 0, sc.DirectionalLight.GetInfo()); _allPerFrameRenderablesSet.Clear(); _tasks[0] = Task.Run(() => { // Near Matrix4x4 viewProj0 = UpdateDirectionalLightMatrices( gd.IsDepthRangeZeroToOne, sc, Camera.NearDistance, _nearCascadeLimit, sc.ShadowMapTexture.Width, out BoundingFrustum lightFrustum0); cls[1].UpdateBuffer(sc.LightViewProjectionBuffer0, 0, ref viewProj0); cls[1].SetFramebuffer(sc.NearShadowMapFramebuffer); cls[1].SetViewport(0, new Viewport(0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height, 0, 1)); cls[1].SetScissorRect(0, 0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height); cls[1].ClearDepthStencil(depthClear); Render(gd, cls[1], sc, RenderPasses.ShadowMapNear, lightFrustum0, lightPos, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, true); }); _tasks[1] = Task.Run(() => { // Mid Matrix4x4 viewProj1 = UpdateDirectionalLightMatrices( gd.IsDepthRangeZeroToOne, sc, _nearCascadeLimit, _midCascadeLimit, sc.ShadowMapTexture.Width, out var lightFrustum1); cls[2].UpdateBuffer(sc.LightViewProjectionBuffer1, 0, ref viewProj1); cls[2].SetFramebuffer(sc.MidShadowMapFramebuffer); cls[2].SetViewport(0, new Viewport(0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height, 0, 1)); cls[2].SetScissorRect(0, 0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height); cls[2].ClearDepthStencil(depthClear); Render(gd, cls[2], sc, RenderPasses.ShadowMapMid, lightFrustum1, lightPos, _renderQueues[1], _cullableStage[1], _renderableStage[1], null, true); }); _tasks[2] = Task.Run(() => { // Far Matrix4x4 viewProj2 = UpdateDirectionalLightMatrices( gd.IsDepthRangeZeroToOne, sc, _midCascadeLimit, _farCascadeLimit, sc.ShadowMapTexture.Width, out var lightFrustum2); cls[3].UpdateBuffer(sc.LightViewProjectionBuffer2, 0, ref viewProj2); cls[3].SetFramebuffer(sc.FarShadowMapFramebuffer); cls[3].SetViewport(0, new Viewport(0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height, 0, 1)); cls[3].SetScissorRect(0, 0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height); cls[3].ClearDepthStencil(depthClear); Render(gd, cls[3], sc, RenderPasses.ShadowMapFar, lightFrustum2, lightPos, _renderQueues[2], _cullableStage[2], _renderableStage[2], null, true); }); _tasks[3] = Task.Run(() => { // Reflections cls[4].SetFramebuffer(sc.ReflectionFramebuffer); float scWidth = sc.ReflectionFramebuffer.Width; float scHeight = sc.ReflectionFramebuffer.Height; cls[4].SetViewport(0, new Viewport(0, 0, scWidth, scHeight, 0, 1)); cls[4].SetFullViewports(); cls[4].SetFullScissorRects(); cls[4].ClearColorTarget(0, RgbaFloat.Black); cls[4].ClearDepthStencil(depthClear); // Render reflected scene. Matrix4x4 planeReflectionMatrix = Matrix4x4.CreateReflection(MirrorMesh.Plane); CameraInfo camInfo = new CameraInfo(); camInfo.CameraLookDirection = Vector3.Normalize(Vector3.Reflect(_camera.LookDirection, MirrorMesh.Plane.Normal)); camInfo.CameraPosition_WorldSpace = Vector3.Transform(_camera.Position, planeReflectionMatrix); cls[4].UpdateBuffer(sc.CameraInfoBuffer, 0, ref camInfo); Matrix4x4 view = sc.Camera.ViewMatrix; view = planeReflectionMatrix * view; cls[4].UpdateBuffer(sc.ViewMatrixBuffer, 0, view); Matrix4x4 projection = _camera.ProjectionMatrix; cls[4].UpdateBuffer(sc.ReflectionViewProjBuffer, 0, view * projection); BoundingFrustum cameraFrustum = new BoundingFrustum(view * projection); Render(gd, cls[4], sc, RenderPasses.ReflectionMap, cameraFrustum, _camera.Position, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true); cl.GenerateMipmaps(sc.ReflectionColorTexture); // Main scene cls[4].SetFramebuffer(sc.MainSceneFramebuffer); scWidth = sc.MainSceneFramebuffer.Width; scHeight = sc.MainSceneFramebuffer.Height; cls[4].SetViewport(0, new Viewport(0, 0, scWidth, scHeight, 0, 1)); cls[4].SetScissorRect(0, 0, 0, (uint)scWidth, (uint)scHeight); cls[4].ClearColorTarget(0, RgbaFloat.Black); cls[4].ClearDepthStencil(depthClear); sc.UpdateCameraBuffers(cls[4]); cameraFrustum = new BoundingFrustum(_camera.ViewMatrix * _camera.ProjectionMatrix); Render(gd, cls[4], sc, RenderPasses.Standard, cameraFrustum, _camera.Position, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true); Render(gd, cls[4], sc, RenderPasses.AlphaBlend, cameraFrustum, _camera.Position, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true); Render(gd, cls[4], sc, RenderPasses.Overlay, cameraFrustum, _camera.Position, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true); }); Task.WaitAll(_tasks); foreach (IRenderable renderable in _allPerFrameRenderablesSet) { renderable.UpdatePerFrameResources(gd, _resourceUpdateCL, sc); } _resourceUpdateCL.End(); gd.SubmitCommands(_resourceUpdateCL); for (int i = 0; i < cls.Length; i++) { cls[i].End(); gd.SubmitCommands(cls[i]); cls[i].Dispose(); } if (sc.MainSceneColorTexture.SampleCount != TextureSampleCount.Count1) { cl.ResolveTexture(sc.MainSceneColorTexture, sc.MainSceneResolvedColorTexture); } cl.SetFramebuffer(sc.DuplicatorFramebuffer); uint fbWidth = sc.DuplicatorFramebuffer.Width; uint fbHeight = sc.DuplicatorFramebuffer.Height; cl.SetViewport(0, new Viewport(0, 0, fbWidth, fbHeight, 0, 1)); cl.SetViewport(1, new Viewport(0, 0, fbWidth, fbHeight, 0, 1)); cl.SetScissorRect(0, 0, 0, fbWidth, fbHeight); cl.SetScissorRect(1, 0, 0, fbWidth, fbHeight); Render(gd, cl, sc, RenderPasses.Duplicator, new BoundingFrustum(), _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false); cl.SetFramebuffer(gd.SwapchainFramebuffer); fbWidth = gd.SwapchainFramebuffer.Width; fbHeight = gd.SwapchainFramebuffer.Height; cl.SetViewport(0, new Viewport(0, 0, fbWidth, fbHeight, 0, 1)); cl.SetScissorRect(0, 0, 0, fbWidth, fbHeight); Render(gd, cl, sc, RenderPasses.SwapchainOutput, new BoundingFrustum(), _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false); cl.End(); gd.SubmitCommands(cl); }
public GlitchDemo() { // Window & Graphics Device // -------------------------------------------------- WindowCreateInfo windowCI = new WindowCreateInfo { X = 50, Y = 50, WindowWidth = 960, WindowHeight = 540, WindowInitialState = WindowState.Normal, WindowTitle = "Glitch Demo" }; GraphicsDeviceOptions gdOptions = new GraphicsDeviceOptions(false, null, false, ResourceBindingModel.Improved, true); #if DEBUG gdOptions.Debug = true; #endif VeldridStartup.CreateWindowAndGraphicsDevice( windowCI, gdOptions, //GraphicsBackend.Metal, //GraphicsBackend.Vulkan, GraphicsBackend.OpenGL, //GraphicsBackend.OpenGLES, out _window, out _gd); _window.Resized += () => _windowResized = true; // Project Manifest // -------------------------------------------------- ProjectManifest projectManifest; string currentDir = AppContext.BaseDirectory; string manifestName = null; foreach (var file in Directory.EnumerateFiles(currentDir + "Assets")) { if (file.EndsWith("manifest")) { if (manifestName != null) { string errorMessage = "Error: Multiple project manifests in this directory: " + currentDir; Console.WriteLine(errorMessage); throw new System.Exception(errorMessage); } manifestName = file; } } using (var fs = File.OpenRead(manifestName)) using (var sr = new StreamReader(fs)) using (var jtr = new JsonTextReader(sr)) { var js = new JsonSerializer(); try { projectManifest = js.Deserialize <ProjectManifest>(jtr); } catch (Exception e) { string errorMessage = "An error was encountered while loading the project manifest."; Console.WriteLine(errorMessage); Console.WriteLine(e); throw new System.NullReferenceException(errorMessage); } } // Initialize Game() // -------------------------------------------------- _game = new Game(); // Assembly & Asset System // -------------------------------------------------- AssemblyLoadSystem als = new AssemblyLoadSystem(); als.LoadFromProjectManifest(projectManifest, AppContext.BaseDirectory); _game.SystemRegistry.Register(als); AssetSystem assetSystem = new AssetSystem(Path.Combine(AppContext.BaseDirectory, projectManifest.AssetRoot), als.Binder); _game.SystemRegistry.Register(assetSystem); // Graphics System // -------------------------------------------------- _gs = new GraphicsSystem(_gd); _game.SystemRegistry.Register(_gs); // Scene // -------------------------------------------------- _scene = new Scene(_gd, _window.Width, _window.Height); // [For Debugging] - Custom SceneAsset Serializer // -------------------------------------------------- SceneAsset programaticSceneAsset = new SceneAsset(); programaticSceneAsset.Name = "MainMenu"; // Custom GameObject (for camera & skybox) GameObject go1 = new GameObject(); go1.Name = "PlayerCamera"; go1.Enabled = true; // Add custom camera to GameObject Camera camera = new Camera(); camera.WindowHeight = _window.Height; camera.WindowWidth = _window.Width; go1.AddComponent(camera); go1.Transform.LocalPosition = new Vector3(0f, 0f, 0f); // Add custom skybox to GameObject Skybox skybox = Skybox.LoadDefaultSkybox(_game.SystemRegistry); go1.AddComponent(skybox); // Custom GameObject (for sphere mesh) GameObject go2 = new GameObject(); go2.Name = "My Sphere"; go2.Enabled = true; // Add custom sphere MeshRenderer component to GameObject Vector3 scale2 = new Vector3(1f); Vector3 offset2 = new Vector3(0f, 0f, -5f); Quaternion rotation2 = Quaternion.Identity; var meshAssetID2 = new AssetID("Internal:SphereModel"); var meshAssetRef2 = new AssetRef <MeshData>(meshAssetID2); var textureAssetID2 = new AssetID("Textures/rust.jpg"); var textureAssetRef2 = new AssetRef <ImageSharpTexture>(textureAssetID2); go2.Transform.LocalPosition = offset2; go2.Transform.LocalRotation = rotation2; go2.Transform.LocalScale = scale2; MeshRenderer meshrenderer2 = new MeshRenderer(meshAssetRef2, textureAssetRef2); go2.AddComponent(meshrenderer2); // Custom GameObject (for plane mesh) GameObject go3 = new GameObject(); go3.Name = "My Plane Model"; go3.Enabled = true; // Add custom Plane MeshRenderer component to GameObject Vector3 scale3 = new Vector3(10f); Vector3 offset3 = new Vector3(0f, -1f, -5f); Quaternion rotation3 = Quaternion.Identity; var meshAssetID3 = new AssetID("Internal:PlaneModel"); var meshAssetRef3 = new AssetRef <MeshData>(meshAssetID3); var textureAssetID3 = new AssetID("Textures/Wood.png"); var textureAssetRef3 = new AssetRef <ImageSharpTexture>(textureAssetID3); go3.Transform.LocalPosition = offset3; go3.Transform.LocalRotation = rotation3; go3.Transform.LocalScale = scale3; MeshRenderer meshrenderer3 = new MeshRenderer(meshAssetRef3, textureAssetRef3); go3.AddComponent(meshrenderer3); // Custom GameObject (another sphere mesh) GameObject go4 = new GameObject(); go4.Name = "Another Sphere"; go4.Enabled = true; Vector3 scale4 = new Vector3(0.5f); Vector3 offset4 = new Vector3(2f, -0.5f, -3f); Quaternion rotation4 = Quaternion.Identity; var meshAssetID4 = new AssetID("Internal:SphereModel"); var meshAssetRef4 = new AssetRef <MeshData>(meshAssetID4); var textureAssetID4 = new AssetID("Textures/rust.jpg"); var textureAssetRef4 = new AssetRef <ImageSharpTexture>(textureAssetID4); go4.Transform.LocalPosition = offset4; go4.Transform.LocalRotation = rotation4; go4.Transform.LocalScale = scale4; MeshRenderer meshrenderer4 = new MeshRenderer(meshAssetRef4, textureAssetRef4); go4.AddComponent(meshrenderer4); // Add custom GameObject to SceneAsset SerializedGameObject sgo1 = new SerializedGameObject(go1); SerializedGameObject sgo2 = new SerializedGameObject(go2); SerializedGameObject sgo3 = new SerializedGameObject(go3); SerializedGameObject sgo4 = new SerializedGameObject(go4); programaticSceneAsset.GameObjects = new SerializedGameObject[4]; programaticSceneAsset.GameObjects[0] = sgo1; programaticSceneAsset.GameObjects[1] = sgo2; programaticSceneAsset.GameObjects[2] = sgo3; programaticSceneAsset.GameObjects[3] = sgo4; // Serialize SceneAsset LooseFileDatabase lfd = new LooseFileDatabase("/Assets"); StringWriter stringwriter = new StringWriter(new StringBuilder()); using (StreamWriter file = File.CreateText(@"DebugSceneAsset.json")) { JsonSerializer serializer = lfd.DefaultSerializer; serializer.Serialize(file, programaticSceneAsset); } // Scene Assets // -------------------------------------------------- SceneAsset sceneAsset; AssetID mainSceneID = projectManifest.OpeningScene.ID; if (mainSceneID.IsEmpty) { var scenes = assetSystem.Database.GetAssetsOfType(typeof(SceneAsset)); if (!scenes.Any()) { Console.WriteLine("No scenes were available to load."); throw new System.Exception("No scenes were available to load."); } else { mainSceneID = scenes.First(); } } var readSceneFromProgramaticAsset = true; sceneAsset = assetSystem.Database.LoadAsset <SceneAsset>(mainSceneID); _scene.LoadSceneAsset(readSceneFromProgramaticAsset ? programaticSceneAsset : sceneAsset); _gs.SetCurrentScene(_scene); // GUI // -------------------------------------------------- _igRenderable = new ImGuiRenderable(_window.Width, _window.Height); _resizeHandled += (w, h) => _igRenderable.WindowResized(w, h); _scene.AddRenderable(_igRenderable); _scene.AddUpdateable(_igRenderable); // Duplicate Screen (for post-processing filters) // -------------------------------------------------- ScreenDuplicator duplicator = new ScreenDuplicator(); _scene.AddRenderable(duplicator); // TODO: rename FullScreenQuad to FinalBufferObject or something _fsq = new FullScreenQuad(); _scene.AddRenderable(_fsq); CreateAllObjects(); }