ImGui: Add font path and size options to InterfacePane and adjust common ImGui draws that break from variable sizes.
This commit is contained in:
parent
2e22a3cf42
commit
9f56a3f6f1
|
@ -422,6 +422,8 @@ const Info<bool> MAIN_USE_BUILT_IN_TITLE_DATABASE{
|
|||
{System::Main, "Interface", "UseBuiltinTitleDatabase"}, true};
|
||||
const Info<std::string> MAIN_THEME_NAME{{System::Main, "Interface", "ThemeName"},
|
||||
DEFAULT_THEME_DIR};
|
||||
const Info<std::string> MAIN_IMGUI_FONT_PATH{{System::Main, "Interface", "ImguiFontPath"}, ""};
|
||||
const Info<int> MAIN_IMGUI_FONT_SIZE{{System::Main, "Interface", "ImguiFontSize"}, 16};
|
||||
const Info<bool> MAIN_PAUSE_ON_FOCUS_LOST{{System::Main, "Interface", "PauseOnFocusLost"}, false};
|
||||
const Info<bool> MAIN_ENABLE_DEBUGGING{{System::Main, "Interface", "DebugModeEnabled"}, false};
|
||||
|
||||
|
|
|
@ -255,6 +255,8 @@ extern const Info<std::string> MAIN_INTERFACE_LANGUAGE;
|
|||
extern const Info<bool> MAIN_SHOW_ACTIVE_TITLE;
|
||||
extern const Info<bool> MAIN_USE_BUILT_IN_TITLE_DATABASE;
|
||||
extern const Info<std::string> MAIN_THEME_NAME;
|
||||
extern const Info<std::string> MAIN_IMGUI_FONT_PATH;
|
||||
extern const Info<int> MAIN_IMGUI_FONT_SIZE;
|
||||
extern const Info<bool> MAIN_PAUSE_ON_FOCUS_LOST;
|
||||
extern const Info<bool> MAIN_ENABLE_DEBUGGING;
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QRadioButton>
|
||||
#include <QStandardPaths>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
|
@ -28,14 +30,19 @@
|
|||
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
|
||||
#include "DolphinQt/Config/ConfigControls/ConfigChoice.h"
|
||||
#include "DolphinQt/Config/ConfigControls/ConfigRadio.h"
|
||||
#include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
|
||||
#include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h"
|
||||
#include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h"
|
||||
#include "DolphinQt/QtUtils/DolphinFileDialog.h"
|
||||
#include "DolphinQt/QtUtils/ModalMessageBox.h"
|
||||
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
|
||||
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
#include "UICommon/GameFile.h"
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
static ConfigStringChoice* MakeLanguageComboBox()
|
||||
{
|
||||
using QPair = std::pair<QString, QString>;
|
||||
|
@ -151,6 +158,37 @@ void InterfacePane::CreateUI()
|
|||
|
||||
m_combobox_userstyle->addItem(tr("(System)"), static_cast<int>(Settings::StyleType::System));
|
||||
|
||||
// ImGui Font
|
||||
auto* imgui_layout = new QHBoxLayout;
|
||||
|
||||
m_imgui_font_edit =
|
||||
new QLineEdit(QString::fromStdString(Config::Get(Config::MAIN_IMGUI_FONT_PATH)), this);
|
||||
connect(m_imgui_font_edit, &QLineEdit::editingFinished, [this] {
|
||||
Config::SetBase(Config::MAIN_IMGUI_FONT_PATH, m_imgui_font_edit->text().toStdString());
|
||||
});
|
||||
|
||||
QPushButton* imgui_font_browse = new NonDefaultQPushButton(QStringLiteral("..."));
|
||||
connect(imgui_font_browse, &QPushButton::clicked, this, &InterfacePane::ImguiFontBrowse);
|
||||
|
||||
imgui_layout->addWidget(m_imgui_font_edit);
|
||||
imgui_layout->addWidget(imgui_font_browse);
|
||||
imgui_layout->setContentsMargins(0, 0, 0, 0);
|
||||
combobox_layout->addRow(tr("Imgui Font Path:"), imgui_layout);
|
||||
|
||||
// ImGui Font Size
|
||||
auto* imgui_size_layout = new QHBoxLayout();
|
||||
|
||||
m_imgui_size = new ConfigSlider(12, 40, Config::MAIN_IMGUI_FONT_SIZE);
|
||||
auto* imgui_size_number = new QLabel(QString::number(m_imgui_size->value()));
|
||||
connect(m_imgui_size, &QSlider::valueChanged, this, [this, imgui_size_number](int value) {
|
||||
imgui_size_number->setText(QString::number(value));
|
||||
});
|
||||
|
||||
imgui_size_layout->addWidget(m_imgui_size);
|
||||
imgui_size_layout->addWidget(imgui_size_number);
|
||||
imgui_size_layout->setContentsMargins(0, 0, 0, 0);
|
||||
combobox_layout->addRow(tr("Imgui Font Size:"), imgui_size_layout);
|
||||
|
||||
// TODO: Support forcing light/dark on other OSes too.
|
||||
#ifdef _WIN32
|
||||
m_combobox_userstyle->addItem(tr("(Light)"), static_cast<int>(Settings::StyleType::Light));
|
||||
|
@ -315,6 +353,23 @@ void InterfacePane::OnUserStyleChanged()
|
|||
Settings::Instance().ApplyStyle();
|
||||
}
|
||||
|
||||
void InterfacePane::ImguiFontBrowse()
|
||||
{
|
||||
QString path = QString::fromStdString(Config::Get(Config::MAIN_IMGUI_FONT_PATH));
|
||||
if (path.isEmpty())
|
||||
path = QStandardPaths::standardLocations(QStandardPaths::FontsLocation)[0];
|
||||
|
||||
QString file = QDir::toNativeSeparators(
|
||||
DolphinFileDialog::getOpenFileName(this, tr("Select ttf Font"), path, QStringLiteral("*.ttf"),
|
||||
nullptr, QFileDialog::DontUseNativeDialog));
|
||||
|
||||
if (!file.isEmpty())
|
||||
{
|
||||
Config::SetBaseOrCurrent(Config::MAIN_IMGUI_FONT_PATH, file.toStdString());
|
||||
m_imgui_font_edit->setText(file);
|
||||
}
|
||||
}
|
||||
|
||||
void InterfacePane::OnLanguageChanged()
|
||||
{
|
||||
ModalMessageBox::information(
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
#include <QWidget>
|
||||
|
||||
class ConfigBool;
|
||||
class ConfigSlider;
|
||||
class ConfigRadioInt;
|
||||
class ConfigStringChoice;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QVBoxLayout;
|
||||
class ToolTipCheckBox;
|
||||
class ToolTipComboBox;
|
||||
|
@ -33,6 +35,7 @@ private:
|
|||
void UpdateShowDebuggingCheckbox();
|
||||
void LoadUserStyle();
|
||||
void OnUserStyleChanged();
|
||||
void ImguiFontBrowse();
|
||||
void OnLanguageChanged();
|
||||
|
||||
void OnEmulationStateChanged(Core::State state);
|
||||
|
@ -43,6 +46,8 @@ private:
|
|||
ConfigStringChoice* m_combobox_theme;
|
||||
ToolTipComboBox* m_combobox_userstyle;
|
||||
QLabel* m_label_userstyle;
|
||||
QLineEdit* m_imgui_font_edit;
|
||||
ConfigSlider* m_imgui_size;
|
||||
ConfigBool* m_checkbox_top_window;
|
||||
ConfigBool* m_checkbox_use_builtin_title_database;
|
||||
ToolTipCheckBox* m_checkbox_show_debugging_ui;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "VideoCommon/OnScreenUI.h"
|
||||
|
||||
#include "Common/EnumMap.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Profiler.h"
|
||||
#include "Common/Timer.h"
|
||||
|
||||
|
@ -57,6 +58,7 @@ bool OnScreenUI::Initialize(u32 width, u32 height, float scale)
|
|||
|
||||
// Don't create an ini file. TODO: Do we want this in the future?
|
||||
ImGui::GetIO().IniFilename = nullptr;
|
||||
SetFont();
|
||||
SetScale(scale);
|
||||
|
||||
PortableVertexDeclaration vdecl = {};
|
||||
|
@ -71,31 +73,6 @@ bool OnScreenUI::Initialize(u32 width, u32 height, float scale)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Font texture(s).
|
||||
{
|
||||
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,
|
||||
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 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())
|
||||
return false;
|
||||
|
||||
|
@ -183,6 +160,10 @@ bool OnScreenUI::RecompileImGuiPipeline()
|
|||
|
||||
void OnScreenUI::BeginImGuiFrame(u32 width, u32 height)
|
||||
{
|
||||
// Check for font changes
|
||||
if (Config::Get(Config::MAIN_IMGUI_FONT_PATH) != m_custom_font_path ||
|
||||
Config::Get(Config::MAIN_IMGUI_FONT_SIZE) != m_custom_font_size)
|
||||
SetFont();
|
||||
std::unique_lock<std::mutex> imgui_lock(m_imgui_mutex);
|
||||
BeginImGuiFrameUnlocked(width, height);
|
||||
}
|
||||
|
@ -279,11 +260,12 @@ void OnScreenUI::DrawDebugText()
|
|||
{
|
||||
// Position under the FPS display.
|
||||
ImGui::SetNextWindowPos(
|
||||
ImVec2(ImGui::GetIO().DisplaySize.x - 10.f * m_backbuffer_scale, 80.f * m_backbuffer_scale),
|
||||
ImVec2(ImGui::GetIO().DisplaySize.x - ImGui::GetFontSize() * m_backbuffer_scale,
|
||||
80.f * m_backbuffer_scale),
|
||||
ImGuiCond_FirstUseEver, ImVec2(1.0f, 0.0f));
|
||||
ImGui::SetNextWindowSizeConstraints(
|
||||
ImVec2(150.0f * m_backbuffer_scale, 20.0f * m_backbuffer_scale),
|
||||
ImGui::GetIO().DisplaySize);
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(5.0f * ImGui::GetFontSize() * m_backbuffer_scale,
|
||||
2.1f * ImGui::GetFontSize() * m_backbuffer_scale),
|
||||
ImGui::GetIO().DisplaySize);
|
||||
if (ImGui::Begin("Movie", nullptr, ImGuiWindowFlags_NoFocusOnAppearing))
|
||||
{
|
||||
auto& movie = Core::System::GetInstance().GetMovie();
|
||||
|
@ -417,6 +399,60 @@ std::unique_lock<std::mutex> OnScreenUI::GetImGuiLock()
|
|||
return std::unique_lock<std::mutex>(m_imgui_mutex);
|
||||
}
|
||||
|
||||
void OnScreenUI::SetFont()
|
||||
{
|
||||
const std::string path = Config::Get(Config::MAIN_IMGUI_FONT_PATH);
|
||||
const bool custom_font = !path.empty() && File::Exists(path) && path.ends_with(".ttf");
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// If imgui has already been loaded and is running.
|
||||
if (ImGui::GetFrameCount() != 0)
|
||||
{
|
||||
if (!custom_font)
|
||||
return;
|
||||
|
||||
io.Fonts->Clear();
|
||||
}
|
||||
|
||||
if (custom_font)
|
||||
{
|
||||
m_custom_font_path = path;
|
||||
m_custom_font_size = Config::Get(Config::MAIN_IMGUI_FONT_SIZE);
|
||||
|
||||
// Small font for things like graph labels. Called with FONTS[0].
|
||||
io.Fonts->AddFontFromFileTTF(path.c_str(), 14.0f);
|
||||
auto* user_font = io.Fonts->AddFontFromFileTTF(path.c_str(), m_custom_font_size);
|
||||
|
||||
io.Fonts->Build();
|
||||
io.FontDefault = user_font;
|
||||
}
|
||||
|
||||
// This always runs once on loading a game. Only runs again if changing fonts.
|
||||
m_imgui_textures.clear();
|
||||
|
||||
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,
|
||||
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, 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));
|
||||
}
|
||||
|
||||
void OnScreenUI::SetScale(float backbuffer_scale)
|
||||
{
|
||||
ImGui::GetIO().DisplayFramebufferScale.x = backbuffer_scale;
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
// Recompiles ImGui pipeline - call when stereo mode changes.
|
||||
bool RecompileImGuiPipeline();
|
||||
|
||||
void SetFont();
|
||||
void SetScale(float backbuffer_scale);
|
||||
|
||||
void Finalize();
|
||||
|
@ -79,6 +80,8 @@ private:
|
|||
std::map<int, std::unique_ptr<AbstractTexture>, std::less<>> m_challenge_texture_map;
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
|
||||
std::string m_custom_font_path;
|
||||
int m_custom_font_size;
|
||||
bool m_ready = false;
|
||||
};
|
||||
} // namespace VideoCommon
|
||||
|
|
|
@ -127,7 +127,6 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
|
|||
}
|
||||
|
||||
const float window_padding = 8.f * backbuffer_scale;
|
||||
const float window_width = 93.f * backbuffer_scale;
|
||||
|
||||
const ImVec2& display_size = ImGui::GetIO().DisplaySize;
|
||||
const bool display_size_changed =
|
||||
|
@ -161,9 +160,8 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
|
|||
ImGui::SetWindowPos(ImVec2(clamped_window_x, clamped_window_y), ImGuiCond_Always);
|
||||
};
|
||||
|
||||
const float graph_width = 50.f * backbuffer_scale + 3.f * window_width + 2.f * window_padding;
|
||||
const float graph_height =
|
||||
std::min(200.f * backbuffer_scale, display_size.y - 85.f * backbuffer_scale);
|
||||
const float graph_width = display_size.x / 4.0;
|
||||
const float graph_height = display_size.y / 4.0;
|
||||
|
||||
const bool stack_vertically = !g_ActiveConfig.bShowGraphs;
|
||||
|
||||
|
@ -171,17 +169,20 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 14.f * backbuffer_scale);
|
||||
if (g_ActiveConfig.bShowGraphs)
|
||||
{
|
||||
// Force smaller font
|
||||
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[0]);
|
||||
ImGui::PushStyleColor(ImGuiCol_ResizeGrip, 0);
|
||||
const auto graph_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings |
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav | movable_flag |
|
||||
ImGuiWindowFlags_NoFocusOnAppearing;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 4.f * backbuffer_scale));
|
||||
|
||||
// Position in the top-right corner of the screen.
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition,
|
||||
ImVec2(1.0f, 0.0f));
|
||||
ImGui::SetNextWindowSize(ImVec2(graph_width, graph_height));
|
||||
ImGui::SetNextWindowSize(ImVec2(graph_width, graph_height), ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowBgAlpha(bg_alpha);
|
||||
window_y += graph_height + window_padding;
|
||||
|
||||
if (ImGui::Begin("PerformanceGraphs", nullptr, imgui_flags))
|
||||
if (ImGui::Begin("PerformanceGraphs", nullptr, graph_flags))
|
||||
{
|
||||
static constexpr std::size_t num_ticks = 17;
|
||||
static constexpr std::array<double, num_ticks> tick_marks = {0.0,
|
||||
|
@ -203,6 +204,7 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
|
|||
2000.0};
|
||||
|
||||
clamp_window_position();
|
||||
window_y += ImGui::GetWindowHeight();
|
||||
|
||||
const DT vblank_time = m_vps_counter.GetDtAvg() + 2 * m_vps_counter.GetDtStd();
|
||||
const DT frame_time = m_fps_counter.GetDtAvg() + 2 * m_fps_counter.GetDtStd();
|
||||
|
@ -245,25 +247,23 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
|
|||
ImGui::PopStyleVar();
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
if (g_ActiveConfig.bShowSpeed)
|
||||
{
|
||||
// Position in the top-right corner of the screen.
|
||||
float window_height = 47.f * backbuffer_scale;
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition,
|
||||
ImVec2(1.0f, 0.0f));
|
||||
ImGui::SetNextWindowSize(ImVec2(window_width, window_height));
|
||||
ImGui::SetNextWindowBgAlpha(bg_alpha);
|
||||
|
||||
if (stack_vertically)
|
||||
window_y += window_height + window_padding;
|
||||
else
|
||||
window_x -= window_width + window_padding;
|
||||
|
||||
if (ImGui::Begin("SpeedStats", nullptr, imgui_flags))
|
||||
{
|
||||
if (stack_vertically)
|
||||
window_y += ImGui::GetWindowHeight() + window_padding;
|
||||
else
|
||||
window_x -= ImGui::GetWindowWidth() + window_padding;
|
||||
clamp_window_position();
|
||||
ImGui::TextColored(ImVec4(r, g, b, 1.0f), "Speed:%4.0lf%%", 100.0 * speed);
|
||||
ImGui::TextColored(ImVec4(r, g, b, 1.0f), "Max:%6.0lf%%", 100.0 * GetMaxSpeed());
|
||||
|
@ -273,22 +273,17 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
|
|||
|
||||
if (g_ActiveConfig.bShowFPS || g_ActiveConfig.bShowFTimes)
|
||||
{
|
||||
int count = g_ActiveConfig.bShowFPS + 2 * g_ActiveConfig.bShowFTimes;
|
||||
float window_height = (12.f + 17.f * count) * backbuffer_scale;
|
||||
|
||||
// Position in the top-right corner of the screen.
|
||||
ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition,
|
||||
ImVec2(1.0f, 0.0f));
|
||||
ImGui::SetNextWindowSize(ImVec2(window_width, window_height));
|
||||
ImGui::SetNextWindowBgAlpha(bg_alpha);
|
||||
|
||||
if (stack_vertically)
|
||||
window_y += window_height + window_padding;
|
||||
else
|
||||
window_x -= window_width + window_padding;
|
||||
|
||||
if (ImGui::Begin("FPSStats", nullptr, imgui_flags))
|
||||
{
|
||||
if (stack_vertically)
|
||||
window_y += ImGui::GetWindowHeight() + window_padding;
|
||||
else
|
||||
window_x -= ImGui::GetWindowWidth() + window_padding;
|
||||
clamp_window_position();
|
||||
if (g_ActiveConfig.bShowFPS)
|
||||
ImGui::TextColored(ImVec4(r, g, b, 1.0f), "FPS:%7.2lf", fps);
|
||||
|
@ -305,22 +300,17 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
|
|||
|
||||
if (g_ActiveConfig.bShowVPS || g_ActiveConfig.bShowVTimes)
|
||||
{
|
||||
int count = g_ActiveConfig.bShowVPS + 2 * g_ActiveConfig.bShowVTimes;
|
||||
float window_height = (12.f + 17.f * count) * backbuffer_scale;
|
||||
|
||||
// Position in the top-right corner of the screen.
|
||||
ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition,
|
||||
ImVec2(1.0f, 0.0f));
|
||||
ImGui::SetNextWindowSize(ImVec2(window_width, (12.f + 17.f * count) * backbuffer_scale));
|
||||
ImGui::SetNextWindowBgAlpha(bg_alpha);
|
||||
|
||||
if (stack_vertically)
|
||||
window_y += window_height + window_padding;
|
||||
else
|
||||
window_x -= window_width + window_padding;
|
||||
|
||||
if (ImGui::Begin("VPSStats", nullptr, imgui_flags))
|
||||
{
|
||||
if (stack_vertically)
|
||||
window_y += ImGui::GetWindowHeight() + window_padding;
|
||||
else
|
||||
window_x -= ImGui::GetWindowWidth() + window_padding;
|
||||
clamp_window_position();
|
||||
if (g_ActiveConfig.bShowVPS)
|
||||
ImGui::TextColored(ImVec4(r, g, b, 1.0f), "VPS:%7.2lf", vps);
|
||||
|
|
Loading…
Reference in New Issue