From 81fa66e9a8b09239efca2e9e17cacfe5ee0677d2 Mon Sep 17 00:00:00 2001 From: archshift Date: Sun, 12 Oct 2014 22:40:26 -0700 Subject: [PATCH] Add implementation for color filling. TODO: Get LCD Color Fill data from GPU --- .../renderer_opengl/renderer_opengl.cpp | 57 +++++++++++++++---- .../renderer_opengl/renderer_opengl.h | 4 +- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 8483f79be..1c32d29f5 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -61,18 +61,28 @@ void RendererOpenGL::SwapBuffers() { for(int i : {0, 1}) { const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; - 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; - } + u32 lcd_color_fill = 0; + // TODO: Get LCD Color Fill data from GPU (main: 0x202204, sub: 0x202A04) - LoadFBToActiveGLTexture(GPU::g_regs.framebuffer_config[i], textures[i]); + if (lcd_color_fill & 1 << 24) { //Enabled + 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; + } + + LoadFBToActiveGLTexture(GPU::g_regs.framebuffer_config[i], textures[i]); + } } DrawScreens(); @@ -124,6 +134,31 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& glBindTexture(GL_TEXTURE_2D, 0); } +/** + * Creates 1x1 framebuffer from color, loads into the active OpenGL texture. + * 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); + + u8 framebuffer_data[3] = { color_r, color_g, color_b }; + + 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, + GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data); + } + + glBindTexture(GL_TEXTURE_2D, 0); +} + /** * Initializes the OpenGL state and creates persistent objects. */ diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 82ef4b14b..be8508b06 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -51,6 +51,8 @@ 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); EmuWindow* render_window; ///< Handle to render window u32 last_mode; ///< Last render mode @@ -62,7 +64,7 @@ private: GLuint vertex_array_handle; GLuint vertex_buffer_handle; GLuint program_id; - std::array textures; + std::array textures; // main, sub respectively // Shader uniform location indices GLuint uniform_modelview_matrix; GLuint uniform_color_texture;