设置像素数据的最佳方式? [英] Optimal way to set pixel data?

查看:58
本文介绍了设置像素数据的最佳方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一种落沙"风格的游戏.

I'm working on a "falling sand" style of game.

我尝试了多种将沙子绘制到屏幕上的方法,但是,每种方法似乎都会以一种或另一种形式产生一些问题.

I've tried many ways of drawing the sand to the screen, however, each way seems to produce some problem in one form or another.

我已经完成的事情列表:

List of things I've worked through:

  1. 单独绘制每个像素,从像素大小的纹理一次一个.问题:每次更新更改大约 100,000 个像素后速度变慢.

  1. Drawing each pixel individually, one at a time from a pixel sized texture. Problem: Slowed down after about 100,000 pixels were changing per update.

将每个像素绘制到一个大的texture2d,绘制texture2d,然后清除数据.问题:使用texture.SetPixel()非常慢,即使处理旧的纹理,也会导致小的内存泄漏(大约每秒30kb,加起来很快),即使在对象上调用dispose之后.我只是想不出如何阻止它.然而,总的来说,这是最好的方法(到目前为止).如果有办法阻止泄漏,我很想听听.

Drawing each pixel to one big texture2d, drawing the texture2d, then clearing the data. Problems: using texture.SetPixel() is very slow, and even with disposing the old texture, it would cause a small memory leak (about 30kb per second, which added up quick), even after calling dispose on the object. I simply could not figure out how to stop it. Overall, however, this has been the best method (so far). If there is a way to stop that leak, I'd like to hear it.

使用位图中的锁定位.从位图的角度来看,这非常有效,但不幸的是,我仍然必须将位图转换回 texture2d,这会导致帧速率下降到小于 1.所以,如果我能找到一种方法在 xna 中绘制位图而不转换它(或其他东西),这有可能会很好地工作.

Using Lockbits from bitmap. This worked wonderfully from the bitmaps perspective, but unfortunately, I still had to convert the bitmap back to a texture2d, which would cause the frame rate to drop to less than one. So, this has the potential to work very well, if I can find a way to draw the bitmap in xna without converting it (or something).

通过用透明像素替换像素的旧"位置,然后用适当的颜色设置新位置,将每个像素设置为具有设置像素的纹理2d.这使完成工作所需的像素集数量增加了一倍,并且比使用数字 2 慢得多.

Setting each pixel into a texture2d with set pixel, by replacing the 'old' position of pixels with transparent pixels, then setting the new position with the proper color. This doubled the number of pixel sets necessary to finish the job, and was much much slower than using number 2.

所以,我的问题是,有什么更好的主意吗?或者关于如何修复样式 2 或 3 的想法?

So, my question is, any better ideas? Or ideas on how to fix styles 2 or 3?

推荐答案

我的直接想法是您正在拖延 GPU 管道.GPU 的流水线可能会滞后于您发出的命令几帧.

My immediate thought is that you are stalling the GPU pipeline. The GPU can have a pipeline that lags several frames behind the commands that you are issuing.

因此,如果您发出命令以在纹理上设置数据,并且 GPU 当前正在使用该纹理渲染旧帧,则它必须先完成所有渲染,然后才能接受新纹理数据.所以它等待,扼杀你的表现.

So if you issue a command to set data on a texture, and the GPU is currently using that texture to render an old frame, it must finish all of its rendering before it can accept the new texture data. So it waits, killing your performance.

解决此问题的方法可能是在双(甚至三或四)缓冲区排列中使用多个纹理.不要尝试写入刚刚用于渲染的纹理.

The workaround for this might be to use several textures in a double- (or even triple- or quad-) buffer arrangement. Don't attempt to write to a texture that you have just used for rendering.

此外 - 您可以从渲染线程以外的线程写入纹理.这可能会派上用场,尤其是在清除纹理时.

Also - you can write to textures from a thread other than your rendering thread. This might come in handy, particularly for clearing textures.

正如您似乎已经发现的那样,实际上 SetData 大块比发出许多小的 SetData 调用更快.确定块"的理想大小因 GPU 而异 - 但它比单个像素大得多.

As you seem to have discovered, it's actually quicker to SetData in large chunks, rather than issue many, small SetData calls. Determining the ideal size for a "chunk" differs between GPUs - but it is a fair bit bigger than a single pixel.

此外,就原始性能而言,创建纹理比重用纹理要慢得多(如果您忽略我刚刚描述的管道效应);所以重用那个纹理.

Also, creating a texture is much slower than reusing one, in raw performance terms (if you ignore the pipeline effect I just described); so reuse that texture.

值得一提的是,像素精灵"需要向 GPU 发送的每像素数据可能是纹理的 30 倍.

It's worth mentioning that a "pixel sprite" requires sending maybe 30 times as much data per-pixel to the GPU than a texture.

另请参阅此答案,如果您想了解更多详细信息和一些深入链接深入一点.

See also this answer, which has a few more details and some in-depth links if you want to go deeper.

这篇关于设置像素数据的最佳方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