mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-09-09 17:50:58 +02:00
Update code to work with new version of ImGui.
UpdateImGuiTexture now handles creating font textures and modifying them.
This commit is contained in:
@@ -20,6 +20,11 @@ AbstractTexture::AbstractTexture(const TextureConfig& c) : m_config(c)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractTexture::operator ImTextureRef() const
|
||||||
|
{
|
||||||
|
return ImTextureRef(reinterpret_cast<AbstractTexture::imgui_texture_id>(this));
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractTexture::FinishedRendering()
|
void AbstractTexture::FinishedRendering()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -10,15 +10,18 @@
|
|||||||
#include "Common/MathUtil.h"
|
#include "Common/MathUtil.h"
|
||||||
#include "VideoCommon/TextureConfig.h"
|
#include "VideoCommon/TextureConfig.h"
|
||||||
|
|
||||||
|
struct ImTextureRef;
|
||||||
|
|
||||||
class AbstractTexture
|
class AbstractTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit AbstractTexture(const TextureConfig& c);
|
explicit AbstractTexture(const TextureConfig& c);
|
||||||
virtual ~AbstractTexture() = default;
|
virtual ~AbstractTexture() = default;
|
||||||
|
|
||||||
// Support implicit conversion between AbstractTexture and ImTextureId
|
// Support implicit conversion between AbstractTexture and ImTextureId and ImTextureRef.
|
||||||
using imgui_texture_id = unsigned long long;
|
using imgui_texture_id = unsigned long long;
|
||||||
operator imgui_texture_id() const { return reinterpret_cast<imgui_texture_id>(this); }
|
operator imgui_texture_id() const { return reinterpret_cast<imgui_texture_id>(this); }
|
||||||
|
operator ImTextureRef() const;
|
||||||
|
|
||||||
virtual void CopyRectangleFromTexture(const AbstractTexture* src,
|
virtual void CopyRectangleFromTexture(const AbstractTexture* src,
|
||||||
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
|
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "VideoCommon/AbstractGfx.h"
|
#include "VideoCommon/AbstractGfx.h"
|
||||||
#include "VideoCommon/AbstractPipeline.h"
|
#include "VideoCommon/AbstractPipeline.h"
|
||||||
#include "VideoCommon/AbstractShader.h"
|
#include "VideoCommon/AbstractShader.h"
|
||||||
|
#include "VideoCommon/AbstractStagingTexture.h"
|
||||||
#include "VideoCommon/FramebufferShaderGen.h"
|
#include "VideoCommon/FramebufferShaderGen.h"
|
||||||
#include "VideoCommon/NetPlayChatUI.h"
|
#include "VideoCommon/NetPlayChatUI.h"
|
||||||
#include "VideoCommon/NetPlayGolfUI.h"
|
#include "VideoCommon/NetPlayGolfUI.h"
|
||||||
@@ -71,30 +72,12 @@ bool OnScreenUI::Initialize(u32 width, u32 height, float scale)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Font texture(s).
|
// Font defaults
|
||||||
{
|
m_imgui_textures.clear();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
u8* font_tex_pixels;
|
|
||||||
int font_tex_width, font_tex_height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&font_tex_pixels, &font_tex_width, &font_tex_height);
|
|
||||||
|
|
||||||
TextureConfig font_tex_config(font_tex_width, font_tex_height, 1, 1, 1,
|
// Setup new font management behavior.
|
||||||
AbstractTextureFormat::RGBA8, 0,
|
ImGui::GetIO().BackendFlags |=
|
||||||
AbstractTextureType::Texture_2DArray);
|
ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasVtxOffset;
|
||||||
std::unique_ptr<AbstractTexture> font_tex =
|
|
||||||
g_gfx->CreateTexture(font_tex_config, "ImGui font texture");
|
|
||||||
if (!font_tex)
|
|
||||||
{
|
|
||||||
PanicAlertFmt("Failed to create ImGui texture");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
font_tex->Load(0, font_tex_width, font_tex_height, font_tex_width, font_tex_pixels,
|
|
||||||
sizeof(u32) * font_tex_width * font_tex_height);
|
|
||||||
|
|
||||||
io.Fonts->TexID = *font_tex.get();
|
|
||||||
|
|
||||||
m_imgui_textures.push_back(std::move(font_tex));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RecompileImGuiPipeline())
|
if (!RecompileImGuiPipeline())
|
||||||
return false;
|
return false;
|
||||||
@@ -113,6 +96,7 @@ OnScreenUI::~OnScreenUI()
|
|||||||
ImGui::EndFrame();
|
ImGui::EndFrame();
|
||||||
ImPlot::DestroyContext();
|
ImPlot::DestroyContext();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
m_imgui_textures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnScreenUI::RecompileImGuiPipeline()
|
bool OnScreenUI::RecompileImGuiPipeline()
|
||||||
@@ -252,7 +236,7 @@ void OnScreenUI::DrawImGui()
|
|||||||
static_cast<int>(cmd.ClipRect.x), static_cast<int>(cmd.ClipRect.y),
|
static_cast<int>(cmd.ClipRect.x), static_cast<int>(cmd.ClipRect.y),
|
||||||
static_cast<int>(cmd.ClipRect.z), static_cast<int>(cmd.ClipRect.w)),
|
static_cast<int>(cmd.ClipRect.z), static_cast<int>(cmd.ClipRect.w)),
|
||||||
g_gfx->GetCurrentFramebuffer()));
|
g_gfx->GetCurrentFramebuffer()));
|
||||||
g_gfx->SetTexture(0, reinterpret_cast<const AbstractTexture*>(cmd.TextureId));
|
g_gfx->SetTexture(0, reinterpret_cast<const AbstractTexture*>(cmd.GetTexID()));
|
||||||
g_gfx->DrawIndexed(base_index, cmd.ElemCount, base_vertex);
|
g_gfx->DrawIndexed(base_index, cmd.ElemCount, base_vertex);
|
||||||
base_index += cmd.ElemCount;
|
base_index += cmd.ElemCount;
|
||||||
}
|
}
|
||||||
@@ -410,6 +394,98 @@ void OnScreenUI::Finalize()
|
|||||||
OSD::DrawMessages();
|
OSD::DrawMessages();
|
||||||
DrawChallengesAndLeaderboards();
|
DrawChallengesAndLeaderboards();
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
|
// Create or update fonts.
|
||||||
|
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
UpdateImguiTexture(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnScreenUI::UpdateImguiTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
|
{
|
||||||
|
// Create new font texture.
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
TextureConfig font_tex_config(tex->Width, tex->Height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0,
|
||||||
|
AbstractTextureType::Texture_2DArray);
|
||||||
|
std::unique_ptr<AbstractTexture> font_tex =
|
||||||
|
g_gfx->CreateTexture(font_tex_config, "ImGui font texture");
|
||||||
|
|
||||||
|
if (!font_tex)
|
||||||
|
{
|
||||||
|
PanicAlertFmt("Failed to create ImGui texture");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_tex->Load(0, tex->Width, tex->Height, tex->Width, tex->Pixels,
|
||||||
|
sizeof(u32) * tex->Width * tex->Height);
|
||||||
|
|
||||||
|
tex->SetTexID(static_cast<ImTextureID>(*font_tex.get()));
|
||||||
|
// Keeps the texture alive.
|
||||||
|
m_imgui_textures.push_back(std::move(font_tex));
|
||||||
|
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
AbstractTexture* font_tex = reinterpret_cast<AbstractTexture*>(tex->GetTexID());
|
||||||
|
|
||||||
|
if (!font_tex || tex->TexID == ImTextureID_Invalid)
|
||||||
|
{
|
||||||
|
PanicAlertFmt("ImGui texture not created before update");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const ImTextureRect& r : tex->Updates)
|
||||||
|
{
|
||||||
|
// Rect of texture that will be updated.
|
||||||
|
const int x_offset = static_cast<int>(r.x);
|
||||||
|
const int y_offset = static_cast<int>(r.y);
|
||||||
|
const int width = static_cast<int>(r.w);
|
||||||
|
const int height = static_cast<int>(r.h);
|
||||||
|
|
||||||
|
// Create a staging texture to update the font texture with.
|
||||||
|
TextureConfig font_tex_config(width, height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0,
|
||||||
|
AbstractTextureType::Texture_2DArray);
|
||||||
|
std::unique_ptr<AbstractStagingTexture> stage =
|
||||||
|
g_gfx->CreateStagingTexture(StagingTextureType::Upload, font_tex_config);
|
||||||
|
|
||||||
|
const int src_pitch = width * tex->BytesPerPixel;
|
||||||
|
|
||||||
|
// Write to staging texture.
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
const MathUtil::Rectangle<int> rect_line = {0, y, width, y + 1};
|
||||||
|
stage->WriteTexels(rect_line, tex->GetPixelsAt(x_offset, y_offset + y), src_pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy to font texture.
|
||||||
|
const MathUtil::Rectangle<int> rect_staging = {0, 0, width, height};
|
||||||
|
const MathUtil::Rectangle<int> rect_target = {x_offset, y_offset, width + x_offset,
|
||||||
|
height + y_offset};
|
||||||
|
|
||||||
|
stage->CopyToTexture(rect_staging, font_tex, rect_target, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
|
{
|
||||||
|
AbstractTexture* font_tex = reinterpret_cast<AbstractTexture*>(tex->GetTexID());
|
||||||
|
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
|
||||||
|
m_imgui_textures.erase(
|
||||||
|
std::find_if(m_imgui_textures.begin(), m_imgui_textures.end(),
|
||||||
|
[font_tex](auto& element) { return element.get() == font_tex; }));
|
||||||
|
|
||||||
|
tex->Status = ImTextureStatus_Destroyed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock<std::mutex> OnScreenUI::GetImGuiLock()
|
std::unique_lock<std::mutex> OnScreenUI::GetImGuiLock()
|
||||||
@@ -421,12 +497,14 @@ void OnScreenUI::SetScale(float backbuffer_scale)
|
|||||||
{
|
{
|
||||||
ImGui::GetIO().DisplayFramebufferScale.x = backbuffer_scale;
|
ImGui::GetIO().DisplayFramebufferScale.x = backbuffer_scale;
|
||||||
ImGui::GetIO().DisplayFramebufferScale.y = backbuffer_scale;
|
ImGui::GetIO().DisplayFramebufferScale.y = backbuffer_scale;
|
||||||
ImGui::GetIO().FontGlobalScale = backbuffer_scale;
|
|
||||||
// ScaleAllSizes scales in-place, so calling it twice will double-apply the scale
|
// ScaleAllSizes scales in-place, so calling it twice will double-apply the scale
|
||||||
// Reset the style first so that the scale is applied to the base style, not an already-scaled one
|
// Reset the style first so that the scale is applied to the base style, not an already-scaled one
|
||||||
ImGui::GetStyle() = {};
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::GetStyle().WindowRounding = 7.0f;
|
style = {};
|
||||||
ImGui::GetStyle().ScaleAllSizes(backbuffer_scale);
|
style.FontScaleMain = backbuffer_scale;
|
||||||
|
style.WindowRounding = 7.0f;
|
||||||
|
style.ScaleAllSizes(backbuffer_scale);
|
||||||
|
|
||||||
m_backbuffer_scale = backbuffer_scale;
|
m_backbuffer_scale = backbuffer_scale;
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
class NativeVertexFormat;
|
class NativeVertexFormat;
|
||||||
class AbstractTexture;
|
class AbstractTexture;
|
||||||
class AbstractPipeline;
|
class AbstractPipeline;
|
||||||
|
class ImTextureData;
|
||||||
|
|
||||||
namespace VideoCommon
|
namespace VideoCommon
|
||||||
{
|
{
|
||||||
@@ -62,6 +63,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void DrawDebugText();
|
void DrawDebugText();
|
||||||
void DrawChallengesAndLeaderboards();
|
void DrawChallengesAndLeaderboards();
|
||||||
|
void UpdateImguiTexture(ImTextureData* tex);
|
||||||
|
|
||||||
// ImGui resources.
|
// ImGui resources.
|
||||||
std::unique_ptr<NativeVertexFormat> m_imgui_vertex_format;
|
std::unique_ptr<NativeVertexFormat> m_imgui_vertex_format;
|
||||||
|
Reference in New Issue
Block a user