如何在 MonoGame/XNA 中逐像素动态绘制 2D?

How to draw on the fly 2D pixel-by-pixel in MonoGame/XNA?

我想知道如何在 XNA/MonoGame 中逐像素动态绘制,但只能找到 this。问题是,问题的核心不是如何实际逐个像素地绘制,而是管理资源和更新内容。

因为我找不到任何简单而简短的答案并且一直在想如何做,所以我将分享一个我偶然发现的片段(见答案)。

注意:如果有人有更好的方法或替代方法,请随时post或发表评论!

您需要使用之前用 1 x 1 大小初始化的 Texture2D 对象的 SetData() 方法。

代码如下:

Texture2D pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new Color[] {Color.White});

编辑: 正如 Strom 在他的回答中提到的那样,必须在 class 级别声明 Texture2D 对象。 您应该避免在 Draw() 方法中声明或修改纹理,因为它会减慢游戏循环。

为您的纹理和大小声明一个 class 级别变量:

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 缓冲区),任何变化仍在发生(来自更新和 IsRunningSlowly = = true) 此时渲染时会造成撕裂。

GraphicsDevice.Textures[0] = null; 的解决方法会阻止 Draw 调用和游戏,直到传输到 GPU 完成,从而减慢整个游戏循环。