コード例 #1
0
 /// <summary>
 /// Synchronously renders a complete frame to the specified render target.
 /// Automatically sets up the device's viewport and the view transform of your materials and restores them afterwards.
 /// </summary>
 public bool SynchronousDrawToRenderTarget(
     RenderTarget2D renderTarget,
     DefaultMaterialSet materials,
     Action <Frame> drawBehavior
     )
 {
     return(SynchronousDrawToRenderTargetSetup(renderTarget, materials, drawBehavior, null));
 }
コード例 #2
0
 /// <summary>
 /// Synchronously renders a complete frame to the specified render target.
 /// Automatically sets up the device's viewport and the view transform of your materials and restores them afterwards.
 /// </summary>
 public bool SynchronousDrawToRenderTarget(
     RenderTarget2D renderTarget,
     DefaultMaterialSet materials,
     PendingDrawHandler drawBehavior,
     object userData = null
     )
 {
     return(SynchronousDrawToRenderTargetSetup(renderTarget, materials, drawBehavior, userData));
 }
コード例 #3
0
        /// <summary>
        /// Synchronously renders a complete frame to the specified render target.
        /// Automatically sets up the device's viewport and the view transform of your materials and restores them afterwards.
        /// </summary>
        public bool SynchronousDrawToRenderTarget(RenderTarget2D renderTarget, DefaultMaterialSet materials, Action <Frame> drawBehavior)
        {
            if (renderTarget.IsDisposed)
            {
                return(false);
            }
            if (!SynchronousDrawsEnabled)
            {
                throw new InvalidOperationException("Synchronous draws not available inside of Game.Draw");
            }

            WaitForActiveDraw();

            var oldDrawIsActive = Interlocked.Exchange(ref _SynchronousDrawIsActive, 1);

            if (oldDrawIsActive != 0)
            {
                throw new InvalidOperationException("A synchronous draw is already in progress");
            }

            _SynchronousDrawFinishedSignal.Reset();

            WaitForActiveDraw();

            try {
                using (var frame = Manager.CreateFrame()) {
                    materials.PushViewTransform(ViewTransform.CreateOrthographic(renderTarget.Width, renderTarget.Height));

                    ClearBatch.AddNew(frame, int.MinValue, materials.Clear, clearColor: Color.Transparent);

                    drawBehavior(frame);

                    PrepareNextFrame(frame, false);

                    var oldRenderTargets = Device.GetRenderTargets();
                    var oldViewport      = Device.Viewport;
                    try {
                        Device.SetRenderTarget(renderTarget);
                        RenderManager.ResetDeviceState(Device);
                        Device.Viewport = new Viewport(0, 0, renderTarget.Width, renderTarget.Height);

                        RenderFrameToDraw(frame, false);
                    } finally {
                        Device.SetRenderTargets(oldRenderTargets);
                        materials.PopViewTransform();
                        Device.Viewport = oldViewport;
                    }
                }

                return(true);
            } finally {
                _SynchronousDrawFinishedSignal.Set();
                Interlocked.Exchange(ref _SynchronousDrawIsActive, 0);
            }
        }
コード例 #4
0
        private bool ValidateDrawToRenderTarget(RenderTarget2D renderTarget, DefaultMaterialSet materials)
        {
            if (renderTarget == null)
            {
                throw new ArgumentNullException("renderTarget");
            }
            if (renderTarget.IsDisposed)
            {
                return(false);
            }
            if (materials == null)
            {
                throw new ArgumentNullException("materials");
            }

            return(true);
        }
