XNA中的圆角?


10

有什么方法可以通过图元(直线)在XNA中渲染的矩形上制作圆角?我想让UI变得比以前更漂亮,并且我希望代码灵活,并且不涉及太多纹理。


基本上:对线条使用一种纹理,对线条的圆端使用一种纹理。适当地旋转和缩放使用这两个纹理的精灵。
Olhovsky 2011年

Answers:


8

您可以渲染图元,并创建可以创建这些圆角的着色器。
这是一个伪代码中的简单像素着色器,可以绘制圆角正方形:

xDist = abs(x-0.5)
yDist = abs(y-0.5)
xD = xDist*xDist*4
yD = yDist*yDist*4
alpha = floor((1-xD)*(1-yD)*5)

此像素着色器的结果:

在此处输入图片说明

如果使用着色器,则可以制作真正精美的UI,甚至可以制作动画的UI。

对我来说,简单的像素着色器的原型制作程序是EvalDraw


5

另一种方法是使用“按钮拉伸”(也称为“框拉伸”或“九补丁”)。本质上,您创建的图像由9个部分组成:

按钮资源

为了绘制任意大小的按钮,您需要绘制每块(从上到下,从左到右):

  1. 在目标矩形的左上角按比例绘制。
  2. width - ((1) + (2)).Width在目标矩形的顶部水平缩放(带有),向左偏移(1)的宽度。
  3. 在目标矩形的右上角按比例绘制。
  4. 垂直缩放的绘图(带有 height - ((1) + (2)).Height在目标矩形的左侧),顶部偏移高度(1)。
  5. 绘制在两个方向上缩放(宽度为(2),高度为(4)),但偏移了宽度和高度(1)。
  6. 在目标矩形的右侧垂直缩放(与(4)高度相同)绘制,偏移高度(1)。
  7. 在目标矩形的左下角按比例绘制。
  8. 在目标矩形的底部水平缩放(与(2)高度相同)绘制,偏移(1)的宽度。
  9. 在目标矩形的右下角无比例绘制。

如果看一下按钮,您会发现(2),(5)和(7)是否水平缩放(因为它本质上是一条直线)并不重要。以相同的方式,可以垂直缩放(4),(5)和(6),而不会影响图像质量。


是的,这不能直接回答问题-但是有人可能仍然觉得它有用。
乔纳森·迪金森

4
它称为九修补程序,实际上比使用着色器更灵活(并且更便宜!),因为您可以使它看起来像您想要的纹理。然后,您可以将所有窗口小部件图像放在一个纹理图集中。大多数GUI都是这样做的。
Elisée

0

这是“九补丁”方法的代码:

public static class SpriteBatchExtensions
{
    public static void DrawRoundedRect(this SpriteBatch spriteBatch, Rectangle destinationRectangle, 
        Texture2D texture, int border, Color color)
    {
        // Top left
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location, new Point(border)), 
            new Rectangle(0, 0, border, border), 
            color);

        // Top
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(border, 0), 
                new Point(destinationRectangle.Width - border * 2, border)), 
            new Rectangle(border, 0, texture.Width - border * 2, border), 
            color);

        // Top right
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(destinationRectangle.Width - border, 0), new Point(border)), 
            new Rectangle(texture.Width - border, 0, border, border), 
            color);

        // Middle left
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(0, border), new Point(border, destinationRectangle.Height - border * 2)), 
            new Rectangle(0, border, border, texture.Height - border * 2), 
            color);

        // Middle
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(border), destinationRectangle.Size - new Point(border * 2)), 
            new Rectangle(border, border, texture.Width - border * 2, texture.Height - border * 2), 
            color);

        // Middle right
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(destinationRectangle.Width - border, border), 
                new Point(border, destinationRectangle.Height - border * 2)), 
            new Rectangle(texture.Width - border, border, border, texture.Height - border * 2), 
            color);

        // Bottom left
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(0, destinationRectangle.Height - border), new Point(border)), 
            new Rectangle(0, texture.Height - border, border, border), 
            color);

        // Bottom
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + new Point(border, destinationRectangle.Height - border), 
                new Point(destinationRectangle.Width - border * 2, border)), 
            new Rectangle(border, texture.Height - border, texture.Width - border * 2, border), 
            color);

        // Bottom right
        spriteBatch.Draw(
            texture, 
            new Rectangle(destinationRectangle.Location + destinationRectangle.Size - new Point(border), new Point(border)), 
            new Rectangle(texture.Width - border, texture.Height - border, border, border), 
            color);
    }
}

它的调用方式为:

spriteBatch.DrawRoundedRect(
    dest, // The coordinates of the Rectangle to be drawn
    rectangleTexture, // Texture for the whole rounded rectangle
    16, // Distance from the edges of the texture to the "middle" patch
    Color.OrangeRed);

这对我不起作用...我只是得到一个普通矩形。这就是我的使用方式Texture2D _texture = new Texture2D(GraphicsDevice, 1, 1); _texture.SetData(new Color[] { Color.Blue }); SpriteBatch sb = new SpriteBatch(GraphicsDevice); sb.Begin(); //sb.Draw(_texture, new Rectangle(100, 100, 100, 100), Color.White); sb.DrawRoundedRect(_texture, new Rectangle(100, 100, 100, 100), Color.Pink, 16); sb.End();
莱昂纳多·塞西亚

您的纹理只是一个蓝色像素,此方法假定圆角是纹理的一部分。
sdgfsdh

抱歉-平台非常新...感谢您尽快回复我
Leonardo Seccia
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.