我正在使用2D纹理,我想绘制一个简单的圆,使用此函数来了解圆上是否有像素,然后为其指定一种颜色:
其中(a,b)是圆的中心。
我不介意这是否是一种愚蠢,低效的方式来实现这种效果,我只是想学习如何操纵浮点数来绘制那个圆圈。假设C#中的所有部分都是正确的,并且纹理是正方形,我该如何纠正我的代码呢?
sampler s0;
int radius;
static const float X_c = radius/2;
static const float Y_c = radius/2;
float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
{
float4 color = tex2D(s0, coords);
float2 coords_sec = coords*radius*2; //To map coordinates in [0, radius*2] instead of [0,1]
//The same equation as above, just putting to the left radius
if ( ( (int)pow((coords_sec.x - X_c),2)
+ (int)pow((coords_sec.y - Y_c),2)
- (int)pow(radius,2) ) == 0.0 )
{
color.r = 1; //I want to draw a red circle
}
return color;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction(); //Dice quale versione del pixelshader compilare
}
}
聚苯乙烯。看来我什么都没画。我怀疑if条件总是假的
第二个问题:是否有一个简单的指南,博客或书籍来帮助我理解这些概念(关于2D)?
答案 0 :(得分:1)
首先,施放到int
会产生反作用。您有float
个值,并且不希望通过转换为int
来放松精度,{0, 1 ... 4 * radius^2}
始终是== 0
之一。
此外,与<= 0
的比较需要一些运气才能被击中。如果你想填充圆圈,请使用abs(...) <= epsilon
或者如果你想绘制一条线,请尝试类似float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
{
float dx = coords.x - 0.5f;
float dy = coords.y - 0.5f;
if(dx * dx + dy * dy <= 0.25f)
return float4(1.0f, 0.0f, 0.0f, 1.0f);
else
return float4(0.0f, 0.0f, 0.0f, 0.0f);
}
的内容,其中epsilon是一个描述线条粗细的小数字。
请注意,您只需将返回颜色的r分量设置为1.这不需要产生红色圆圈(例如,如果您已经有白色纹理)。
我会做以下事情:
{{1}}
请注意,您不需要显式半径或中心,因为纹理坐标已标准化。
答案 1 :(得分:1)
这是一种非常简单的方法(但可能不是很快);它有效。我并不认为它是最好的解决方案,但它运行良好,非常灵活和简单,允许您使用GDI +。
首先:添加引用&#34; System.Drawing&#34;从项目菜单中。
第二:在新文件中创建此类。
using Microsoft.Xna.Framework.Graphics;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace WindowsGame1 // This should be the namespace of your application.
{
class CircleDrawer
{
public static Texture2D GetCircle(GraphicsDevice device, System.Drawing.Color color, int radius)
{
Image img = new Bitmap(radius, radius);
Graphics g = Graphics.FromImage(img);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.FillEllipse(new SolidBrush(color), 0, 0, radius, radius);
img.Save("temp.png", System.Drawing.Imaging.ImageFormat.Png);
Texture2D result = Texture2D.FromFile(device, "temp.png");
System.IO.File.Delete("temp.png");
return result;
}
}
}
第三:现在所有人都有一个方法可以画一个圆圈的方法
让我们看一个如何应用它的示例:
只需在&#34; Draw&#34;中写下这四行。游戏类的方法
Texture2D txt = CircleDrawer.GetCircle(GraphicsDevice,
System.Drawing.Color.Green, 40);
spriteBatch.Begin();
spriteBatch.Draw(txt, new Rectangle(10, 10, 60, 60), Color.White);
spriteBatch.End();