#pragma once #include #include #include #include #include #include #include #include // The launcher window's Direct3D 12 renderer and its image decoding. namespace dingosdk::launcher_gui::detail { using Microsoft::WRL::ComPtr; constexpr UINT frame_count = 2; class Renderer { public: bool init(HWND window); void render(); // The swap chain's buffers at the window's new client size, once the GPU is done with the old ones. void resize(UINT width, UINT height); // Uploads RGBA pixels into a free SRV slot (slot 0 is the font) and // returns its ImGui texture id; empty when the slots are used up. ImTextureID upload_texture(const std::vector& pixels, UINT width, UINT height); // Frees a texture's slot once the GPU is done with it (Mods browser icons). void release_texture(ImTextureID id); void shutdown(); private: struct Frame { ComPtr allocator; UINT64 fence_value{}; }; struct Target { ComPtr resource; D3D12_CPU_DESCRIPTOR_HANDLE handle{}; }; ComPtr device_; // The background photo, tile icons and Thunderstore package icons. static constexpr UINT max_textures = 160; std::vector> textures_; // index + 1 = SRV slot; null when free ComPtr rtv_heap_, srv_heap_; ComPtr queue_; ComPtr list_; ComPtr fence_; ComPtr swap_; std::array frames_; std::array targets_; HANDLE fence_event_{}; HANDLE waitable_{}; UINT64 fence_value_{}; UINT64 frame_index_{}; void wait(UINT64 value); }; // Decodes a JPEG/PNG with WIC, scaled down to cover `cover` pixels at most. bool decode_image(const std::vector& bytes, ImVec2 cover, std::vector& pixels, UINT& width, UINT& height); // ReSkateLauncher.background.jpg/.png beside the exe, else the embedded photo. std::vector background_bytes(const std::filesystem::path& directory); // An embedded RCDATA resource; empty when it is missing. std::vector resource_bytes(const wchar_t* name); } // namespace dingosdk::launcher_gui::detail