Search code examples
c++directxdirectx-11hresultdds-format

Can't get CreateDDSTextureFromFile to work


So, I've been trying to figure out my problem for a few hours now, but I have no idea what I'm doing wrong. I'm a noob when it comes to DirectX programming, so I've been following some tutorials, and right now, I'm trying to create a obj loader. http://www.braynzarsoft.net/index.php?p=D3D11OBJMODEL

However, I can't get my texture to work.

This is how I try to load the DDS-texture:

ID3D11ShaderResourceView* tempMeshSRV = nullptr;
hr = CreateDDSTextureFromFile(gDevice, L"boxTexture.dds", NULL, &tempMeshSRV);

if (SUCCEEDED(hr))
 {
 textureNameArray.push_back(L"boxTexture.dds");
 material[matCount - 1].texArrayIndex = meshSRV.size();
 meshSRV.push_back(tempMeshSRV);
 material[matCount - 1].hasTexture = true;
 }

However, my HRESULT will never Succeed, but it doesn't crash either. If I hoover over the hr, it just says "HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) I also tried to remove the if statement, but that will just turn my box black. Any idea on what I'm doing wrong? =/

Thanks in advance!


Solution

  • The most likely problem is that your "boxTexture.dds" is a 24 bit-per-pixel format file. In Direct3D 9, this was D3DFMT_R8G8B8 and was reasonably common. However, there is no DXGI equivalent format for 24 bits-per-pixel and it therefore requires format conversion to work.

    The DDSTextureLoader module in DirectX Tool Kit is designed to be a minimum-overhead function, and therefore does no runtime conversions at all. If the data directly maps to a DXGI format, it loads. If it doesn't, it fails with HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).

    There are two different solutions depending on your usage scenario.

    1. The ideal solution is to convert 'boxTexture.dds' to a supported format. You can do this with the texconv command-line tool provided with DirectXTex. This is by far the best option so that the potentially expensive conversion operation is done once and not very single time your application runs and loads the data.
    2. If you don't actually control the source of the dds files you are trying load (i.e. they are arbitrary files provided by a user or you are doing some kind of content tool that has to support legacy formats), then you should make use of the DirectXTex 'full-fat' LoadFromDDSFile function which has extensive conversion code for handling legacy DDS file formats.

    Note this situation can happen for a number of legacy format DDS files as list in the CodePlex wiki documentation

    • D3DFMT_R8G8B8 (24bpp RGB) - Use a 32bpp format
    • D3DFMT_X8B8G8R8 (32bpp RGBX) - Use BGRX, BGRA, or RGBA
    • D3DFMT_A2R10G10B10 (BGRA 10:10:10:2) - Use RGBA 10:10:10:2
    • D3DFMT_X1R5G5B5 (BGR 5:5:5) - Use BGRA 5:5:5:1 or BGR 5:6:5
    • D3DFMT_A8R3G3B2, D3DFMT_R3G3B2 (BGR 3:3:2) - Expand to a supported format
    • D3DFMT_P8, D3DFMT_A8P8 (8-bit palette) - Expand to a supported format
    • D3DFMT_A4L4 (Luminance 4:4) - Expand to a supported format
    • D3DFMT_UYVY (YUV 4:2:2 16bpp) - Swizzle to YUY2

    See also Direct3D 11 Textures and Block Compression