C++ ImGui Не отображает DX11 Текстуру

Участник
Статус
Оффлайн
Регистрация
6 Сен 2020
Сообщения
755
Реакции[?]
367
Поинты[?]
8K
Загрузка текстуры:
void Renderer::LoadTextures() {
    LoadTexture("Images\\Coin.png", &Menu::ImageTextures.Coin);
    //LoadTexture("Images\\Seedling.png", info, pump, &Menu::ImageTextures.Seedling);
}

void Renderer::LoadTexture(std::string resourcePath, ID3D11Resource** texture) {
    auto fullPath = Globals::GetExecutablePath().string() + "\\Resources\\" + resourcePath;
    D3DX11_IMAGE_LOAD_INFO info;
    auto result = D3DX11CreateTextureFromFile(g_pd3dDevice, fullPath.c_str(), &info, NULL, texture, NULL);

    if (result != S_OK)
        Console::LogDebug("Something went wrong"); // Не выводится, то-есть загрузка текстуры прошла без ошибок (по документации microsoft)
}
Использование текстуры:
// в header-e
inline struct {
    ID3D11Resource* Coin;
    ID3D11Resource* Seedling;
} ImageTextures;

// в функции отрисовки меню
ImGui::Image(ImageTextures.Coin, ImVec2(32, 32)); // пустота в меню
LoadTextures вызывается после CreateDeviceD3D
 
Забаненный
Статус
Оффлайн
Регистрация
10 Авг 2023
Сообщения
5
Реакции[?]
0
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
чё-то странный у тебя код
 
артём диджитал дизайнер
Участник
Статус
Онлайн
Регистрация
10 Окт 2020
Сообщения
489
Реакции[?]
472
Поинты[?]
61K
привет, ID3D11Resource это базовый класс для любого ресурса DirectX11 (текстуры/буферы etc.), сам по себе он не предназначен для рендера. для рендера шейдера создавай и инициализируй ID3D11ShaderResourceView, его представление позволит imgui обращаться к буферу ресурса и юзать его для рендеринга.

C++:
ID3D11ShaderResourceView* Coin = nullptr;

void LoadTexture(std::string_view resourcePath, ID3D11ShaderResourceView** texture)
{
    auto fullPath = std::format("{}\\Resources\\{}", Globals::GetExecutablePath().string(), resourcePath);
    auto result = ::D3DX11CreateShaderResourceViewFromFileA(g_pd3dDevice, fullPath.c_str(), nullptr, nullptr, texture, nullptr);

    if (result != S_OK)
        Console::LogDebug("D3DX11CreateShaderResourceViewFromFileA failed");
}

LoadTexture("Images\\Coin.png", &Coin);
 
Участник
Статус
Оффлайн
Регистрация
6 Сен 2020
Сообщения
755
Реакции[?]
367
Поинты[?]
8K
привет, ID3D11Resource это базовый класс для любого ресурса DirectX11 (текстуры/буферы etc.), сам по себе он не предназначен для рендера. для рендера шейдера создавай и инициализируй ID3D11ShaderResourceView, его представление позволит imgui обращаться к буферу ресурса и юзать его для рендеринга.

C++:
ID3D11ShaderResourceView* Coin = nullptr;

void LoadTexture(std::string_view resourcePath, ID3D11ShaderResourceView** texture)
{
    auto fullPath = std::format("{}\\Resources\\{}", Globals::GetExecutablePath().string(), resourcePath);
    auto result = ::D3DX11CreateShaderResourceViewFromFileA(g_pd3dDevice, fullPath.c_str(), nullptr, nullptr, texture, nullptr);

    if (result != S_OK)
        Console::LogDebug("D3DX11CreateShaderResourceViewFromFileA failed");
}

LoadTexture("Images\\Coin.png", &Coin);
Спасибо, сделал с ресурсом но всё равно не работало, я вывел в ImGui такое:

C++:
if (ImageTextures.Coin == nullptr)
    ImGui::Text("Uninitialized texture");

ImGui::Image(ImageTextures.Coin, ImVec2(50, 50));
И выводится как раз то что текстура пустая
 
артём диджитал дизайнер
Участник
Статус
Онлайн
Регистрация
10 Окт 2020
Сообщения
489
Реакции[?]
472
Поинты[?]
61K
Спасибо, сделал с ресурсом но всё равно не работало, я вывел в ImGui такое:

C++:
if (ImageTextures.Coin == nullptr)
    ImGui::Text("Uninitialized texture");

ImGui::Image(ImageTextures.Coin, ImVec2(50, 50));
И выводится как раз то что текстура пустая
значит ты где-то в другом месте ошибся, дай больше контекста
1718865872535.png

лишний раз убедись что вызываешь LoadTextures после ImGui_ImplDX11_Init
 
Участник
Статус
Оффлайн
Регистрация
6 Сен 2020
Сообщения
755
Реакции[?]
367
Поинты[?]
8K
значит ты где-то в другом месте ошибся, дай больше контекста
Посмотреть вложение 279704

лишний раз убедись что вызываешь LoadTextures после ImGui_ImplDX11_Init
С поинтерами может быть проблема? Я попробовал вывести текст прямо в функции LoadTextures если ресурс = nullptr, не вывело, а в самой менюшке вывело.

Renderer.cpp:
void Renderer::Setup() {
    // тут создание класса окна и самого окна
    // тут инициализация dx11
    // показ окна
    // imgui context и стили

    // Setup Platform/Renderer backends
    ImGui_ImplWin32_Init(hwnd);
    ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);

    // Load Textures
    LoadTextures();
}

