changing pipeline part 2

This commit is contained in:
KojoZero 2026-04-30 18:54:11 -07:00
parent 5e6ac1a315
commit 479b078394
5 changed files with 113 additions and 59 deletions

View file

@ -9,11 +9,22 @@ layout(location = 0) out vec4 color;
layout(binding = 0) uniform sampler2D color_texture;
uniform vec4 i_resolution;
uniform vec4 o_resolution;
uniform int layer;
uniform int convert_colors;
vec3 sRGBToLinear(vec3 c) {
return mix(c / 12.92, pow((c + 0.055) / 1.055, vec3(2.4)), step(0.04045, c));
}
vec3 LinearTosRGB(vec3 c) {
return mix(c * 12.92, 1.055 * pow(c, vec3(1.0/2.4)) - 0.055, step(0.0031308, c));
}
void main() {
color = texture(color_texture, frag_tex_coord);
vec4 pixel = texture(color_texture, frag_tex_coord);
if (convert_colors == 1){
pixel = vec4(LinearTosRGB(pixel.rgb), pixel.a);
} else if (convert_colors == 2){
pixel = vec4(sRGBToLinear(pixel.rgb), pixel.a);
}
color = pixel;
}

View file

@ -0,0 +1,30 @@
// Copyright 2023 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
//? #version 430 core
layout(location = 0) in vec2 frag_tex_coord;
layout(location = 0) out vec4 color;
layout(binding = 0) uniform sampler2D color_texture;
uniform int convert_colors;
vec3 sRGBToLinear(vec3 c) {
return mix(c / 12.92, pow((c + 0.055) / 1.055, vec3(2.4)), step(0.04045, c));
}
vec3 LinearTosRGB(vec3 c) {
return mix(c * 12.92, 1.055 * pow(c, vec3(1.0/2.4)) - 0.055, step(0.0031308, c));
}
void main() {
vec4 pixel = texture(color_texture, frag_tex_coord);
if (convert_colors == 1){
pixel = vec4(LinearTosRGB(pixel.rgb), pixel.a);
} else if (convert_colors == 2){
pixel = vec4(sRGBToLinear(pixel.rgb), pixel.a);
}
color = pixel;
}

View file

@ -0,0 +1,13 @@
// Copyright 2023 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
//? #version 430 core
layout(location = 0) in vec2 vert_position;
layout(location = 1) in vec2 vert_tex_coord;
layout(location = 0) out vec2 frag_tex_coord;
void main() {
gl_Position = vec4(vert_position, 0.0, 1.0);
frag_tex_coord = vert_tex_coord;
}

View file

