예제 #1
0
        private void RecursiveDrawWithClipping(RenderDrawContext context, UIElement element, ref Matrix worldViewProj, UIBatch batch, ref DepthStencilStateDescription dstate, SamplerState samplerState)
        {
            // not visible, remove children too
            if (!element.IsVisible)
            {
                return;
            }

            var renderingContext = batch.renderingContext as UIRenderingContext;
            var layoutingContext = batch.layoutingContext as LayoutingContext;

            var renderer = rendererManager.GetRenderer(element);

            renderingContext.DepthBias = element.DepthBias;

            // render the clipping region of the element
            if (element.ClipToBounds)
            {
                // flush current elements
                batch.End();

                // render the clipping region
                batch.Begin(context.GraphicsContext, ref worldViewProj, BlendStates.ColorDisabled, samplerState, null, uiSystem.IncreaseStencilValueState, renderingContext.StencilTestReferenceValue);
                renderer.RenderClipping(element, renderingContext, batch);
                batch.End();

                // update context and restart the batch
                renderingContext.StencilTestReferenceValue += 1;
                batch.Begin(context.GraphicsContext, ref worldViewProj, BlendStates.AlphaBlend, samplerState, null, dstate, renderingContext.StencilTestReferenceValue);
            }

            // render the design of the element
            renderer.RenderColor(element, renderingContext, batch);

            // render the children
            foreach (var child in element.VisualChildrenCollection)
            {
                RecursiveDrawWithClipping(context, child, ref worldViewProj, batch, ref dstate, samplerState);
            }

            // clear the element clipping region from the stencil buffer
            if (element.ClipToBounds)
            {
                // flush current elements
                batch.End();

                renderingContext.DepthBias = element.MaxChildrenDepthBias;

                // render the clipping region
                batch.Begin(context.GraphicsContext, ref worldViewProj, BlendStates.ColorDisabled, samplerState, null, uiSystem.DecreaseStencilValueState, renderingContext.StencilTestReferenceValue);
                renderer.RenderClipping(element, renderingContext, batch);
                batch.End();

                // update context and restart the batch
                renderingContext.StencilTestReferenceValue -= 1;
                batch.Begin(context.GraphicsContext, ref worldViewProj, BlendStates.AlphaBlend, samplerState, null, dstate, renderingContext.StencilTestReferenceValue);
            }
        }
예제 #2
0
        public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch)
        {
            var modalElement = (ModalElement)element;

            // end the current UI image batching so that the overlay is written over it with correct transparency
            Batch.End();

            var uiResolution = new Vector3(context.Resolution.X, context.Resolution.Y, 0);

            Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.AlphaBlend, noStencilNoDepth, 0);
            Batch.DrawRectangle(ref identity, ref uiResolution, ref modalElement.OverlayColorInternal, context.DepthBias);
            Batch.End(); // ensure that overlay is written before possible next transparent element.

            // restart the image batch session
            Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.AlphaBlend, KeepStencilValueState, context.StencilTestReferenceValue);

            context.DepthBias += 1;

            base.RenderColor(element, context, Batch);
        }
예제 #3
0
        protected override void OnRendering(RenderContext context)
        {
            if (uiSystem.RootElement == null)
            {
                return;
            }

            var drawTime             = game.DrawTime;
            var rootElement          = uiSystem.RootElement;
            var virtualResolution    = uiSystem.VirtualResolution;
            var updatableRootElement = (IUIElementUpdate)rootElement;

            // perform the time-based updates of the UI element
            updatableRootElement.Update(drawTime);

            // update the UI element disposition
            rootElement.Measure(virtualResolution);
            rootElement.Arrange(virtualResolution, false);

            // update the UI element hierarchical properties
            updatableRootElement.UpdateWorldMatrix(ref uiSystem.WorldMatrix, uiResolutionChanged);
            updatableRootElement.UpdateElementState(0);
            uiResolutionChanged = false;

            // set render targets and reset Depth buffer
            GraphicsDevice.SetDepthAndRenderTarget(GraphicsDevice.DepthStencilBuffer, GraphicsDevice.BackBuffer);
            GraphicsDevice.Clear(GraphicsDevice.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer | DepthStencilClearOptions.Stencil);

            // update the context time
            renderingContext.Time = game.DrawTime;

            // start the image draw session
            renderingContext.StencilTestReferenceValue = 0;
            batch.Begin(ref uiSystem.ViewProjectionInternal, GraphicsDevice.BlendStates.AlphaBlend, uiSystem.KeepStencilValueState, renderingContext.StencilTestReferenceValue);

            // Render the UI elements in the final render target
            ReccursiveDrawWithClipping(rootElement);

            // end the image draw session
            batch.End();
        }
