diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 1c32d29f5..afa25b213 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -59,8 +59,6 @@ void RendererOpenGL::SwapBuffers() { render_window->MakeCurrent(); for(int i : {0, 1}) { - const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; - u32 lcd_color_fill = 0; // TODO: Get LCD Color Fill data from GPU (main: 0x202204, sub: 0x202A04) @@ -68,20 +66,18 @@ void RendererOpenGL::SwapBuffers() { u8 r = (lcd_color_fill >> 0) & 0xFF; u8 g = (lcd_color_fill >> 8) & 0xFF; u8 b = (lcd_color_fill >> 16) & 0xFF; - LoadColorToActiveGLTexture(r, g, b, &textures[i]); - } else { - if (textures[i].width != framebuffer.width || textures[i].height != framebuffer.height) { - // Reallocate texture if the framebuffer size has changed. - // This is expected to not happen very often and hence should not be a - // performance problem. - glBindTexture(GL_TEXTURE_2D, textures[i].handle); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, framebuffer.width, framebuffer.height, 0, - GL_BGR, GL_UNSIGNED_BYTE, nullptr); - textures[i].width = framebuffer.width; - textures[i].height = framebuffer.height; - } + LoadColorToActiveGLTexture(r, g, b, textures[i]); - LoadFBToActiveGLTexture(GPU::g_regs.framebuffer_config[i], textures[i]); + // Resize the texture in case the framebuffer size has changed + textures[i].width = 1; + textures[i].height = 1; + } else { + const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; + LoadFBToActiveGLTexture(framebuffer, textures[i]); + + // Resize the texture in case the framebuffer size has changed + textures[i].width = framebuffer.width; + textures[i].height = framebuffer.height; } } @@ -121,38 +117,44 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& glBindTexture(GL_TEXTURE_2D, texture.handle); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride); - // Update existing texture - // TODO: Test what happens on hardware when you change the framebuffer dimensions so that they - // differ from the LCD resolution. - // TODO: Applications could theoretically crash Citra here by specifying too large - // framebuffer sizes. We should make sure that this cannot happen. - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height, - GL_BGR, GL_UNSIGNED_BYTE, framebuffer_data); + if (texture.width != framebuffer.width || texture.height != framebuffer.height) { + // Reallocate texture if the framebuffer size has changed. + // This is expected to not happen very often and hence should not be a + // performance problem. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, framebuffer.width, framebuffer.height, 0, + GL_BGR, GL_UNSIGNED_BYTE, framebuffer_data); + } else { + // Update existing texture + // TODO: Test what happens on hardware when you change the framebuffer dimensions so that they + // differ from the LCD resolution. + // TODO: Applications could theoretically crash Citra here by specifying too large + // framebuffer sizes. We should make sure that this cannot happen. + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height, + GL_BGR, GL_UNSIGNED_BYTE, framebuffer_data); + } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glBindTexture(GL_TEXTURE_2D, 0); } /** - * Creates 1x1 framebuffer from color, loads into the active OpenGL texture. + * Fills active OpenGL texture with the given RGB color. * Since the color is solid, the texture can be 1x1 but will stretch across whatever it's rendered on. * This has the added benefit of being *really fast*. */ -void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, TextureInfo* texture) { - glBindTexture(GL_TEXTURE_2D, texture->handle); +void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, + const TextureInfo& texture) { + glBindTexture(GL_TEXTURE_2D, texture.handle); u8 framebuffer_data[3] = { color_r, color_g, color_b }; - if (texture->width != 1 || texture->height != 1) { + if (texture.width != 1 || texture.height != 1) { // Reallocate texture if the framebuffer size has changed. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data); - texture->width = 1; - texture->height = 1; } else { // Update existing texture - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->width, texture->height, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture.width, texture.height, GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data); } diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index be8508b06..fdaa2d30a 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -51,8 +51,9 @@ private: // Loads framebuffer from emulated memory into the active OpenGL texture. static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer, const TextureInfo& texture); - // Creates 1x1 framebuffer from color, loads into the active OpenGL texture. - static void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, TextureInfo* texture); + // Fills active OpenGL texture with the given RGB color. + static void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, + const TextureInfo& texture); EmuWindow* render_window; ///< Handle to render window u32 last_mode; ///< Last render mode @@ -64,7 +65,7 @@ private: GLuint vertex_array_handle; GLuint vertex_buffer_handle; GLuint program_id; - std::array textures; // main, sub respectively + std::array textures; // main and sub respectively // Shader uniform location indices GLuint uniform_modelview_matrix; GLuint uniform_color_texture;