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: enter image description here

Here's how it should be: enter image description here

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;

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. Also, I created this same topic in Gamedev forums -> http://www.gamedev.net/topic/653037-problem-with-billboarding-geometry-shader-and-texture-array/


closed as off-topic by Anko, Sean Middleditch, Josh Feb 8 '14 at 20:06

  • This question does not appear to be about game development within the scope defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ Two quick tips: check your textures if they are in fact loaded (been there once :) ), and maybe in PSSetShaderResources the second parameter should be the number of textures (But maybe I am utterly wrong, didn't try this method yet). \$\endgroup\$ – János Turánszki Feb 5 '14 at 21:40
  • \$\begingroup\$ Hey János, thanks for the reply. I did check by setting the land texture with the array texture (even though in the land hlsl file the texture variable is not a array) and it did print the trees on the ground, so at least one tree got loaded. Also, if I set the number of shader resources to 4, the program stops working. It's a shame there's not much info on how to load texture arrays without using the effects framework or using the old D3DX helper functions. Anyway, I'll keep trying other stuff. Thank you again. \$\endgroup\$ – Bdv Feb 5 '14 at 21:51
  • \$\begingroup\$ Did you try this with a single texture? Also, be sure to check the graphics debugger in the new Visual Studio (if you haven't done already), I would be checking for the correct input of the shader. \$\endgroup\$ – János Turánszki Feb 5 '14 at 22:16
  • \$\begingroup\$ I did, but then it doesn't show anything (for the billboards, the rest of the scene is ok). Now I have also changed the texture formats from BC1 to R8G8B8A8_UNORM, and now it also doesn't draw anything, not even those black quads. So I don't know what is going on. I hope someone that did study Luna's books knows how to handle this. Thanks again János! \$\endgroup\$ – Bdv Feb 5 '14 at 22:36
  • \$\begingroup\$ This question appears to be off-topic because it is about debugging your code for you. \$\endgroup\$ – Josh Feb 8 '14 at 20:06

A guy nicknamed "unbird" at Gamedev.net found the problem. Here's the link to the solution.

"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)"


Thank you everyone for your time, János, unbird.


Not the answer you're looking for? Browse other questions tagged or ask your own question.