mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #7478 from stenzek/imgui
Replace raster font with dear imgui
This commit is contained in:
@@ -21,7 +21,16 @@ import java.lang.ref.WeakReference;
|
||||
*/
|
||||
public final class NativeLibrary
|
||||
{
|
||||
public static WeakReference<EmulationActivity> sEmulationActivity = new WeakReference<>(null);
|
||||
private static WeakReference<EmulationActivity> sEmulationActivity = new WeakReference<>(null);
|
||||
|
||||
/**
|
||||
* Returns the current instance of EmulationActivity.
|
||||
* There should only ever be one EmulationActivity instantiated.
|
||||
*/
|
||||
public static EmulationActivity getEmulationActivity()
|
||||
{
|
||||
return sEmulationActivity.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Button type for use in onTouchEvent
|
||||
|
||||
+2
-2
@@ -31,7 +31,7 @@ public class Java_GCAdapter
|
||||
|
||||
private static void RequestPermission()
|
||||
{
|
||||
Context context = NativeLibrary.sEmulationActivity.get();
|
||||
Context context = NativeLibrary.getEmulationActivity();
|
||||
if (context != null)
|
||||
{
|
||||
HashMap<String, UsbDevice> devices = manager.getDeviceList();
|
||||
@@ -141,7 +141,7 @@ public class Java_GCAdapter
|
||||
}
|
||||
}
|
||||
|
||||
final Activity emulationActivity = NativeLibrary.sEmulationActivity.get();
|
||||
final Activity emulationActivity = NativeLibrary.getEmulationActivity();
|
||||
if (emulationActivity != null)
|
||||
{
|
||||
emulationActivity.runOnUiThread(() -> Toast.makeText(emulationActivity,
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ public class Java_WiimoteAdapter
|
||||
|
||||
private static void RequestPermission()
|
||||
{
|
||||
Context context = NativeLibrary.sEmulationActivity.get();
|
||||
Context context = NativeLibrary.getEmulationActivity();
|
||||
if (context != null)
|
||||
{
|
||||
HashMap<String, UsbDevice> devices = manager.getDeviceList();
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
|
||||
#include "../../Core/Common/WindowSystemInfo.h"
|
||||
#include "jni/AndroidCommon/AndroidCommon.h"
|
||||
#include "jni/AndroidCommon/IDCache.h"
|
||||
#include "jni/ButtonManager.h"
|
||||
@@ -589,15 +590,57 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ReloadWiimot
|
||||
Wiimote::LoadConfig();
|
||||
}
|
||||
|
||||
static void Run(const std::vector<std::string>& paths, bool first_open,
|
||||
// Returns the scale factor for imgui rendering.
|
||||
// Based on the scaledDensity of the device's display metrics.
|
||||
static float GetRenderSurfaceScale(JNIEnv* env)
|
||||
{
|
||||
// NativeLibrary emulation_activity = NativeLibrary.getEmulationActivity();
|
||||
jclass native_library_class = env->FindClass("org/dolphinemu/dolphinemu/NativeLibrary");
|
||||
jmethodID get_emulation_activity_method =
|
||||
env->GetStaticMethodID(native_library_class, "getEmulationActivity",
|
||||
"()Lorg/dolphinemu/dolphinemu/activities/EmulationActivity;");
|
||||
jobject emulation_activity =
|
||||
env->CallStaticObjectMethod(native_library_class, get_emulation_activity_method);
|
||||
|
||||
// WindowManager window_manager = emulation_activity.getWindowManager();
|
||||
jmethodID get_window_manager_method =
|
||||
env->GetMethodID(env->GetObjectClass(emulation_activity), "getWindowManager",
|
||||
"()Landroid/view/WindowManager;");
|
||||
jobject window_manager = env->CallObjectMethod(emulation_activity, get_window_manager_method);
|
||||
|
||||
// Display display = window_manager.getDisplay();
|
||||
jmethodID get_display_method = env->GetMethodID(env->GetObjectClass(window_manager),
|
||||
"getDefaultDisplay", "()Landroid/view/Display;");
|
||||
jobject display = env->CallObjectMethod(window_manager, get_display_method);
|
||||
|
||||
// DisplayMetrics metrics = new DisplayMetrics();
|
||||
jclass display_metrics_class = env->FindClass("android/util/DisplayMetrics");
|
||||
jmethodID display_metrics_constructor = env->GetMethodID(display_metrics_class, "<init>", "()V");
|
||||
jobject metrics = env->NewObject(display_metrics_class, display_metrics_constructor);
|
||||
|
||||
// display.getMetrics(metrics);
|
||||
jmethodID get_metrics_method = env->GetMethodID(env->GetObjectClass(display), "getMetrics",
|
||||
"(Landroid/util/DisplayMetrics;)V");
|
||||
env->CallVoidMethod(display, get_metrics_method, metrics);
|
||||
|
||||
// float scaled_density = metrics.scaledDensity;
|
||||
jfieldID scaled_density_field =
|
||||
env->GetFieldID(env->GetObjectClass(metrics), "scaledDensity", "F");
|
||||
float scaled_density = env->GetFloatField(metrics, scaled_density_field);
|
||||
__android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Using %f for render surface scale.",
|
||||
scaled_density);
|
||||
|
||||
// cleanup
|
||||
env->DeleteLocalRef(metrics);
|
||||
return scaled_density;
|
||||
}
|
||||
|
||||
static void Run(JNIEnv* env, const std::vector<std::string>& paths, bool first_open,
|
||||
std::optional<std::string> savestate_path = {}, bool delete_savestate = false)
|
||||
{
|
||||
ASSERT(!paths.empty());
|
||||
__android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Running : %s", paths[0].c_str());
|
||||
|
||||
// Install our callbacks
|
||||
OSD::AddCallback(OSD::CallbackType::Shutdown, ButtonManager::Shutdown);
|
||||
|
||||
RegisterMsgAlertHandler(&MsgAlert);
|
||||
Common::AndroidSetReportHandler(&ReportSend);
|
||||
DolphinAnalytics::AndroidSetGetValFunc(&GetAnalyticValue);
|
||||
@@ -617,6 +660,7 @@ static void Run(const std::vector<std::string>& paths, bool first_open,
|
||||
std::unique_ptr<BootParameters> boot = BootParameters::GenerateFromFile(paths, savestate_path);
|
||||
boot->delete_savestate = delete_savestate;
|
||||
WindowSystemInfo wsi(WindowSystemType::Android, nullptr, s_surf);
|
||||
wsi.render_surface_scale = GetRenderSurfaceScale(env);
|
||||
if (BootManager::BootCore(std::move(boot), wsi))
|
||||
{
|
||||
ButtonManager::Init(SConfig::GetInstance().GetGameID());
|
||||
@@ -639,6 +683,7 @@ static void Run(const std::vector<std::string>& paths, bool first_open,
|
||||
}
|
||||
|
||||
Core::Shutdown();
|
||||
ButtonManager::Shutdown();
|
||||
UICommon::Shutdown();
|
||||
guard.unlock();
|
||||
|
||||
@@ -652,14 +697,14 @@ static void Run(const std::vector<std::string>& paths, bool first_open,
|
||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run___3Ljava_lang_String_2Z(
|
||||
JNIEnv* env, jobject obj, jobjectArray jPaths, jboolean jfirstOpen)
|
||||
{
|
||||
Run(JStringArrayToVector(env, jPaths), jfirstOpen);
|
||||
Run(env, JStringArrayToVector(env, jPaths), jfirstOpen);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_NativeLibrary_Run___3Ljava_lang_String_2Ljava_lang_String_2Z(
|
||||
JNIEnv* env, jobject obj, jobjectArray jPaths, jstring jSavestate, jboolean jDeleteSavestate)
|
||||
{
|
||||
Run(JStringArrayToVector(env, jPaths), false, GetJString(env, jSavestate), jDeleteSavestate);
|
||||
Run(env, JStringArrayToVector(env, jPaths), false, GetJString(env, jSavestate), jDeleteSavestate);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ChangeDisc(JNIEnv* env,
|
||||
|
||||
@@ -32,4 +32,7 @@ struct WindowSystemInfo
|
||||
// on the platform. e.g. HWND for Windows, Window for X11. If the surface is
|
||||
// set to nullptr, the video backend will run in headless mode.
|
||||
void* render_surface = nullptr;
|
||||
|
||||
// Scale of the render surface. For hidpi systems, this will be >1.
|
||||
float render_surface_scale = 1.0f;
|
||||
};
|
||||
|
||||
@@ -143,6 +143,7 @@ PRIVATE
|
||||
core
|
||||
Qt5::Widgets
|
||||
uicommon
|
||||
imgui
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
||||
@@ -463,6 +463,9 @@
|
||||
<ProjectReference Include="$(CoreDir)VideoBackends\Vulkan\Vulkan.vcxproj">
|
||||
<Project>{29f29a19-f141-45ad-9679-5a2923b49da3}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\Externals\imgui\imgui.vcxproj">
|
||||
<Project>{4c3b2264-ea73-4a7b-9cfe-65b0fd635ebb}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "DolphinQt/HotkeyScheduler.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <thread>
|
||||
|
||||
#include <QCoreApplication>
|
||||
@@ -26,6 +27,7 @@
|
||||
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
|
||||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
@@ -286,43 +288,62 @@ void HotkeyScheduler::Run()
|
||||
else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_4))
|
||||
m_profile_cycler.NextWiimoteProfileForGame(3);
|
||||
|
||||
const auto show_msg = [](OSDMessage message) {
|
||||
if (g_renderer)
|
||||
g_renderer->ShowOSDMessage(message);
|
||||
auto ShowVolume = []() {
|
||||
OSD::AddMessage(std::string("Volume: ") +
|
||||
(SConfig::GetInstance().m_IsMuted ?
|
||||
"Muted" :
|
||||
std::to_string(SConfig::GetInstance().m_Volume)) +
|
||||
"%");
|
||||
};
|
||||
|
||||
// Volume
|
||||
if (IsHotkey(HK_VOLUME_DOWN))
|
||||
{
|
||||
show_msg(OSDMessage::VolumeChanged);
|
||||
settings.DecreaseVolume(3);
|
||||
ShowVolume();
|
||||
}
|
||||
|
||||
if (IsHotkey(HK_VOLUME_UP))
|
||||
{
|
||||
show_msg(OSDMessage::VolumeChanged);
|
||||
settings.IncreaseVolume(3);
|
||||
ShowVolume();
|
||||
}
|
||||
|
||||
if (IsHotkey(HK_VOLUME_TOGGLE_MUTE))
|
||||
{
|
||||
show_msg(OSDMessage::VolumeChanged);
|
||||
AudioCommon::ToggleMuteVolume();
|
||||
ShowVolume();
|
||||
}
|
||||
|
||||
// Graphics
|
||||
const auto efb_scale = Config::Get(Config::GFX_EFB_SCALE);
|
||||
auto ShowEFBScale = []() {
|
||||
switch (Config::Get(Config::GFX_EFB_SCALE))
|
||||
{
|
||||
case EFB_SCALE_AUTO_INTEGRAL:
|
||||
OSD::AddMessage("Internal Resolution: Auto (integral)");
|
||||
break;
|
||||
case 1:
|
||||
OSD::AddMessage("Internal Resolution: Native");
|
||||
break;
|
||||
default:
|
||||
OSD::AddMessage("Internal Resolution: %dx", g_Config.iEFBScale);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if (IsHotkey(HK_INCREASE_IR))
|
||||
{
|
||||
show_msg(OSDMessage::IRChanged);
|
||||
Config::SetCurrent(Config::GFX_EFB_SCALE, efb_scale + 1);
|
||||
ShowEFBScale();
|
||||
}
|
||||
if (IsHotkey(HK_DECREASE_IR))
|
||||
{
|
||||
show_msg(OSDMessage::IRChanged);
|
||||
if (efb_scale > EFB_SCALE_AUTO_INTEGRAL)
|
||||
{
|
||||
Config::SetCurrent(Config::GFX_EFB_SCALE, efb_scale - 1);
|
||||
ShowEFBScale();
|
||||
}
|
||||
}
|
||||
|
||||
if (IsHotkey(HK_TOGGLE_CROP))
|
||||
@@ -330,34 +351,55 @@ void HotkeyScheduler::Run()
|
||||
|
||||
if (IsHotkey(HK_TOGGLE_AR))
|
||||
{
|
||||
show_msg(OSDMessage::ARToggled);
|
||||
const int aspect_ratio = (static_cast<int>(Config::Get(Config::GFX_ASPECT_RATIO)) + 1) & 3;
|
||||
Config::SetCurrent(Config::GFX_ASPECT_RATIO, static_cast<AspectMode>(aspect_ratio));
|
||||
switch (static_cast<AspectMode>(aspect_ratio))
|
||||
{
|
||||
case AspectMode::Stretch:
|
||||
OSD::AddMessage("Stretch");
|
||||
break;
|
||||
case AspectMode::Analog:
|
||||
OSD::AddMessage("Force 4:3");
|
||||
break;
|
||||
case AspectMode::AnalogWide:
|
||||
OSD::AddMessage("Force 16:9");
|
||||
break;
|
||||
case AspectMode::Auto:
|
||||
default:
|
||||
OSD::AddMessage("Auto");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (IsHotkey(HK_TOGGLE_EFBCOPIES))
|
||||
{
|
||||
show_msg(OSDMessage::EFBCopyToggled);
|
||||
Config::SetCurrent(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM,
|
||||
!Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM));
|
||||
const bool new_value = !Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM);
|
||||
Config::SetCurrent(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, new_value);
|
||||
OSD::AddMessage(StringFromFormat("Copy EFB: %s", new_value ? "to Texture" : "to RAM"));
|
||||
}
|
||||
|
||||
auto ShowXFBCopies = []() {
|
||||
OSD::AddMessage(StringFromFormat(
|
||||
"Copy XFB: %s%s", Config::Get(Config::GFX_HACK_IMMEDIATE_XFB) ? " (Immediate)" : "",
|
||||
Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM) ? "to Texture" : "to RAM"));
|
||||
};
|
||||
|
||||
if (IsHotkey(HK_TOGGLE_XFBCOPIES))
|
||||
{
|
||||
show_msg(OSDMessage::XFBChanged);
|
||||
Config::SetCurrent(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM,
|
||||
!Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM));
|
||||
ShowXFBCopies();
|
||||
}
|
||||
if (IsHotkey(HK_TOGGLE_IMMEDIATE_XFB))
|
||||
{
|
||||
show_msg(OSDMessage::XFBChanged);
|
||||
|
||||
Config::SetCurrent(Config::GFX_HACK_IMMEDIATE_XFB,
|
||||
!Config::Get(Config::GFX_HACK_IMMEDIATE_XFB));
|
||||
ShowXFBCopies();
|
||||
}
|
||||
if (IsHotkey(HK_TOGGLE_FOG))
|
||||
{
|
||||
show_msg(OSDMessage::FogToggled);
|
||||
Config::SetCurrent(Config::GFX_DISABLE_FOG, !Config::Get(Config::GFX_DISABLE_FOG));
|
||||
const bool new_value = !Config::Get(Config::GFX_DISABLE_FOG);
|
||||
Config::SetCurrent(Config::GFX_DISABLE_FOG, new_value);
|
||||
OSD::AddMessage(StringFromFormat("Fog: %s", new_value ? "Enabled" : "Disabled"));
|
||||
}
|
||||
|
||||
if (IsHotkey(HK_TOGGLE_DUMPTEXTURES))
|
||||
@@ -368,22 +410,28 @@ void HotkeyScheduler::Run()
|
||||
|
||||
Core::SetIsThrottlerTempDisabled(IsHotkey(HK_TOGGLE_THROTTLE, true));
|
||||
|
||||
auto ShowEmulationSpeed = []() {
|
||||
OSD::AddMessage(
|
||||
SConfig::GetInstance().m_EmulationSpeed <= 0 ?
|
||||
"Speed Limit: Unlimited" :
|
||||
StringFromFormat("Speed Limit: %li%%",
|
||||
std::lround(SConfig::GetInstance().m_EmulationSpeed * 100.f)));
|
||||
};
|
||||
|
||||
if (IsHotkey(HK_DECREASE_EMULATION_SPEED))
|
||||
{
|
||||
show_msg(OSDMessage::SpeedChanged);
|
||||
|
||||
auto speed = SConfig::GetInstance().m_EmulationSpeed - 0.1;
|
||||
speed = (speed <= 0 || (speed >= 0.95 && speed <= 1.05)) ? 1.0 : speed;
|
||||
SConfig::GetInstance().m_EmulationSpeed = speed;
|
||||
ShowEmulationSpeed();
|
||||
}
|
||||
|
||||
if (IsHotkey(HK_INCREASE_EMULATION_SPEED))
|
||||
{
|
||||
show_msg(OSDMessage::SpeedChanged);
|
||||
|
||||
auto speed = SConfig::GetInstance().m_EmulationSpeed + 0.1;
|
||||
speed = (speed >= 0.95 && speed <= 1.05) ? 1.0 : speed;
|
||||
SConfig::GetInstance().m_EmulationSpeed = speed;
|
||||
ShowEmulationSpeed();
|
||||
}
|
||||
|
||||
// Slot Saving / Loading
|
||||
|
||||
@@ -164,6 +164,7 @@ static WindowSystemInfo GetWindowSystemInfo(QWindow* window)
|
||||
else
|
||||
wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr;
|
||||
#endif
|
||||
wsi.render_surface_scale = window ? static_cast<float>(window->devicePixelRatio()) : 1.0f;
|
||||
|
||||
return wsi;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <QScreen>
|
||||
#include <QTimer>
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/State.h"
|
||||
@@ -26,6 +28,7 @@
|
||||
#include "DolphinQt/Resources.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/VertexShaderManager.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
@@ -49,6 +52,8 @@ RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent)
|
||||
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this](Core::State state) {
|
||||
SetFillBackground(SConfig::GetInstance().bRenderToMain && state == Core::State::Uninitialized);
|
||||
if (state == Core::State::Running)
|
||||
SetImGuiKeyMap();
|
||||
});
|
||||
|
||||
// We have to use Qt::DirectConnection here because we don't want those signals to get queued
|
||||
@@ -153,6 +158,8 @@ void RenderWidget::showFullScreen()
|
||||
|
||||
bool RenderWidget::event(QEvent* event)
|
||||
{
|
||||
PassEventToImGui(event);
|
||||
|
||||
switch (event->type())
|
||||
{
|
||||
case QEvent::Paint:
|
||||
@@ -244,3 +251,83 @@ void RenderWidget::OnFreeLookMouseMove(QMouseEvent* event)
|
||||
m_last_mouse[0] = event->x();
|
||||
m_last_mouse[1] = event->y();
|
||||
}
|
||||
|
||||
void RenderWidget::PassEventToImGui(const QEvent* event)
|
||||
{
|
||||
if (!Core::IsRunningAndStarted())
|
||||
return;
|
||||
|
||||
switch (event->type())
|
||||
{
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease:
|
||||
{
|
||||
// As the imgui KeysDown array is only 512 elements wide, and some Qt keys which
|
||||
// we need to track (e.g. alt) are above this value, we mask the lower 9 bits.
|
||||
// Even masked, the key codes are still unique, so conflicts aren't an issue.
|
||||
// The actual text input goes through AddInputCharactersUTF8().
|
||||
const QKeyEvent* key_event = static_cast<const QKeyEvent*>(event);
|
||||
const bool is_down = event->type() == QEvent::KeyPress;
|
||||
const int key = (key_event->key() & 0x1FF);
|
||||
auto lock = g_renderer->GetImGuiLock();
|
||||
if (key < ArraySize(ImGui::GetIO().KeysDown))
|
||||
ImGui::GetIO().KeysDown[key] = is_down;
|
||||
|
||||
if (is_down)
|
||||
{
|
||||
auto utf8 = key_event->text().toUtf8();
|
||||
ImGui::GetIO().AddInputCharactersUTF8(utf8.constData());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::MouseMove:
|
||||
{
|
||||
auto lock = g_renderer->GetImGuiLock();
|
||||
ImGui::GetIO().MousePos.x = static_cast<const QMouseEvent*>(event)->x();
|
||||
ImGui::GetIO().MousePos.y = static_cast<const QMouseEvent*>(event)->y();
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseButtonRelease:
|
||||
{
|
||||
auto lock = g_renderer->GetImGuiLock();
|
||||
const u32 button_mask = static_cast<u32>(static_cast<const QMouseEvent*>(event)->buttons());
|
||||
for (size_t i = 0; i < ArraySize(ImGui::GetIO().MouseDown); i++)
|
||||
ImGui::GetIO().MouseDown[i] = (button_mask & (1u << i)) != 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWidget::SetImGuiKeyMap()
|
||||
{
|
||||
static const int key_map[][2] = {{ImGuiKey_Tab, Qt::Key_Tab},
|
||||
{ImGuiKey_LeftArrow, Qt::Key_Left},
|
||||
{ImGuiKey_RightArrow, Qt::Key_Right},
|
||||
{ImGuiKey_UpArrow, Qt::Key_Up},
|
||||
{ImGuiKey_DownArrow, Qt::Key_Down},
|
||||
{ImGuiKey_PageUp, Qt::Key_PageUp},
|
||||
{ImGuiKey_PageDown, Qt::Key_PageDown},
|
||||
{ImGuiKey_Home, Qt::Key_Home},
|
||||
{ImGuiKey_End, Qt::Key_End},
|
||||
{ImGuiKey_Insert, Qt::Key_Insert},
|
||||
{ImGuiKey_Delete, Qt::Key_Delete},
|
||||
{ImGuiKey_Backspace, Qt::Key_Backspace},
|
||||
{ImGuiKey_Space, Qt::Key_Space},
|
||||
{ImGuiKey_Enter, Qt::Key_Enter},
|
||||
{ImGuiKey_Escape, Qt::Key_Escape},
|
||||
{ImGuiKey_A, Qt::Key_A},
|
||||
{ImGuiKey_C, Qt::Key_C},
|
||||
{ImGuiKey_V, Qt::Key_V},
|
||||
{ImGuiKey_X, Qt::Key_X},
|
||||
{ImGuiKey_Y, Qt::Key_Y},
|
||||
{ImGuiKey_Z, Qt::Key_Z}};
|
||||
auto lock = g_renderer->GetImGuiLock();
|
||||
for (size_t i = 0; i < ArraySize(key_map); i++)
|
||||
ImGui::GetIO().KeyMap[key_map[i][0]] = (key_map[i][1] & 0x1FF);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ private:
|
||||
void OnKeepOnTopChanged(bool top);
|
||||
void SetFillBackground(bool fill);
|
||||
void OnFreeLookMouseMove(QMouseEvent* event);
|
||||
void PassEventToImGui(const QEvent* event);
|
||||
void SetImGuiKeyMap();
|
||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||
void dropEvent(QDropEvent* event) override;
|
||||
|
||||
|
||||
@@ -98,390 +98,7 @@ private:
|
||||
std::list<bool*> observers;
|
||||
};
|
||||
|
||||
class CD3DFont
|
||||
{
|
||||
public:
|
||||
CD3DFont();
|
||||
// 2D text drawing function
|
||||
// Initializing and destroying device-dependent objects
|
||||
int Init();
|
||||
int Shutdown();
|
||||
int DrawTextScaled(float x, float y, float size, float spacing, u32 dwColor,
|
||||
const std::string& text);
|
||||
|
||||
private:
|
||||
ID3D11ShaderResourceView* m_pTexture;
|
||||
ID3D11Buffer* m_pVB;
|
||||
ID3D11InputLayout* m_InputLayout;
|
||||
ID3D11PixelShader* m_pshader;
|
||||
ID3D11VertexShader* m_vshader;
|
||||
ID3D11BlendState* m_blendstate;
|
||||
ID3D11RasterizerState* m_raststate;
|
||||
const int m_dwTexWidth;
|
||||
const int m_dwTexHeight;
|
||||
unsigned int m_LineHeight;
|
||||
float m_fTexCoords[128 - 32][4];
|
||||
};
|
||||
|
||||
static CD3DFont font;
|
||||
static UtilVertexBuffer* util_vbuf = nullptr;
|
||||
|
||||
#define MAX_NUM_VERTICES 50 * 6
|
||||
struct FONT2DVERTEX
|
||||
{
|
||||
float x, y, z;
|
||||
float col[4];
|
||||
float tu, tv;
|
||||
};
|
||||
|
||||
inline FONT2DVERTEX InitFont2DVertex(float x, float y, u32 color, float tu, float tv)
|
||||
{
|
||||
FONT2DVERTEX v;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
v.z = 0;
|
||||
v.tu = tu;
|
||||
v.tv = tv;
|
||||
v.col[0] = ((float)((color >> 16) & 0xFF)) / 255.f;
|
||||
v.col[1] = ((float)((color >> 8) & 0xFF)) / 255.f;
|
||||
v.col[2] = ((float)((color >> 0) & 0xFF)) / 255.f;
|
||||
v.col[3] = ((float)((color >> 24) & 0xFF)) / 255.f;
|
||||
return v;
|
||||
}
|
||||
|
||||
CD3DFont::CD3DFont() : m_dwTexWidth(512), m_dwTexHeight(512)
|
||||
{
|
||||
m_pTexture = nullptr;
|
||||
m_pVB = nullptr;
|
||||
m_InputLayout = nullptr;
|
||||
m_pshader = nullptr;
|
||||
m_vshader = nullptr;
|
||||
}
|
||||
|
||||
const char fontpixshader[] = {"Texture2D tex2D;\n"
|
||||
"SamplerState linearSampler\n"
|
||||
"{\n"
|
||||
" Filter = MIN_MAG_MIP_LINEAR;\n"
|
||||
" AddressU = D3D11_TEXTURE_ADDRESS_BORDER;\n"
|
||||
" AddressV = D3D11_TEXTURE_ADDRESS_BORDER;\n"
|
||||
" BorderColor = float4(0.f, 0.f, 0.f, 0.f);\n"
|
||||
"};\n"
|
||||
"struct PS_INPUT\n"
|
||||
"{\n"
|
||||
" float4 pos : SV_POSITION;\n"
|
||||
" float4 col : COLOR;\n"
|
||||
" float2 tex : TEXCOORD;\n"
|
||||
"};\n"
|
||||
"float4 main( PS_INPUT input ) : SV_Target\n"
|
||||
"{\n"
|
||||
" return tex2D.Sample( linearSampler, input.tex ) * input.col;\n"
|
||||
"};\n"};
|
||||
|
||||
const char fontvertshader[] = {"struct VS_INPUT\n"
|
||||
"{\n"
|
||||
" float4 pos : POSITION;\n"
|
||||
" float4 col : COLOR;\n"
|
||||
" float2 tex : TEXCOORD;\n"
|
||||
"};\n"
|
||||
"struct PS_INPUT\n"
|
||||
"{\n"
|
||||
" float4 pos : SV_POSITION;\n"
|
||||
" float4 col : COLOR;\n"
|
||||
" float2 tex : TEXCOORD;\n"
|
||||
"};\n"
|
||||
"PS_INPUT main( VS_INPUT input )\n"
|
||||
"{\n"
|
||||
" PS_INPUT output;\n"
|
||||
" output.pos = input.pos;\n"
|
||||
" output.col = input.col;\n"
|
||||
" output.tex = input.tex;\n"
|
||||
" return output;\n"
|
||||
"};\n"};
|
||||
|
||||
int CD3DFont::Init()
|
||||
{
|
||||
// Create vertex buffer for the letters
|
||||
HRESULT hr;
|
||||
|
||||
// Prepare to create a bitmap
|
||||
unsigned int* pBitmapBits;
|
||||
BITMAPINFO bmi;
|
||||
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
|
||||
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
|
||||
// Create a DC and a bitmap for the font
|
||||
HDC hDC = CreateCompatibleDC(nullptr);
|
||||
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, nullptr, 0);
|
||||
SetMapMode(hDC, MM_TEXT);
|
||||
|
||||
// create a GDI font
|
||||
HFONT hFont =
|
||||
CreateFont(24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH, _T("Tahoma"));
|
||||
if (nullptr == hFont)
|
||||
return E_FAIL;
|
||||
|
||||
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
|
||||
HGDIOBJ hOldFont = SelectObject(hDC, hFont);
|
||||
|
||||
// Set text properties
|
||||
SetTextColor(hDC, 0xFFFFFF);
|
||||
SetBkColor(hDC, 0);
|
||||
SetTextAlign(hDC, TA_TOP);
|
||||
|
||||
TEXTMETRICW tm;
|
||||
GetTextMetricsW(hDC, &tm);
|
||||
m_LineHeight = tm.tmHeight;
|
||||
|
||||
// Loop through all printable characters and output them to the bitmap
|
||||
// Meanwhile, keep track of the corresponding tex coords for each character.
|
||||
int x = 0, y = 0;
|
||||
char str[2] = "\0";
|
||||
for (int c = 0; c < 127 - 32; c++)
|
||||
{
|
||||
str[0] = c + 32;
|
||||
SIZE size;
|
||||
GetTextExtentPoint32A(hDC, str, 1, &size);
|
||||
if ((int)(x + size.cx + 1) > m_dwTexWidth)
|
||||
{
|
||||
x = 0;
|
||||
y += m_LineHeight;
|
||||
}
|
||||
|
||||
ExtTextOutA(hDC, x + 1, y + 0, ETO_OPAQUE | ETO_CLIPPED, nullptr, str, 1, nullptr);
|
||||
m_fTexCoords[c][0] = ((float)(x + 0)) / m_dwTexWidth;
|
||||
m_fTexCoords[c][1] = ((float)(y + 0)) / m_dwTexHeight;
|
||||
m_fTexCoords[c][2] = ((float)(x + 0 + size.cx)) / m_dwTexWidth;
|
||||
m_fTexCoords[c][3] = ((float)(y + 0 + size.cy)) / m_dwTexHeight;
|
||||
|
||||
x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i)
|
||||
}
|
||||
|
||||
// Create a new texture for the font
|
||||
// possible optimization: store the converted data in a buffer and fill the texture on creation.
|
||||
// That way, we can use a static texture
|
||||
ID3D11Texture2D* buftex;
|
||||
D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, m_dwTexWidth, m_dwTexHeight, 1, 1, D3D11_BIND_SHADER_RESOURCE,
|
||||
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
hr = device->CreateTexture2D(&texdesc, nullptr, &buftex);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
PanicAlert("Failed to create font texture");
|
||||
return hr;
|
||||
}
|
||||
D3D::SetDebugObjectName(buftex, "texture of a CD3DFont object");
|
||||
|
||||
// Lock the surface and write the alpha values for the set pixels
|
||||
D3D11_MAPPED_SUBRESOURCE texmap;
|
||||
hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap);
|
||||
if (FAILED(hr))
|
||||
PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__);
|
||||
|
||||
for (y = 0; y < m_dwTexHeight; y++)
|
||||
{
|
||||
u32* pDst32 = (u32*)((u8*)texmap.pData + y * texmap.RowPitch);
|
||||
for (x = 0; x < m_dwTexWidth; x++)
|
||||
{
|
||||
const u8 bAlpha = (pBitmapBits[m_dwTexWidth * y + x] & 0xff);
|
||||
*pDst32++ = (((bAlpha << 4) | bAlpha) << 24) | 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
// Done updating texture, so clean up used objects
|
||||
context->Unmap(buftex, 0);
|
||||
hr = D3D::device->CreateShaderResourceView(buftex, nullptr, &m_pTexture);
|
||||
if (FAILED(hr))
|
||||
PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__);
|
||||
SAFE_RELEASE(buftex);
|
||||
|
||||
SelectObject(hDC, hOldbmBitmap);
|
||||
DeleteObject(hbmBitmap);
|
||||
|
||||
SelectObject(hDC, hOldFont);
|
||||
DeleteObject(hFont);
|
||||
|
||||
// setup device objects for drawing
|
||||
m_pshader = D3D::CompileAndCreatePixelShader(fontpixshader);
|
||||
if (m_pshader == nullptr)
|
||||
PanicAlert("Failed to create pixel shader, %s %d\n", __FILE__, __LINE__);
|
||||
D3D::SetDebugObjectName(m_pshader, "pixel shader of a CD3DFont object");
|
||||
|
||||
D3DBlob* vsbytecode;
|
||||
D3D::CompileVertexShader(fontvertshader, &vsbytecode);
|
||||
if (vsbytecode == nullptr)
|
||||
PanicAlert("Failed to compile vertex shader, %s %d\n", __FILE__, __LINE__);
|
||||
m_vshader = D3D::CreateVertexShaderFromByteCode(vsbytecode);
|
||||
if (m_vshader == nullptr)
|
||||
PanicAlert("Failed to create vertex shader, %s %d\n", __FILE__, __LINE__);
|
||||
D3D::SetDebugObjectName(m_vshader, "vertex shader of a CD3DFont object");
|
||||
|
||||
const D3D11_INPUT_ELEMENT_DESC desc[] = {
|
||||
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
};
|
||||
hr = D3D::device->CreateInputLayout(desc, 3, vsbytecode->Data(), vsbytecode->Size(),
|
||||
&m_InputLayout);
|
||||
if (FAILED(hr))
|
||||
PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
|
||||
SAFE_RELEASE(vsbytecode);
|
||||
|
||||
D3D11_BLEND_DESC blenddesc;
|
||||
blenddesc.AlphaToCoverageEnable = FALSE;
|
||||
blenddesc.IndependentBlendEnable = FALSE;
|
||||
blenddesc.RenderTarget[0].BlendEnable = TRUE;
|
||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||
blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
hr = D3D::device->CreateBlendState(&blenddesc, &m_blendstate);
|
||||
CHECK(hr == S_OK, "Create font blend state");
|
||||
D3D::SetDebugObjectName(m_blendstate, "blend state of a CD3DFont object");
|
||||
|
||||
D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false,
|
||||
0, 0.f, 0.f, false, false, false, false);
|
||||
hr = D3D::device->CreateRasterizerState(&rastdesc, &m_raststate);
|
||||
CHECK(hr == S_OK, "Create font rasterizer state");
|
||||
D3D::SetDebugObjectName(m_raststate, "rasterizer state of a CD3DFont object");
|
||||
|
||||
D3D11_BUFFER_DESC vbdesc =
|
||||
CD3D11_BUFFER_DESC(MAX_NUM_VERTICES * sizeof(FONT2DVERTEX), D3D11_BIND_VERTEX_BUFFER,
|
||||
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
if (FAILED(hr = device->CreateBuffer(&vbdesc, nullptr, &m_pVB)))
|
||||
{
|
||||
PanicAlert("Failed to create font vertex buffer at %s, line %d\n", __FILE__, __LINE__);
|
||||
return hr;
|
||||
}
|
||||
D3D::SetDebugObjectName(m_pVB, "vertex buffer of a CD3DFont object");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int CD3DFont::Shutdown()
|
||||
{
|
||||
SAFE_RELEASE(m_pVB);
|
||||
SAFE_RELEASE(m_pTexture);
|
||||
SAFE_RELEASE(m_InputLayout);
|
||||
SAFE_RELEASE(m_pshader);
|
||||
SAFE_RELEASE(m_vshader);
|
||||
|
||||
SAFE_RELEASE(m_blendstate);
|
||||
SAFE_RELEASE(m_raststate);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dwColor,
|
||||
const std::string& text)
|
||||
{
|
||||
if (!m_pVB)
|
||||
return 0;
|
||||
|
||||
UINT stride = sizeof(FONT2DVERTEX);
|
||||
UINT bufoffset = 0;
|
||||
|
||||
float scalex = 1.0f / g_renderer->GetBackbufferWidth() * 2.f;
|
||||
float scaley = 1.0f / g_renderer->GetBackbufferHeight() * 2.f;
|
||||
float sizeratio = size / m_LineHeight;
|
||||
|
||||
// translate starting positions
|
||||
float sx = x * scalex - 1.f;
|
||||
float sy = 1.f - y * scaley;
|
||||
|
||||
// Fill vertex buffer
|
||||
FONT2DVERTEX* pVertices;
|
||||
int dwNumTriangles = 0L;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE vbmap;
|
||||
HRESULT hr = context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vbmap);
|
||||
if (FAILED(hr))
|
||||
PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__);
|
||||
pVertices = (D3D::FONT2DVERTEX*)vbmap.pData;
|
||||
|
||||
// set general pipeline state
|
||||
D3D::stateman->SetBlendState(m_blendstate);
|
||||
D3D::stateman->SetRasterizerState(m_raststate);
|
||||
|
||||
D3D::stateman->SetPixelShader(m_pshader);
|
||||
D3D::stateman->SetVertexShader(m_vshader);
|
||||
D3D::stateman->SetGeometryShader(nullptr);
|
||||
|
||||
D3D::stateman->SetInputLayout(m_InputLayout);
|
||||
D3D::stateman->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
D3D::stateman->SetTexture(0, m_pTexture);
|
||||
|
||||
float fStartX = sx;
|
||||
for (char c : text)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
sx = fStartX;
|
||||
sy -= scaley * size;
|
||||
}
|
||||
if (!std::isprint(c))
|
||||
continue;
|
||||
|
||||
c -= 32;
|
||||
float tx1 = m_fTexCoords[c][0];
|
||||
float ty1 = m_fTexCoords[c][1];
|
||||
float tx2 = m_fTexCoords[c][2];
|
||||
float ty2 = m_fTexCoords[c][3];
|
||||
|
||||
float w = (float)(tx2 - tx1) * m_dwTexWidth * scalex * sizeratio;
|
||||
float h = (float)(ty1 - ty2) * m_dwTexHeight * scaley * sizeratio;
|
||||
|
||||
FONT2DVERTEX v[6];
|
||||
v[0] = InitFont2DVertex(sx, sy + h, dwColor, tx1, ty2);
|
||||
v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
|
||||
v[2] = InitFont2DVertex(sx + w, sy + h, dwColor, tx2, ty2);
|
||||
v[3] = InitFont2DVertex(sx + w, sy, dwColor, tx2, ty1);
|
||||
v[4] = v[2];
|
||||
v[5] = v[1];
|
||||
|
||||
memcpy(pVertices, v, 6 * sizeof(FONT2DVERTEX));
|
||||
|
||||
pVertices += 6;
|
||||
dwNumTriangles += 2;
|
||||
|
||||
if (dwNumTriangles * 3 > (MAX_NUM_VERTICES - 6))
|
||||
{
|
||||
context->Unmap(m_pVB, 0);
|
||||
|
||||
D3D::stateman->SetVertexBuffer(m_pVB, stride, bufoffset);
|
||||
|
||||
D3D::stateman->Apply();
|
||||
D3D::context->Draw(3 * dwNumTriangles, 0);
|
||||
|
||||
dwNumTriangles = 0;
|
||||
D3D11_MAPPED_SUBRESOURCE _vbmap;
|
||||
hr = context->Map(m_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &_vbmap);
|
||||
if (FAILED(hr))
|
||||
PanicAlert("Mapping vertex buffer failed, %s %d\n", __FILE__, __LINE__);
|
||||
pVertices = (D3D::FONT2DVERTEX*)_vbmap.pData;
|
||||
}
|
||||
sx += w + spacing * scalex * size;
|
||||
}
|
||||
|
||||
// Unlock and render the vertex buffer
|
||||
context->Unmap(m_pVB, 0);
|
||||
if (dwNumTriangles > 0)
|
||||
{
|
||||
D3D::stateman->SetVertexBuffer(m_pVB, stride, bufoffset);
|
||||
|
||||
D3D::stateman->Apply();
|
||||
D3D::context->Draw(3 * dwNumTriangles, 0);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ID3D11SamplerState* linear_copy_sampler = nullptr;
|
||||
static ID3D11SamplerState* point_copy_sampler = nullptr;
|
||||
|
||||
@@ -560,13 +177,10 @@ void InitUtils()
|
||||
util_vbuf->AddWrapObserver(&stq_observer);
|
||||
util_vbuf->AddWrapObserver(&cq_observer);
|
||||
util_vbuf->AddWrapObserver(&clearq_observer);
|
||||
|
||||
font.Init();
|
||||
}
|
||||
|
||||
void ShutdownUtils()
|
||||
{
|
||||
font.Shutdown();
|
||||
SAFE_RELEASE(point_copy_sampler);
|
||||
SAFE_RELEASE(linear_copy_sampler);
|
||||
SAFE_DELETE(util_vbuf);
|
||||
@@ -788,10 +402,6 @@ void DrawEFBPokeQuads(EFBAccessType type, const EfbPokeData* points, size_t num_
|
||||
stateman->SetGeometryShader(GeometryShaderCache::GetClearGeometryShader());
|
||||
}
|
||||
|
||||
void DrawTextScaled(float x, float y, float size, float spacing, u32 color, const std::string& text)
|
||||
{
|
||||
font.DrawTextScaled(x, y, size, spacing, color, text);
|
||||
}
|
||||
} // namespace D3D
|
||||
|
||||
} // namespace DX11
|
||||
|
||||
@@ -28,7 +28,5 @@ void drawClearQuad(u32 Color, float z);
|
||||
void drawColorQuad(u32 Color, float z, float x1, float y1, float x2, float y2);
|
||||
|
||||
void DrawEFBPokeQuads(EFBAccessType type, const EfbPokeData* points, size_t num_points);
|
||||
void DrawTextScaled(float x, float y, float size, float spacing, u32 color,
|
||||
const std::string& text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ void FramebufferManager::BindEFBRenderTarget(bool bind_depth)
|
||||
|
||||
FramebufferManager::FramebufferManager(int target_width, int target_height)
|
||||
{
|
||||
static constexpr std::array<float, 4> clear_color = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
m_target_width = static_cast<unsigned int>(std::max(target_width, 1));
|
||||
m_target_height = static_cast<unsigned int>(std::max(target_height, 1));
|
||||
DXGI_SAMPLE_DESC sample_desc;
|
||||
@@ -154,6 +155,7 @@ FramebufferManager::FramebufferManager(int target_width, int target_height)
|
||||
D3D::SetDebugObjectName(m_efb.color_tex->GetTex(), "EFB color texture");
|
||||
D3D::SetDebugObjectName(m_efb.color_tex->GetSRV(), "EFB color texture shader resource view");
|
||||
D3D::SetDebugObjectName(m_efb.color_tex->GetRTV(), "EFB color texture render target view");
|
||||
D3D::context->ClearRenderTargetView(m_efb.color_tex->GetRTV(), clear_color.data());
|
||||
|
||||
// Temporary EFB color texture - used in ReinterpretPixelData
|
||||
texdesc =
|
||||
@@ -173,6 +175,7 @@ FramebufferManager::FramebufferManager(int target_width, int target_height)
|
||||
"EFB color temp texture shader resource view");
|
||||
D3D::SetDebugObjectName(m_efb.color_temp_tex->GetRTV(),
|
||||
"EFB color temp texture render target view");
|
||||
D3D::context->ClearRenderTargetView(m_efb.color_temp_tex->GetRTV(), clear_color.data());
|
||||
|
||||
// Integer render targets for EFB, used for logic op
|
||||
CD3D11_RENDER_TARGET_VIEW_DESC int_rtv_desc(m_efb.color_tex->GetTex(),
|
||||
@@ -222,6 +225,7 @@ FramebufferManager::FramebufferManager(int target_width, int target_height)
|
||||
D3D::SetDebugObjectName(m_efb.depth_tex->GetTex(), "EFB depth texture");
|
||||
D3D::SetDebugObjectName(m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view");
|
||||
D3D::SetDebugObjectName(m_efb.depth_tex->GetSRV(), "EFB depth texture shader resource view");
|
||||
D3D::context->ClearDepthStencilView(m_efb.depth_tex->GetDSV(), D3D11_CLEAR_DEPTH, 0.0f, 0);
|
||||
|
||||
// Render buffer for AccessEFB (depth data)
|
||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 1, 1, 1, 1, D3D11_BIND_RENDER_TARGET);
|
||||
|
||||
@@ -62,22 +62,14 @@ typedef struct _Nv_Stereo_Image_Header
|
||||
|
||||
#define NVSTEREO_IMAGE_SIGNATURE 0x4433564e
|
||||
|
||||
Renderer::Renderer(int backbuffer_width, int backbuffer_height)
|
||||
: ::Renderer(backbuffer_width, backbuffer_height, AbstractTextureFormat::RGBA8)
|
||||
Renderer::Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale)
|
||||
: ::Renderer(backbuffer_width, backbuffer_height, backbuffer_scale,
|
||||
AbstractTextureFormat::RGBA8)
|
||||
{
|
||||
m_last_multisamples = g_ActiveConfig.iMultisamples;
|
||||
m_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off;
|
||||
m_last_fullscreen_state = D3D::GetFullscreenState();
|
||||
g_framebuffer_manager = std::make_unique<FramebufferManager>(m_target_width, m_target_height);
|
||||
SetupDeviceObjects();
|
||||
|
||||
// Clear EFB textures
|
||||
constexpr std::array<float, 4> clear_color{{0.f, 0.f, 0.f, 1.f}};
|
||||
D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
||||
clear_color.data());
|
||||
D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(),
|
||||
D3D11_CLEAR_DEPTH, 0.f, 0);
|
||||
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)m_target_width, (float)m_target_height);
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
FramebufferManager::BindEFBRenderTarget();
|
||||
@@ -237,13 +229,6 @@ Renderer::CreateFramebuffer(const AbstractTexture* color_attachment,
|
||||
static_cast<const DXTexture*>(depth_attachment));
|
||||
}
|
||||
|
||||
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
|
||||
{
|
||||
D3D::DrawTextScaled(static_cast<float>(left + 1), static_cast<float>(top + 1), 20.f, 0.0f,
|
||||
color & 0xFF000000, text);
|
||||
D3D::DrawTextScaled(static_cast<float>(left), static_cast<float>(top), 20.f, 0.0f, color, text);
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractShader> Renderer::CreateShaderFromSource(ShaderStage stage,
|
||||
const char* source, size_t length)
|
||||
{
|
||||
@@ -566,71 +551,33 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
|
||||
RestoreAPIState();
|
||||
}
|
||||
|
||||
// This function has the final picture. We adjust the aspect ratio here.
|
||||
void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region, u64 ticks)
|
||||
void Renderer::BindBackbuffer(const ClearColor& clear_color)
|
||||
{
|
||||
ResetAPIState();
|
||||
|
||||
// Prepare to copy the XFBs to our backbuffer
|
||||
CheckForSurfaceChange();
|
||||
CheckForSurfaceResize();
|
||||
UpdateDrawRectangle();
|
||||
|
||||
TargetRectangle targetRc = GetTargetRectangle();
|
||||
static constexpr std::array<float, 4> clear_color{{0.f, 0.f, 0.f, 1.f}};
|
||||
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr);
|
||||
D3D::context->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV(), clear_color.data());
|
||||
m_current_framebuffer = nullptr;
|
||||
m_current_framebuffer_width = m_backbuffer_width;
|
||||
m_current_framebuffer_height = m_backbuffer_height;
|
||||
}
|
||||
|
||||
// activate linear filtering for the buffer copies
|
||||
D3D::SetLinearCopySampler();
|
||||
auto* xfb_texture = static_cast<DXTexture*>(texture);
|
||||
|
||||
BlitScreen(xfb_region, targetRc, xfb_texture->GetRawTexIdentifier(),
|
||||
xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
|
||||
|
||||
// Reset viewport for drawing text
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.0f, 0.0f, static_cast<float>(m_backbuffer_width),
|
||||
static_cast<float>(m_backbuffer_height));
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
|
||||
Renderer::DrawDebugText();
|
||||
|
||||
OSD::DrawMessages();
|
||||
|
||||
g_texture_cache->Cleanup(frameCount);
|
||||
|
||||
// Enable configuration changes
|
||||
UpdateActiveConfig();
|
||||
g_texture_cache->OnConfigChanged(g_ActiveConfig);
|
||||
|
||||
// Flip/present backbuffer to frontbuffer here
|
||||
if (D3D::swapchain)
|
||||
D3D::Present();
|
||||
void Renderer::PresentBackbuffer()
|
||||
{
|
||||
D3D::Present();
|
||||
}
|
||||
|
||||
void Renderer::OnConfigChanged(u32 bits)
|
||||
{
|
||||
// Resize the back buffers NOW to avoid flickering
|
||||
if (CalculateTargetSize() || m_last_multisamples != g_ActiveConfig.iMultisamples ||
|
||||
m_last_stereo_mode != (g_ActiveConfig.stereo_mode != StereoMode::Off))
|
||||
if (bits & (CONFIG_CHANGE_BIT_TARGET_SIZE | CONFIG_CHANGE_BIT_MULTISAMPLES |
|
||||
CONFIG_CHANGE_BIT_STEREO_MODE))
|
||||
{
|
||||
m_last_multisamples = g_ActiveConfig.iMultisamples;
|
||||
m_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off;
|
||||
PixelShaderCache::InvalidateMSAAShaders();
|
||||
UpdateDrawRectangle();
|
||||
|
||||
g_framebuffer_manager.reset();
|
||||
g_framebuffer_manager = std::make_unique<FramebufferManager>(m_target_width, m_target_height);
|
||||
D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
||||
clear_color.data());
|
||||
D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(),
|
||||
D3D11_CLEAR_DEPTH, 0.f, 0);
|
||||
}
|
||||
|
||||
CheckForHostConfigChanges();
|
||||
|
||||
// begin next frame
|
||||
RestoreAPIState();
|
||||
}
|
||||
|
||||
void Renderer::CheckForSurfaceChange()
|
||||
@@ -789,28 +736,34 @@ void Renderer::BBoxWrite(int index, u16 _value)
|
||||
BBox::Set(index, value);
|
||||
}
|
||||
|
||||
void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture,
|
||||
u32 src_width, u32 src_height)
|
||||
void Renderer::RenderXFBToScreen(const AbstractTexture* texture, const EFBRectangle& rc)
|
||||
{
|
||||
const CD3D11_RECT source_rc(rc.left, rc.top, rc.right, rc.bottom);
|
||||
const TargetRectangle target_rc = GetTargetRectangle();
|
||||
|
||||
// activate linear filtering for the buffer copies
|
||||
D3D::SetLinearCopySampler();
|
||||
|
||||
if (g_ActiveConfig.stereo_mode == StereoMode::SBS ||
|
||||
g_ActiveConfig.stereo_mode == StereoMode::TAB)
|
||||
{
|
||||
TargetRectangle leftRc, rightRc;
|
||||
std::tie(leftRc, rightRc) = ConvertStereoRectangle(dst);
|
||||
TargetRectangle left_rc, right_rc;
|
||||
std::tie(left_rc, right_rc) = ConvertStereoRectangle(target_rc);
|
||||
|
||||
D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)leftRc.left, (float)leftRc.top,
|
||||
(float)leftRc.GetWidth(), (float)leftRc.GetHeight());
|
||||
D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)rightRc.left, (float)rightRc.top,
|
||||
(float)rightRc.GetWidth(), (float)rightRc.GetHeight());
|
||||
|
||||
D3D::context->RSSetViewports(1, &leftVp);
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height,
|
||||
SetViewport(static_cast<float>(left_rc.left), static_cast<float>(left_rc.top),
|
||||
static_cast<float>(left_rc.GetWidth()), static_cast<float>(right_rc.GetHeight()),
|
||||
0.0f, 1.0f);
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(false),
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), nullptr, 0);
|
||||
|
||||
D3D::context->RSSetViewports(1, &rightVp);
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height,
|
||||
SetViewport(static_cast<float>(right_rc.left), static_cast<float>(right_rc.top),
|
||||
static_cast<float>(right_rc.GetWidth()), static_cast<float>(right_rc.GetHeight()),
|
||||
0.0f, 1.0f);
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(false),
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), nullptr, 1);
|
||||
@@ -820,29 +773,33 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D
|
||||
if (!m_3d_vision_texture)
|
||||
Create3DVisionTexture(m_backbuffer_width, m_backbuffer_height);
|
||||
|
||||
D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)dst.left, (float)dst.top, (float)dst.GetWidth(),
|
||||
(float)dst.GetHeight());
|
||||
D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)(dst.left + m_backbuffer_width), (float)dst.top,
|
||||
(float)dst.GetWidth(), (float)dst.GetHeight());
|
||||
const CD3D11_VIEWPORT left_vp(
|
||||
static_cast<float>(target_rc.left), static_cast<float>(target_rc.top),
|
||||
static_cast<float>(target_rc.GetWidth()), static_cast<float>(target_rc.GetHeight()));
|
||||
const CD3D11_VIEWPORT right_vp(
|
||||
static_cast<float>(target_rc.left + m_backbuffer_width), static_cast<float>(target_rc.top),
|
||||
static_cast<float>(target_rc.GetWidth()), static_cast<float>(target_rc.GetHeight()));
|
||||
|
||||
// Render to staging texture which is double the width of the backbuffer
|
||||
D3D::context->OMSetRenderTargets(1, &m_3d_vision_texture->GetRTV(), nullptr);
|
||||
|
||||
D3D::context->RSSetViewports(1, &leftVp);
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height,
|
||||
D3D::context->RSSetViewports(1, &left_vp);
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(false),
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), nullptr, 0);
|
||||
|
||||
D3D::context->RSSetViewports(1, &rightVp);
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height,
|
||||
D3D::context->RSSetViewports(1, &right_vp);
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(false),
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), nullptr, 1);
|
||||
|
||||
// Copy the left eye to the backbuffer, if Nvidia 3D Vision is enabled it should
|
||||
// recognize the signature and automatically include the right eye frame.
|
||||
D3D11_BOX box = CD3D11_BOX(0, 0, 0, m_backbuffer_width, m_backbuffer_height, 1);
|
||||
const CD3D11_BOX box(0, 0, 0, m_backbuffer_width, m_backbuffer_height, 1);
|
||||
D3D::context->CopySubresourceRegion(D3D::GetBackBuffer()->GetTex(), 0, 0, 0, 0,
|
||||
m_3d_vision_texture->GetTex(), 0, &box);
|
||||
|
||||
@@ -851,9 +808,9 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)dst.left, (float)dst.top, (float)dst.GetWidth(),
|
||||
(float)dst.GetHeight());
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
SetViewport(static_cast<float>(target_rc.left), static_cast<float>(target_rc.top),
|
||||
static_cast<float>(target_rc.GetWidth()), static_cast<float>(target_rc.GetHeight()),
|
||||
0.0f, 1.0f);
|
||||
|
||||
ID3D11PixelShader* pixelShader = (g_Config.stereo_mode == StereoMode::Anaglyph) ?
|
||||
PixelShaderCache::GetAnaglyphProgram() :
|
||||
@@ -861,7 +818,8 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D
|
||||
ID3D11GeometryShader* geomShader = (g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer) ?
|
||||
GeometryShaderCache::GetCopyGeometryShader() :
|
||||
nullptr;
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height, pixelShader,
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(), pixelShader,
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), geomShader);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class D3DTexture2D;
|
||||
class Renderer : public ::Renderer
|
||||
{
|
||||
public:
|
||||
Renderer(int backbuffer_width, int backbuffer_height);
|
||||
Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale);
|
||||
~Renderer() override;
|
||||
|
||||
StateCache& GetStateCache() { return m_state_cache; }
|
||||
@@ -52,11 +52,11 @@ public:
|
||||
float far_depth) override;
|
||||
void Draw(u32 base_vertex, u32 num_vertices) override;
|
||||
void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) override;
|
||||
void BindBackbuffer(const ClearColor& clear_color = {}) override;
|
||||
void PresentBackbuffer() override;
|
||||
void SetFullscreen(bool enable_fullscreen) override;
|
||||
bool IsFullscreen() const override;
|
||||
|
||||
void RenderText(const std::string& text, int left, int top, u32 color) override;
|
||||
|
||||
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
|
||||
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override;
|
||||
|
||||
@@ -68,7 +68,8 @@ public:
|
||||
|
||||
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override;
|
||||
|
||||
void SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ticks) override;
|
||||
void RenderXFBToScreen(const AbstractTexture* texture, const EFBRectangle& rc) override;
|
||||
void OnConfigChanged(u32 bits) override;
|
||||
|
||||
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
|
||||
u32 color, u32 z) override;
|
||||
@@ -83,9 +84,6 @@ private:
|
||||
void CheckForSurfaceResize();
|
||||
void UpdateBackbufferSize();
|
||||
|
||||
void BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture,
|
||||
u32 src_width, u32 src_height);
|
||||
|
||||
StateCache m_state_cache;
|
||||
|
||||
std::array<ID3D11BlendState*, 4> m_clear_blend_states{};
|
||||
@@ -97,8 +95,6 @@ private:
|
||||
ID3D11Texture2D* m_screenshot_texture = nullptr;
|
||||
D3DTexture2D* m_3d_vision_texture = nullptr;
|
||||
|
||||
u32 m_last_multisamples = 1;
|
||||
bool m_last_stereo_mode = false;
|
||||
bool m_last_fullscreen_state = false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -147,7 +147,8 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
|
||||
}
|
||||
|
||||
// internal interfaces
|
||||
g_renderer = std::make_unique<Renderer>(backbuffer_width, backbuffer_height);
|
||||
g_renderer =
|
||||
std::make_unique<Renderer>(backbuffer_width, backbuffer_height, wsi.render_surface_scale);
|
||||
g_shader_cache = std::make_unique<VideoCommon::ShaderCache>();
|
||||
g_texture_cache = std::make_unique<TextureCache>();
|
||||
g_vertex_manager = std::make_unique<VertexManager>();
|
||||
@@ -156,13 +157,14 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
|
||||
VertexShaderCache::Init();
|
||||
PixelShaderCache::Init();
|
||||
GeometryShaderCache::Init();
|
||||
if (!g_shader_cache->Initialize())
|
||||
|
||||
if (!g_renderer->Initialize() || !g_shader_cache->Initialize())
|
||||
return false;
|
||||
|
||||
D3D::InitUtils();
|
||||
BBox::Init();
|
||||
|
||||
return g_renderer->Initialize();
|
||||
return true;
|
||||
}
|
||||
|
||||
void VideoBackend::Shutdown()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace Null
|
||||
{
|
||||
// Init functions
|
||||
Renderer::Renderer() : ::Renderer(1, 1, AbstractTextureFormat::RGBA8)
|
||||
Renderer::Renderer() : ::Renderer(1, 1, 1.0f, AbstractTextureFormat::RGBA8)
|
||||
{
|
||||
UpdateActiveConfig();
|
||||
}
|
||||
@@ -82,11 +82,6 @@ Renderer::CreateFramebuffer(const AbstractTexture* color_attachment,
|
||||
static_cast<const NullTexture*>(depth_attachment));
|
||||
}
|
||||
|
||||
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
|
||||
{
|
||||
NOTICE_LOG(VIDEO, "RenderText: %s", text.c_str());
|
||||
}
|
||||
|
||||
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||
{
|
||||
TargetRectangle result;
|
||||
@@ -97,9 +92,4 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||
return result;
|
||||
}
|
||||
|
||||
void Renderer::SwapImpl(AbstractTexture*, const EFBRectangle&, u64)
|
||||
{
|
||||
UpdateActiveConfig();
|
||||
}
|
||||
|
||||
} // namespace Null
|
||||
|
||||
@@ -29,15 +29,12 @@ public:
|
||||
size_t length) override;
|
||||
std::unique_ptr<AbstractPipeline> CreatePipeline(const AbstractPipelineConfig& config) override;
|
||||
|
||||
void RenderText(const std::string& pstr, int left, int top, u32 color) override;
|
||||
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override { return 0; }
|
||||
void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) override {}
|
||||
u16 BBoxRead(int index) override { return 0; }
|
||||
void BBoxWrite(int index, u16 value) override {}
|
||||
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override;
|
||||
|
||||
void SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ticks) override;
|
||||
|
||||
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
|
||||
u32 color, u32 z) override
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@ add_library(videoogl
|
||||
PerfQuery.cpp
|
||||
PostProcessing.cpp
|
||||
ProgramShaderCache.cpp
|
||||
RasterFont.cpp
|
||||
Render.cpp
|
||||
SamplerCache.cpp
|
||||
StreamBuffer.cpp
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user