ImGui + stb_image will not render image, renders a test image (?)

Viewed 873

I am trying to render JPEG or PNG images within ImGui using stb_image.h and DirectX11.

It gets the image information correctly, loads it into memory (pointers valid) and knows the image size. However it will not render the image, I've tried many .jpegs and .pngs incase it was a broken file but to no avail.

I'm using the DX11 example code provided by the ImGui developer but I don't seem to be having much luck. https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples#Example-for-DirectX11-users

My LoadTextureFromFile function, my edits are between the comment bars:

bool LoadTextureFromFile(const char* filename, ID3D11ShaderResourceView** out_srv, int* out_width, int* out_height)
{
    // Load from disk into a raw RGBA buffer
    int image_width = 0;
    int image_height = 0;
    unsigned char* image_data = stbi_load(filename, &image_width, &image_height, NULL, 4);
    if (image_data == NULL)
        return false;
    // Create texture
    D3D11_TEXTURE2D_DESC desc;
    ZeroMemory(&desc, sizeof(desc));
    desc.Width = image_width;
    desc.Height = image_height;
    desc.MipLevels = 1;
    desc.ArraySize = 1;
    desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    desc.SampleDesc.Count = 1;
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    desc.CPUAccessFlags = 0;

    ID3D11Texture2D* pTexture = NULL;
    D3D11_SUBRESOURCE_DATA subResource;
    subResource.pSysMem = image_data;
    subResource.SysMemPitch = desc.Width * 4;
    subResource.SysMemSlicePitch = 0;

////////////
    DWORD createDeviceFlags = 0;
    #ifdef _DEBUG
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif

    Microsoft::WRL::ComPtr<ID3D11Device> device;
    Microsoft::WRL::ComPtr<ID3D11DeviceContext> context;
    D3D_FEATURE_LEVEL fl;
    HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE,
        nullptr, createDeviceFlags, nullptr,
        0, D3D11_SDK_VERSION, &device, &fl, &context);
////////////
    device->CreateTexture2D(&desc, &subResource, &pTexture);
    // Create texture view
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    ZeroMemory(&srvDesc, sizeof(srvDesc));
    srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    srvDesc.Texture2D.MipLevels = desc.MipLevels;
    srvDesc.Texture2D.MostDetailedMip = 0;
    device->CreateShaderResourceView(pTexture, &srvDesc, out_srv);
    pTexture->Release();

    *out_width = image_width;
    *out_height = image_height;
    stbi_image_free(image_data);

    return true;
}

Initialised like this, once:

bool ret = LoadTextureFromFile("C:\\Users\\User\\Desktop\\MyImage01.png", &my_texture, &my_image_width, &my_image_height);

Displayed like this in a the GUI code body:

        ImGui::Begin("DirectX11 Texture Test");
        ImGui::Text("pointer = %p", my_texture);
        ImGui::Text("size = %d x %d", my_image_width, my_image_height);
        ImGui::Image((void*)my_texture, ImVec2(my_image_width, my_image_height));
        ImGui::End();

The end result is a window that displays the pointer and correct size but renders a strange image that looks like a placeholder. I don't know if my issue is strictly ImGui or stbi_image and if this placeholder is from ImGui or stbi.

Here is a screenshot of the window.

0 Answers
Related