Исходник ImGui загрузка raw изображений из интернета.

Stop Staring At the Shadows
Участник
Участник
Статус
Оффлайн
Регистрация
10 Окт 2020
Сообщения
535
Реакции
508
Всем привет, супер быстрый гайд (спать уже пора).

Когда я только начинал всю эту движуху с имгуем и плюсами в целом - эта тема меня очень интересовала, поэтому я решил показать самый простейший пример.
Здесь не будет использоваться всяких curl`ов и прочего, чистый wininet, поэтому парить голову для установки 100500 библиотек вам не нужно.
Таргет - DirectX 11, но переписать под вашу платформу можно очень просто (для тех кто совсем не тут - можете написать в телегу, перепишу под ваш directx)

Что нужно для использования?
1 - DirectX девайс
2 - Ссылка на "сырую" картинку, пример - откройте любое изображение в Discord и нажмите "Открыть в браузере", это и есть сырое изображение и ссылка на него.

ImageLoader.hpp:
Expand Collapse Copy
#ifndef IMAGE_LOADER_HPP
#define IMAGE_LOADER_HPP

#if _HAS_CXX17
#include <string_view>
#else
#include <string>
#endif

#include <d3d11.h>

class ImageLoader {
public:
#if _HAS_CXX17
    using string_t = std::string_view;
#else
    using string_t = const std::string&;
#endif

    ImageLoader() = default;
    ImageLoader(ID3D11Device* dx_device, string_t image_url);
    ~ImageLoader();

    /* Same as ImageLoader constructor just might be called later */
    void initialize(ID3D11Device* dx_device, string_t image_url);

    /* Get image instance */
    ID3D11ShaderResourceView* image() const noexcept;

private:;
    ID3D11ShaderResourceView* m_image;
};

#endif

ImageLoader.cpp:
Expand Collapse Copy
#include "ImageLoader.hpp"

#include <Windows.h>
#include <wininet.h>
#include <vector>
#include <stdexcept>
#include <memory>
#include <d3dx11.h>

#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "wininet.lib")

#define MAX_FILESIZE_TO_READ 4096

ImageLoader::ImageLoader(ID3D11Device* dx_device, string_t image_url) : m_image(nullptr)
{
    if (m_image != nullptr)
        return;

    initialize(dx_device, image_url);
}

ImageLoader::~ImageLoader() {}

void ImageLoader::initialize(ID3D11Device* dx_device, string_t image_url)
{
    if (m_image != nullptr)
        return;

    std::unique_ptr<std::remove_pointer_t<HINTERNET>, decltype(&InternetCloseHandle)>
        hInternet(InternetOpenA("ImGui ImageLoader", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0), InternetCloseHandle);

    if (!hInternet) {
        throw std::runtime_error("InternetOpenA failed");
    }

    std::unique_ptr<std::remove_pointer_t<HINTERNET>, decltype(&InternetCloseHandle)>
        hURL(InternetOpenUrlA(hInternet.get(), image_url.data(), NULL, 0, INTERNET_FLAG_RELOAD, 0), InternetCloseHandle);

    if (!hURL) {
        throw std::runtime_error("InternetOpenUrl failed");
    }

    std::vector<BYTE> image_data;
    std::vector<BYTE> buffer(MAX_FILESIZE_TO_READ); // Why the heap and not the stack? Because that's the way i want it.
    DWORD bytes_read = 0;
    while (InternetReadFile(hURL.get(), buffer.data(), MAX_FILESIZE_TO_READ, &bytes_read) && bytes_read > 0) {
        image_data.insert(image_data.end(), buffer.data(), buffer.data() + bytes_read);
    }

    D3DX11_IMAGE_LOAD_INFO image_load_info;
    ID3DX11ThreadPump* thread_pump{ nullptr };
    HRESULT hr = D3DX11CreateShaderResourceViewFromMemory(dx_device, image_data.data(), image_data.size(), &image_load_info, thread_pump, &m_image, 0);
    if (FAILED(hr)) {
        throw std::runtime_error("D3DX11CreateShaderResourceViewFromMemory failed");
    }
}

ID3D11ShaderResourceView* ImageLoader::image() const noexcept 
{ 
    return m_image; 
}

Пример использования:
1701823686166.png

1701823705285.png


Результат:

1701823773533.png
 
Последнее редактирование:
ебать спасибо
 
Всем привет, супер быстрый гайд (спать уже пора).

Когда я только начинал всю эту движуху с имгуем и плюсами в целом - эта тема меня очень интересовала, поэтому я решил показать самый простейший пример.
Здесь не будет использоваться всяких curl`ов и прочего, чистый wininet, поэтому парить голову для установки 100500 библиотек вам не нужно.
Таргет - DirectX 11, но переписать под вашу платформу можно очень просто (для тех кто совсем не тут - можете написать в телегу, перепишу под ваш directx)

