Add implementation for color filling.

TODO: Get LCD Color Fill data from GPU
This commit is contained in:
archshift 2014-10-12 22:40:26 -07:00
parent e4905143c8
commit 81fa66e9a8
2 changed files with 49 additions and 12 deletions

View file

@ -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.
*/

View file

@ -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<TextureInfo, 2> textures;
std::array<TextureInfo, 2> textures; // main, sub respectively
// Shader uniform location indices
GLuint uniform_modelview_matrix;
GLuint uniform_color_texture;