Ejemplo n.º 1
0
    /**
     * Draws a texture with given parameter
     *
     * @param uvFrame frame for UVs in texels.
     */
    private static void DrawMaster(Rect screenRect, Texture texture, Rect uvFrame, DrawParameters dp, RectOffset origionalBorder = null)
    {
        //3ms for these 4 lines
        if (!isRepaint)
        {
            return;
        }
        if (texture == null)
        {
            return;
        }
        if (!dp.IsVisibile(texture))
        {
            return;
        }
        if (dp.Scale.x * dp.Scale.y == 0)
        {
            return;
        }

        screenRect.width  *= dp.Scale.x;
        screenRect.height *= dp.Scale.y;

        Material material = dp.GetPreparedMaterial(texture);

        // --------------------------------------
        // Transform and clip.

        Vector4 clipping = Vector4.zero;

        Rect transformedRect = TransformTheRect(screenRect);
        Rect clippedRect     = transformedRect;
        Rect sourceRect      = new Rect(uvFrame);

        int borderLeft   = origionalBorder == null ? 0 : origionalBorder.left;
        int borderRight  = origionalBorder == null ? 0 : origionalBorder.right;
        int borderTop    = origionalBorder == null ? 0 : origionalBorder.top;
        int borderBottom = origionalBorder == null ? 0 : origionalBorder.bottom;

        // No clipping for rotated sprites yet.
        bool disableClip = dp.Rotation != 0;

        if (!disableClip)
        {
            clippedRect = ClipTheRect(transformedRect, ref clipping);
            bool hasClipped = (clipping != Vector4.zero);

            //stub:

            /*
             * if (hasClipped) {
             *      SmartUI.Color = Color.red;
             *      if (screenRect.Contains(new Vector2(InputEx.mousePosition.x, InputEx.mousePosition.y)))
             *              Trace.LogDebug("Clipped {0} to {1}", transformedRect, clippedRect);
             * } else
             *      SmartUI.Color = Color.green;
             */

            if ((clippedRect.width <= 0) || (clippedRect.height <= 0))
            {
                return;
            }

            if (hasClipped)
            {
                // Calculate clipped UVs.
                sourceRect     = new Rect();
                sourceRect.min = PixelToUV(transformedRect, uvFrame, clippedRect.min, origionalBorder);
                sourceRect.max = PixelToUV(transformedRect, uvFrame, clippedRect.max, origionalBorder);

                // Upside down swap.  This has something todo with the fact that the screen has (0,0) at the top left
                // and the texture has (0,0) at the bottom left.
                float newMin = uvFrame.yMin + (uvFrame.yMax - sourceRect.yMax);
                float newMax = uvFrame.yMax + (uvFrame.yMin - sourceRect.yMin);
                sourceRect.yMin = newMin;
                sourceRect.yMax = newMax;


                // Adjust border for clipping.
                if (origionalBorder != null)
                {
                    clipping[0] /= dp.Scale.x;
                    clipping[2] /= dp.Scale.x;
                    clipping[1] /= dp.Scale.y;
                    clipping[3] /= dp.Scale.y;

                    borderLeft  = Util.ClampInt(borderLeft - (int)clipping[0], 0, int.MaxValue);
                    borderRight = Util.ClampInt(borderRight - (int)clipping[2], 0, int.MaxValue);

                    borderTop    = Util.ClampInt(borderTop - (int)clipping[1], 0, int.MaxValue);
                    borderBottom = Util.ClampInt(borderBottom - (int)clipping[3], 0, int.MaxValue);
                }
            }
        }

        // Convert source rect to normalised.
        sourceRect.xMin *= texture.texelSize.x;
        sourceRect.xMax *= texture.texelSize.x;
        sourceRect.yMin *= texture.texelSize.y;
        sourceRect.yMax *= texture.texelSize.y;

        // Work out the best way to draw this.
        DrawMethod drawMethod = DrawMethod.Standard;

        if (origionalBorder != null)
        {
            drawMethod = DrawMethod.Bordered;
        }

        if ((origionalBorder != null) && (texture.HighDPI()))
        {
            drawMethod = DrawMethod.Native;
        }

        if (ShowGuiMaterial && !dp.IsDebugDraw)
        {
            drawMethod = DrawMethod.DebugColor;
        }

        // Apply rotation
        if (dp.Rotation != 0)
        {
            Engine.PushGUI();
            var rotationMatrix =
                Extentions.GetTranslationMatrix(clippedRect.center.x, clippedRect.center.y, 0) *
                Extentions.GetRotationMatrix(0, 0, dp.Rotation) *
                Extentions.GetTranslationMatrix(-clippedRect.center.x, -clippedRect.center.y, 0);

            GUI.matrix *= rotationMatrix;
        }

        // Draw the thing.
        switch (drawMethod)
        {
        case DrawMethod.DebugColor:
            Color = dp.DebugColor;
            DrawMaster(screenRect, StockTexture.White, new Rect(0, 0, 2, 2), DrawParameters.DebugDraw);
            break;

        case DrawMethod.Standard:
            Graphics.DrawTexture(clippedRect, texture, sourceRect, 0, 0, 0, 0, SmartUI.Color, material);
            break;

        case DrawMethod.Bordered:
            Graphics.DrawTexture(clippedRect, texture, sourceRect, borderLeft, borderRight, borderTop, borderBottom, SmartUI.Color, material);
            break;

        // The native draw will reverse the DPI scaling on the Gui matrix and then draw the object at an adjusted size.
        // This allows things like bordered gui objects to display correctly without distortion.

        case DrawMethod.Native:
            const float scale = 2;
            Engine.PushGUI();
            GUI.matrix *= Matrix4x4.Scale(Vector3.one / scale);
            clippedRect = clippedRect.Scaled(scale);
            Graphics.DrawTexture(clippedRect, texture, sourceRect, (int)(borderLeft * scale), (int)(borderRight * scale), (int)(borderTop * scale), (int)(borderBottom * scale), SmartUI.Color, material);
            Engine.PopGUI();
            break;
        }

        if (ShowGuiBounds && !dp.IsDebugDraw)
        {
            Color = Color.red;
            DrawMaster(screenRect, StockTexture.SimpleRect, new Rect(0, 0, 4, 4), DrawParameters.DebugDraw, BORDER_2PX);
        }

        if (dp.Rotation != 0)
        {
            Engine.PopGUI();
        }

        Color = Color.white;
    }