XNAの角を丸めますか?


10

プリミティブ(ラインストリップ)を介してXNAでレンダリングされた四角形の角を丸くする方法はありますか?UIを今よりも少し派手にしたいと思います。あまりにも多くのテクスチャーを必要とせずに、コードを柔軟にしたいと思います。


基本的に:ラインに1つのテクスチャを使用し、ラインの丸い端に1つのテクスチャを使用します。これら2つのテクスチャを使用するスプライトを適切に回転およびスケーリングします。
Olhovsky

回答:


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. 幅と高さ(1)でオフセットされた、(2の幅と(4)の高さを持つ)両方向にスケーリングされた描画。
  6. (1)の高さでオフセットして、宛先の長方形の右側に垂直にスケーリングされた((4)と同じ高さ)を描画します。
  7. 宛先の長方形の左下にスケールなしで描画します。
  8. (1)の幅でオフセットされた、宛先長方形の下部で水平にスケーリングされた((2)と同じ高さ)を描画します。
  9. 宛先長方形の右下にスケールなしで描画します。

ボタンを見ると、(2)、(5)、および(7)が水平方向にスケーリングされていても問題ないことがわかります(これは基本的に直線であるため)。同様に、(4)、(5)、(6)は、イメージの品質に影響を与えることなく垂直方向にスケーリングできます。


はい、これは質問に直接回答するものではありませんが、誰かがそれを役に立つと思うかもしれません。
ジョナサンディキンソン、

4
これは9パッチと呼ばれ、テクスチャを使用して好きなように見せることができるため、実際にはシェーダーを使用するよりもはるかに柔軟です(そして安価です!)。次に、すべてのウィジェット画像を1つのテクスチャアトラスに配置できます。ほとんどのGUIはこの方法でそれを行います。
Elisée

0

以下は、「9パッチ」アプローチのコードです。

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();
レオナルドセッシア

テクスチャは1つの青いピクセルにすぎません。このアプローチでは、角の丸い部分がテクスチャの一部であると想定しています。
sdgfsdh 2018

すみません-プラットフォームに非常に新しい...すぐに返信してくれてありがとう
Leonardo Seccia 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.