private void ReturnBatch(UIBatch batch) { if (batch != directXBatch) { batches.Enqueue(batch); } }
public override void DrawDraggingImage(Point mousePosition) { Rectangle sourceRectangle = Sheet.Get(sprite).UvToPixels(); UIBatch.Draw(atlas, mousePosition.ToVector2() - new Vector2(sourceRectangle.Width / 2, sourceRectangle.Height / 2), sourceRectangle, Color.White, 0f, Vector2.Zero, 1, SpriteEffects.None, 0); }
protected override void LoadContent() { base.LoadContent(); // create effect and geometric primitives Batch = new UIBatch(GraphicsDevice); // create depth stencil states var depthStencilDescription = new DepthStencilStateDescription(true, true) { StencilEnable = true, FrontFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, BackFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, }; KeepStencilValueState = DepthStencilState.New(GraphicsDevice, depthStencilDescription); depthStencilDescription.FrontFace.StencilPass = StencilOperation.Increment; depthStencilDescription.BackFace.StencilPass = StencilOperation.Increment; IncreaseStencilValueState = DepthStencilState.New(GraphicsDevice, depthStencilDescription); depthStencilDescription.FrontFace.StencilPass = StencilOperation.Decrement; depthStencilDescription.BackFace.StencilPass = StencilOperation.Decrement; DecreaseStencilValueState = DepthStencilState.New(GraphicsDevice, depthStencilDescription); // set the default design of the UI elements. var designsTexture = TextureExtensions.FromFileData(GraphicsDevice, DefaultDesigns.Designs); Button.PressedImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default button pressed design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(71, 3, 32, 32)}); Button.NotPressedImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default button not pressed design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(3, 3, 32, 32) }); Button.MouseOverImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default button overred design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(37, 3, 32, 32) }); EditText.ActiveImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default edit active design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(105, 3, 32, 32) }); EditText.InactiveImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default edit inactive design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(139, 3, 32, 32) }); EditText.MouseOverImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default edit overred design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(173, 3, 32, 32) }); ToggleButton.CheckedImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default toggle button checked design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(71, 3, 32, 32) }); ToggleButton.UncheckedImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default toggle button unchecked design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(3, 3, 32, 32) }); ToggleButton.IndeterminateImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default toggle button indeterminate design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(37, 3, 32, 32) }); Slider.TrackBackgroundImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider track background design", designsTexture) { Borders = 14 * Vector4.One, Region = new RectangleF(207, 3, 32, 32) }); Slider.TrackForegroundImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider track foreground design", designsTexture) { Borders = 0 * Vector4.One, Region = new RectangleF(3, 37, 32, 32) }); Slider.ThumbImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider thumb design", designsTexture) { Borders = 4 * Vector4.One, Region = new RectangleF(37, 37, 16, 32) }); Slider.MouseOverThumbImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider thumb overred design", designsTexture) { Borders = 4 * Vector4.One, Region = new RectangleF(71, 37, 16, 32) }); Slider.TickImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider track foreground design", designsTexture) { Region = new RectangleF(245, 3, 3, 6) }); Slider.TickOffsetPropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(13f); Slider.TrackStartingOffsetsrPropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new Vector2(3)); }
/// <summary>Adds the given batch to the main linked list for processing.</summary> public void AddBatch(UIBatch batch) { if (FirstBatch == null) { FirstBatch = LastBatch = batch; } else { LastBatch = LastBatch.BatchAfter = batch; } }
public UIRenderer(IServiceRegistry services) : base(services) { game = (IGame)services.GetService(typeof(IGame)); uiSystem = (UISystem)services.GetService(typeof(UISystem)); batch = uiSystem.Batch; rendererManager = new RendererManager(new DefaultRenderersFactory(services)); DebugName = "UIRenderer"; }
/// <summary>Puts all batches of this renderer into the given unity layer.</summary> /// <param name="id">The ID of the unity layer.</param> public void RenderWithCamera(int id) { RenderLayer = id; // Set the layer of each batch: UIBatch current = FirstBatch; while (current != null) { current.RenderWithCamera(id); current = current.BatchAfter; } }
protected override void InitializeCore() { base.InitializeCore(); Name = "UIComponentRenderer"; game = (IGame)Services.GetService(typeof(IGame)); input = (InputManager)Services.GetService(typeof(InputManager)); uiSystem = (UISystem)Services.GetService(typeof(UISystem)); rendererManager = new RendererManager(new DefaultRenderersFactory(Services)); batch = uiSystem.Batch; }
protected override void InitializeCore() { base.InitializeCore(); Name = "UIComponentRenderer"; game = (IGame)RenderSystem.Services.GetService(typeof(IGame)); input = (InputManager)RenderSystem.Services.GetService(typeof(InputManager)); uiSystem = (UISystem)RenderSystem.Services.GetService(typeof(UISystem)); rendererManager = new RendererManager(new DefaultRenderersFactory(RenderSystem.Services)); batch = uiSystem.Batch; }
public MeshBlock Add(Renderman renderer) { // Allocate the block: MeshBlock block = renderer.CurrentBatch.Mesh.Allocate(renderer); if (Batch == null) { Batch = renderer.CurrentBatch; FirstBlockIndex = block.Buffer.BlocksBefore + block.BlockIndex; } BlockCount++; return(block); }
private UIBatch getFreeBatch(RenderDrawContext context) { if (GraphicsDevice.Platform == GraphicsPlatform.Vulkan) { if (batches.TryDequeue(out UIBatch batch) == false) { return(new UIBatch(context.GraphicsDevice, new UIRenderingContext(), new LayoutingContext())); } return(batch); } else { if (directXBatch == null) { directXBatch = new UIBatch(context.GraphicsDevice, new UIRenderingContext(), new LayoutingContext()); } return(directXBatch); } }
/// <summary>Resets all values in the renderer. Called before each layout.</summary> public void Reset() { Depth = 0f; MaxDepth = 0f; ViewportBackground = true; BatchDepth = RenderQueue; PositionedAncestors.Clear(); TransformedAncestors.Clear(); FlowRootAncestors.Clear(); ColorOverlay = Color.white; FontAliasingTop = InfiniText.Fonts.OutlineLocation + InfiniText.Fonts.Aliasing; FontAliasingBottom = InfiniText.Fonts.OutlineLocation - InfiniText.Fonts.Aliasing; BoxStack.Clear(); LastBlockBox = null; ResetBoundary(); DepthUsed = false; CurrentBatch = null; CurrentShaderSet = ShaderSet.Standard; FirstInformer = null; FirstLetter = null; FirstLine = null; if (Counters != null) { Counters.Clear(); } // Reapply screen viewport as the root one: Viewport = ScreenViewport; // Clean input grid: InputGrid.Clean(Viewport.Width, Viewport.Height); if (InWorldUI == null) { // This is the main UI renderer. // Clear the root node: Node = null; } }
protected override void InitializeCore() { base.InitializeCore(); Name = "UIComponentRenderer"; game = (IGame)RenderSystem.Services.GetService(typeof(IGame)); input = (InputManager)RenderSystem.Services.GetService(typeof(InputManager)); uiSystem = (UISystem)RenderSystem.Services.GetService(typeof(UISystem)); graphicsDeviceService = RenderSystem.Services.GetSafeServiceAs <IGraphicsDeviceService>(); if (uiSystem == null) { var gameSytems = RenderSystem.Services.GetServiceAs <IGameSystemCollection>(); uiSystem = new UISystem(RenderSystem.Services); gameSytems.Add(uiSystem); } rendererManager = new RendererManager(new DefaultRenderersFactory(RenderSystem.Services)); batch = uiSystem.Batch; }
protected override void InitializeCore() { base.InitializeCore(); Name = "UIComponentRenderer"; game = (IGame)RenderSystem.Services.GetService(typeof(IGame)); input = (InputManager)RenderSystem.Services.GetService(typeof(InputManager)); uiSystem = (UISystem)RenderSystem.Services.GetService(typeof(UISystem)); graphicsDeviceService = RenderSystem.Services.GetSafeServiceAs<IGraphicsDeviceService>(); if (uiSystem == null) { var gameSytems = RenderSystem.Services.GetServiceAs<IGameSystemCollection>(); uiSystem = new UISystem(RenderSystem.Services); gameSytems.Add(uiSystem); } rendererManager = new RendererManager(new DefaultRenderersFactory(RenderSystem.Services)); batch = uiSystem.Batch; }
protected override void LoadContent() { base.LoadContent(); // Create effects and geometric primitives Batch = new UIBatch(GraphicsDevice); // Create depth stencil states var depthStencilDescription = new DepthStencilStateDescription(depthEnable: true, depthWriteEnable: true) { StencilEnable = true, FrontFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, BackFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, }; KeepStencilValueState = depthStencilDescription; depthStencilDescription.FrontFace.StencilPass = StencilOperation.Increment; depthStencilDescription.BackFace.StencilPass = StencilOperation.Increment; IncreaseStencilValueState = depthStencilDescription; depthStencilDescription.FrontFace.StencilPass = StencilOperation.Decrement; depthStencilDescription.BackFace.StencilPass = StencilOperation.Decrement; DecreaseStencilValueState = depthStencilDescription; }
private void DrawBorder(Border border, ref Vector3 offsets, ref Vector3 borderSize, ref Color borderColor, UIRenderingContext context, UIBatch Batch) { var worldMatrix = border.WorldMatrixInternal; worldMatrix.M41 += worldMatrix.M11 * offsets.X + worldMatrix.M21 * offsets.Y + worldMatrix.M31 * offsets.Z; worldMatrix.M42 += worldMatrix.M12 * offsets.X + worldMatrix.M22 * offsets.Y + worldMatrix.M32 * offsets.Z; worldMatrix.M43 += worldMatrix.M13 * offsets.X + worldMatrix.M23 * offsets.Y + worldMatrix.M33 * offsets.Z; Batch.DrawCube(ref worldMatrix, ref borderSize, ref borderColor, context.DepthBias); }
public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch) { base.RenderColor(element, context, Batch); var button = (Button)element; var sprite = button.ButtonImage; if (sprite?.Texture == null) { return; } var color = element.RenderOpacity * Color.White; Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref element.RenderSizeInternal, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); }
protected override void LoadContent() { base.LoadContent(); // create effect and geometric primitives Batch = new UIBatch(GraphicsDevice); // create depth stencil states var depthStencilDescription = new DepthStencilStateDescription(true, true) { StencilEnable = true, FrontFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, BackFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, }; KeepStencilValueState = depthStencilDescription; depthStencilDescription.FrontFace.StencilPass = StencilOperation.Increment; depthStencilDescription.BackFace.StencilPass = StencilOperation.Increment; IncreaseStencilValueState = depthStencilDescription; depthStencilDescription.FrontFace.StencilPass = StencilOperation.Decrement; depthStencilDescription.BackFace.StencilPass = StencilOperation.Decrement; DecreaseStencilValueState = depthStencilDescription; // set the default design of the UI elements. var designsTexture = TextureExtensions.FromFileData(GraphicsDevice, DefaultDesigns.Designs); DefaultResourceDictionary = new ResourceDictionary { [typeof(Button)] = new Style(typeof(Button)) { Setters = { new Setter <ISpriteProvider>(Button.PressedImagePropertyKey, (SpriteFromTexture) new Sprite("Default button pressed design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(71, 3, 32, 32) }), new Setter <ISpriteProvider>(Button.NotPressedImagePropertyKey, (SpriteFromTexture) new Sprite("Default button not pressed design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(3, 3, 32, 32) }), new Setter <ISpriteProvider>(Button.MouseOverImagePropertyKey, (SpriteFromTexture) new Sprite("Default button overred design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(37, 3, 32, 32) }), } }, [typeof(EditText)] = new Style(typeof(EditText)) { Setters = { new Setter <ISpriteProvider>(EditText.ActiveImagePropertyKey, (SpriteFromTexture) new Sprite("Default edit active design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(105, 3, 32, 32) }), new Setter <ISpriteProvider>(EditText.InactiveImagePropertyKey, (SpriteFromTexture) new Sprite("Default edit inactive design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(139, 3, 32, 32) }), new Setter <ISpriteProvider>(EditText.MouseOverImagePropertyKey, (SpriteFromTexture) new Sprite("Default edit overred design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(173, 3, 32, 32) }), } }, [typeof(ToggleButton)] = new Style(typeof(ToggleButton)) { Setters = { new Setter <ISpriteProvider>(ToggleButton.CheckedImagePropertyKey, (SpriteFromTexture) new Sprite("Default toggle button checked design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(71, 3, 32, 32) }), new Setter <ISpriteProvider>(ToggleButton.UncheckedImagePropertyKey, (SpriteFromTexture) new Sprite("Default toggle button unchecked design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(3, 3, 32, 32) }), new Setter <ISpriteProvider>(ToggleButton.IndeterminateImagePropertyKey, (SpriteFromTexture) new Sprite("Default toggle button indeterminate design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(37, 3, 32, 32) }), } }, [typeof(Slider)] = new Style(typeof(Slider)) { Setters = { new Setter <ISpriteProvider>(Slider.TrackBackgroundImagePropertyKey, (SpriteFromTexture) new Sprite("Default slider track background design", designsTexture) { Borders = 14 * Vector4.One, Region = new RectangleF(207, 3, 32, 32) }), new Setter <ISpriteProvider>(Slider.TrackForegroundImagePropertyKey, (SpriteFromTexture) new Sprite("Default slider track foreground design", designsTexture) { Borders = 0 * Vector4.One, Region = new RectangleF(3, 37, 32, 32) }), new Setter <ISpriteProvider>(Slider.ThumbImagePropertyKey, (SpriteFromTexture) new Sprite("Default slider thumb design", designsTexture) { Borders = 4 * Vector4.One, Region = new RectangleF(37, 37, 16, 32) }), new Setter <ISpriteProvider>(Slider.MouseOverThumbImagePropertyKey, (SpriteFromTexture) new Sprite("Default slider thumb overred design", designsTexture) { Borders = 4 * Vector4.One, Region = new RectangleF(71, 37, 16, 32) }), new Setter <ISpriteProvider>(Slider.TickImagePropertyKey, (SpriteFromTexture) new Sprite("Default slider track foreground design", designsTexture) { Region = new RectangleF(245, 3, 3, 6) }), new Setter <float>(Slider.TickOffsetPropertyKey, 13f), new Setter <Vector2>(Slider.TrackStartingOffsetsrPropertyKey, new Vector2(3)), } }, }; }
public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch) { base.RenderColor(element, context, Batch); var slider = (Slider)element; if (slider.Orientation == Orientation.InDepth) { return; // No rendering for in-depth slider for the moment. } var axis = (int)slider.Orientation; var axisPrime = (axis + 1) % 2; var isGaugeReverted = axis == 1 ? !slider.IsDirectionReversed : slider.IsDirectionReversed; // we want the track going up from the bottom in vertical mode by default var sliderRatio = MathUtil.InverseLerp(slider.Minimum, slider.Maximum, slider.Value); var trackOffsets = new Vector2(slider.TrackStartingOffsets[axis], slider.TrackStartingOffsets[axisPrime]); var fullGaugeSize = slider.RenderSizeInternal[axis] - trackOffsets.X - trackOffsets.Y; var image = slider.TrackBackgroundImage?.GetSprite(); // draws the track background if (image?.Texture != null) { var imageAxis = (int)image.Orientation; var imageOrientation = (ImageOrientation)(axis ^ imageAxis); var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, (axis & imageAxis) == 1); Color tbt = slider.TrackBackgroundTint * slider.RenderOpacity; Batch.DrawImage(image.Texture, ref worldMatrix, ref image.RegionInternal, ref slider.RenderSizeInternal, ref image.BordersInternal, ref tbt, context.DepthBias, imageOrientation); context.DepthBias += 1; } // draw the track foreground image = slider.TrackForegroundImage?.GetSprite(); if (image?.Texture != null) { var imageAxis = (int)image.Orientation; var imageOrientation = (ImageOrientation)(axis ^ imageAxis); var shouldRotate180Degrees = (axis & imageAxis) == 1; var size = new Vector3(); size[axis] = sliderRatio * fullGaugeSize; size[axisPrime] = slider.TrackForegroundHeightScale * slider.RenderSizeInternal[axisPrime]; var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, shouldRotate180Degrees); var halfSizeLeft = (slider.RenderSizeInternal[axis] - size[axis]) / 2; var worldTranslation = GetAdjustedTranslation(isGaugeReverted ? halfSizeLeft - trackOffsets.Y : trackOffsets.X - halfSizeLeft, shouldRotate180Degrees); worldMatrix.M41 += worldTranslation * worldMatrix[(axis << 2) + 0]; worldMatrix.M42 += worldTranslation * worldMatrix[(axis << 2) + 1]; worldMatrix.M43 += worldTranslation * worldMatrix[(axis << 2) + 2]; var borders = image.BordersInternal; var borderStartIndex = (imageAxis) + (slider.IsDirectionReversed? 2 : 0); var borderStopIndex = (imageAxis) + (slider.IsDirectionReversed ? 0 : 2); borders[borderStartIndex] = Math.Min(borders[borderStartIndex], size[axis]); borders[borderStopIndex] = Math.Max(0, size[axis] - fullGaugeSize + borders[borderStopIndex]); var position = image.RegionInternal.Location; var oldRegionSize = new Vector2(image.RegionInternal.Width, image.RegionInternal.Height); var originalBordersSize = image.BordersInternal[borderStartIndex] + image.BordersInternal[borderStopIndex]; var newRegionSize = oldRegionSize; newRegionSize[imageAxis] = borders[borderStartIndex] + borders[borderStopIndex] + (oldRegionSize[imageAxis] - originalBordersSize) * Math.Min(1, (size[axis] - borders[borderStartIndex]) / (fullGaugeSize - originalBordersSize)); if (slider.IsDirectionReversed) { position[imageAxis] = position[imageAxis] + oldRegionSize[imageAxis] - newRegionSize[imageAxis]; } var region = new RectangleF(position.X, position.Y, newRegionSize.X, newRegionSize.Y); Color tft = slider.TrackForegroundTint * slider.RenderOpacity; Batch.DrawImage(image.Texture, ref worldMatrix, ref region, ref size, ref borders, ref tft, context.DepthBias, imageOrientation); context.DepthBias += 1; } // draws the ticks image = slider.TickImage?.GetSprite(); if (slider.AreTicksDisplayed && image?.Texture != null) { var imageAxis = (int)image.Orientation; var imageOrientation = (ImageOrientation)(axis ^ imageAxis); var shouldRotate180Degrees = (axis & imageAxis) == 1; var size = new Vector3(); size[axis] = slider.RenderSizeInternal[axis] * slider.TickWidthScale; size[axisPrime] = slider.RenderSizeInternal[axisPrime] * slider.TickHeightScale; var startOffset = new Vector2(GetAdjustedTranslation(slider.TickOffset, shouldRotate180Degrees)); startOffset[axis] = GetAdjustedTranslation(-fullGaugeSize / 2, shouldRotate180Degrees); var stepOffset = GetAdjustedTranslation(fullGaugeSize / slider.TickFrequency, shouldRotate180Degrees); var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, shouldRotate180Degrees); worldMatrix.M41 += startOffset[axis] * worldMatrix[(axis << 2) + 0] + startOffset[axisPrime] * worldMatrix[(axisPrime << 2) + 0]; worldMatrix.M42 += startOffset[axis] * worldMatrix[(axis << 2) + 1] + startOffset[axisPrime] * worldMatrix[(axisPrime << 2) + 1]; worldMatrix.M43 += startOffset[axis] * worldMatrix[(axis << 2) + 2] + startOffset[axisPrime] * worldMatrix[(axisPrime << 2) + 2]; Color tclr = slider.TickTint * slider.RenderOpacity; for (var i = 0; i < slider.TickFrequency + 1; i++) { Batch.DrawImage(image.Texture, ref worldMatrix, ref image.RegionInternal, ref size, ref image.BordersInternal, ref tclr, context.DepthBias, imageOrientation, SwizzleMode.None, true); worldMatrix.M41 += stepOffset * worldMatrix[(axis << 2) + 0]; worldMatrix.M42 += stepOffset * worldMatrix[(axis << 2) + 1]; worldMatrix.M43 += stepOffset * worldMatrix[(axis << 2) + 2]; } context.DepthBias += 1; } //draws the thumb image = (slider.MouseOverState == MouseOverState.MouseOverElement ? slider.MouseOverThumbImage : slider.ThumbImage)?.GetSprite(); if (image?.Texture != null) { var imageAxis = (int)image.Orientation; var imageOrientation = (ImageOrientation)(axis ^ imageAxis); var shouldRotate180Degrees = (axis & imageAxis) == 1; var size = new Vector3(); size[axis] = slider.RenderSizeInternal[axis] * slider.ThumbWidthScale; size[axisPrime] = slider.RenderSizeInternal[axisPrime] * slider.ThumbHeightScale; var revertedRatio = isGaugeReverted ? 1 - sliderRatio : sliderRatio; var offset = GetAdjustedTranslation((revertedRatio - 0.5f) * fullGaugeSize, shouldRotate180Degrees); var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, shouldRotate180Degrees); worldMatrix.M41 += offset * worldMatrix[(axis << 2) + 0]; worldMatrix.M42 += offset * worldMatrix[(axis << 2) + 1]; worldMatrix.M43 += offset * worldMatrix[(axis << 2) + 2]; Color tc = slider.ThumbTint * slider.RenderOpacity; Batch.DrawImage(image.Texture, ref worldMatrix, ref image.RegionInternal, ref size, ref image.BordersInternal, ref tc, context.DepthBias, imageOrientation); context.DepthBias += 1; } }
private void initUIElementStates(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, ref UIElementState[] uiElementStates, int index, int storeIndex, GameTime drawTime, List <PointerEvent> events, ulong posecount) { var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode; var renderNode = GetRenderNode(renderNodeReference); var renderElement = (RenderUIElement)renderNode.RenderObject; var uiElementState = new UIElementState(renderElement); uiElementStates[storeIndex] = uiElementState; var renderObject = uiElementState.RenderObject; var rootElement = renderObject.Page?.RootElement; if (rootElement != null) { UIBatch batch = getFreeBatch(context); var virtualResolution = renderObject.Resolution; var updatableRootElement = (IUIElementUpdate)rootElement; // update the UI element disposition rootElement.Measure(virtualResolution); rootElement.Arrange(virtualResolution, false); // calculate an estimate of the UI real size by projecting the element virtual resolution on the screen var virtualOrigin = uiElementState.WorldViewProjectionMatrix.Row4; var virtualWidth = new Vector4(virtualResolution.X / 2, 0, 0, 1); var virtualHeight = new Vector4(0, virtualResolution.Y / 2, 0, 1); var transformedVirtualWidth = Vector4.Zero; var transformedVirtualHeight = Vector4.Zero; for (var i = 0; i < 4; i++) { transformedVirtualWidth[i] = virtualWidth[0] * uiElementState.WorldViewProjectionMatrix[0 + i] + uiElementState.WorldViewProjectionMatrix[12 + i]; transformedVirtualHeight[i] = virtualHeight[1] * uiElementState.WorldViewProjectionMatrix[4 + i] + uiElementState.WorldViewProjectionMatrix[12 + i]; } var viewportSize = context.CommandList.Viewport.Size; var projectedOrigin = virtualOrigin.XY() / virtualOrigin.W; var projectedVirtualWidth = viewportSize * (transformedVirtualWidth.XY() / transformedVirtualWidth.W - projectedOrigin); var projectedVirtualHeight = viewportSize * (transformedVirtualHeight.XY() / transformedVirtualHeight.W - projectedOrigin); // Set default services rootElement.UIElementServices = new UIElementServices { Services = RenderSystem.Services }; // perform the time-based updates of the UI element updatableRootElement.Update(drawTime); // update the UI element hierarchical properties var rootMatrix = Matrix.Translation(-virtualResolution / 2); // UI world is translated by a half resolution compared to its quad, which is centered around the origin updatableRootElement.UpdateWorldMatrix(ref rootMatrix, rootMatrix != uiElementState.RenderObject.LastRootMatrix); updatableRootElement.UpdateElementState(0); uiElementState.RenderObject.LastRootMatrix = rootMatrix; // set default resource dictionary // update layouting context. var layoutingContext = batch.layoutingContext as LayoutingContext; layoutingContext.VirtualResolution = virtualResolution; layoutingContext.RealResolution = viewportSize; layoutingContext.RealVirtualResolutionRatio = new Vector2(projectedVirtualWidth.Length() / virtualResolution.X, projectedVirtualHeight.Length() / virtualResolution.Y); rootElement.LayoutingContext = layoutingContext; if (renderObject.IsFullScreen) { //var targetSize = viewportSize; var targetSize = new Vector2(context.CommandList.RenderTargets[0].Width, context.CommandList.RenderTargets[0].Height); // update the virtual resolution of the renderer switch (renderObject.ResolutionStretch) { case ResolutionStretch.FixedWidthAdaptableHeight: virtualResolution.Y = virtualResolution.X * targetSize.Y / targetSize.X; break; case ResolutionStretch.FixedHeightAdaptableWidth: virtualResolution.X = virtualResolution.Y * targetSize.X / targetSize.Y; break; case ResolutionStretch.AutoFit: float aspect = targetSize.X / targetSize.Y; float virtAspect = virtualResolution.X / virtualResolution.Y; if (aspect >= virtAspect) { goto case ResolutionStretch.FixedHeightAdaptableWidth; } goto case ResolutionStretch.FixedWidthAdaptableHeight; case ResolutionStretch.AutoShrink: if (targetSize.X < virtualResolution.X || targetSize.Y < virtualResolution.Y) { goto case ResolutionStretch.AutoFit; } else { virtualResolution.X = targetSize.X * targetSize.X / virtualResolution.X; virtualResolution.Y = targetSize.Y * targetSize.Y / virtualResolution.Y; } break; } uiElementState.Update(renderObject, virtualResolution); } else { CameraComponent cameraComponent = renderView.Camera as CameraComponent; if (cameraComponent != null) { uiElementState.Update(renderObject, cameraComponent.VerticalFieldOfView, ref renderView.View, ref renderView.Projection); } } if (renderObject.Source is UIComponent uic) { uic.RenderedResolution = virtualResolution; if (posecount == 0 || posecount != uic.VRPoseUpdate) { PickingUpdate(uiElementState.RenderObject, context.CommandList.Viewport, ref uiElementState.WorldViewProjectionMatrix, drawTime, events); uic.VRPoseUpdate = posecount; } } ReturnBatch(batch); } }
public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch) { base.RenderColor(element, context, Batch); var editText = (EditText)element; if (editText.Font == null) { return; } // determine the image to draw in background of the edit text var fontScale = element.LayoutingContext.RealVirtualResolutionRatio; var color = editText.RenderOpacity * Color.White; var provider = editText.IsSelectionActive ? editText.ActiveImage : editText.MouseOverState == MouseOverState.MouseOverElement ? editText.MouseOverImage : editText.InactiveImage; var image = provider?.GetSprite(); if (image?.Texture != null) { Batch.DrawImage(image.Texture, ref editText.WorldMatrixInternal, ref image.RegionInternal, ref editText.RenderSizeInternal, ref image.BordersInternal, ref color, context.DepthBias, image.Orientation); } // calculate the size of the text region by removing padding var textRegionSize = new Vector2(editText.ActualWidth - editText.Padding.Left - editText.Padding.Right, editText.ActualHeight - editText.Padding.Top - editText.Padding.Bottom); var font = editText.Font; var caretColor = editText.RenderOpacity * editText.CaretColor; var offsetTextStart = 0f; var offsetAlignment = 0f; var selectionSize = 0f; // Draw the composition selection if (editText.Composition.Length > 0) { var imeSelectionColor = editText.RenderOpacity * editText.IMESelectionColor; RenderSelection(editText, context, editText.SelectionStart, editText.Composition.Length, imeSelectionColor, out offsetTextStart, out offsetAlignment, out selectionSize, Batch); } // Draw the regular selection else if (editText.IsSelectionActive) { var selectionColor = editText.RenderOpacity * editText.SelectionColor; RenderSelection(editText, context, editText.SelectionStart, editText.SelectionLength, selectionColor, out offsetTextStart, out offsetAlignment, out selectionSize, Batch); } // create the text draw command var drawCommand = new SpriteFont.InternalUIDrawCommand { Color = editText.RenderOpacity * editText.TextColor, DepthBias = context.DepthBias + 2, RealVirtualResolutionRatio = fontScale, RequestedFontSize = editText.ActualTextSize, Batch = Batch, SnapText = context.ShouldSnapText && !editText.DoNotSnapText, Matrix = editText.WorldMatrixInternal, Alignment = editText.TextAlignment, TextBoxSize = textRegionSize }; if (editText.Font.FontType == SpriteFontType.SDF) { Batch.End(); Batch.BeginCustom(context.GraphicsContext, 1); } // Draw the text Batch.DrawString(font, editText.TextToDisplay, ref drawCommand); if (editText.Font.FontType == SpriteFontType.SDF) { Batch.End(); Batch.BeginCustom(context.GraphicsContext, 0); } // Draw the cursor if (editText.IsCaretVisible) { var lineSpacing = editText.Font.GetTotalLineSpacing(editText.ActualTextSize); if (editText.Font.FontType != SpriteFontType.Dynamic) { lineSpacing *= editText.ActualTextSize / font.Size; } var sizeCaret = editText.CaretWidth / fontScale.X; var caretWorldMatrix = element.WorldMatrixInternal; caretWorldMatrix.M41 += offsetTextStart + offsetAlignment + (editText.CaretPosition > editText.SelectionStart? selectionSize: 0); var caretScaleVector = new Vector3(sizeCaret, editText.LineCount * lineSpacing, 0); Batch.DrawRectangle(ref caretWorldMatrix, ref caretScaleVector, ref caretColor, context.DepthBias + 3); } }
public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch) { base.RenderColor(element, context, Batch); var image = (ImageElement)element; var sprite = image.Source?.GetSprite(); if (sprite?.Texture == null) { return; } float finalOpacity = element.RenderOpacity * image.Tint.A; var color = new Color4(image.Tint.R * finalOpacity, image.Tint.G * finalOpacity, image.Tint.B * finalOpacity, finalOpacity); Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref element.RenderSizeInternal, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); }
protected override void LoadContent() { base.LoadContent(); // create effect and geometric primitives Batch = new UIBatch(GraphicsDevice); // create depth stencil states var depthStencilDescription = new DepthStencilStateDescription(true, true) { StencilEnable = true, FrontFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, BackFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, }; KeepStencilValueState = DepthStencilState.New(GraphicsDevice, depthStencilDescription); depthStencilDescription.FrontFace.StencilPass = StencilOperation.Increment; depthStencilDescription.BackFace.StencilPass = StencilOperation.Increment; IncreaseStencilValueState = DepthStencilState.New(GraphicsDevice, depthStencilDescription); depthStencilDescription.FrontFace.StencilPass = StencilOperation.Decrement; depthStencilDescription.BackFace.StencilPass = StencilOperation.Decrement; DecreaseStencilValueState = DepthStencilState.New(GraphicsDevice, depthStencilDescription); // set the default design of the UI elements. var designsTexture = TextureExtensions.CreateTextureFromFileData(GraphicsDevice, DefaultDesigns.Designs); Button.PressedImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default button pressed design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(71, 3, 32, 32) }); Button.NotPressedImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default button not pressed design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(3, 3, 32, 32) }); Button.MouseOverImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default button overred design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(37, 3, 32, 32) }); EditText.ActiveImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default edit active design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(105, 3, 32, 32) }); EditText.InactiveImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default edit inactive design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(139, 3, 32, 32) }); EditText.MouseOverImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default edit overred design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(173, 3, 32, 32) }); ToggleButton.CheckedImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default toggle button checked design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(71, 3, 32, 32) }); ToggleButton.UncheckedImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default toggle button unchecked design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(3, 3, 32, 32) }); ToggleButton.IndeterminateImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default toggle button indeterminate design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(37, 3, 32, 32) }); Slider.TrackBackgroundImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider track background design", designsTexture) { Borders = 14 * Vector4.One, Region = new RectangleF(207, 3, 32, 32) }); Slider.TrackForegroundImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider track foreground design", designsTexture) { Borders = 0 * Vector4.One, Region = new RectangleF(3, 37, 32, 32) }); Slider.ThumbImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider thumb design", designsTexture) { Borders = 4 * Vector4.One, Region = new RectangleF(37, 37, 16, 32) }); Slider.MouseOverThumbImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider thumb overred design", designsTexture) { Borders = 4 * Vector4.One, Region = new RectangleF(71, 37, 16, 32) }); Slider.TickImagePropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new UIImage("Default slider track foreground design", designsTexture) { Region = new RectangleF(245, 3, 3, 6) }); Slider.TickOffsetPropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(13f); Slider.TrackStartingOffsetsrPropertyKey.DefaultValueMetadata = DefaultValueMetadata.Static(new Vector2(3)); }
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); } }
/// <summary>Sets up the current batch based on the isolation settings requested by a property.</summary> /// <param name="property">The displayable property which wants the batch.</param> /// <param name="fontTexture">The font texture to use with this batch.</param> public void SetupBatch(DisplayableProperty property, TextureAtlas graphics, TextureAtlas font) { if (property.Isolated) { if (property.GotBatchAlready) { // The property already got a batch on this layout - it doesn't need another. return; } // Isolated properties always get a new batch every time. CurrentBatch = UIBatchPool.Get(this); if (CurrentBatch == null) { CurrentBatch = new UIBatch(this); } property.GotBatchAlready = true; // And push it to the active stack: AddBatch(CurrentBatch); // Make sure it knows it's isolated: CurrentBatch.IsIsolated(property); } else { if (CurrentBatch != null && !CurrentBatch.Isolated) { // Re-use existing batch? if (font != null) { if (CurrentBatch.FontAtlas == null) { // Didn't have one assigned before. Assign now: CurrentBatch.SetFontAtlas(font); } else if (font != CurrentBatch.FontAtlas) { // Font atlas changed. Can't share. CurrentBatch = null; } } if (graphics != null) { if (CurrentBatch.GraphicsAtlas == null) { // Didn't have one assigned before. Assign now: CurrentBatch.SetGraphicsAtlas(graphics); } else if (graphics != CurrentBatch.GraphicsAtlas) { // Atlas changed. Can't share. CurrentBatch = null; } } if (CurrentBatch != null) { // Yep - reuse it. return; } } // Pull a batch from the pool and set it to currentbatch. May need to generate a new one. CurrentBatch = UIBatchPool.Get(this); if (CurrentBatch == null) { CurrentBatch = new UIBatch(this); } // And push it to the active stack: AddBatch(CurrentBatch); // Make sure it knows it's not isolated: CurrentBatch.NotIsolated(graphics, font); } // Finally, prepare it for layout: CurrentBatch.PrepareForLayout(); }
/// <summary> /// Render the provided <see cref="UIElement"/>. /// </summary> /// <param name="element">The element to render.</param> /// <param name="context">The rendering context containing information how to draw the element.</param> /// <remarks>The render target, the depth stencil buffer and the depth stencil state are already correctly set when entering this function. /// If the user wants to perform some intermediate rendering, it is his responsibility to bind them back correctly before the final rendering.</remarks> public virtual void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch) { var backgroundColor = element.RenderOpacity * element.BackgroundColor; // pass the 3D matrix onto the element for picking element.WorldMatrix3D = context.IsFullscreen ? (Matrix?)null : context.WorldMatrix3D; // optimization: don't draw the background if transparent if (backgroundColor.A == (byte)0) { return; } // Default implementation: render an back-face cube with background color Batch.DrawBackground(ref element.WorldMatrixInternal, ref element.RenderSizeInternal, ref backgroundColor, context.DepthBias); // increase depth bias value so that next elements renders on top of it. context.DepthBias += 1; }
/// <summary> /// Render the clipping region of the provided <see cref="UIElement"/>. /// </summary> /// <param name="element">The element to render.</param> /// <param name="context">The rendering context containing information how to draw the element.</param> /// <remarks>The render target, the depth stencil buffer and the depth stencil state are already correctly set when entering this function. /// If the user wants to perform some intermediate rendering, it is his responsibility to bind them back correctly before the final rendering.</remarks> public virtual void RenderClipping(UIElement element, UIRenderingContext context, UIBatch Batch) { // Default implementation: render an back-face cube Batch.DrawBackground(ref element.WorldMatrixInternal, ref element.RenderSizeInternal, ref blackColor, context.DepthBias); // increase the context depth bias for next elements. context.DepthBias += 1; }
public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch) { base.RenderColor(element, context, Batch); Vector3 offsets; Vector3 borderSize; var border = (Border)element; var borderColor = border.RenderOpacity * border.BorderColorInternal; // optimization: don't draw the border if transparent if (borderColor == new Color()) { return; } var borderThickness = border.BorderThickness; var elementHalfBorders = borderThickness / 2; var elementSize = element.RenderSizeInternal; var elementHalfSize = elementSize / 2; // left/front offsets = new Vector3(-elementHalfSize.X + elementHalfBorders.Left, 0, -elementHalfSize.Z + elementHalfBorders.Front); borderSize = new Vector3(borderThickness.Left, elementSize.Y, borderThickness.Front); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // right/front offsets = new Vector3(elementHalfSize.X - elementHalfBorders.Right, 0, -elementHalfSize.Z + elementHalfBorders.Front); borderSize = new Vector3(borderThickness.Right, elementSize.Y, borderThickness.Front); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // top/front offsets = new Vector3(0, -elementHalfSize.Y + elementHalfBorders.Top, -elementHalfSize.Z + elementHalfBorders.Front); borderSize = new Vector3(elementSize.X, borderThickness.Top, borderThickness.Front); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // bottom/front offsets = new Vector3(0, elementHalfSize.Y - elementHalfBorders.Bottom, -elementHalfSize.Z + elementHalfBorders.Front); borderSize = new Vector3(elementSize.X, borderThickness.Bottom, borderThickness.Back); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // if the element is 3D draw the extra borders if (element.ActualDepth > MathUtil.ZeroTolerance) { // left/back offsets = new Vector3(-elementHalfSize.X + elementHalfBorders.Left, 0, elementHalfSize.Z - elementHalfBorders.Back); borderSize = new Vector3(borderThickness.Left, elementSize.Y, borderThickness.Back); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // right/back offsets = new Vector3(elementHalfSize.X - elementHalfBorders.Right, 0, elementHalfSize.Z - elementHalfBorders.Back); borderSize = new Vector3(borderThickness.Right, elementSize.Y, borderThickness.Back); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // top/back offsets = new Vector3(0, -elementHalfSize.Y + elementHalfBorders.Top, elementHalfSize.Z - elementHalfBorders.Back); borderSize = new Vector3(elementSize.X, borderThickness.Top, borderThickness.Back); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // bottom/back offsets = new Vector3(0, elementHalfSize.Y - elementHalfBorders.Bottom, elementHalfSize.Z - elementHalfBorders.Back); borderSize = new Vector3(elementSize.X, borderThickness.Bottom, borderThickness.Back); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // left/top offsets = new Vector3(-elementHalfSize.X + elementHalfBorders.Left, -elementHalfSize.Y + elementHalfBorders.Top, 0); borderSize = new Vector3(borderThickness.Left, borderThickness.Top, elementSize.Z); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // right/top offsets = new Vector3(elementHalfSize.X - elementHalfBorders.Right, -elementHalfSize.Y + elementHalfBorders.Top, 0); borderSize = new Vector3(borderThickness.Right, borderThickness.Top, elementSize.Z); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // left/bottom offsets = new Vector3(-elementHalfSize.X + elementHalfBorders.Left, elementHalfSize.Y - elementHalfBorders.Bottom, 0); borderSize = new Vector3(borderThickness.Left, borderThickness.Bottom, elementSize.Z); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, Batch); // right/bottom offsets = new Vector3(elementHalfSize.X - elementHalfBorders.Right, elementHalfSize.Y - elementHalfBorders.Bottom, 0); borderSize = new Vector3(borderThickness.Right, borderThickness.Bottom, elementSize.Z); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context, 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); }
public ThumbnailGenerator(EffectCompilerBase effectCompiler) { // create base services Services = new ServiceRegistry(); Services.AddService(MicrothreadLocalDatabases.ProviderService); ContentManager = new ContentManager(Services); Services.AddService <IContentManager>(ContentManager); Services.AddService(ContentManager); GraphicsDevice = GraphicsDevice.New(); GraphicsContext = new GraphicsContext(GraphicsDevice); GraphicsCommandList = GraphicsContext.CommandList; Services.AddService(GraphicsContext); sceneSystem = new SceneSystem(Services); Services.AddService(sceneSystem); fontSystem = new GameFontSystem(Services); Services.AddService(fontSystem.FontSystem); Services.AddService <IFontFactory>(fontSystem.FontSystem); GraphicsDeviceService = new GraphicsDeviceServiceLocal(Services, GraphicsDevice); Services.AddService(GraphicsDeviceService); var uiSystem = new UISystem(Services); Services.AddService(uiSystem); var physicsSystem = new Bullet2PhysicsSystem(Services); Services.AddService <IPhysicsSystem>(physicsSystem); gameSystems = new GameSystemCollection(Services) { fontSystem, uiSystem, physicsSystem }; Services.AddService <IGameSystemCollection>(gameSystems); Simulation.DisableSimulation = true; //make sure we do not simulate physics within the editor // initialize base services gameSystems.Initialize(); // create remaining services EffectSystem = new EffectSystem(Services); Services.AddService(EffectSystem); gameSystems.Add(EffectSystem); gameSystems.Add(sceneSystem); EffectSystem.Initialize(); // Mount the same database for the cache EffectSystem.Compiler = EffectCompilerFactory.CreateEffectCompiler(effectCompiler.FileProvider, EffectSystem); // Deactivate the asynchronous effect compilation ((EffectCompilerCache)EffectSystem.Compiler).CompileEffectAsynchronously = false; // load game system content gameSystems.LoadContent(); // create the default fonts var fontItem = OfflineRasterizedSpriteFontFactory.Create(); fontItem.FontType.Size = 22; DefaultFont = OfflineRasterizedFontCompiler.Compile(fontSystem.FontSystem, fontItem, true); // create utility members nullGameTime = new GameTime(); SpriteBatch = new SpriteBatch(GraphicsDevice); UIBatch = new UIBatch(GraphicsDevice); // create the pipeline SetUpPipeline(); }
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); } }
private void RenderSelection(EditText editText, UIRenderingContext context, int start, int length, Color color, out float offsetTextStart, out float offsetAlignment, out float selectionSize, UIBatch Batch) { // calculate the size of the text region by removing padding var textRegionSize = new Vector2(editText.ActualWidth - editText.Padding.Left - editText.Padding.Right, editText.ActualHeight - editText.Padding.Top - editText.Padding.Bottom); var font = editText.Font; // determine the image to draw in background of the edit text var fontScale = editText.LayoutingContext.RealVirtualResolutionRatio; var provider = editText.IsSelectionActive ? editText.ActiveImage : editText.MouseOverState == MouseOverState.MouseOverElement ? editText.MouseOverImage : editText.InactiveImage; var image = provider?.GetSprite(); var fontSize = new Vector2(fontScale.Y * editText.ActualTextSize); offsetTextStart = font.MeasureString(editText.TextToDisplay, ref fontSize, start).X; selectionSize = font.MeasureString(editText.TextToDisplay, ref fontSize, start + length).X - offsetTextStart; var lineSpacing = font.GetTotalLineSpacing(editText.ActualTextSize); if (font.FontType == SpriteFontType.Dynamic) { offsetTextStart /= fontScale.X; selectionSize /= fontScale.X; } var scaleRatio = editText.ActualTextSize / font.Size; if (font.FontType != SpriteFontType.Dynamic) { offsetTextStart *= scaleRatio; selectionSize *= scaleRatio; lineSpacing *= editText.ActualTextSize / font.Size; } offsetAlignment = -textRegionSize.X / 2f; if (editText.TextAlignment != TextAlignment.Left) { var textWidth = font.MeasureString(editText.TextToDisplay, ref fontSize).X; if (font.FontType == SpriteFontType.Dynamic) { textWidth /= fontScale.X; } else { textWidth *= scaleRatio; } offsetAlignment = editText.TextAlignment == TextAlignment.Center ? -textWidth / 2 : -textRegionSize.X / 2f + (textRegionSize.X - textWidth); } var selectionWorldMatrix = editText.WorldMatrixInternal; selectionWorldMatrix.M41 += offsetTextStart + selectionSize / 2 + offsetAlignment; var selectionScaleVector = new Vector3(selectionSize, editText.LineCount * lineSpacing, 0); Batch.DrawRectangle(ref selectionWorldMatrix, ref selectionScaleVector, ref color, context.DepthBias + 1); }
public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch) { base.RenderColor(element, context, Batch); var toggleButton = (ToggleButton)element; var sprite = GetToggleStateImage(toggleButton); if (sprite?.Texture == null) { return; } var color = new Color4(toggleButton.RenderOpacity); Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref element.RenderSizeInternal, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); }
protected override void LoadContent() { base.LoadContent(); // create effect and geometric primitives Batch = new UIBatch(GraphicsDevice); // create depth stencil states var depthStencilDescription = new DepthStencilStateDescription(true, true) { StencilEnable = true, FrontFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, BackFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Keep, StencilFunction = CompareFunction.Equal }, }; KeepStencilValueState = depthStencilDescription; depthStencilDescription.FrontFace.StencilPass = StencilOperation.Increment; depthStencilDescription.BackFace.StencilPass = StencilOperation.Increment; IncreaseStencilValueState = depthStencilDescription; depthStencilDescription.FrontFace.StencilPass = StencilOperation.Decrement; depthStencilDescription.BackFace.StencilPass = StencilOperation.Decrement; DecreaseStencilValueState = depthStencilDescription; // set the default design of the UI elements. var designsTexture = TextureExtensions.FromFileData(GraphicsDevice, DefaultDesigns.Designs); DefaultResourceDictionary = new ResourceDictionary { [typeof(Button)] = new Style(typeof(Button)) { Setters = { new Setter<ISpriteProvider>(Button.PressedImagePropertyKey, (SpriteFromTexture)new Sprite("Default button pressed design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(71, 3, 32, 32) }), new Setter<ISpriteProvider>(Button.NotPressedImagePropertyKey, (SpriteFromTexture)new Sprite("Default button not pressed design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(3, 3, 32, 32) }), new Setter<ISpriteProvider>(Button.MouseOverImagePropertyKey, (SpriteFromTexture)new Sprite("Default button overred design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(37, 3, 32, 32) }), } }, [typeof(EditText)] = new Style(typeof(EditText)) { Setters = { new Setter<ISpriteProvider>(EditText.ActiveImagePropertyKey, (SpriteFromTexture)new Sprite("Default edit active design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(105, 3, 32, 32) }), new Setter<ISpriteProvider>(EditText.InactiveImagePropertyKey, (SpriteFromTexture)new Sprite("Default edit inactive design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(139, 3, 32, 32) }), new Setter<ISpriteProvider>(EditText.MouseOverImagePropertyKey, (SpriteFromTexture)new Sprite("Default edit overred design", designsTexture) { Borders = 12 * Vector4.One, Region = new RectangleF(173, 3, 32, 32) }), } }, [typeof(ToggleButton)] = new Style(typeof(ToggleButton)) { Setters = { new Setter<ISpriteProvider>(ToggleButton.CheckedImagePropertyKey, (SpriteFromTexture)new Sprite("Default toggle button checked design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(71, 3, 32, 32) }), new Setter<ISpriteProvider>(ToggleButton.UncheckedImagePropertyKey, (SpriteFromTexture)new Sprite("Default toggle button unchecked design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(3, 3, 32, 32) }), new Setter<ISpriteProvider>(ToggleButton.IndeterminateImagePropertyKey, (SpriteFromTexture)new Sprite("Default toggle button indeterminate design", designsTexture) { Borders = 8 * Vector4.One, Region = new RectangleF(37, 3, 32, 32) }), } }, [typeof(Slider)] = new Style(typeof(Slider)) { Setters = { new Setter<ISpriteProvider>(Slider.TrackBackgroundImagePropertyKey, (SpriteFromTexture)new Sprite("Default slider track background design", designsTexture) { Borders = 14 * Vector4.One, Region = new RectangleF(207, 3, 32, 32) }), new Setter<ISpriteProvider>(Slider.TrackForegroundImagePropertyKey, (SpriteFromTexture)new Sprite("Default slider track foreground design", designsTexture) { Borders = 0 * Vector4.One, Region = new RectangleF(3, 37, 32, 32) }), new Setter<ISpriteProvider>(Slider.ThumbImagePropertyKey, (SpriteFromTexture)new Sprite("Default slider thumb design", designsTexture) { Borders = 4 * Vector4.One, Region = new RectangleF(37, 37, 16, 32) }), new Setter<ISpriteProvider>(Slider.MouseOverThumbImagePropertyKey, (SpriteFromTexture)new Sprite("Default slider thumb overred design", designsTexture) { Borders = 4 * Vector4.One, Region = new RectangleF(71, 37, 16, 32) }), new Setter<ISpriteProvider>(Slider.TickImagePropertyKey, (SpriteFromTexture)new Sprite("Default slider track foreground design", designsTexture) { Region = new RectangleF(245, 3, 3, 6) }), new Setter<float>(Slider.TickOffsetPropertyKey, 13f), new Setter<Vector2>(Slider.TrackStartingOffsetsrPropertyKey, new Vector2(3)), } }, }; }
public override void RenderColor(UIElement element, UIRenderingContext context, UIBatch Batch) { base.RenderColor(element, context, Batch); var bar = (ScrollBar)element; // round the size of the bar to nearest pixel modulo to avoid to have a bar varying by one pixel length while scrolling var barSize = bar.RenderSizeInternal; var realVirtualRatio = bar.LayoutingContext.RealVirtualResolutionRatio; for (var i = 0; i < 2; i++) { barSize[i] = (float)(Math.Ceiling(barSize[i] * realVirtualRatio[i]) / realVirtualRatio[i]); } Batch.DrawRectangle(ref element.WorldMatrixInternal, ref barSize, ref bar.BarColorInternal, context.DepthBias); }