private void OnGenerateVisualContent(MeshGenerationContext mgc) { if (image == null && sprite == null && vectorImage == null) { return; } var alignedRect = GUIUtility.AlignRectToDevice(contentRect); var rectParams = new MeshGenerationContextUtils.RectangleParams(); if (image != null) { rectParams = MeshGenerationContextUtils.RectangleParams.MakeTextured(alignedRect, uv, image, scaleMode, panel.contextType); } else if (sprite != null) { var slices = Vector4.zero; rectParams = MeshGenerationContextUtils.RectangleParams.MakeSprite(alignedRect, sprite, scaleMode, panel.contextType, false, ref slices); } else if (vectorImage != null) { rectParams = MeshGenerationContextUtils.RectangleParams.MakeVectorTextured(alignedRect, uv, vectorImage, scaleMode, panel.contextType); } rectParams.color = tintColor; mgc.Rectangle(rectParams); }
public void DrawVisualElementBorder() { bool flag = this.currentElement.layout.width >= Mathf.Epsilon && this.currentElement.layout.height >= Mathf.Epsilon; if (flag) { ComputedStyle computedStyle = this.currentElement.computedStyle; bool flag2 = (computedStyle.borderLeftColor != Color.clear && computedStyle.borderLeftWidth.value > 0f) || (computedStyle.borderTopColor != Color.clear && computedStyle.borderTopWidth.value > 0f) || (computedStyle.borderRightColor != Color.clear && computedStyle.borderRightWidth.value > 0f) || (computedStyle.borderBottomColor != Color.clear && computedStyle.borderBottomWidth.value > 0f); if (flag2) { MeshGenerationContextUtils.BorderParams borderParams = new MeshGenerationContextUtils.BorderParams { rect = GUIUtility.AlignRectToDevice(this.currentElement.rect), leftColor = computedStyle.borderLeftColor.value, topColor = computedStyle.borderTopColor.value, rightColor = computedStyle.borderRightColor.value, bottomColor = computedStyle.borderBottomColor.value, leftWidth = computedStyle.borderLeftWidth.value, topWidth = computedStyle.borderTopWidth.value, rightWidth = computedStyle.borderRightWidth.value, bottomWidth = computedStyle.borderBottomWidth.value, playmodeTintColor = ((this.currentElement.panel.contextType == ContextType.Editor) ? UIElementsUtility.editorPlayModeTintColor : Color.white) }; MeshGenerationContextUtils.GetVisualElementRadii(this.currentElement, out borderParams.topLeftRadius, out borderParams.bottomLeftRadius, out borderParams.topRightRadius, out borderParams.bottomRightRadius); this.DrawBorder(borderParams); } } }
// Helper function: Get all mouse rects private static Rect[] CalcMouseRects(Rect position, GUIContent[] contents, int xCount, float elemWidth, float elemHeight, GUIStyle style, GUIStyle firstStyle, GUIStyle midStyle, GUIStyle lastStyle, bool addBorders, GUI.ToolbarButtonSize buttonSize) { int count = contents.Length; int x = 0; float xPos = position.xMin, yPos = position.yMin; GUIStyle currentStyle = style; Rect[] retval = new Rect[count]; if (count > 1) { currentStyle = firstStyle; } for (int i = 0; i < count; i++) { float w = 0; switch (buttonSize) { case GUI.ToolbarButtonSize.Fixed: w = elemWidth; break; case GUI.ToolbarButtonSize.FitToContents: w = currentStyle.CalcSize(contents[i]).x; break; } if (!addBorders) { retval[i] = new Rect(xPos, yPos, w, elemHeight); } else { retval[i] = currentStyle.margin.Add(new Rect(xPos, yPos, w, elemHeight)); } //we round the values to the dpi-aware pixel grid retval[i] = GUIUtility.AlignRectToDevice(retval[i]); GUIStyle nextStyle = midStyle; if (i == count - 2 || i == xCount - 2) { nextStyle = lastStyle; } xPos = retval[i].xMax + Mathf.Max(currentStyle.margin.right, nextStyle.margin.left); x++; if (x >= xCount) { x = 0; yPos += elemHeight + Mathf.Max(style.margin.top, style.margin.bottom); xPos = position.xMin; nextStyle = firstStyle; } currentStyle = nextStyle; } return(retval); }
private void GenerateStencilClipEntryForRoundedRectBackground() { bool flag = this.currentElement.layout.width <= Mathf.Epsilon || this.currentElement.layout.height <= Mathf.Epsilon; if (!flag) { ComputedStyle computedStyle = this.currentElement.computedStyle; Vector2 a; Vector2 a2; Vector2 a3; Vector2 a4; MeshGenerationContextUtils.GetVisualElementRadii(this.currentElement, out a, out a2, out a3, out a4); float value = computedStyle.borderTopWidth.value; float value2 = computedStyle.borderLeftWidth.value; float value3 = computedStyle.borderBottomWidth.value; float value4 = computedStyle.borderRightWidth.value; MeshGenerationContextUtils.RectangleParams rectParams = new MeshGenerationContextUtils.RectangleParams { rect = GUIUtility.AlignRectToDevice(this.currentElement.rect), color = Color.white, topLeftRadius = Vector2.Max(Vector2.zero, a - new Vector2(value2, value)), topRightRadius = Vector2.Max(Vector2.zero, a3 - new Vector2(value4, value)), bottomLeftRadius = Vector2.Max(Vector2.zero, a2 - new Vector2(value2, value3)), bottomRightRadius = Vector2.Max(Vector2.zero, a4 - new Vector2(value4, value3)), playmodeTintColor = ((this.currentElement.panel.contextType == ContextType.Editor) ? UIElementsUtility.editorPlayModeTintColor : Color.white) }; rectParams.rect.x = rectParams.rect.x + value2; rectParams.rect.y = rectParams.rect.y + value; rectParams.rect.width = rectParams.rect.width - (value2 + value4); rectParams.rect.height = rectParams.rect.height - (value + value3); bool flag2 = computedStyle.unityOverflowClipBox == OverflowClipBox.ContentBox; if (flag2) { rectParams.rect.x = rectParams.rect.x + computedStyle.paddingLeft.value.value; rectParams.rect.y = rectParams.rect.y + computedStyle.paddingTop.value.value; rectParams.rect.width = rectParams.rect.width - (computedStyle.paddingLeft.value.value + computedStyle.paddingRight.value.value); rectParams.rect.height = rectParams.rect.height - (computedStyle.paddingTop.value.value + computedStyle.paddingBottom.value.value); } this.m_CurrentEntry.clipRectID = this.m_ClipRectID; this.m_CurrentEntry.isStencilClipped = this.m_StencilClip; this.m_CurrentEntry.isClipRegisterEntry = true; MeshBuilder.MakeSolidRect(rectParams, 1f, new MeshBuilder.AllocMeshData { alloc = this.m_AllocRawVertsIndicesDelegate }); bool flag3 = this.m_CurrentEntry.vertices.Length > 0 && this.m_CurrentEntry.indices.Length > 0; if (flag3) { this.m_Entries.Add(this.m_CurrentEntry); this.totalVertices += this.m_CurrentEntry.vertices.Length; this.totalIndices += this.m_CurrentEntry.indices.Length; this.m_StencilClip = true; this.m_ClosingInfo.needsClosing = true; } this.m_CurrentEntry = default(UIRStylePainter.Entry); } }
public static RectStylePainterParameters GetDefault(VisualElement ve) { ComputedStyle style = ve.computedStyle; var painterParams = new RectStylePainterParameters { rect = GUIUtility.AlignRectToDevice(ve.rect), color = style.backgroundColor.value, }; BorderParameters.SetFromStyle(ref painterParams.border, style); return(painterParams); }
void OnGUI() { if (consoleOpen) { if (Event.current.keyCode == toggleKey) { GUIUtility.keyboardControl = 0; } ApplySkins(); consoleRect = GUIUtility.AlignRectToDevice(consoleRect); consoleRect = GUI.Window(0, consoleRect, OnWindow, ""); } }
public void DrawVisualElementBackground() { bool flag = this.currentElement.layout.width <= Mathf.Epsilon || this.currentElement.layout.height <= Mathf.Epsilon; if (!flag) { ComputedStyle computedStyle = this.currentElement.computedStyle; bool flag2 = computedStyle.backgroundColor != Color.clear; if (flag2) { MeshGenerationContextUtils.RectangleParams rectParams = new MeshGenerationContextUtils.RectangleParams { rect = GUIUtility.AlignRectToDevice(this.currentElement.rect), color = computedStyle.backgroundColor.value, playmodeTintColor = ((this.currentElement.panel.contextType == ContextType.Editor) ? UIElementsUtility.editorPlayModeTintColor : Color.white) }; MeshGenerationContextUtils.GetVisualElementRadii(this.currentElement, out rectParams.topLeftRadius, out rectParams.bottomLeftRadius, out rectParams.topRightRadius, out rectParams.bottomRightRadius); this.DrawRectangle(rectParams); } Background value = computedStyle.backgroundImage.value; bool flag3 = value.texture != null || value.vectorImage != null; if (flag3) { MeshGenerationContextUtils.RectangleParams rectParams2 = default(MeshGenerationContextUtils.RectangleParams); bool flag4 = value.texture != null; if (flag4) { rectParams2 = MeshGenerationContextUtils.RectangleParams.MakeTextured(GUIUtility.AlignRectToDevice(this.currentElement.rect), new Rect(0f, 0f, 1f, 1f), value.texture, computedStyle.unityBackgroundScaleMode.value, this.currentElement.panel.contextType); } else { bool flag5 = value.vectorImage != null; if (flag5) { rectParams2 = MeshGenerationContextUtils.RectangleParams.MakeVectorTextured(GUIUtility.AlignRectToDevice(this.currentElement.rect), new Rect(0f, 0f, 1f, 1f), value.vectorImage, computedStyle.unityBackgroundScaleMode.value, this.currentElement.panel.contextType); } } MeshGenerationContextUtils.GetVisualElementRadii(this.currentElement, out rectParams2.topLeftRadius, out rectParams2.bottomLeftRadius, out rectParams2.topRightRadius, out rectParams2.bottomRightRadius); rectParams2.leftSlice = computedStyle.unitySliceLeft.value; rectParams2.topSlice = computedStyle.unitySliceTop.value; rectParams2.rightSlice = computedStyle.unitySliceRight.value; rectParams2.bottomSlice = computedStyle.unitySliceBottom.value; bool flag6 = computedStyle.unityBackgroundImageTintColor != Color.clear; if (flag6) { rectParams2.color = computedStyle.unityBackgroundImageTintColor.value; } this.DrawRectangle(rectParams2); } } }
public static TextureStylePainterParameters GetDefault(VisualElement ve) { ComputedStyle style = ve.computedStyle; var painterParams = new TextureStylePainterParameters { rect = GUIUtility.AlignRectToDevice(ve.rect), uv = new Rect(0, 0, 1, 1), color = (Color)Color.white, texture = style.backgroundImage.value.texture, scaleMode = style.unityBackgroundScaleMode.value, sliceLeft = style.unitySliceLeft.value, sliceTop = style.unitySliceTop.value, sliceRight = style.unitySliceRight.value, sliceBottom = style.unitySliceBottom.value }; BorderParameters.SetFromStyle(ref painterParams.border, style); return(painterParams); }
public static TextureStylePainterParameters GetDefault(VisualElement ve) { IStyle style = ve.style; var painterParams = new TextureStylePainterParameters { rect = GUIUtility.AlignRectToDevice(ve.rect), uv = new Rect(0, 0, 1, 1), // When the background color is not clear, we have to embed it into the texture... // whereas if the color is clear, the white color is used... color = (style.backgroundColor != Color.clear) ? (Color)style.backgroundColor : (Color)Color.white, texture = style.backgroundImage, scaleMode = style.backgroundScaleMode, sliceLeft = style.sliceLeft, sliceTop = style.sliceTop, sliceRight = style.sliceRight, sliceBottom = style.sliceBottom }; BorderParameters.SetFromStyle(ref painterParams.border, style); return(painterParams); }
private void PaintSubTree(Event e, VisualElement root, Matrix4x4 offset, VisualElement.ClippingOptions clippingOption, Rect currentGlobalClip) { if (root == null || root.panel != this) { return; } if (root.visible == false || root.style.opacity.GetSpecifiedValueOrDefault(1.0f) < Mathf.Epsilon) { return; } // update clip if (root.clippingOptions != VisualElement.ClippingOptions.NoClipping) { var worldBound = ComputeAAAlignedBound(root.rect, offset * root.worldTransform); // are we and our children clipped? if (!worldBound.Overlaps(currentGlobalClip)) { return; } float x1 = Mathf.Max(worldBound.x, currentGlobalClip.x); float x2 = Mathf.Min(worldBound.xMax, currentGlobalClip.xMax); float y1 = Mathf.Max(worldBound.y, currentGlobalClip.y); float y2 = Mathf.Min(worldBound.yMax, currentGlobalClip.yMax); // new global clip and hierarchical clip space option. currentGlobalClip = new Rect(x1, y1, x2 - x1, y2 - y1); clippingOption = root.clippingOptions; } else { //since our children are not clipped, there is no early out. } // Check for the rotated space - clipping issue. if (!whinedOnceAboutRotatedClipSpaceThisFrame && clippingOption == VisualElement.ClippingOptions.ClipContents && DoesMatrixHaveUnsupportedRotation(root.worldTransform)) { Debug.LogError("Panel.PaintSubTree - Rotated clip-spaces are only supported by the VisualElement.ClippingOptions.ClipAndCacheContents mode. First offending Panel:'" + root.name + "'."); whinedOnceAboutRotatedClipSpaceThisFrame = true; } if (ShouldUsePixelCache(root)) { // now actually paint the texture to previous group IStylePainter painter = stylePainter; // validate cache texture size first var worldBound = root.worldBound; Rect alignedRect; int textureWidth, textureHeight; painter.currentWorldClip = currentGlobalClip; painter.currentTransform = offset * root.worldTransform; using (new GUIClip.ParentClipScope(painter.currentTransform, currentGlobalClip)) { alignedRect = GUIUtility.AlignRectToDevice(root.rect, out textureWidth, out textureHeight); } // Prevent the texture size from going empty, which may occur if the element has a sub-pixel size textureWidth = Math.Max(textureWidth, 1); textureHeight = Math.Max(textureHeight, 1); var cache = root.renderData.pixelCache; if (cache != null && (cache.width != textureWidth || cache.height != textureHeight) && (!keepPixelCacheOnWorldBoundChange || root.IsDirty(ChangeType.Repaint))) { Object.DestroyImmediate(cache); cache = root.renderData.pixelCache = null; } // if the child node world transforms are not up to date due to changes below the pixel cache this is fine. if (root.IsDirty(ChangeType.Repaint) || root.renderData.pixelCache == null || !root.renderData.pixelCache.IsCreated()) { // Recreate as needed if (cache == null) { root.renderData.pixelCache = cache = new RenderTexture( textureWidth, textureHeight, 32, // depth RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); } bool hasRoundedBorderRects = (root.style.borderTopLeftRadius > 0 || root.style.borderTopRightRadius > 0 || root.style.borderBottomLeftRadius > 0 || root.style.borderBottomRightRadius > 0); RenderTexture temporaryTexture = null; var old = RenderTexture.active; try { // We first render to a temp texture, then blit the result into the result pixelCache again to mask the rounder corners if (hasRoundedBorderRects) { temporaryTexture = cache = RenderTexture.GetTemporary(textureWidth, textureHeight, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); } // render the texture again to clip the round rect borders RenderTexture.active = cache; GL.Clear(true, true, new Color(0, 0, 0, 0)); // Calculate the offset required to translate the origin of the rect to the upper left corner // of the pixel cache. We need to round because the rect will be rounded when rendered. Rect worldAlignedRect = root.LocalToWorld(alignedRect); var childrenOffset = Matrix4x4.Translate(new Vector3(-worldAlignedRect.x, -worldAlignedRect.y, 0)); Matrix4x4 offsetWorldTransform = childrenOffset * root.worldTransform; // reset clipping var textureClip = new Rect(0, 0, worldAlignedRect.width, worldAlignedRect.height); painter.currentTransform = offsetWorldTransform; // Metal ignores the sRGBWrite flag and will always do linear to gamma conversions // when writing to an sRGB buffer. In this situation, we disable the manual sRGB // conversion since it will be done automatically when writing to the framebuffer. bool manualTex2SRGBEnabled = (SystemInfo.graphicsDeviceType != GraphicsDeviceType.Metal); using (new GUIUtility.ManualTex2SRGBScope(manualTex2SRGBEnabled)) using (new GUIClip.ParentClipScope(painter.currentTransform, textureClip)) { // Paint self painter.currentWorldClip = textureClip; stylePainter.opacity = root.style.opacity.GetSpecifiedValueOrDefault(1.0f); root.DoRepaint(painter); stylePainter.opacity = 1.0f; root.ClearDirty(ChangeType.Repaint); PaintSubTreeChildren(e, root, childrenOffset, clippingOption, textureClip); } if (hasRoundedBorderRects) { RenderTexture.active = root.renderData.pixelCache; // Fix up transform for subtree to match texture upper left. painter.currentTransform = Matrix4x4.identity; using (new GUIUtility.ManualTex2SRGBScope(manualTex2SRGBEnabled)) using (new GUIClip.ParentClipScope(painter.currentTransform, textureClip)) { GL.Clear(true, true, new Color(0, 0, 0, 0)); var textureParams = painter.GetDefaultTextureParameters(root); textureParams.texture = cache; textureParams.scaleMode = ScaleMode.StretchToFill; textureParams.rect = textureClip; textureParams.border.SetWidth(0.0f); // The rect of the temporary texture implicitly carries the scale factor of the // transform. Since we are blitting with an identity matrix, we need to scale the // radius manually. // We assume uniform positive scaling without rotations. Vector4 toScale = new Vector4(1, 0, 0, 0); Vector4 scaled = offsetWorldTransform * toScale; float radiusScale = scaled.x; textureParams.border.SetRadius( textureParams.border.topLeftRadius * radiusScale, textureParams.border.topRightRadius * radiusScale, textureParams.border.bottomRightRadius * radiusScale, textureParams.border.bottomLeftRadius * radiusScale); // No border is drawn but the rounded corners are clipped properly. // Use premultiply alpha to avoid blending again. textureParams.usePremultiplyAlpha = true; painter.DrawTexture(textureParams); } // Redraw the border (border was already drawn in first root.DoRepaint call). painter.currentTransform = offsetWorldTransform; using (new GUIUtility.ManualTex2SRGBScope(manualTex2SRGBEnabled)) using (new GUIClip.ParentClipScope(painter.currentTransform, textureClip)) { painter.DrawBorder(root); } } } finally { cache = null; if (temporaryTexture != null) { RenderTexture.ReleaseTemporary(temporaryTexture); } RenderTexture.active = old; } } // now actually paint the texture to previous group painter.currentWorldClip = currentGlobalClip; painter.currentTransform = offset * root.worldTransform; using (new GUIClip.ParentClipScope(painter.currentTransform, currentGlobalClip)) { var painterParams = new TextureStylePainterParameters { rect = GUIUtility.AlignRectToDevice(root.rect), uv = new Rect(0, 0, 1, 1), texture = root.renderData.pixelCache, color = Color.white, scaleMode = ScaleMode.StretchToFill, usePremultiplyAlpha = true }; painter.DrawTexture(painterParams); } } else { stylePainter.currentTransform = offset * root.worldTransform; using (new GUIClip.ParentClipScope(stylePainter.currentTransform, currentGlobalClip)) { stylePainter.currentWorldClip = currentGlobalClip; stylePainter.mousePosition = root.worldTransform.inverse.MultiplyPoint3x4(e.mousePosition); stylePainter.opacity = root.style.opacity.GetSpecifiedValueOrDefault(1.0f); root.DoRepaint(stylePainter); stylePainter.opacity = 1.0f; root.ClearDirty(ChangeType.Repaint); PaintSubTreeChildren(e, root, offset, clippingOption, currentGlobalClip); } } }
public static Rect AlignRectToDevice(Rect rect) { return(GUIUtility.AlignRectToDevice(rect)); }
public static Rect AlignRectToDevice(Rect rect, out int widthInPixels, out int heightInPixels) { return(GUIUtility.AlignRectToDevice(rect, out widthInPixels, out heightInPixels)); }
private void PaintSubTree(VisualElement root, Matrix4x4 offset, bool shouldClip, bool shouldCache, Rect currentGlobalClip) { if (root == null || root.panel != panel) { return; } if (root.visible == false || root.style.opacity.GetSpecifiedValueOrDefault(1.0f) < Mathf.Epsilon) { return; } // update clip if (root.ShouldClip()) { var worldBound = VisualElement.ComputeAAAlignedBound(root.rect, offset * root.worldTransform); // are we and our children clipped? if (!worldBound.Overlaps(currentGlobalClip)) { return; } float x1 = Mathf.Max(worldBound.x, currentGlobalClip.x); float x2 = Mathf.Min(worldBound.xMax, currentGlobalClip.xMax); float y1 = Mathf.Max(worldBound.y, currentGlobalClip.y); float y2 = Mathf.Min(worldBound.yMax, currentGlobalClip.yMax); // new global clip and hierarchical clip space option. currentGlobalClip = new Rect(x1, y1, x2 - x1, y2 - y1); shouldClip = true; shouldCache = root.clippingOptions == VisualElement.ClippingOptions.ClipAndCacheContents; } else { //since our children are not clipped, there is no early out. } // Check for the rotated space - clipping issue. if (!m_WhinedOnceAboutRotatedClipSpaceThisFrame && shouldClip && !shouldCache && DoesMatrixHaveUnsupportedRotation(root.worldTransform)) { Debug.LogError("Panel.PaintSubTree - Rotated clip-spaces are only supported by the VisualElement.ClippingOptions.ClipAndCacheContents mode. First offending Panel:'" + root.name + "'."); m_WhinedOnceAboutRotatedClipSpaceThisFrame = true; } var prevElement = m_StylePainter.currentElement; m_StylePainter.currentElement = root; var repaintData = panel.repaintData; if (ShouldUsePixelCache(root)) { // now actually paint the texture to previous group // validate cache texture size first var worldBound = root.worldBound; Rect alignedRect; int textureWidth, textureHeight; repaintData.currentWorldClip = currentGlobalClip; repaintData.currentOffset = offset; using (new GUIClip.ParentClipScope(offset * root.worldTransform, currentGlobalClip)) { alignedRect = GUIUtility.AlignRectToDevice(root.rect, out textureWidth, out textureHeight); } // Prevent the texture size from going empty, which may occur if the element has a sub-pixel size textureWidth = Math.Max(textureWidth, 1); textureHeight = Math.Max(textureHeight, 1); var cache = root.renderData.pixelCache; if (cache != null && (cache.width != textureWidth || cache.height != textureHeight) && (!panel.keepPixelCacheOnWorldBoundChange || m_RepaintList.Contains(root))) { Object.DestroyImmediate(cache); cache = root.renderData.pixelCache = null; } // if the child node world transforms are not up to date due to changes below the pixel cache this is fine. if (m_RepaintList.Contains(root) || root.renderData.pixelCache == null || !root.renderData.pixelCache.IsCreated()) { // Recreate as needed if (cache == null) { root.renderData.pixelCache = cache = new RenderTexture( textureWidth, textureHeight, 32, // depth RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); } bool hasRoundedBorderRects = (root.style.borderTopLeftRadius > 0 || root.style.borderTopRightRadius > 0 || root.style.borderBottomLeftRadius > 0 || root.style.borderBottomRightRadius > 0); RenderTexture temporaryTexture = null; var old = RenderTexture.active; try { // We first render to a temp texture, then blit the result into the result pixelCache again to mask the rounder corners if (hasRoundedBorderRects) { // This should be an sRGB texture to conform with editor texture guidelines, however // converting the cache to sRGB requires a shader to do it, and this whole pixel cache // thing is slated to go away, so we take a short-cut here and use a linear texture // along with the use of manualTex2SRGBEnabled to get the correct results. temporaryTexture = cache = RenderTexture.GetTemporary(textureWidth, textureHeight, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); } // render the texture again to clip the round rect borders RenderTexture.active = cache; GL.Clear(true, true, new Color(0, 0, 0, 0)); // Calculate the offset required to translate the origin of the rect to the upper left corner // of the pixel cache. We need to round because the rect will be rounded when rendered. Rect worldAlignedRect = root.LocalToWorld(alignedRect); var childrenOffset = Matrix4x4.Translate(new Vector3(-worldAlignedRect.x, -worldAlignedRect.y, 0)); Matrix4x4 offsetWorldTransform = childrenOffset * root.worldTransform; // reset clipping var textureClip = new Rect(0, 0, worldAlignedRect.width, worldAlignedRect.height); repaintData.currentOffset = childrenOffset; using (new GUIClip.ParentClipScope(offsetWorldTransform, textureClip)) { // Paint self repaintData.currentWorldClip = textureClip; m_StylePainter.opacity = root.style.opacity.GetSpecifiedValueOrDefault(1.0f); root.Repaint(m_StylePainter); m_StylePainter.opacity = 1.0f; PaintSubTreeChildren(root, childrenOffset, shouldClip, shouldCache, textureClip); } if (hasRoundedBorderRects) { RenderTexture.active = root.renderData.pixelCache; bool oldManualTex2SRGBEnabled = GUIUtility.manualTex2SRGBEnabled; GUIUtility.manualTex2SRGBEnabled = false; using (new GUIClip.ParentClipScope(Matrix4x4.identity, textureClip)) { GL.Clear(true, true, new Color(0, 0, 0, 0)); var textureParams = TextureStylePainterParameters.GetDefault(root); textureParams.color = Color.white; textureParams.texture = cache; textureParams.scaleMode = ScaleMode.StretchToFill; textureParams.rect = textureClip; textureParams.border.SetWidth(0.0f); // The rect of the temporary texture implicitly carries the scale factor of the // transform. Since we are blitting with an identity matrix, we need to scale the // radius manually. // We assume uniform positive scaling without rotations. Vector4 toScale = new Vector4(1, 0, 0, 0); Vector4 scaled = offsetWorldTransform * toScale; float radiusScale = scaled.x; textureParams.border.SetRadius( textureParams.border.topLeftRadius * radiusScale, textureParams.border.topRightRadius * radiusScale, textureParams.border.bottomRightRadius * radiusScale, textureParams.border.bottomLeftRadius * radiusScale); // No border is drawn but the rounded corners are clipped properly. // Use premultiply alpha to avoid blending again. textureParams.usePremultiplyAlpha = true; m_StylePainter.DrawTexture(textureParams); } // Redraw the border (border was already drawn in first root.DoRepaint call). using (new GUIClip.ParentClipScope(offsetWorldTransform, textureClip)) { m_StylePainter.DrawBorder(); } GUIUtility.manualTex2SRGBEnabled = oldManualTex2SRGBEnabled; } } finally { cache = null; if (temporaryTexture != null) { RenderTexture.ReleaseTemporary(temporaryTexture); } RenderTexture.active = old; } } // now actually paint the texture to previous group repaintData.currentWorldClip = currentGlobalClip; repaintData.currentOffset = offset; bool oldManualTex2SRGBEnabled2 = GUIUtility.manualTex2SRGBEnabled; GUIUtility.manualTex2SRGBEnabled = false; using (new GUIClip.ParentClipScope(offset * root.worldTransform, currentGlobalClip)) { var painterParams = new TextureStylePainterParameters { rect = GUIUtility.AlignRectToDevice(root.rect), uv = new Rect(0, 0, 1, 1), texture = root.renderData.pixelCache, color = Color.white, scaleMode = ScaleMode.StretchToFill, usePremultiplyAlpha = true }; // We must not reapply the editor Play Mode Tint if it was already applied ! var playModeTint = UIElementsUtility.editorPlayModeTintColor; UIElementsUtility.editorPlayModeTintColor = Color.white; m_StylePainter.DrawTexture(painterParams); UIElementsUtility.editorPlayModeTintColor = playModeTint; } GUIUtility.manualTex2SRGBEnabled = oldManualTex2SRGBEnabled2; } else { repaintData.currentOffset = offset; using (new GUIClip.ParentClipScope(offset * root.worldTransform, currentGlobalClip)) { repaintData.currentWorldClip = currentGlobalClip; repaintData.mousePosition = root.worldTransform.inverse.MultiplyPoint3x4(repaintData.repaintEvent.mousePosition); m_StylePainter.opacity = root.style.opacity.GetSpecifiedValueOrDefault(1.0f); root.Repaint(m_StylePainter); m_StylePainter.opacity = 1.0f; PaintSubTreeChildren(root, offset, shouldClip, shouldCache, currentGlobalClip); } } m_StylePainter.currentElement = prevElement; }