public override void Update() { // Wait until visibility group is available if (VisibilityGroup == null) { VisibilityGroup = SceneSystem.SceneInstance.VisibilityGroups.FirstOrDefault(); } if (VisibilityGroup == null) { return; } // Check whether counts have changed if (lastCountX != CountX || lastCountY != CountY) { RebuildRenderObjects(); } // Update render objects UpdateRenderObjects(); lastCountX = CountX; lastCountY = CountY; }
public VisibilityGroup GetOrCreateVisibilityGroup(RenderSystem renderSystem) { // Find if it exists VisibilityGroup visibilityGroup = null; foreach (var currentVisibilityGroup in VisibilityGroups) { if (currentVisibilityGroup.RenderSystem == renderSystem) { visibilityGroup = currentVisibilityGroup; break; } } // If first time, let's create and register it if (visibilityGroup == null) { VisibilityGroups.Add(visibilityGroup = new VisibilityGroup(renderSystem)); } return(visibilityGroup); }
/// <inheritdoc/> protected override void DrawCore(RenderDrawContext context) { if (Game != null) { // Get or create VisibilityGroup for this RenderSystem + SceneInstance var sceneInstance = SceneInstance.GetCurrent(context.RenderContext); VisibilityGroup visibilityGroup = null; if (sceneInstance != null) { // Find if VisibilityGroup foreach (var currentVisibilityGroup in sceneInstance.VisibilityGroups) { if (currentVisibilityGroup.RenderSystem == RenderSystem) { visibilityGroup = currentVisibilityGroup; break; } } // If first time, let's create and register it if (visibilityGroup == null) { sceneInstance.VisibilityGroups.Add(visibilityGroup = new VisibilityGroup(RenderSystem)); initializedSceneInstances.Add(sceneInstance); } // Reset & cleanup visibilityGroup.Reset(); } using (context.RenderContext.PushTagAndRestore(SceneInstance.CurrentVisibilityGroup, visibilityGroup)) using (context.RenderContext.PushTagAndRestore(SceneInstance.CurrentRenderSystem, RenderSystem)) using (context.RenderContext.PushTagAndRestore(SceneCameraSlotCollection.Current, Cameras)) { // Set render system context.RenderContext.RenderSystem = RenderSystem; context.RenderContext.VisibilityGroup = visibilityGroup; // Set start states for viewports and output (it will be used during the Collect phase) var renderOutputs = new RenderOutputDescription(); renderOutputs.CaptureState(context.CommandList); context.RenderContext.RenderOutput = renderOutputs; var viewports = new ViewportState(); viewports.CaptureState(context.CommandList); context.RenderContext.ViewportState = viewports; try { // Collect in the game graphics compositor: Setup features/stages, enumerate views and populates VisibilityGroup Game.Collect(context.RenderContext); // Collect in render features RenderSystem.Collect(context.RenderContext); // Collect visibile objects from each view (that were not properly collected previously) if (visibilityGroup != null) { foreach (var view in RenderSystem.Views) { visibilityGroup.TryCollect(view); } } // Extract RenderSystem.Extract(context.RenderContext); // Prepare RenderSystem.Prepare(context); // Draw using the game graphics compositor Game.Draw(context); // Flush RenderSystem.Flush(context); } finally { // Reset render context data RenderSystem.Reset(); } } } }
private bool DrawBoundingVolumes(RenderDrawContext context, IReadOnlyList <RenderLightShaftBoundingVolume> boundingVolumes, Matrix viewProjection) { var commandList = context.CommandList; bool effectUpdated = minmaxVolumeEffectShader.UpdateEffect(GraphicsDevice); if (minmaxVolumeEffectShader.Effect == null) { return(false); } var needEffectUpdate = effectUpdated || previousMinmaxEffectBytecode != minmaxVolumeEffectShader.Effect.Bytecode; bool visibleMeshes = false; for (int pass = 0; pass < 2; ++pass) { var minmaxPipelineState = minmaxPipelineStates[pass]; bool pipelineDirty = false; if (needEffectUpdate) { // The EffectInstance might have been updated from outside previousMinmaxEffectBytecode = minmaxVolumeEffectShader.Effect.Bytecode; minmaxPipelineState.State.RootSignature = minmaxVolumeEffectShader.RootSignature; minmaxPipelineState.State.EffectBytecode = minmaxVolumeEffectShader.Effect.Bytecode; minmaxPipelineState.State.Output.RenderTargetCount = 1; minmaxPipelineState.State.Output.RenderTargetFormat0 = commandList.RenderTarget.Format; pipelineDirty = true; } MeshDraw currentDraw = null; var frustum = new BoundingFrustum(ref viewProjection); foreach (var volume in boundingVolumes) { if (volume.Model == null) { continue; } // Update parameters for the minmax shader Matrix worldViewProjection = Matrix.Multiply(volume.World, viewProjection); minmaxVolumeEffectShader.Parameters.Set(VolumeMinMaxShaderKeys.WorldViewProjection, worldViewProjection); foreach (var mesh in volume.Model.Meshes) { // Frustum culling BoundingBox meshBoundingBox; Matrix world = volume.World; BoundingBox.Transform(ref mesh.BoundingBox, ref world, out meshBoundingBox); var boundingBoxExt = new BoundingBoxExt(meshBoundingBox); if (boundingBoxExt.Extent != Vector3.Zero && !VisibilityGroup.FrustumContainsBox(ref frustum, ref boundingBoxExt, true)) { continue; } visibleMeshes = true; var draw = mesh.Draw; if (currentDraw != draw) { if (minmaxPipelineState.State.PrimitiveType != draw.PrimitiveType) { minmaxPipelineState.State.PrimitiveType = draw.PrimitiveType; pipelineDirty = true; } var inputElements = draw.VertexBuffers.CreateInputElements(); if (inputElements.ComputeHash() != minmaxPipelineState.State.InputElements.ComputeHash()) { minmaxPipelineState.State.InputElements = inputElements; pipelineDirty = true; } // Update mesh for (int i = 0; i < draw.VertexBuffers.Length; i++) { var vertexBuffer = draw.VertexBuffers[i]; commandList.SetVertexBuffer(i, vertexBuffer.Buffer, vertexBuffer.Offset, vertexBuffer.Stride); } if (draw.IndexBuffer != null) { commandList.SetIndexBuffer(draw.IndexBuffer.Buffer, draw.IndexBuffer.Offset, draw.IndexBuffer.Is32Bit); } currentDraw = draw; } if (pipelineDirty) { minmaxPipelineState.Update(); pipelineDirty = false; } context.CommandList.SetPipelineState(minmaxPipelineState.CurrentState); minmaxVolumeEffectShader.Apply(context.GraphicsContext); // Draw if (currentDraw.IndexBuffer == null) { commandList.Draw(currentDraw.DrawCount, currentDraw.StartLocation); } else { commandList.DrawIndexed(currentDraw.DrawCount, currentDraw.StartLocation); } } } } return(visibleMeshes); }
private EntityProcessor CreateRenderProcessor(RegisteredRenderProcessors registeredRenderProcessor, VisibilityGroup visibilityGroup) { // Create var processor = (EntityProcessor)Activator.CreateInstance(registeredRenderProcessor.Type); // Set visibility group ((IEntityComponentRenderProcessor)processor).VisibilityGroup = visibilityGroup; // Add processor Processors.Add(processor); registeredRenderProcessor.Instances.Add(new KeyValuePair <VisibilityGroup, EntityProcessor>(visibilityGroup, processor)); return(processor); }