如何使用 XNA API 绘制单个像素?

发布于 2024-10-09 06:20:29 字数 447 浏览 0 评论 0原文

如果我想用单独的彩色像素填充游戏屏幕,我该怎么做?

例如,如果我想编写一个“生命游戏”类型的游戏,其中每个像素都是一个单元格,我如何使用 XNA 实现这一点?

我尝试使用屏幕大小的 Color 值数组在 Texture2D 对象上调用 SetData(),但它抱怨:

当资源在 GraphicsDevice 上主动设置时,您不能对资源调用 SetData。

在调用 SetData 之前将其从设备中取消设置。

我该如何按照它的要求去做?或者更好的是......是否有一种替代的、更好的、有效的方法来用任意像素填充屏幕?

If I wanted to fill my game screen with individually coloured pixels, how would I do this?

For example, if I wanted to write a 'game of life'-type game where each pixel was a cell, how would I achieve this using XNA?

I've tried just calling SetData() on a Texture2D object using a screen-sized array of Color values, but it complains with:

You may not call SetData on a resource while it is actively set on the GraphicsDevice.

Unset it from the device before calling SetData.

How do I do as it asks? Or better still... is there an alternative, better, efficient way to fill a screen with arbitrary pixels?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

魔法唧唧 2024-10-16 06:20:29

关于您收到的错误,这意味着您正在尝试修改纹理数据,而它仍然绑定到设备上的采样器单元之一。您是否在 SpriteBatch.Begin/End 块内调用 SetData?如果是,那就是问题所在(在进行任何绘图之前更新纹理)。否则,您是否使用 GraphicsDevice.Textures[x] = yourTexture 直接在设备的纹理采样器之一上设置纹理?如果是,请在开始更改数据之前将Textures[x] 设置为null。

就您所做的事情的效率而言,它并不理想,但对于您的目的来说可能并不重要。尝试保持合理的图像分辨率,并意识到使用这种方法您可能不会达到 200 FPS,但在您开始担心性能之前,我会尝试一下,看看它是否足够快。

Regarding the error you're getting, it means you're attempting to modify the texture data while it is still bound to one of the sampler units on the device. Are you calling SetData inside of a SpriteBatch.Begin/End block? If you are, that's the problem (update your texture before you do any drawing). Otherwise are you setting your texture directly on one of the device's texture samplers, with GraphicsDevice.Textures[x] = yourTexture? If you are, set Textures[x] to null before you start changing the data.

As far as the efficiency of what you're doing, it's not ideal, but it probably doesn't matter for your purposes. Try to keep the image resolution reasonable and realize you're probably not going to hit 200 FPS with this approach, but I would try it and see if it's fast enough, before you start worrying about performance.

如梦 2024-10-16 06:20:29

在 Texture2D 上设置数据后,您将无法再更改它。解决这个问题的方法是创建一个 1x1 纹理 2D 并将其颜色设置为白色。然后,您将使用您想要像素的颜色来绘制它。由于您的纹理是白色的,因此所需的颜色将完美地呈现您选择的颜色。

Texture2D pixel = new Texture2D(App.GraphicsDevice, 1, 1);
colors = new Color[1];
colors[0] = Color.White;
pixel.SetData(colors);

这是一个使用上面的像素绘制像素的示例函数。

public void DrawPixel(SpriteBatch spriteBatch, Vector2 pos, Color tint)
{
    spriteBatch.Draw(pixel, pos, tint);
}

对每个像素绘制重复使用此Texture2D。

After setting the data on a Texture2D you cannot change it anymore. The way to get around this is by creating a 1x1 Texture2D and set its color to white. You will then draw it with a tint of what color you want the pixel to be. Since your texture is white, the desired color will come out shaded perfectly your color of choice.

Texture2D pixel = new Texture2D(App.GraphicsDevice, 1, 1);
colors = new Color[1];
colors[0] = Color.White;
pixel.SetData(colors);

This is a sample function to draw your pixel, using the pixel from above.

public void DrawPixel(SpriteBatch spriteBatch, Vector2 pos, Color tint)
{
    spriteBatch.Draw(pixel, pos, tint);
}

Reuse this Texture2D for every pixel draw.

小嗷兮 2024-10-16 06:20:29

最理想的方法是让你的着色器为你做这件事。在仅使用着色器之前,我已经实现了一个生命模拟游戏,其他人也使用 XNA http://www.xnainfo.com/content.php?content=21

这个想法是使用两种纹理,一种用于旧状态,一种用于新状态。设置它以便渲染到新纹理并从旧纹理读取。您可以直接在着色器中进行细胞自治:)。

您可以通过此获得出色的性能,我使用 1024x1024 网格时的帧速率约为 300fps。

The most ideal approach would be to get your shader to do it for you. I've implemented a game of life simulation before using only shaders, and others have done the same with XNA http://www.xnainfo.com/content.php?content=21.

The idea is to use two textures, one for the old state and one for the new state. Set it up so that you render to your new texture and read from the old one. You can do your cellular autonoma directly in the shader :).

You can get great performance with this, I had about 300fps using a 1024x1024 grid.

不气馁 2024-10-16 06:20:29

您可以使用我在此处提到的技术来绘制矩形SpriteBatch。然后您可以使用它来绘制覆盖屏幕的 1x1 矩形。我不知道它的性能如何,但它应该有效。

这篇应用中心帖子似乎讨论了您遇到的确切问题正在尝试解决。

You can use the technique I mention here to draw rectangles using SpriteBatch. You could then use that to draw 1x1 rectangles which cover the screen. I don't know how performant that would be but it should work.

This App Hub post seems to talk about the exact problem you're trying to solve.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文