mirror of
https://github.com/azahar-emu/azahar.git
synced 2026-06-06 02:33:44 -04:00
opengl implemented fxaa and gamma corrected bilinear
This commit is contained in:
parent
1877140f21
commit
652db82300
1 changed files with 221 additions and 80 deletions
|
|
@ -560,6 +560,7 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float scree
|
|||
textureWidth = static_cast<float>(screen_info.texture.height * scale_factor);
|
||||
textureHeight = static_cast<float>(screen_info.texture.width * scale_factor);
|
||||
bool isDownsampling = false;
|
||||
int antialiasingMode = 1; //0 is none, 1 is FXAA, 2 is SMAA
|
||||
if (orientation == Layout::DisplayOrientation::Landscape || orientation == Layout::DisplayOrientation::LandscapeFlipped) {
|
||||
if (textureWidth > screenWidth){
|
||||
isDownsampling = true;
|
||||
|
|
@ -569,7 +570,7 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float scree
|
|||
isDownsampling = true;
|
||||
}
|
||||
}
|
||||
// Rotate Internal Texture to Landscape (The 3DS stores images rotated 90° Counter Clockkwise internally)
|
||||
// Rotate Internal Texture to Landscape (The 3DS stores images rotated 90° internally)
|
||||
std::array<ScreenRectVertex, 4> rotate_vertices;
|
||||
rotate_vertices = {{
|
||||
ScreenRectVertex(-1.f, 1.f, 1.f, 0.f), //Left, Top
|
||||
|
|
@ -588,18 +589,6 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float scree
|
|||
ScreenRectVertex(1.f, -1.f, 1.f, 0.f), //Right, Bottom
|
||||
}};
|
||||
|
||||
// Rotate for Output Orientation,
|
||||
// MAKE SURE TO USE ORTHOGRAPHIC MATRIX
|
||||
|
||||
//Test
|
||||
std::array<ScreenRectVertex, 4> rotate_output_vertices;
|
||||
rotate_output_vertices = {{
|
||||
ScreenRectVertex(screenLeft, screenTop, 1.f, 0.f), //Left, Top
|
||||
ScreenRectVertex(screenLeft + screenWidth, screenTop, 1.f, 1.f), //Right, Top
|
||||
ScreenRectVertex(screenLeft, screenTop + screenHeight, 0.f, 0.f), //Left, Bottom
|
||||
ScreenRectVertex(screenLeft + screenWidth, screenTop + screenHeight, 0.f, 1.f), //Right, Bottom
|
||||
}};
|
||||
|
||||
std::array<ScreenRectVertex, 4> output_vertices;
|
||||
switch (orientation) {
|
||||
case Layout::DisplayOrientation::Landscape:
|
||||
|
|
@ -693,75 +682,221 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float scree
|
|||
GLuint originalDrawFramebuffer = state.draw.draw_framebuffer;
|
||||
int originalViewport[4] = {state.viewport.x, state.viewport.y, state.viewport.width, state.viewport.height};
|
||||
// -------------------------------------------------------------
|
||||
/*
|
||||
Implement Gamma Corrected Bilinear:
|
||||
Rotate Texture and Convert to Linear
|
||||
Bilinear downscale to Screen width/height and convert to srgb
|
||||
*/
|
||||
// Create and bind Framebuffer, Create Framebuffer Texture, Bind the texture to the Framebuffer
|
||||
OGLFramebuffer postFBO;
|
||||
postFBO.Create();
|
||||
state.draw.read_framebuffer = postFBO.handle;
|
||||
state.draw.draw_framebuffer = postFBO.handle;
|
||||
state.Apply();
|
||||
state.viewport.x = 0;
|
||||
state.viewport.y = 0;
|
||||
state.viewport.width = textureWidth;
|
||||
state.viewport.height = textureHeight;
|
||||
state.Apply();
|
||||
OGLTexture postFBOTexture;
|
||||
postFBOTexture.Create();
|
||||
postFBOTexture.Allocate(GL_TEXTURE_2D, 1, GL_RGBA8, textureWidth, textureHeight);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, postFBOTexture.handle, 0);
|
||||
if (antialiasingMode == 1){
|
||||
if (isDownsampling){
|
||||
//Pass 1
|
||||
OGLFramebuffer textureFBO;
|
||||
textureFBO.Create();
|
||||
state.draw.read_framebuffer = textureFBO.handle;
|
||||
state.draw.draw_framebuffer = textureFBO.handle;
|
||||
state.Apply();
|
||||
state.viewport.x = 0;
|
||||
state.viewport.y = 0;
|
||||
state.viewport.width = textureWidth;
|
||||
state.viewport.height = textureHeight;
|
||||
state.Apply();
|
||||
OGLTexture pass1FBOTexture;
|
||||
pass1FBOTexture.Create();
|
||||
pass1FBOTexture.Allocate(GL_TEXTURE_2D, 1, GL_RGBA16F, textureWidth, textureHeight);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pass1FBOTexture.handle, 0);
|
||||
state.draw.shader_program = SimplePresent_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = screen_info.display_texture;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 1);
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(rotate_vertices), rotate_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
// Use the simple present shader handle to draw to the texture
|
||||
state.draw.shader_program = SimplePresent_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = screen_info.display_texture;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 1);
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(rotate_vertices), rotate_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
//Pass 2
|
||||
state.viewport.x = 0;
|
||||
state.viewport.y = 0;
|
||||
state.viewport.width = screenWidth;
|
||||
state.viewport.height = screenHeight;
|
||||
state.Apply();
|
||||
OGLTexture pass2FBOTexture;
|
||||
pass2FBOTexture.Create();
|
||||
pass2FBOTexture.Allocate(GL_TEXTURE_2D, 1, GL_RGBA16F, screenWidth, screenHeight);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pass2FBOTexture.handle, 0);
|
||||
state.draw.shader_program = SimplePresent_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = pass1FBOTexture.handle;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 2);
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(pass_through_vertices), pass_through_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
//Pass 3
|
||||
state.viewport.x = 0;
|
||||
state.viewport.y = 0;
|
||||
state.viewport.width = screenWidth;
|
||||
state.viewport.height = screenHeight;
|
||||
state.Apply();
|
||||
OGLTexture pass3FBOTexture;
|
||||
pass3FBOTexture.Create();
|
||||
pass3FBOTexture.Allocate(GL_TEXTURE_2D, 1, GL_RGBA16F, screenWidth, screenHeight);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pass3FBOTexture.handle, 0);
|
||||
state.draw.shader_program = FXAA_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = pass2FBOTexture.handle;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 0);
|
||||
glUniform4f(uniform_i_resolution, screenWidth, screenHeight, 1.0f / screenWidth, 1.0f / screenHeight);
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(pass_through_vertices), pass_through_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
//Output
|
||||
state.draw.read_framebuffer = originalReadFramebuffer;
|
||||
state.draw.draw_framebuffer = originalDrawFramebuffer;
|
||||
state.Apply();
|
||||
state.viewport.x = originalViewport[0];
|
||||
state.viewport.y = originalViewport[1];
|
||||
state.viewport.width = originalViewport[2];
|
||||
state.viewport.height = originalViewport[3];
|
||||
state.Apply();
|
||||
state.draw.shader_program = Present_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = pass3FBOTexture.handle;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 0);
|
||||
glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(output_vertices), output_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
} else {
|
||||
//Pass 1
|
||||
OGLFramebuffer textureFBO;
|
||||
textureFBO.Create();
|
||||
state.draw.read_framebuffer = textureFBO.handle;
|
||||
state.draw.draw_framebuffer = textureFBO.handle;
|
||||
state.Apply();
|
||||
state.viewport.x = 0;
|
||||
state.viewport.y = 0;
|
||||
state.viewport.width = textureWidth;
|
||||
state.viewport.height = textureHeight;
|
||||
state.Apply();
|
||||
OGLTexture pass1FBOTexture;
|
||||
pass1FBOTexture.Create();
|
||||
pass1FBOTexture.Allocate(GL_TEXTURE_2D, 1, GL_RGBA16F, textureWidth, textureHeight);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pass1FBOTexture.handle, 0);
|
||||
state.draw.shader_program = SimplePresent_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = screen_info.display_texture;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 0);
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(rotate_vertices), rotate_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
//Pass 2
|
||||
state.viewport.x = 0;
|
||||
state.viewport.y = 0;
|
||||
state.viewport.width = textureWidth;
|
||||
state.viewport.height = textureHeight;
|
||||
state.Apply();
|
||||
OGLTexture pass2FBOTexture;
|
||||
pass2FBOTexture.Create();
|
||||
pass2FBOTexture.Allocate(GL_TEXTURE_2D, 1, GL_RGBA16F, textureWidth, textureHeight);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pass2FBOTexture.handle, 0);
|
||||
state.draw.shader_program = FXAA_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = pass1FBOTexture.handle;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 1);
|
||||
glUniform4f(uniform_i_resolution, textureWidth, textureHeight, 1.0f / textureWidth, 1.0f / textureHeight);
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(pass_through_vertices), pass_through_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
//Output
|
||||
state.draw.read_framebuffer = originalReadFramebuffer;
|
||||
state.draw.draw_framebuffer = originalDrawFramebuffer;
|
||||
state.Apply();
|
||||
state.viewport.x = originalViewport[0];
|
||||
state.viewport.y = originalViewport[1];
|
||||
state.viewport.width = originalViewport[2];
|
||||
state.viewport.height = originalViewport[3];
|
||||
state.Apply();
|
||||
state.draw.shader_program = Present_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = pass2FBOTexture.handle;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 2);
|
||||
glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(output_vertices), output_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
}
|
||||
} else {
|
||||
OGLFramebuffer postFBO;
|
||||
postFBO.Create();
|
||||
state.draw.read_framebuffer = postFBO.handle;
|
||||
state.draw.draw_framebuffer = postFBO.handle;
|
||||
state.Apply();
|
||||
state.viewport.x = 0;
|
||||
state.viewport.y = 0;
|
||||
state.viewport.width = textureWidth;
|
||||
state.viewport.height = textureHeight;
|
||||
state.Apply();
|
||||
OGLTexture postFBOTexture;
|
||||
postFBOTexture.Create();
|
||||
postFBOTexture.Allocate(GL_TEXTURE_2D, 1, GL_RGBA16F, textureWidth, textureHeight);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, postFBOTexture.handle, 0);
|
||||
|
||||
// Use the simple present shader handle to draw to the texture
|
||||
state.draw.shader_program = SimplePresent_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = screen_info.display_texture;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 1);
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(rotate_vertices), rotate_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
// Draw to screen
|
||||
state.draw.read_framebuffer = originalReadFramebuffer;
|
||||
state.draw.draw_framebuffer = originalDrawFramebuffer;
|
||||
state.Apply();
|
||||
state.viewport.x = originalViewport[0];
|
||||
state.viewport.y = originalViewport[1];
|
||||
state.viewport.width = originalViewport[2];
|
||||
state.viewport.height = originalViewport[3];
|
||||
// LOG_INFO(Render_OpenGL, "Texture Width: {}, Texture Height: {}", textureWidth, textureHeight);
|
||||
// LOG_INFO(Render_OpenGL, "Viewport Width: {}, Viewport Height: {}", originalViewport[2], originalViewport[3]);
|
||||
state.Apply();
|
||||
state.draw.shader_program = Present_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = postFBOTexture.handle;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 2);
|
||||
glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(output_vertices), output_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
// Draw to screen
|
||||
state.draw.read_framebuffer = originalReadFramebuffer;
|
||||
state.draw.draw_framebuffer = originalDrawFramebuffer;
|
||||
state.Apply();
|
||||
// state.viewport.x = originalViewport[0];
|
||||
// state.viewport.y = originalViewport[1];
|
||||
// state.viewport.width = originalViewport[2];
|
||||
// state.viewport.height = originalViewport[3];
|
||||
// state.Apply();
|
||||
state.draw.shader_program = Present_shader.handle;
|
||||
state.Apply();
|
||||
AttachUniforms();
|
||||
state.texture_units[0].texture_2d = postFBOTexture.handle;
|
||||
state.texture_units[0].sampler = samplers[1].handle;
|
||||
glUniform1i(uniform_color_texture, 0);
|
||||
glUniform1i(uniform_convert_colors, 2);
|
||||
glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
|
||||
state.Apply();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(output_vertices), output_vertices.data());
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
// -------------------------------------------------------------
|
||||
// // Draw to screen (No Intermediate) [For Debugging]
|
||||
// state.draw.read_framebuffer = originalReadFramebuffer;
|
||||
// state.draw.draw_framebuffer = originalDrawFramebuffer;
|
||||
// state.Apply();
|
||||
// state.draw.shader_program = Present_shader.handle;
|
||||
// state.Apply();
|
||||
// AttachUniforms();
|
||||
// state.texture_units[0].texture_2d = screen_info.display_texture;
|
||||
// state.texture_units[0].sampler = samplers[1].handle;
|
||||
// glUniform1i(uniform_color_texture, 0);
|
||||
// glUniform1i(uniform_convert_colors, 2);
|
||||
// glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
|
||||
// state.Apply();
|
||||
// glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(rotate_output_vertices), rotate_output_vertices.data());
|
||||
// glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
// // Draw to screen (No Intermediate Simple) [For Debugging]
|
||||
// state.draw.read_framebuffer = originalReadFramebuffer;
|
||||
|
|
@ -939,7 +1074,13 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
|||
const auto& top_screen = layout.top_screen;
|
||||
const auto& bottom_screen = layout.bottom_screen;
|
||||
|
||||
glViewport(0, 0, layout.width, layout.height);
|
||||
//Set the Viewport
|
||||
state.viewport.x = 0;
|
||||
state.viewport.y = 0;
|
||||
state.viewport.width = layout.width;
|
||||
state.viewport.height = layout.height;
|
||||
state.Apply();
|
||||
|
||||
if (render_window.NeedsClearing()) {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue