From 041e99b6132775ff52822060512b8384b735e582 Mon Sep 17 00:00:00 2001 From: archshift Date: Sun, 12 Oct 2014 22:40:26 -0700 Subject: Added LCD registers, and implementation for color filling in OGL code. --- src/video_core/renderer_opengl/renderer_opengl.cpp | 54 ++++++++++++++++++---- src/video_core/renderer_opengl/renderer_opengl.h | 5 +- 2 files changed, 48 insertions(+), 11 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 27269517..2fcbb0cc 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -3,6 +3,8 @@ // Refer to the license.txt file included. #include "core/hw/gpu.h" +#include "core/hw/hw.h" +#include "core/hw/lcd.h" #include "core/mem_map.h" #include "common/emu_window.h" #include "video_core/video_core.h" @@ -61,16 +63,33 @@ void RendererOpenGL::SwapBuffers() { for(int i : {0, 1}) { const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; - if (textures[i].width != (GLsizei)framebuffer.width || - textures[i].height != (GLsizei)framebuffer.height || - textures[i].format != framebuffer.color_format) { - // Reallocate texture if the framebuffer size has changed. - // This is expected to not happen very often and hence should not be a - // performance problem. - ConfigureFramebufferTexture(textures[i], framebuffer); + // Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04 + u32 lcd_color_addr = (i == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom); + lcd_color_addr = HW::VADDR_LCD + 4 * lcd_color_addr; + LCD::Regs::ColorFill color_fill = {0}; + LCD::Read(color_fill.raw, lcd_color_addr); + + if (color_fill.is_enabled) { + LoadColorToActiveGLTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b, textures[i]); + + // Resize the texture in case the framebuffer size has changed + textures[i].width = 1; + textures[i].height = 1; + } else { + if (textures[i].width != (GLsizei)framebuffer.width || + textures[i].height != (GLsizei)framebuffer.height || + textures[i].format != framebuffer.color_format) { + // Reallocate texture if the framebuffer size has changed. + // This is expected to not happen very often and hence should not be a + // performance problem. + ConfigureFramebufferTexture(textures[i], framebuffer); + } + LoadFBToActiveGLTexture(framebuffer, textures[i]); + + // Resize the texture in case the framebuffer size has changed + textures[i].width = framebuffer.width; + textures[i].height = framebuffer.height; } - - LoadFBToActiveGLTexture(GPU::g_regs.framebuffer_config[i], textures[i]); } DrawScreens(); @@ -115,10 +134,25 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& // 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, - texture.gl_format, texture.gl_type, framebuffer_data); + texture.gl_format, texture.gl_type, framebuffer_data); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glBindTexture(GL_TEXTURE_2D, 0); +} +/** + * 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, + const TextureInfo& texture) { + glBindTexture(GL_TEXTURE_2D, texture.handle); + + u8 framebuffer_data[3] = { color_r, color_g, color_b }; + + // Update existing texture + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data); glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index bcabab55..cd782428 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -58,6 +58,9 @@ private: // Loads framebuffer from emulated memory into the active OpenGL texture. static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer, const 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); /// Computes the viewport rectangle MathUtil::Rectangle GetViewportExtent(); @@ -72,7 +75,7 @@ private: GLuint vertex_array_handle; GLuint vertex_buffer_handle; GLuint program_id; - std::array textures; + std::array textures; ///< Textures for top and bottom screens respectively // Shader uniform location indices GLuint uniform_modelview_matrix; GLuint uniform_color_texture; -- cgit v1.2.3