Что нужно для использования?
1 - DirectX девайс
2 - Ссылка на "сырую" картинку, пример - откройте любое изображение в Discord и нажмите "Открыть в браузере", это и есть сырое изображение и ссылка на него.

ImageLoader.hpp:
Expand Collapse Copy
class ImageLoader {
public:
    ImageLoader() = default;
    ImageLoader(ID3D11Device* dx_device, const std::string& image_url);
    ~ImageLoader();

    /* Same as ImageLoader constructor just might be called later */
    void initialize(ID3D11Device* dx_device, const std::string& image_url);

    /* Get image instance */
    ID3D11ShaderResourceView* image() const noexcept;

private:;
    ID3D11ShaderResourceView* m_image;
};

ImageLoader.cpp:
Expand Collapse Copy
#include "ImageLoader.hpp"

#include <Windows.h>
#include <wininet.h>
#include <vector>
#include <stdexcept>
#include <memory>
#include <d3dx11.h>

#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "wininet.lib")

#define MAX_FILESIZE_TO_READ 4096

ImageLoader::ImageLoader(ID3D11Device* dx_device, const std::string& image_url) : m_image(nullptr)
{
    if (m_image != nullptr)
        return;

    initialize(dx_device, image_url);
}

ImageLoader::~ImageLoader() {}

void ImageLoader::initialize(ID3D11Device* dx_device, const std::string& image_url)
{
    if (m_image != nullptr)
        return;

    std::unique_ptr<std::remove_pointer_t<HINTERNET>, decltype(&InternetCloseHandle)>
        hInternet(InternetOpenA("ImGui ImageLoader", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0), InternetCloseHandle);

    if (!hInternet) {
        throw std::runtime_error("InternetOpenA failed");
    }

    std::unique_ptr<std::remove_pointer_t<HINTERNET>, decltype(&InternetCloseHandle)>
        hURL(InternetOpenUrlA(hInternet.get(), image_url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0), InternetCloseHandle);

    if (!hURL) {
        throw std::runtime_error("InternetOpenUrl failed");
    }

    std::vector<BYTE> image_data;
    std::vector<BYTE> buffer(MAX_FILESIZE_TO_READ); // Why the heap and not the stack? Because that's the way i want it.
    DWORD bytes_read = 0;
    while (InternetReadFile(hURL.get(), buffer.data(), MAX_FILESIZE_TO_READ, &bytes_read) && bytes_read > 0) {
        image_data.insert(image_data.end(), buffer.data(), buffer.data() + bytes_read);
    }

    D3DX11_IMAGE_LOAD_INFO image_load_info;
    ID3DX11ThreadPump* thread_pump{ nullptr };
    HRESULT hr = D3DX11CreateShaderResourceViewFromMemory(dx_device, image_data.data(), image_data.size(), &image_load_info, thread_pump, &m_image, 0);
    if (FAILED(hr)) {
        throw std::runtime_error("D3DX11CreateShaderResourceViewFromMemory failed");
    }
}

ID3D11ShaderResourceView* ImageLoader::image() const noexcept
{
    return m_image;
}

Пример использования:
Посмотреть вложение 265368
Посмотреть вложение 265369

Результат:

Посмотреть вложение 265370
а почему кеш не статичный
 
очень круто
 
Назад
Сверху Снизу