コード例 #5
0
        /// <summary>
        /// Queues a draw operation to the specified render target.
        /// The draw operation will occur at the start of the next frame before the frame itself has been rendered.
        /// </summary>
        /// <param name="onComplete">A Future instance that will have userData stored into it when rendering is complete.</param>
        public bool QueueDrawToRenderTarget(
            RenderTarget2D renderTarget, DefaultMaterialSet materials,
            PendingDrawHandler handler, object userData = null, IFuture onComplete = null,
            ViewTransform?viewTransform = null
            )
        {
            if (!ValidateDrawToRenderTarget(renderTarget, materials))
            {
                return(false);
            }

            lock (PendingDrawQueue)
                PendingDrawQueue.Add(new PendingDraw {
                    RenderTarget  = renderTarget,
                    Handler       = handler,
                    Materials     = materials,
                    UserData      = userData,
                    OnComplete    = onComplete,
                    ViewTransform = viewTransform
                });
            return(true);
        }
コード例 #6
0
        private bool SynchronousDrawToRenderTargetSetup(
            RenderTarget2D renderTarget,
            DefaultMaterialSet materials,
            Delegate drawBehavior, object userData
            )
        {
            if (!ValidateDrawToRenderTarget(renderTarget, materials))
            {
                return(false);
            }

            if (!SynchronousDrawsEnabled)
            {
                throw new InvalidOperationException("Synchronous draws not available inside of Game.Draw");
            }

            WaitForActiveDraw();

            var oldDrawIsActive = Interlocked.Exchange(ref _SynchronousDrawIsActive, 1);

            if (oldDrawIsActive != 0)
            {
                throw new InvalidOperationException("A synchronous draw is already in progress");
            }

            _SynchronousDrawFinishedSignal.Reset();

            WaitForActiveDraw();

            try {
                ViewTransform?vt = null;
                return(DoSynchronousDrawToRenderTarget(renderTarget, materials, drawBehavior, userData, ref vt, "Synchronous Draw"));
            } finally {
                _SynchronousDrawFinishedSignal.Set();
                Interlocked.Exchange(ref _SynchronousDrawIsActive, 0);
            }
        }
コード例 #7
0
        private bool DoSynchronousDrawToRenderTarget(
            RenderTarget2D renderTarget,
            DefaultMaterialSet materials,
            Delegate drawBehavior, object userData,
            ref ViewTransform?viewTransform,
            string description
            )
        {
            var oldLazyState = materials.LazyViewTransformChanges;

            try {
                materials.LazyViewTransformChanges = false;
                materials.ApplyViewTransform(materials.ViewTransform, true);
                using (var frame = Manager.CreateFrame(this)) {
                    frame.ChangeRenderTargets = false;
                    frame.Label = description;
                    if (viewTransform.HasValue)
                    {
                        materials.PushViewTransform(in viewTransform);
                    }
                    else
                    {
                        materials.PushViewTransform(ViewTransform.CreateOrthographic(renderTarget.Width, renderTarget.Height));
                    }

                    try {
                        // FIXME: Should queued draws run here? They are probably meant to run in the next real frame

                        var singleBehavior = drawBehavior as Action <Frame>;
                        var multiBehavior  = drawBehavior as PendingDrawHandler;
                        if (singleBehavior != null)
                        {
                            singleBehavior(frame);
                        }
                        else if (multiBehavior != null)
                        {
                            multiBehavior(frame, materials, userData);
                        }
                        else
                        {
                            throw new ArgumentException("Draw behavior was not of a compatible type");
                        }

                        RunBeforePrepareHandlers();
                        PrepareNextFrame(frame, false);

                        Manager.DeviceManager.SetRenderTarget(renderTarget);
                        RenderManager.ResetDeviceState(Device);
                        Device.Clear(Color.Transparent);

                        RenderFrameToDraw(frame, false);
                        // We don't have to push/pop anymore because the stacks are cleared at the end of a frame.

                        return(true);
                    } finally {
                        materials.PopViewTransform();
                    }
                }
            } finally {
                materials.LazyViewTransformChanges = oldLazyState;
            }
        }
コード例 #8
0
 public static RenderTargetBatchGroup ForRenderTarget(
     IBatchContainer container, int layer, AutoRenderTarget renderTarget,
     Action <DeviceManager, object> before = null, Action <DeviceManager, object> after = null,
     object userData = null,
     DefaultMaterialSet materialSet = null, in ViewTransform?viewTransform = null,