diff options
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 36 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 15 |
2 files changed, 50 insertions, 1 deletions
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 * 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(); 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: static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer, const TextureInfo& texture); + /// Updates the viewport rectangle + void UpdateViewportExtent(); + EmuWindow* render_window; ///< Handle to render window u32 last_mode; ///< Last render mode int resolution_width; ///< Current resolution width int resolution_height; ///< Current resolution height + struct { + int width; + int height; + } framebuffer_size; ///< Current framebuffer size + + struct { + int x; + int y; + int width; + int height; + } viewport_extent; ///< Current viewport rectangle + // OpenGL object IDs GLuint vertex_array_handle; GLuint vertex_buffer_handle; |