void Renderer::LoadTextures() {
    LoadTexture("Images\\Coin.png", &Menu::ImageTextures.Coin);
    LoadTexture("Images\\Seedling.png", &Menu::ImageTextures.Seedling);

    Console::LogDebug("Renderer::LoadTextures() -> Loaded Textures");
}

void Renderer::LoadTexture(std::string resourcePath, ID3D11ShaderResourceView** texture) {
    std::string fullPath = Globals::GetExecutablePath().string() + "\\Resources\\" + resourcePath;

    auto result = D3DX11CreateShaderResourceViewFromFile(g_pd3dDevice, fullPath.c_str(), NULL, NULL, texture, NULL);

    if (texture == nullptr)
        Console::LogDebug("nullptr"); // Не выводит

    if (result != S_OK)
        return Console::LogDebug("Renderer::LoadTexture() -> Failed to load texture " + fullPath);
}
Menu.hpp:
namespace Menu {
    struct {
        ID3D11ShaderResourceView* Coin;
        ID3D11ShaderResourceView* Seedling;
    } ImageTextures;

    // ...
}
Menu.cpp:
if (ImageTextures.Coin == nullptr)
    ImGui::Text("Uninitialized texture"); // Выводит

ImGui::Image(ImageTextures.Coin, ImVec2(50, 50));
 
артём диджитал дизайнер
Участник
Статус
Онлайн
Регистрация
10 Окт 2020
Сообщения
489
Реакции[?]
472
Поинты[?]
61K
С поинтерами может быть проблема? Я попробовал вывести текст прямо в функции LoadTextures если ресурс = nullptr, не вывело, а в самой менюшке вывело.

Renderer.cpp:
void Renderer::Setup() {
    // тут создание класса окна и самого окна
    // тут инициализация dx11
    // показ окна
    // imgui context и стили

    // Setup Platform/Renderer backends
    ImGui_ImplWin32_Init(hwnd);
    ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);

    // Load Textures
    LoadTextures();
}

void Renderer::LoadTextures() {
    LoadTexture("Images\\Coin.png", &Menu::ImageTextures.Coin);
    LoadTexture("Images\\Seedling.png", &Menu::ImageTextures.Seedling);

    Console::LogDebug("Renderer::LoadTextures() -> Loaded Textures");
}

void Renderer::LoadTexture(std::string resourcePath, ID3D11ShaderResourceView** texture) {
    std::string fullPath = Globals::GetExecutablePath().string() + "\\Resources\\" + resourcePath;

    auto result = D3DX11CreateShaderResourceViewFromFile(g_pd3dDevice, fullPath.c_str(), NULL, NULL, texture, NULL);

    if (texture == nullptr)
        Console::LogDebug("nullptr"); // Не выводит

    if (result != S_OK)
        return Console::LogDebug("Renderer::LoadTexture() -> Failed to load texture " + fullPath);
}
Menu.hpp:
namespace Menu {
    struct {
        ID3D11ShaderResourceView* Coin;
        ID3D11ShaderResourceView* Seedling;
    } ImageTextures;

    // ...
}
Menu.cpp:
if (ImageTextures.Coin == nullptr)
    ImGui::Text("Uninitialized texture"); // Выводит

ImGui::Image(ImageTextures.Coin, ImVec2(50, 50));
замени
Menu.hpp:
namespace Menu {
    struct {
        ID3D11ShaderResourceView* Coin;
        ID3D11ShaderResourceView* Seedling;
    } ImageTextures;
}
на
Menu.hpp:
namespace Menu {
    struct ImageTexturesStruct {
        ID3D11ShaderResourceView* Coin = nullptr;
        ID3D11ShaderResourceView* Seedling = nullptr;
    } inline ImageTextures;
}
 
Участник
Статус
Оффлайн
Регистрация
6 Сен 2020
Сообщения
755
Реакции[?]
367
Поинты[?]
8K
замени
Menu.hpp:
namespace Menu {
    struct {
        ID3D11ShaderResourceView* Coin;
        ID3D11ShaderResourceView* Seedling;
    } ImageTextures;
}
на
Menu.hpp:
namespace Menu {
    struct ImageTexturesStruct {
        ID3D11ShaderResourceView* Coin = nullptr;
        ID3D11ShaderResourceView* Seedling = nullptr;
    } inline ImageTextures;
}
Спасибо большое, сработало)
А можно узнать почему всё ломается с безымянной структурой?
 
артём диджитал дизайнер
Участник
Статус
Онлайн
Регистрация
10 Окт 2020
Сообщения
489
Реакции[?]
472
Поинты[?]
61K
Спасибо большое, сработало)
А можно узнать почему всё ломается с безымянной структурой?
честно, я и сам не уверен, но я думаю что проблема в том что объявление анонимной структуры находится в header-файле, и этот файл включается в несколько единиц трансляции, и в итоге каждая единица трансляции может иметь разные экземпляры структуры, и следовательно изменяя один экземпляр - ты не изменяешь другой, и фактически ты ожидаешь использования 1 экземпляра, но компилятор использует несколько, именно поэтому у тебя в одном файле присваивается нормальный адрес твоим переменным, а в другом файле эти же переменные равняются nullptr. если использовать именованную структуру в паре с inline при объявлении, компилятор поймёт что это именно эта переменная должна быть использована во всех единицах трансляции, создавая единый экземпляр для всех файлов
 
Сверху Снизу