aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/video_core/renderer_opengl/renderer_opengl.cpp
diff options
context:
space:
mode:
authorGravatar Kevin Hartman <kevin@hart.mn>2014-08-29 22:23:12 -0700
committerGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-11-18 13:06:05 +0100
commit221a9b023d8c9ca55c093823e9efd6d13d0a54a2 (patch)
tree57a26a0e11416b366688d00c4a2c9216fa0cde78 /src/video_core/renderer_opengl/renderer_opengl.cpp
parentc8d933a14211ce6ee02659ecef758a1f303bc87f (diff)
Viewport scaling and display density independence
The view is scaled to be as large as possible, without changing the aspect, within the bounds of the window. On "retina" displays, or other displays where window units != pixels, the view should no longer draw incorrectly.
Diffstat (limited to 'src/video_core/renderer_opengl/renderer_opengl.cpp')
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 8483f79b..3757482d 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
* Draws the emulated screens to the emulator window.
*/
void RendererOpenGL::DrawScreens() {
- glViewport(0, 0, resolution_width, resolution_height);
+ UpdateViewportExtent();
+ glViewport(viewport_extent.x, viewport_extent.y, viewport_extent.width, viewport_extent.height);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program_id);
@@ -228,6 +229,39 @@ void RendererOpenGL::SetWindow(EmuWindow* window) {
render_window = window;
}
+void RendererOpenGL::UpdateViewportExtent() {
+ int width_in_pixels;
+ int height_in_pixels;
+
+ render_window->GetFramebufferSize(&width_in_pixels, &height_in_pixels);
+
+ // No update needed if framebuffer size hasn't changed
+ if (width_in_pixels == framebuffer_size.width && height_in_pixels == framebuffer_size.height) {
+ return;
+ }
+
+ framebuffer_size.width = width_in_pixels;
+ framebuffer_size.height = height_in_pixels;
+
+ float window_aspect_ratio = static_cast<float>(height_in_pixels) / width_in_pixels;
+ float emulation_aspect_ratio = static_cast<float>(resolution_height) / resolution_width;
+
+ if (window_aspect_ratio > emulation_aspect_ratio) {
+ // If the window is more narrow than the emulation content, borders are applied on the
+ // top and bottom of the window.
+ viewport_extent.width = width_in_pixels;
+ viewport_extent.height = emulation_aspect_ratio * viewport_extent.width;
+ viewport_extent.x = 0;
+ viewport_extent.y = (height_in_pixels - viewport_extent.height) / 2;
+ } else {
+ // Otherwise, borders are applied on the left and right sides of the window.
+ viewport_extent.height = height_in_pixels;
+ viewport_extent.width = (1 / emulation_aspect_ratio) * viewport_extent.height;
+ viewport_extent.x = (width_in_pixels - viewport_extent.width) / 2;
+ viewport_extent.y = 0;
+ }
+}
+
/// Initialize the renderer
void RendererOpenGL::Init() {
render_window->MakeCurrent();