DirectX纹理无法正确绘制

时间:2017-05-04 15:59:25

标签: c++ graphics directx textures directx-11

我正在尝试使用DirectX 在没有 DirectXTK的情况下为屏幕渲染纹理。

这是我试图在屏幕上渲染的纹理(512x512px):

enter image description here

纹理正确加载,但当它被放到屏幕上时,它会出现如下:

Screenshot of rendered texture

我注意到渲染的图像似乎是在x方向上分割四次并且在y方向上多次分割的纹理。当纹理在屏幕下方呈现时,瓷砖的高度似乎会增加。

我对如何错误地渲染纹理有两点想法。

  • 我可能错误地初始化了纹理。
  • 我可能无法正确设置纹理采样器。

关于不正确的纹理初始化,这是我用来初始化纹理的代码。

Texture2D&着色器资源视图创建代码

加载纹理数据

这会将PNG文件的纹理加载到无符号字符的矢量中,并设置纹理的宽度和高度。

std::vector<unsigned char> fileData;
if (!loadFileToBuffer(fileName, fileData))
    return nullptr;
std::vector<unsigned char> imageData;
unsigned long width;
unsigned long height;
decodePNG(imageData, width, height, fileData.data(), fileData.size());

创建纹理描述

D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(D3D11_TEXTURE2D_DESC));
texDesc.Width = width;
texDesc.Height = height;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DYNAMIC;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;

指定纹理子资源数据

D3D11_SUBRESOURCE_DATA texData;
ZeroMemory(&texData, sizeof(D3D11_SUBRESOURCE_DATA));
texData.pSysMem = (void*)imageData.data();
texData.SysMemPitch = sizeof(unsigned char) * width;

//Create DirectX Texture In The Cache
HR(m_pDevice->CreateTexture2D(&texDesc, &texData, &m_textures[fileName]));

为纹理创建着色器资源视图

D3D11_SHADER_RESOURCE_VIEW_DESC srDesc;
ZeroMemory(&srDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
srDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srDesc.Texture2D.MipLevels = 1;

HR(m_pDevice->CreateShaderResourceView(m_textures[fileName], &srDesc,
    &m_resourceViews[fileName]));
return m_resourceViews[fileName];//This return value is used as "texture" in the next line

使用纹理资源

m_pDeviceContext->PSSetShaderResources(0, 1, &texture);

我已经搞乱了MipLevels和SampleDesc.Quality变量,看看他们是否正在改变纹理的某些内容,但更改它们会使纹理变黑或者没有做任何改变。

我还调查了SysMemPitch变量并确保它与MSDN

对齐

关于错误地设置我的采样器,这是​​我用来初始化我的采样器的代码。

//Setup Sampler
D3D11_SAMPLER_DESC samplerDesc;
ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC));

samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
samplerDesc.BorderColor[0] = 1.0f;
samplerDesc.BorderColor[1] = 1.0f;
samplerDesc.BorderColor[2] = 1.0f;
samplerDesc.BorderColor[3] = 1.0f;
samplerDesc.MinLOD = -FLT_MAX;
samplerDesc.MaxLOD = FLT_MAX;

HR(m_pDevice->CreateSamplerState(&samplerDesc, &m_pSamplerState));

//Use the sampler
m_pDeviceContext->PSSetSamplers(0, 1, &m_pSamplerState);

我尝试了不同的AddressU / V / W类型来查看纹理是否加载了不正确的宽度/高度,因此缩小了但是更改这些没有做任何事情。

我的VertexShader使用TEXCOORD0传递纹理坐标,我的PixelShader使用texture.Sample(samplerState, input.texCoord);来获取像素的颜色。

总之,我试图渲染纹理,但纹理得到平铺,我无法弄清楚原因。我需要更改/做什么来渲染我的一个纹理?

1 个答案:

答案 0 :(得分:2)

我认为你指的是错误的音调:

texData.SysMemPitch = sizeof(unsigned char) * width;

应该是

texData.SysMemPitch = 4 * sizeof(unsigned char) * width;

因为每个像素都有DXGI_FORMAT_R8G8B8A8_UNORM格式并占用4个字节。