2017-05-04 97 views
0

我想使用DirectX 而不是 DirectXTK渲染紋理到屏幕。DirectX紋理繪製不正確

這是我想在屏幕上顯示(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);來獲取像素的顏色。


總之,我試圖渲染貼圖,但紋理被平鋪,我無法找出原因。我需要改變/做什麼來渲染我的紋理之一?

回答

2

我想你分配了錯誤的間距:

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

應該

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

因爲每個像素都有DXGI_FORMAT_R8G8B8A8_UNORM格式,佔用4個字節。

+0

請參閱[DirectX Tool Kit](https://github.com/Microsoft/DirectXTK)以獲得一些用於加載紋理等的廣泛示例代碼。 –