diff options
| -rw-r--r-- | src/citra/emu_window/emu_window_glfw.cpp | 5 | ||||
| -rw-r--r-- | src/citra/emu_window/emu_window_glfw.h | 5 | ||||
| -rw-r--r-- | src/citra_qt/bootmanager.cpp | 24 | ||||
| -rw-r--r-- | src/citra_qt/bootmanager.hxx | 1 | ||||
| -rw-r--r-- | src/common/emu_window.h | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 36 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 15 |
7 files changed, 89 insertions, 4 deletions
diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index 0c774bbc5..d0f6e9a9e 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp | |||
| @@ -34,6 +34,10 @@ const bool EmuWindow_GLFW::IsOpen() { | |||
| 34 | return glfwWindowShouldClose(m_render_window) == 0; | 34 | return glfwWindowShouldClose(m_render_window) == 0; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | void EmuWindow_GLFW::GetFramebufferSize(int* fbWidth, int* fbHeight) { | ||
| 38 | glfwGetFramebufferSize(m_render_window, fbWidth, fbHeight); | ||
| 39 | } | ||
| 40 | |||
| 37 | /// EmuWindow_GLFW constructor | 41 | /// EmuWindow_GLFW constructor |
| 38 | EmuWindow_GLFW::EmuWindow_GLFW() { | 42 | EmuWindow_GLFW::EmuWindow_GLFW() { |
| 39 | keyboard_id = KeyMap::NewDeviceId(); | 43 | keyboard_id = KeyMap::NewDeviceId(); |
| @@ -64,6 +68,7 @@ EmuWindow_GLFW::EmuWindow_GLFW() { | |||
| 64 | glfwSetWindowUserPointer(m_render_window, this); | 68 | glfwSetWindowUserPointer(m_render_window, this); |
| 65 | glfwSetKeyCallback(m_render_window, OnKeyEvent); | 69 | glfwSetKeyCallback(m_render_window, OnKeyEvent); |
| 66 | 70 | ||
| 71 | |||
| 67 | DoneCurrent(); | 72 | DoneCurrent(); |
| 68 | } | 73 | } |
| 69 | 74 | ||
diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h index 7c3072145..e96228765 100644 --- a/src/citra/emu_window/emu_window_glfw.h +++ b/src/citra/emu_window/emu_window_glfw.h | |||
| @@ -21,7 +21,7 @@ public: | |||
| 21 | 21 | ||
| 22 | /// Makes the graphics context current for the caller thread | 22 | /// Makes the graphics context current for the caller thread |
| 23 | void MakeCurrent() override; | 23 | void MakeCurrent() override; |
| 24 | 24 | ||
| 25 | /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread | 25 | /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread |
| 26 | void DoneCurrent() override; | 26 | void DoneCurrent() override; |
| 27 | 27 | ||
| @@ -32,6 +32,9 @@ public: | |||
| 32 | 32 | ||
| 33 | void ReloadSetKeymaps() override; | 33 | void ReloadSetKeymaps() override; |
| 34 | 34 | ||
| 35 | /// Gets the size of the window in pixels | ||
| 36 | void GetFramebufferSize(int* fbWidth, int* fbHeight); | ||
| 37 | |||
| 35 | private: | 38 | private: |
| 36 | GLFWwindow* m_render_window; ///< Internal GLFW render window | 39 | GLFWwindow* m_render_window; ///< Internal GLFW render window |
| 37 | 40 | ||
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 20824692d..516e115fd 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp | |||
| @@ -2,6 +2,12 @@ | |||
| 2 | #include <QKeyEvent> | 2 | #include <QKeyEvent> |
| 3 | #include <QApplication> | 3 | #include <QApplication> |
| 4 | 4 | ||
| 5 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) | ||
| 6 | // Required for screen DPI information | ||
| 7 | #include <QScreen> | ||
| 8 | #include <QWindow> | ||
| 9 | #endif | ||
| 10 | |||
| 5 | #include "common/common.h" | 11 | #include "common/common.h" |
| 6 | #include "bootmanager.hxx" | 12 | #include "bootmanager.hxx" |
| 7 | 13 | ||
| @@ -176,6 +182,24 @@ void GRenderWindow::PollEvents() { | |||
| 176 | */ | 182 | */ |
| 177 | } | 183 | } |
| 178 | 184 | ||
| 185 | // On Qt 5.1+, this correctly gets the size of the framebuffer (pixels). | ||
| 186 | // | ||
| 187 | // Older versions get the window size (density independent pixels), | ||
| 188 | // and hence, do not support DPI scaling ("retina" displays). | ||
| 189 | // The result will be a viewport that is smaller than the extent of the window. | ||
| 190 | void GRenderWindow::GetFramebufferSize(int* fbWidth, int* fbHeight) | ||
| 191 | { | ||
| 192 | #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) | ||
| 193 | int pixelRatio = child->QPaintDevice::devicePixelRatio(); | ||
| 194 | |||
| 195 | *fbWidth = child->QPaintDevice::width() * pixelRatio; | ||
| 196 | *fbHeight = child->QPaintDevice::height() * pixelRatio; | ||
| 197 | #else | ||
| 198 | *fbWidth = child->QPaintDevice::width(); | ||
| 199 | *fbHeight = child->QPaintDevice::height(); | ||
| 200 | #endif | ||
| 201 | } | ||
| 202 | |||
| 179 | void GRenderWindow::BackupGeometry() | 203 | void GRenderWindow::BackupGeometry() |
| 180 | { | 204 | { |
| 181 | geometry = ((QGLWidget*)this)->saveGeometry(); | 205 | geometry = ((QGLWidget*)this)->saveGeometry(); |
diff --git a/src/citra_qt/bootmanager.hxx b/src/citra_qt/bootmanager.hxx index f8afc403e..ec3e1fe71 100644 --- a/src/citra_qt/bootmanager.hxx +++ b/src/citra_qt/bootmanager.hxx | |||
| @@ -96,6 +96,7 @@ public: | |||
| 96 | void MakeCurrent() override; | 96 | void MakeCurrent() override; |
| 97 | void DoneCurrent() override; | 97 | void DoneCurrent() override; |
| 98 | void PollEvents() override; | 98 | void PollEvents() override; |
| 99 | void GetFramebufferSize(int* fbWidth, int* fbHeight) override; | ||
| 99 | 100 | ||
| 100 | void BackupGeometry(); | 101 | void BackupGeometry(); |
| 101 | void RestoreGeometry(); | 102 | void RestoreGeometry(); |
diff --git a/src/common/emu_window.h b/src/common/emu_window.h index 6c2b598f6..ba9d4fa76 100644 --- a/src/common/emu_window.h +++ b/src/common/emu_window.h | |||
| @@ -49,8 +49,11 @@ public: | |||
| 49 | void SetConfig(const WindowConfig& val) { | 49 | void SetConfig(const WindowConfig& val) { |
| 50 | m_config = val; | 50 | m_config = val; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | int GetClientAreaWidth() const { | 53 | /// Gets the size of the window in pixels |
| 54 | virtual void GetFramebufferSize(int* fbWidth, int* fbHeight) = 0; | ||
| 55 | |||
| 56 | int GetClientAreaWidth() const { | ||
| 54 | return m_client_area_width; | 57 | return m_client_area_width; |
| 55 | } | 58 | } |
| 56 | 59 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 8483f79be..3757482db 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -191,7 +191,8 @@ void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x | |||
| 191 | * Draws the emulated screens to the emulator window. | 191 | * Draws the emulated screens to the emulator window. |
| 192 | */ | 192 | */ |
| 193 | void RendererOpenGL::DrawScreens() { | 193 | void RendererOpenGL::DrawScreens() { |
| 194 | glViewport(0, 0, resolution_width, resolution_height); | 194 | UpdateViewportExtent(); |
| 195 | glViewport(viewport_extent.x, viewport_extent.y, viewport_extent.width, viewport_extent.height); | ||
| 195 | glClear(GL_COLOR_BUFFER_BIT); | 196 | glClear(GL_COLOR_BUFFER_BIT); |
| 196 | 197 | ||
| 197 | glUseProgram(program_id); | 198 | glUseProgram(program_id); |
| @@ -228,6 +229,39 @@ void RendererOpenGL::SetWindow(EmuWindow* window) { | |||
| 228 | render_window = window; | 229 | render_window = window; |
| 229 | } | 230 | } |
| 230 | 231 | ||
| 232 | void RendererOpenGL::UpdateViewportExtent() { | ||
| 233 | int width_in_pixels; | ||
| 234 | int height_in_pixels; | ||
| 235 | |||
| 236 | render_window->GetFramebufferSize(&width_in_pixels, &height_in_pixels); | ||
| 237 | |||
| 238 | // No update needed if framebuffer size hasn't changed | ||
| 239 | if (width_in_pixels == framebuffer_size.width && height_in_pixels == framebuffer_size.height) { | ||
| 240 | return; | ||
| 241 | } | ||
| 242 | |||
| 243 | framebuffer_size.width = width_in_pixels; | ||
| 244 | framebuffer_size.height = height_in_pixels; | ||
| 245 | |||
| 246 | float window_aspect_ratio = static_cast<float>(height_in_pixels) / width_in_pixels; | ||
| 247 | float emulation_aspect_ratio = static_cast<float>(resolution_height) / resolution_width; | ||
| 248 | |||
| 249 | if (window_aspect_ratio > emulation_aspect_ratio) { | ||
| 250 | // If the window is more narrow than the emulation content, borders are applied on the | ||
| 251 | // top and bottom of the window. | ||
| 252 | viewport_extent.width = width_in_pixels; | ||
| 253 | viewport_extent.height = emulation_aspect_ratio * viewport_extent.width; | ||
| 254 | viewport_extent.x = 0; | ||
| 255 | viewport_extent.y = (height_in_pixels - viewport_extent.height) / 2; | ||
| 256 | } else { | ||
| 257 | // Otherwise, borders are applied on the left and right sides of the window. | ||
| 258 | viewport_extent.height = height_in_pixels; | ||
| 259 | viewport_extent.width = (1 / emulation_aspect_ratio) * viewport_extent.height; | ||
| 260 | viewport_extent.x = (width_in_pixels - viewport_extent.width) / 2; | ||
| 261 | viewport_extent.y = 0; | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 231 | /// Initialize the renderer | 265 | /// Initialize the renderer |
| 232 | void RendererOpenGL::Init() { | 266 | void RendererOpenGL::Init() { |
| 233 | render_window->MakeCurrent(); | 267 | render_window->MakeCurrent(); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index eed201a95..d440e2bc7 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -52,12 +52,27 @@ private: | |||
| 52 | static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer, | 52 | static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer, |
| 53 | const TextureInfo& texture); | 53 | const TextureInfo& texture); |
| 54 | 54 | ||
| 55 | /// Updates the viewport rectangle | ||
| 56 | void UpdateViewportExtent(); | ||
| 57 | |||
| 55 | EmuWindow* render_window; ///< Handle to render window | 58 | EmuWindow* render_window; ///< Handle to render window |
| 56 | u32 last_mode; ///< Last render mode | 59 | u32 last_mode; ///< Last render mode |
| 57 | 60 | ||
| 58 | int resolution_width; ///< Current resolution width | 61 | int resolution_width; ///< Current resolution width |
| 59 | int resolution_height; ///< Current resolution height | 62 | int resolution_height; ///< Current resolution height |
| 60 | 63 | ||
| 64 | struct { | ||
| 65 | int width; | ||
| 66 | int height; | ||
| 67 | } framebuffer_size; ///< Current framebuffer size | ||
| 68 | |||
| 69 | struct { | ||
| 70 | int x; | ||
| 71 | int y; | ||
| 72 | int width; | ||
| 73 | int height; | ||
| 74 | } viewport_extent; ///< Current viewport rectangle | ||
| 75 | |||
| 61 | // OpenGL object IDs | 76 | // OpenGL object IDs |
| 62 | GLuint vertex_array_handle; | 77 | GLuint vertex_array_handle; |
| 63 | GLuint vertex_buffer_handle; | 78 | GLuint vertex_buffer_handle; |