มีวิธีใดบ้างที่ฉันสามารถทำมุมโค้งมนบนสี่เหลี่ยมที่เรนเดอร์ใน XNA ผ่าน primitives (แถบเส้น) ฉันต้องการทำให้ UI ของฉันดูแฟนซีกว่าเดิมเล็กน้อยและฉันต้องการให้โค้ดมีความยืดหยุ่นโดยไม่ต้องมีพื้นผิวมากเกินไป
มีวิธีใดบ้างที่ฉันสามารถทำมุมโค้งมนบนสี่เหลี่ยมที่เรนเดอร์ใน XNA ผ่าน primitives (แถบเส้น) ฉันต้องการทำให้ UI ของฉันดูแฟนซีกว่าเดิมเล็กน้อยและฉันต้องการให้โค้ดมีความยืดหยุ่นโดยไม่ต้องมีพื้นผิวมากเกินไป
คำตอบ:
คุณสามารถสร้างภาพดั้งเดิมของคุณและสร้าง 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
อีกวิธีในการทำเช่นนี้คือใช้ 'การยืดปุ่ม' (หรือที่เรียกว่า 'การยืดกล่อง' หรือ 'เก้าปะ') โดยพื้นฐานแล้วคุณสร้างภาพที่สร้างขึ้นจาก 9 ส่วน:
เพื่อที่จะวาดปุ่มที่ขนาดใด ๆ คุณวาดแต่ละชิ้น (จากบนลงล่างซ้ายไปขวา):
width - ((1) + (2)).Width
) ที่ด้านบนของสี่เหลี่ยมปลายทางโดยให้ออฟเซ็ตซ้ายโดยความกว้างของ (1)height - ((1) + (2)).Height
) ที่ด้านซ้ายของสี่เหลี่ยมปลายทางโดยมีออฟเซ็ตด้านบนด้วยความสูงของ (1)หากคุณดูที่ปุ่มคุณจะเห็นว่ามันไม่สำคัญว่า (2), (5) และ (7) ได้รับการปรับขนาดในแนวนอน (เพราะมันเป็นเส้นตรง) ในลักษณะเดียวกัน (4), (5) และ (6) สามารถปรับขนาดในแนวตั้งโดยไม่ส่งผลกระทบต่อคุณภาพของภาพ
นี่คือรหัสสำหรับวิธีการ "เก้าแพทช์":
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();