【发布时间】:2021-12-29 12:16:13
【问题描述】:
我想知道如何在 XNA/MonoGame 中逐个像素地动态绘制,我只能找到this。问题是,问题不在于如何逐个像素地实际绘制,而是管理资源和更新内容。
因为我找不到任何简单而简短的答案,并且想知道现在该怎么做,所以我将分享一个我偶然发现的 sn-p(见答案)。
注意:如果有人有更好的方法或替代方法,请随时发表或评论!
【问题讨论】:
标签: xna draw pixel monogame texture2d
我想知道如何在 XNA/MonoGame 中逐个像素地动态绘制,我只能找到this。问题是,问题不在于如何逐个像素地实际绘制,而是管理资源和更新内容。
因为我找不到任何简单而简短的答案,并且想知道现在该怎么做,所以我将分享一个我偶然发现的 sn-p(见答案)。
注意:如果有人有更好的方法或替代方法,请随时发表或评论!
【问题讨论】:
标签: xna draw pixel monogame texture2d
为你的纹理和尺寸声明一个类级别变量:
Texture2D Tex, Tex1, Tex2;
const int WIDTH = 32;
const int HEIGHT = 32;
Color[] TexSource = new Color[WIDTH * HEIGHT];
初始化LoadContent()中的变量
int radius = 5;
point center = new Point(WIDTH >> 2, HEIGHT >> 2);
Tex = new Texture2D(GraphicsDevice, WIDTH, HEIGHT);
for(int x = 0 ; x < WIDTH; x++)
for(int y = 0 ; y < HEIGHT; y++)
if(Math.Sqrt((x - center.x)* (x - center.x)) < radius && Math.Sqrt((y - center.y) * (y - center.y) < radius))
TexSource[x + y * WIDTH] = Color.Red;
else
TexSource[x + y * WIDTH] = Color.White;
Tex = SetData<Color>(TexSource);
//The resulting texture is a red circle on a white background.
//If you want to draw on top of an existing texture Tex1 as Tex2:
Tex1 = Content.Load<Texture2D>(Tex1Name);
Tex2 = new Texture2D(GraphicsDevice, Tex1.Width, Tex1.Height);
TexSource = Tex1.GetData<Color>();
// Draw a white \ on the image, we will assume tex1 is square for this task
for(int x = 0 ; x < Tex1.Width; x++)
for(int y = 0 ; y < Tex1.Width; y++)
if(x==y) TexSource[x + y * Tex1.Width] = Color.White;
您可以更改Update()中的纹理
但是,永远不要在 Draw() 永远创建或修改纹理。
SpriteBatch.Draw() 调用期望 GraphicsDevice 缓冲区包含所有纹理数据(通过 GPU 缓冲区扩展),此时仍在发生的任何更改(来自 Update 和 IsRunningSlowly == true)将导致渲染时撕裂。
GraphicsDevice.Textures[0] = null; 的解决方法阻止 Draw 调用和游戏,直到传输到 GPU 完成,从而减慢整个游戏循环。
【讨论】:
您需要使用之前使用 1 x 1 大小初始化的 Texture2D 对象的 SetData() 方法。
代码如下:
Texture2D pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new Color[] {Color.White});
编辑:
正如 Strom 在他的回答中提到的,必须在类级别声明 Texture2D 对象。 您应该避免在Draw() 方法中声明或修改纹理,因为它会减慢游戏循环。
【讨论】: