Czy jest jakiś sposób, aby wykonać zaokrąglone rogi na prostokącie renderowanym w XNA przez prymitywy (paski liniowe)? Chcę, aby mój interfejs był nieco bardziej fantazyjny niż obecnie, i chciałbym, aby kod był elastyczny, bez zbyt wielu tekstur.
Czy jest jakiś sposób, aby wykonać zaokrąglone rogi na prostokącie renderowanym w XNA przez prymitywy (paski liniowe)? Chcę, aby mój interfejs był nieco bardziej fantazyjny niż obecnie, i chciałbym, aby kod był elastyczny, bez zbyt wielu tekstur.
Odpowiedzi:
Możesz wyrenderować prymityw i stworzyć moduł cieniujący, który może tworzyć zaokrąglone rogi.
Oto prosty moduł cieniujący piksele w pseudokodzie, który może narysować zaokrąglony kwadrat:
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)
Wynik tego modułu cieniującego piksele:

Jeśli używasz shaderów, możesz stworzyć naprawdę fantazyjny interfejs użytkownika, nawet animowany.
Dla mnie świetnym prototypem prostych shaderów pikseli jest program EvalDraw
Innym sposobem na to jest użycie „rozciągnięcia guzika” (zwanego również „rozciągnięciem pudełka” lub „dziewięciopłatkiem”). Zasadniczo tworzysz obraz, który składa się z 9 części:

Aby narysować ten przycisk w dowolnym rozmiarze, narysuj każdy element (od góry do dołu, od lewej do prawej):
width - ((1) + (2)).Width) u góry docelowego prostokąta, z lewym przesunięciem o szerokość (1).height - ((1) + (2)).Height) po lewej stronie prostokąta docelowego, z górnym przesunięciem o wysokość (1).Jeśli spojrzysz na przycisk, zobaczysz, że nie ma znaczenia, czy (2), (5) i (7) są skalowane w poziomie (ponieważ jest to zasadniczo linia prosta); w ten sam sposób (4), (5) i (6) można przeskalować w pionie bez wpływu na jakość obrazu.
Oto kod metody „dziewięciu łatek”:
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);
}
}
Jest wywoływany jako:
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();