มุมโค้งมนใน XNA


10

มีวิธีใดบ้างที่ฉันสามารถทำมุมโค้งมนบนสี่เหลี่ยมที่เรนเดอร์ใน XNA ผ่าน primitives (แถบเส้น) ฉันต้องการทำให้ UI ของฉันดูแฟนซีกว่าเดิมเล็กน้อยและฉันต้องการให้โค้ดมีความยืดหยุ่นโดยไม่ต้องมีพื้นผิวมากเกินไป


โดยพื้นฐาน: ใช้หนึ่งพื้นผิวสำหรับบรรทัดหนึ่งพื้นผิวสำหรับปลายกลมของบรรทัด หมุนและสไปรต์สเกลที่ใช้พื้นผิวทั้งสองนี้อย่างเหมาะสม
Olhovsky

คำตอบ:


8

คุณสามารถสร้างภาพดั้งเดิมของคุณและสร้าง shader ที่สามารถสร้างมุมโค้งมนเหล่านี้
นี่คือ shader พิกเซลแบบง่าย ๆ ใน pseudocode ที่สามารถวาดสี่เหลี่ยมจัตุรัส:

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)

ผลลัพธ์ของ Pixel Shader:

ป้อนคำอธิบายรูปภาพที่นี่

หากคุณใช้เฉดสีคุณสามารถสร้าง 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) สามารถปรับขนาดในแนวตั้งโดยไม่ส่งผลกระทบต่อคุณภาพของภาพ


ใช่สิ่งนี้ไม่ตอบคำถามโดยตรง - แต่บางคนอาจพบว่ามันมีประโยชน์
Jonathan Dickinson

4
มันเรียกว่าเก้าแพทช์และจริง ๆ แล้วมีความยืดหยุ่นมากกว่า (และราคาถูกกว่า!) มากกว่าการใช้ shader เนื่องจากคุณสามารถทำให้มันดูได้ตามที่คุณต้องการด้วยพื้นผิว จากนั้นคุณสามารถวางภาพวิดเจ็ตทั้งหมดของคุณไว้ในแผนที่พื้นผิวเดียว GUIs ส่วนใหญ่ทำเช่นนี้
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();
Leonardo Seccia

พื้นผิวของคุณเป็นเพียงพิกเซลสีน้ำเงินวิธีนี้จะถือว่ามุมมนเป็นส่วนหนึ่งของพื้นผิวของคุณ
sdgfsdh

ขอโทษ - ใหม่มากสำหรับแพลตฟอร์ม ... ขอบคุณที่กลับมาหาฉันอย่างรวดเร็ว
Leonardo Seccia
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.