DirectX 纹理未正确绘制
DirectX Texture Not Drawing Correctly
我正在尝试使用 DirectX 不使用 DirectXTK 将纹理渲染到屏幕。
这是我要在屏幕上渲染的纹理 (512x512px):
纹理加载正确,但是当它被放到屏幕上时,它是这样的:
我注意到渲染图像似乎是纹理在 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 类型来查看纹理是否加载了不正确的 width/height 并因此缩小,但改变这些没有任何作用。
我的 VertexShader 使用 TEXCOORD0
传递纹理坐标,我的 PixelShader 使用 texture.Sample(samplerState, input.texCoord);
获取像素的颜色。
总而言之,我正在尝试渲染纹理,但纹理平铺,我无法弄清楚原因。我需要什么才能 change/do 渲染我的纹理之一?
我认为你指定了错误的音调:
texData.SysMemPitch = sizeof(unsigned char) * width;
应该是
texData.SysMemPitch = 4 * sizeof(unsigned char) * width;
因为每个像素都有DXGI_FORMAT_R8G8B8A8_UNORM
格式,占用4个字节。
我正在尝试使用 DirectX 不使用 DirectXTK 将纹理渲染到屏幕。
这是我要在屏幕上渲染的纹理 (512x512px):
纹理加载正确,但是当它被放到屏幕上时,它是这样的:
我注意到渲染图像似乎是纹理在 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 类型来查看纹理是否加载了不正确的 width/height 并因此缩小,但改变这些没有任何作用。
我的 VertexShader 使用 TEXCOORD0
传递纹理坐标,我的 PixelShader 使用 texture.Sample(samplerState, input.texCoord);
获取像素的颜色。
总而言之,我正在尝试渲染纹理,但纹理平铺,我无法弄清楚原因。我需要什么才能 change/do 渲染我的纹理之一?
我认为你指定了错误的音调:
texData.SysMemPitch = sizeof(unsigned char) * width;
应该是
texData.SysMemPitch = 4 * sizeof(unsigned char) * width;
因为每个像素都有DXGI_FORMAT_R8G8B8A8_UNORM
格式,占用4个字节。