Jump to content
  • Advertisement
Sign in to follow this  

Problem with Billboarding, Geometry Shader and Texture Array

This topic is 2085 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone.
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.


Create Texture Array function:

void TreeBillboard::CreateTextureArray()
vector<ComPtr<ID3D11Texture2D>> textures(4);
ID3D11ShaderResourceView* v = nullptr;
HR(CreateDDSTextureFromFile(m_pDevice.Get(), L"../Direct3D11-Study/Textures/tree0.dds", reinterpret_cast<ID3D11Resource**>(textures[0].ReleaseAndGetAddressOf()), &v));
v->Release(); v = nullptr;
HR(CreateDDSTextureFromFile(m_pDevice.Get(), L"../Direct3D11-Study/Textures/tree1.dds", reinterpret_cast<ID3D11Resource**>(textures[1].ReleaseAndGetAddressOf()), &v));
v->Release(); v = nullptr;
HR(CreateDDSTextureFromFile(m_pDevice.Get(), L"../Direct3D11-Study/Textures/tree2.dds", reinterpret_cast<ID3D11Resource**>(textures[2].ReleaseAndGetAddressOf()), &v));
v->Release(); v = nullptr;
HR(CreateDDSTextureFromFile(m_pDevice.Get(), L"../Direct3D11-Study/Textures/tree3.dds", reinterpret_cast<ID3D11Resource**>(textures[3].ReleaseAndGetAddressOf()), &v));
v->Release(); v = nullptr;
// Create the texture array.  Each element in the texture 
// array has the same format/dimensions.
D3D11_TEXTURE2D_DESC 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.
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++)

And the Draw Tree Sprites function:

void TreeBillboard::DrawTreeSprites()
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};
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.

Edited by Bdv

Share this post

Link to post
Share on other sites

There's also a constant buffer for the tex-coords (cbFixed), filled with default values. These only work with the effect framework, so you have to fill it manually and set it to the correct slot, just like the other constant buffers. For this particular case I for one wouldn't even use a constant buffer but declare this array as a static (which then gets hardwired in the shader)

Share this post

Link to post
Share on other sites

Thank you very much, unbird. You solved the mistery, man. I really appreciate it.


Here's how it's looking now:



Also, thanks for the heads up about the fixed values in that constant buffer, I really didn't know that it would make a difference.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!