DirectX 11改变像素字节

时间:2016-01-27 16:46:44

标签: visual-c++ directx-11

按照本指南here

我的任务是使用map和unmap方法在屏幕上画一条线,方法是将像素字节数据设置为rgb红色值"。

我有精灵和背景显示,但不知道如何获取数据。

我也试过这样做:

//Create device
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = 500;
desc.Height = 300;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;


m_d3dDevice->CreateTexture2D(&desc, nullptr, &texture);
m_d3dDevice->CreateShaderResourceView(texture, 0, &textureView);

// Render
D3D11_MAPPED_SUBRESOURCE mapped;
m_d3dContext->Map(texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);

data = (BYTE*)mapped.pData;
rows = (BYTE)sizeof(data);

std::cout << "hi" << std::endl;
m_d3dContext->Unmap(texture, 0);

问题在于,在这种情况下,数据数组的大小为0,但有一个指针。这意味着我指的是一个没有任何数据的纹理,或者我没有得到这个?

编辑: 目前我找到了

D3D11_SHADER_RESOURCE_VIEW_DESC desc;
m_background->GetDesc(&desc);
desc.Buffer; // buffer

2 个答案:

答案 0 :(得分:0)

首先,大多数函数返回您忽略的HRESULT值。这是不安全的,因为您将错过使剩余代码无效的重要错误。您可以根据需要使用if(FAILED(...)),也可以使用ThrowIfFailed,但是您无法忽略正常运行的应用中的返回值。

HRESULT hr = m_d3dDevice->CreateTexture2D(&desc, nullptr, &texture);
if (FAILED(hr))
    // error!
hr = m_d3dDevice->CreateShaderResourceView(texture, 0, &textureView);
if (FAILED(hr))
    // error!

// Render
D3D11_MAPPED_SUBRESOURCE mapped;
hr = m_d3dContext->Map(texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
if (FAILED(hr))
    // error!

其次,您应该启用Debug Device并查找诊断输出,这可能会指出您失败的原因。

sizeof(data)总是4或8,因为数据是BYTE*,即指针的大小。它与数据数组的大小无关。 mapped.pData指向的锁定缓冲区大小为mapped.RowPitch * desc.Height个字节。

您必须逐行将像素数据复制到其中。根据格式和其他因素,mapped.RowPitch不一定是4 * desc.Width - 每个像素4个字节,因为您使用的格式为DXGI_FORMAT_B8G8R8A8_UNORM。它应该至少是那么大,但是可以更大来调整整体尺寸。

这是伪代码,不一定是一种有效的方法,但是:

for(UINT y = 0; y < desc.Height; ++y )
{
    for(UINT x = 0; x < desc.Width; ++x )
    {
        // Find the memory location of the pixel at (x,y)
        int pixel = y * mapped.RowPitch + (x*4)
        BYTE* blue = data[pixel];
        BYTE* green = data[pixel] + 1;
        BYTE* red = data[pixel] + 2;
        BYTE* alpha = data[pixel] + 3;

        *blue = /* value between 0 and 255 */;
        *green = /* value between 0 and 255 */;
        *red = /* value between 0 and 255 */;
        *alpha = /* value between 0 and 255 */;
    }
}

你应该看看DirectXTex,它做了很多这种逐行处理。

答案 1 :(得分:0)

我觉得有必要为此创建答案,就像我搜索如何做到这一点一样。这个问题首先弹出,提供的答案对我来说并没有真正解决问题,也不是我想这样做的方式...

在我的程序中,我有以下方法。

Traceback (most recent call last):
  File "/tmp/785402618/main.py", line 29, in <module>
    print(rotations(1000))
  File "/tmp/785402618/main.py", line 25, in rotations
    if is_prime(rotater) in numString == True: 
  File "/tmp/785402618/main.py", line 2, in is_prime
    m = int(n)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

然后使用以下代码测试了绘制带有白线的蓝色正方形。而且效果很好。在查看WICTextureLoader类后,我遇到的问题是设置系统内存切片和内存间距,从而能够弄清楚数据的存储方式。这样看来

MemPitch =行的大小(以字节为单位)。 MemSlice =总图像像素大小(以字节为单位)。

pigz *