It's my first post here. My name is Bruno and I'm from Brazil. I'm trying to learn DirectX 11, and I'm using Frank Luna's book. The problem is that he uses the Effects Framework to do everything, and I have to port everything I learn. But now, I'm stuck at the Billboard Lesson (Geometry Shader).
Aparently, it seems to be a problem with the texture, but I tried changing everything, but still couldn't find what was wrong in code. I hope someone may help me on this. The billboards are drawn as full black quads, as if there was no texture, or if it was all black.
Here's the image:
Here's how it should be:
The HLSL codes are intact, I didn't do anything, except numbering the resources (register b0, t0, s0, etc). Here are 2 parts of my code, that I think may be broken.
void TreeBillboard::CreateTextureArray()
{
vector<ComPtr<ID3D11Texture2D>> textures(4);
HR(CreateDDSTextureFromFile(m_pDevice.Get(), L"../Direct3D11-Study/Textures/tree0.dds", reinterpret_cast<ID3D11Resource**>(textures[0].ReleaseAndGetAddressOf()), nullptr));
HR(CreateDDSTextureFromFile(m_pDevice.Get(), L"../Direct3D11-Study/Textures/tree1.dds", reinterpret_cast<ID3D11Resource**>(textures[1].ReleaseAndGetAddressOf()), nullptr));
HR(CreateDDSTextureFromFile(m_pDevice.Get(), L"../Direct3D11-Study/Textures/tree2.dds", reinterpret_cast<ID3D11Resource**>(textures[2].ReleaseAndGetAddressOf()), nullptr));
HR(CreateDDSTextureFromFile(m_pDevice.Get(), L"../Direct3D11-Study/Textures/tree3.dds", reinterpret_cast<ID3D11Resource**>(textures[3].ReleaseAndGetAddressOf()), nullptr));
//
// Create the texture array. Each element in the texture
// array has the same format/dimensions.
//
D3D11_TEXTURE2D_DESC texElementDesc;
textures[0]->GetDesc(&texElementDesc);
D3D11_TEXTURE2D_DESC texArrayDesc;
texArrayDesc.Width = texElementDesc.Width;
texArrayDesc.Height = texElementDesc.Height;
texArrayDesc.MipLevels = texElementDesc.MipLevels;
texArrayDesc.ArraySize = textures.size();
texArrayDesc.Format = texElementDesc.Format;
texArrayDesc.SampleDesc.Count = 1;
texArrayDesc.SampleDesc.Quality = 0;
texArrayDesc.Usage = D3D11_USAGE_DEFAULT;
texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texArrayDesc.CPUAccessFlags = 0;
texArrayDesc.MiscFlags = 0;
ID3D11Texture2D* texArray = 0;
HR(m_pDevice->CreateTexture2D( &texArrayDesc, 0, &texArray));
//
// Copy individual texture elements into texture array.
//
// for each texture element...
for(UINT texElement = 0; texElement < textures.size(); ++texElement)
{
// for each mipmap level...
for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel)
{
const uint32_t subResourceIndex = D3D11CalcSubresource(mipLevel, 0, texElementDesc.MipLevels);
const uint32_t destinationSubresource = D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels);
m_pContext->CopySubresourceRegion(texArray, static_cast<UINT> (destinationSubresource), 0, 0, 0, textures[texElement].Get(), subResourceIndex, nullptr);
}
}
//
// Create a resource view to the texture array.
//
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
viewDesc.Format = texArrayDesc.Format;
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
viewDesc.Texture2DArray.MostDetailedMip = 0;
viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels;
viewDesc.Texture2DArray.FirstArraySlice = 0;
viewDesc.Texture2DArray.ArraySize = textures.size();
HR(m_pDevice->CreateShaderResourceView(texArray, &viewDesc, m_pTexArraySRV.ReleaseAndGetAddressOf()));
//
// Cleanup--we only need the resource view.
//
for (UINT i = 0; i < textures.size(); i++)
{
textures[i].Reset();
}
};
And the Draw Tree Sprites function:
void TreeBillboard::DrawTreeSprites()
{
m_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
m_pContext->IASetInputLayout(m_pInputLayoutTree.Get());
m_pContext->VSSetShader(m_pVSTree.Get(), nullptr, 0);
m_pContext->GSSetShader(m_pGSTree.Get(), nullptr, 0);
m_pContext->PSSetShader(m_pPSTree.Get(), nullptr, 0);
m_pContext->PSSetSamplers(0, 1, m_pSamLinear.GetAddressOf());
ID3D11Buffer* buffers[3] = { m_pCBPerObjectTree.Get(), m_pCBPerFrame.Get(), m_pCBPerOption.Get() };
//m_pContext->VSSetConstantBuffers(0, 3, buffers);
m_pContext->GSSetConstantBuffers(0, 2, buffers);
m_pContext->PSSetConstantBuffers(0, 3, buffers);
XMStoreFloat4x4(&m_cbPerObjectTree.m_mViewProj, XMMatrixTranspose(XMLoadFloat4x4(&m_view) * XMLoadFloat4x4(&m_proj)));
m_cbPerObjectTree.m_material = m_treeMat;
D3D11_MAPPED_SUBRESOURCE mappedResource;
HR(m_pContext->Map(m_pCBPerObjectTree.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
CopyMemory(mappedResource.pData, reinterpret_cast<void*>(&m_cbPerObjectTree), sizeof(CBPerObjectTree));
m_pContext->Unmap(m_pCBPerObjectTree.Get(), 0);
UINT vertexSize = sizeof(TreeVertex);
UINT offset = 0;
m_pContext->IASetVertexBuffers(0, 1, m_pTreeVB.GetAddressOf(), &vertexSize, &offset);
float blendFactor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
//if(mAlphaToCoverageOn)
//{
m_pContext->OMSetBlendState(m_pAlphaToCoverageBS.Get(), blendFactor, 0xffffffff);
//}
//m_pContext->GSSetShaderResources(0, 1, m_pTexArraySRV.GetAddressOf());
m_pContext->PSSetShaderResources(0, 1, m_pTexArraySRV.GetAddressOf());
m_pContext->Draw(16, 0);
m_pContext->GSSetShader(nullptr, nullptr, 0);
m_pContext->OMSetBlendState(nullptr, blendFactor, 0xffffffff);
};
Hope someone can help. Thanks in advance.
PS: Let me know if you guys need any other part of the code. Also, I created this same topic in Gamedev forums -> http://www.gamedev.net/topic/653037-problem-with-billboarding-geometry-shader-and-texture-array/