如何设置Direct3D纹理中单个像素的颜色?

时间:2009-05-04 01:45:53

标签: c++ graphics directx direct3d

我正在尝试在Direct3D中将2D图像绘制到屏幕上,我假设必须通过将纹理映射到投影到填充屏幕的矩形广告牌多边形来完成。 (我不感兴趣或不能使用Direct2D。)我在SDK中找到的所有纹理信息都描述了从文件加载位图并指定纹理来使用该位图,但我还没有找到一种方法来操作纹理作为位图逐像素。

我真正喜欢的是像

这样的功能

void TextureBitmap::SetBitmapPixel(int x, int y, DWORD color);

如果我不能直接在纹理对象中设置像素,我是否需要保留一个作为位图的DWORD数组,然后将纹理分配给每一帧?

最后,虽然我最初假设我将在CPU上执行此操作,但每像素颜色计算也可能在GPU上完成。 HLSL代码是设置纹理中单个像素的颜色,还是像素着色器仅用于修改显示像素?

感谢。

1 个答案:

答案 0 :(得分:4)

首先,直接提问:

从技术上讲,您可以在纹理中设置像素。这需要使用LockRectUnlockRect API。

在D3D上下文中,“锁定”通常是指将资源从GPU内存传输到系统内存(从而禁止其参与渲染操作)。锁定后,您可以根据需要修改填充的缓冲区,然后解锁 - 即将修改后的数据传输回GPU。 通常锁定被认为是非常昂贵的操作,但由于PCIe 2.0可能不再是主要问题。您还可以指定一个小的(甚至1像素)RECT作为LockRect的第二个参数,从而要求内存传输可忽略不计的数据量,并希望驱动程序确实足够聪明以便传输(我知道一个事实)在较旧的nVidia驱动程序中,情况并非如此)。

实现这一目标的更有效(和代码密集)的方式确实永远不会离开GPU。如果您create your texture作为RenderTarget(即,将D3DU​​SAGE_RENDERTARGET指定为其usage参数),则可以在进行任何绘制调用之前将其设置为管道的目标,并编写着色器(也许{ {3}})绘制像素。渲染目标的这种使用被认为是标准的,你应该能够找到许多代码样本 - 但除非你已经面临性能问题,否则我会说这对于单个2D广告牌来说太过分了。

HTH。