@ -434,6 +434,7 @@ void RendererOpenGL::ReloadShader(Settings::StereoRenderOption render_3d) {
}
uniform_i_resolution = glGetUniformLocation(shader.handle, "i_resolution");
uniform_o_resolution = glGetUniformLocation(shader.handle, "o_resolution");
uniform_convert_colors = glGetUniformLocation(shader.handle, "convert_colors");
uniform_layer = glGetUniformLocation(shader.handle, "layer");
attrib_position = glGetAttribLocation(shader.handle, "vert_position");
attrib_tex_coord = glGetAttribLocation(shader.handle, "vert_tex_coord");
@ -543,75 +544,69 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float scree
// Rotate Internal Texture to Landscape (The 3DS stores images rotated 90° Counter Clockkwise internally)
std::array<ScreenRectVertex, 4> landscape_rotation_vertices;
landscape_rotation_vertices = {{
ScreenRectVertex(0.f, 0.f, 1.f, 0.f), //Left, Top
ScreenRectVertex(textureWidth, 0.f, 1.f, 1.f), //Right, Top
ScreenRectVertex(0.f, textureHeight, 0.f, 0.f), //Left, Bottom
ScreenRectVertex(textureWidth, textureHeight, 0.f, 1.f), //Right, Bottom
ScreenRectVertex(-1.f, 1.f, 1.f, 0.f), //Left, Top
ScreenRectVertex(1.f, 1.f, 1.f, 1.f), //Right, Top
ScreenRectVertex(-1.f, -1.f, 0.f, 0.f), //Left, Bottom
ScreenRectVertex(1.f, -1.f, 0.f, 1.f), //Right, Bottom
}};
// Vertices for 1:1 Texture Mapping.
std::array<ScreenRectVertex, 4> pass_through_vertices;
pass_through_vertices = {{
ScreenRectVertex(0.f, 0.f, 0.f, 1.f), //Left, Top
ScreenRectVertex(textureWidth, 0.f, 1.f, 1.f), //Right, Top
ScreenRectVertex(0.f, textureHeight, 0.f, 0.f), //Left, Bottom
ScreenRectVertex(textureWidth, textureHeight, 1.f, 0.f), //Right, Bottom
ScreenRectVertex(-1.f, 1.f, 0.f, 1.f), //Left, Top
ScreenRectVertex(1.f, 1.f, 1.f, 1.f), //Right, Top
ScreenRectVertex(-1.f, -1.f, 0.f, 0.f), //Left, Bottom
ScreenRectVertex(1.f, -1.f, 1.f, 0.f), //Right, Bottom
}};
// Rotate for Output Orientation,
// MAKE SURE TO USE ORTHOGRAPHIC MATRIX
std::array<ScreenRectVertex, 4> output_vertices;
output_vertices = {{
ScreenRectVertex(screenLeft, screenTop, 0.f, 1.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, 1.f, 0.f), //Right, Bottom
}};
// switch (orientation) {
// case Layout::DisplayOrientation::Landscape:
// vertices = {{
// ScreenRectVertex(x, y, texcoords.bottom, texcoords.left), //Top Left
// ScreenRectVertex(x + w, y, texcoords.bottom, texcoords.right), //Top Right
// ScreenRectVertex(x, y + h, texcoords.top, texcoords.left), //Bottom Left
// ScreenRectVertex(x + w, y + h, texcoords.top, texcoords.right), //Bottom Right
// }};
// break;
// case Layout::DisplayOrientation::Portrait:
// vertices = {{
// ScreenRectVertex(x, y, texcoords.bottom, texcoords.right),
// ScreenRectVertex(x + w, y, texcoords.top, texcoords.right),
// ScreenRectVertex(x, y + h, texcoords.bottom, texcoords.left),
// ScreenRectVertex(x + w, y + h, texcoords.top, texcoords.left),
// }};
// std::swap(h, w);
// break;
// case Layout::DisplayOrientation::LandscapeFlipped:
// vertices = {{
// ScreenRectVertex(x, y, texcoords.top, texcoords.right),
// ScreenRectVertex(x + w, y, texcoords.top, texcoords.left),
// ScreenRectVertex(x, y + h, texcoords.bottom, texcoords.right),
// ScreenRectVertex(x + w, y + h, texcoords.bottom, texcoords.left),
// }};
// break;
// case Layout::DisplayOrientation::PortraitFlipped:
// vertices = {{
// ScreenRectVertex(x, y, texcoords.top, texcoords.left),
// ScreenRectVertex(x + w, y, texcoords.bottom, texcoords.left),
// ScreenRectVertex(x, y + h, texcoords.top, texcoords.right),
// ScreenRectVertex(x + w, y + h, texcoords.bottom, texcoords.right),
// }};
// std::swap(h, w);
// break;
// default:
// LOG_ERROR(Render_OpenGL, "Unknown DisplayOrientation: {}", orientation);
// break;
// }
switch (orientation) {
case Layout::DisplayOrientation::Landscape:
output_vertices = {{
ScreenRectVertex(screenLeft, screenTop, 0.f, 1.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, 1.f, 0.f), //Right, Bottom
}};
break;
case Layout::DisplayOrientation::Portrait:
output_vertices = {{
ScreenRectVertex(screenLeft, screenTop, 1.f, 1.f), //Left, Top
ScreenRectVertex(screenLeft + screenWidth, screenTop, 1.f, 0.f), //Right, Top
ScreenRectVertex(screenLeft, screenTop + screenHeight, 0.f, 1.f), //Left, Bottom
ScreenRectVertex(screenLeft + screenWidth, screenTop + screenHeight, 0.f, 0.f), //Right, Bottom
}};
std::swap(screenHeight, screenWidth);
break;
case Layout::DisplayOrientation::LandscapeFlipped:
output_vertices = {{
ScreenRectVertex(screenLeft, screenTop, 0.f, 0.f), //Left, Top
ScreenRectVertex(screenLeft + screenWidth, screenTop, 1.f, 0.f), //Right, Top
ScreenRectVertex(screenLeft, screenTop + screenHeight, 0.f, 1.f), //Left, Bottom
ScreenRectVertex(screenLeft + screenWidth, screenTop + screenHeight, 1.f, 1.f), //Right, Bottom
}};
break;
case Layout::DisplayOrientation::PortraitFlipped:
output_vertices = {{
ScreenRectVertex(screenLeft, screenTop, 0.f, 0.f), //Left, Top
ScreenRectVertex(screenLeft + screenWidth, screenTop, 0.f, 1.f), //Right, Top
ScreenRectVertex(screenLeft, screenTop + screenHeight, 1.f, 0.f), //Left, Bottom
ScreenRectVertex(screenLeft + screenWidth, screenTop + screenHeight, 1.f, 1.f), //Right, Bottom
}};
std::swap(screenHeight, screenWidth);
break;
default:
LOG_ERROR(Render_OpenGL, "Unknown DisplayOrientation: {}", orientation);
break;
}
const GLuint sampler = samplers[Settings::values.filter_mode.GetValue()].handle;
glUniform4f(uniform_i_resolution, textureWidth, textureHeight, 1.0f / textureWidth, 1.0f / textureHeight);
glUniform4f(uniform_o_resolution, screenWidth, screenHeight, 1.0f / screenWidth, 1.0f / screenHeight);
glUniform1i(uniform_convert_colors, 1);
state.texture_units[0].texture_2d = screen_info.display_texture;
state.texture_units[0].sampler = sampler;
state.Apply();
@ -625,6 +620,8 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float scree
Then do:
initial rotation shader -> opengl_present shader (and all the variants)
simple present is used for internal textures. It uses ndc coordinates directly
present is used for final mapping to screen. It uses screen coordinates, and transforms it accordingly
*/
GLuint old_read_fb = state.draw.read_framebuffer;

View file

@ -102,6 +102,9 @@ private:
GLuint uniform_color_texture;
GLuint uniform_color_texture_r;
// Shader Uniform for converting colors. 0 is no conversion, 1 is Linear -> sRGB, 2 is sRGB -> linear
GLuint uniform_convert_colors;
// Shader uniform for Dolphin compatibility
GLuint uniform_i_resolution;
GLuint uniform_o_resolution;