예제 #4
0
        private void DrawInternal(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            base.Draw(context, renderView, renderViewStage, startIndex, endIndex);

            var uiProcessor = SceneInstance.GetCurrent(context.RenderContext).GetProcessor <UIRenderProcessor>();

            if (uiProcessor == null)
            {
                return;
            }

            // evaluate the current draw time (game instance is null for thumbnails)
            var drawTime = game != null ? game.DrawTime : new GameTime();

            // Prepare content required for Picking and MouseOver events
            var events = new List <PointerEvent>();

            PickingPrepare(events);

            ulong poseCount = VirtualReality.VRDeviceSystem.GetSystem?.Device?.PoseCount ?? 0;

            // build the list of the UI elements to render
            UIElementState[] uiElementStates = new UIElementState[endIndex - startIndex];
            if (uiElementStates.Length > 1 && GraphicsDevice.Platform == GraphicsPlatform.Vulkan)
            {
                Xenko.Core.Threading.Dispatcher.For(startIndex, endIndex, (index) =>
                {
                    initUIElementStates(context, renderView, renderViewStage, ref uiElementStates, index, index - startIndex, drawTime, events, poseCount);
                });
            }
            else
            {
                for (int i = startIndex; i < endIndex; i++)
                {
                    initUIElementStates(context, renderView, renderViewStage, ref uiElementStates, i, i - startIndex, drawTime, events, poseCount);
                }
            }

            events?.Clear();

            lock (drawLocker)
            {
                UIBatch batch = getFreeBatch(context);

                var renderingContext = batch.renderingContext as UIRenderingContext;

                // update the rendering context
                renderingContext.GraphicsContext = context.GraphicsContext;
                renderingContext.Time            = drawTime;

                DepthStencilStateDescription stencilState = uiSystem.KeepStencilValueState;

                // actually draw stuff
                for (int j = 0; j < uiElementStates.Length; j++)
                {
                    var uiElementState = uiElementStates[j];

                    renderingContext.RenderObject = uiElementState.RenderObject;
                    var rootElement = renderingContext.RenderObject.Page?.RootElement;
                    if (rootElement == null || rootElement.IsVisible == false)
                    {
                        continue;
                    }

                    // update the rendering context values specific to this element
                    renderingContext.ViewProjectionMatrix = uiElementState.WorldViewProjectionMatrix;

                    switch (renderingContext.RenderObject.depthMode)
                    {
                    case Sprites.RenderSprite.SpriteDepthMode.Ignore:
                        stencilState.DepthBufferWriteEnable = false;
                        stencilState.DepthBufferEnable      = false;
                        break;

                    case Sprites.RenderSprite.SpriteDepthMode.ReadOnly:
                        stencilState.DepthBufferWriteEnable = false;
                        stencilState.DepthBufferEnable      = true;
                        break;

                    default:
                        stencilState.DepthBufferWriteEnable = true;
                        stencilState.DepthBufferEnable      = true;
                        break;

                    case Sprites.RenderSprite.SpriteDepthMode.WriteOnly:
                        stencilState.DepthBufferWriteEnable = true;
                        stencilState.DepthBufferEnable      = true;
                        stencilState.DepthBufferFunction    = CompareFunction.Always;
                        break;
                    }

                    SamplerState samplerState;
                    switch (renderingContext.RenderObject.Sampler)
                    {
                    default:
                        samplerState = context.GraphicsDevice.SamplerStates.LinearClamp;
                        break;

                    case UIElementSampler.PointClamp:
                        samplerState = context.GraphicsDevice.SamplerStates.PointClamp;
                        break;

                    case UIElementSampler.AnisotropicClamp:
                        samplerState = context.GraphicsDevice.SamplerStates.AnisotropicClamp;
                        break;
                    }

                    // start the image draw session
                    renderingContext.StencilTestReferenceValue = 0;
                    batch.Begin(context.GraphicsContext, ref uiElementState.WorldViewProjectionMatrix, BlendStates.AlphaBlend, samplerState, null, stencilState, renderingContext.StencilTestReferenceValue);

                    // Render the UI elements in the final render target
                    RecursiveDrawWithClipping(context, rootElement, ref uiElementState.WorldViewProjectionMatrix, batch, ref stencilState, samplerState);

                    batch.End();
                }

                ReturnBatch(batch);
            }
        }
        public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch)
        {
            base.RenderColor(element, context, Batch);

            var scrollingText = (ScrollingText)element;

            if (scrollingText.Font == null || scrollingText.TextToDisplay == null)
            {
                return;
            }

            var offset          = scrollingText.ScrollingOffset;
            var textWorldMatrix = element.WorldMatrix;

            textWorldMatrix.M41 += textWorldMatrix.M11 * offset;
            textWorldMatrix.M42 += textWorldMatrix.M12 * offset;
            textWorldMatrix.M43 += textWorldMatrix.M13 * offset;
            textWorldMatrix.M44 += textWorldMatrix.M14 * offset;

            // create the scrolling text draw command
            var drawCommand = new SpriteFont.InternalUIDrawCommand
            {
                Color                      = scrollingText.RenderOpacity * scrollingText.TextColor,
                VertAlignment              = scrollingText.TextVerticalAlignment,
                LineSpacingAdjustment      = scrollingText.LineSpacingAdjustment,
                DepthBias                  = context.DepthBias + 1,
                RealVirtualResolutionRatio = element.LayoutingContext.RealVirtualResolutionRatio,
                RequestedFontSize          = scrollingText.ActualTextSize,
                Batch                      = Batch,
                SnapText                   = context.ShouldSnapText && !scrollingText.DoNotSnapText,
                Matrix                     = textWorldMatrix,
                Alignment                  = TextAlignment.Left,
                TextBoxSize                = new Vector2(scrollingText.ActualWidth, scrollingText.ActualHeight)
            };

            // flush the current content of the UI image batch
            Batch.End();

            // draw a clipping mask
            Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.ColorDisabled, IncreaseStencilValueState, context.StencilTestReferenceValue);
            Batch.DrawRectangle(ref element.WorldMatrixInternal, ref element.RenderSizeInternal, ref blackColor, context.DepthBias);
            Batch.End();

            // draw the element it-self with stencil test value of "Context.Value + 1"
            Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.AlphaBlend, KeepStencilValueState, context.StencilTestReferenceValue + 1);
            if (scrollingText.Font.FontType == SpriteFontType.SDF)
            {
                Batch.End();

                Batch.BeginCustom(context.GraphicsContext, 1);
            }

            Batch.DrawString(scrollingText.Font, scrollingText.TextToDisplay, ref drawCommand);
            Batch.End();

            // un-draw the clipping mask
            Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.ColorDisabled, DecreaseStencilValueState, context.StencilTestReferenceValue + 1);
            Batch.DrawRectangle(ref element.WorldMatrixInternal, ref element.RenderSizeInternal, ref blackColor, context.DepthBias + 2);
            Batch.End();

            // restart the Batch session
            Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.AlphaBlend, KeepStencilValueState, context.StencilTestReferenceValue);
        }
예제 #6
0
        private void DrawInternal(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            base.Draw(context, renderView, renderViewStage, startIndex, endIndex);

            var uiProcessor = SceneInstance.GetCurrent(context.RenderContext).GetProcessor <UIRenderProcessor>();

            if (uiProcessor == null)
            {
                return;
            }

            // evaluate the current draw time (game instance is null for thumbnails)
            var drawTime = game != null ? game.DrawTime : new GameTime();

            // Prepare content required for Picking and MouseOver events
            List <PointerEvent> events = new List <PointerEvent>();

            PickingPrepare(events);

            // build the list of the UI elements to render
            ConcurrentCollector <UIElementState> uiElementStates = new ConcurrentCollector <UIElementState>();

            if (GraphicsDevice.Platform == GraphicsPlatform.Vulkan)
            {
                Xenko.Core.Threading.Dispatcher.For(startIndex, endIndex, (index) =>
                {
                    initUIElementStates(context, renderView, renderViewStage, uiElementStates, index, drawTime, events);
                });
            }
            else
            {
                for (int i = startIndex; i < endIndex; i++)
                {
                    initUIElementStates(context, renderView, renderViewStage, uiElementStates, i, drawTime, events);
                }
            }

            events.Clear();

            uiElementStates.Close();

            lock (drawLocker)
            {
                UIBatch batch = getFreeBatch(context);

                var renderingContext = batch.renderingContext as UIRenderingContext;

                // update the rendering context
                renderingContext.GraphicsContext = context.GraphicsContext;
                renderingContext.Time            = drawTime;

                DepthStencilStateDescription stencilState = uiSystem.KeepStencilValueState;

                // actually draw stuff
                for (int j = 0; j < uiElementStates.Count; j++)
                {
                    var uiElementState = uiElementStates[j];

                    var renderObject = uiElementState.RenderObject;
                    var rootElement  = renderObject.Page?.RootElement;
                    if (rootElement == null)
                    {
                        continue;
                    }

                    // update the rendering context values specific to this element
                    renderingContext.Resolution           = renderObject.Resolution;
                    renderingContext.ViewProjectionMatrix = uiElementState.WorldViewProjectionMatrix;
                    renderingContext.ShouldSnapText       = renderObject.SnapText;
                    renderingContext.IsFullscreen         = renderObject.IsFullScreen;
                    renderingContext.WorldMatrix3D        = renderObject.WorldMatrix3D;

                    switch (renderObject.depthMode)
                    {
                    case Sprites.RenderSprite.SpriteDepthMode.Ignore:
                        stencilState.DepthBufferWriteEnable = false;
                        stencilState.DepthBufferEnable      = false;
                        break;

                    case Sprites.RenderSprite.SpriteDepthMode.ReadOnly:
                        stencilState.DepthBufferWriteEnable = false;
                        stencilState.DepthBufferEnable      = true;
                        break;

                    default:
                        stencilState.DepthBufferWriteEnable = true;
                        stencilState.DepthBufferEnable      = true;
                        break;

                    case Sprites.RenderSprite.SpriteDepthMode.WriteOnly:
                        stencilState.DepthBufferWriteEnable = true;
                        stencilState.DepthBufferEnable      = false;
                        break;
                    }

                    // start the image draw session
                    renderingContext.StencilTestReferenceValue = 0;
                    batch.Begin(context.GraphicsContext, ref uiElementState.WorldViewProjectionMatrix, BlendStates.AlphaBlend, stencilState, renderingContext.StencilTestReferenceValue);

                    // Render the UI elements in the final render target
                    RecursiveDrawWithClipping(context, rootElement, ref uiElementState.WorldViewProjectionMatrix, batch, ref stencilState);

                    batch.End();
                }

                ReturnBatch(batch);
            }
        }