mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-23 22:30:09 +00:00
video_core: Make the OpenGL renderer work on GL 2.0+ and GLES 2.0+
This commit is contained in:
parent
8885c118ff
commit
6e95f273cc
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace ShaderUtil {
|
namespace ShaderUtil {
|
||||||
|
|
||||||
GLuint LoadShaders(const char* vertex_shader, const char* fragment_shader) {
|
GLuint LoadShaders(const char* glsl_header, const char* vertex_shader, const char* fragment_shader) {
|
||||||
|
|
||||||
// Create the shaders
|
// Create the shaders
|
||||||
GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
|
GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
|
||||||
@ -22,7 +22,8 @@ GLuint LoadShaders(const char* vertex_shader, const char* fragment_shader) {
|
|||||||
// Compile Vertex Shader
|
// Compile Vertex Shader
|
||||||
LOG_DEBUG(Render_OpenGL, "Compiling vertex shader...");
|
LOG_DEBUG(Render_OpenGL, "Compiling vertex shader...");
|
||||||
|
|
||||||
glShaderSource(vertex_shader_id, 1, &vertex_shader, nullptr);
|
const char* vertex_source[2] = {glsl_header, vertex_shader};
|
||||||
|
glShaderSource(vertex_shader_id, 2, vertex_source, nullptr);
|
||||||
glCompileShader(vertex_shader_id);
|
glCompileShader(vertex_shader_id);
|
||||||
|
|
||||||
// Check Vertex Shader
|
// Check Vertex Shader
|
||||||
@ -42,7 +43,8 @@ GLuint LoadShaders(const char* vertex_shader, const char* fragment_shader) {
|
|||||||
// Compile Fragment Shader
|
// Compile Fragment Shader
|
||||||
LOG_DEBUG(Render_OpenGL, "Compiling fragment shader...");
|
LOG_DEBUG(Render_OpenGL, "Compiling fragment shader...");
|
||||||
|
|
||||||
glShaderSource(fragment_shader_id, 1, &fragment_shader, nullptr);
|
const char* fragment_source[2] = {glsl_header, fragment_shader};
|
||||||
|
glShaderSource(fragment_shader_id, 2, fragment_source, nullptr);
|
||||||
glCompileShader(fragment_shader_id);
|
glCompileShader(fragment_shader_id);
|
||||||
|
|
||||||
// Check Fragment Shader
|
// Check Fragment Shader
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
|
|
||||||
namespace ShaderUtil {
|
namespace ShaderUtil {
|
||||||
|
|
||||||
GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path);
|
GLuint LoadShaders(const char* glsl_header, const char* vertex_shader, const char* fragment_shader);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,38 +7,40 @@
|
|||||||
namespace GLShaders {
|
namespace GLShaders {
|
||||||
|
|
||||||
const char g_vertex_shader[] = R"(
|
const char g_vertex_shader[] = R"(
|
||||||
#version 150 core
|
#if GL_ES && __VERSION__ >= 300 || !GL_ES && __VERSION__ >= 130
|
||||||
|
#define attribute in
|
||||||
|
#define varying out
|
||||||
|
#endif
|
||||||
|
|
||||||
in vec2 vert_position;
|
attribute mediump vec2 vert_position;
|
||||||
in vec2 vert_tex_coord;
|
attribute mediump vec2 vert_tex_coord;
|
||||||
out vec2 frag_tex_coord;
|
varying mediump vec2 frag_tex_coord;
|
||||||
|
|
||||||
// This is a truncated 3x3 matrix for 2D transformations:
|
uniform mat3 modelview_matrix;
|
||||||
// The upper-left 2x2 submatrix performs scaling/rotation/mirroring.
|
|
||||||
// The third column performs translation.
|
|
||||||
// The third row could be used for projection, which we don't need in 2D. It hence is assumed to
|
|
||||||
// implicitly be [0, 0, 1]
|
|
||||||
uniform mat3x2 modelview_matrix;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Multiply input position by the rotscale part of the matrix and then manually translate by
|
gl_Position = vec4(modelview_matrix * vec3(vert_position, 1.0), 1.0);
|
||||||
// the last column. This is equivalent to using a full 3x3 matrix and expanding the vector
|
|
||||||
// to `vec3(vert_position.xy, 1.0)`
|
|
||||||
gl_Position = vec4(mat2(modelview_matrix) * vert_position + modelview_matrix[2], 0.0, 1.0);
|
|
||||||
frag_tex_coord = vert_tex_coord;
|
frag_tex_coord = vert_tex_coord;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
const char g_fragment_shader[] = R"(
|
const char g_fragment_shader[] = R"(
|
||||||
#version 150 core
|
#if GL_ES && __VERSION__ >= 300 || !GL_ES && __VERSION__ >= 130
|
||||||
|
#define varying in
|
||||||
|
#endif
|
||||||
|
|
||||||
in vec2 frag_tex_coord;
|
varying mediump vec2 frag_tex_coord;
|
||||||
out vec4 color;
|
|
||||||
|
#if GL_ES && __VERSION__ >= 300
|
||||||
|
out mediump vec4 color;
|
||||||
|
#else
|
||||||
|
#define color gl_FragColor
|
||||||
|
#endif
|
||||||
|
|
||||||
uniform sampler2D color_texture;
|
uniform sampler2D color_texture;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
color = texture(color_texture, frag_tex_coord);
|
color = texture2D(color_texture, frag_tex_coord);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
@ -34,12 +34,12 @@ struct ScreenRectVertex {
|
|||||||
* The projection part of the matrix is trivial, hence these operations are represented
|
* The projection part of the matrix is trivial, hence these operations are represented
|
||||||
* by a 3x2 matrix.
|
* by a 3x2 matrix.
|
||||||
*/
|
*/
|
||||||
static std::array<GLfloat, 3*2> MakeOrthographicMatrix(const float width, const float height) {
|
static std::array<GLfloat, 3*3> MakeOrthographicMatrix(const float width, const float height) {
|
||||||
std::array<GLfloat, 3*2> matrix;
|
std::array<GLfloat, 3*3> matrix;
|
||||||
|
|
||||||
matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f;
|
matrix[0] = 2.f / width; matrix[3] = 0.f; matrix[6] = -1.f;
|
||||||
matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f;
|
matrix[1] = 0.f; matrix[4] = -2.f / height; matrix[7] = 1.f;
|
||||||
// Last matrix row is implicitly assumed to be [0, 0, 1].
|
matrix[2] = 0.f; matrix[5] = 0.f; matrix[8] = 1.f;
|
||||||
|
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
@ -131,11 +131,38 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
|
|||||||
* Initializes the OpenGL state and creates persistent objects.
|
* Initializes the OpenGL state and creates persistent objects.
|
||||||
*/
|
*/
|
||||||
void RendererOpenGL::InitOpenGLObjects() {
|
void RendererOpenGL::InitOpenGLObjects() {
|
||||||
|
std::string glsl_header;
|
||||||
|
|
||||||
|
// Select the right GLSL version for our context
|
||||||
|
int version = epoxy_gl_version();
|
||||||
|
if (epoxy_is_desktop_gl()) {
|
||||||
|
if (version == 20)
|
||||||
|
glsl_header = "#version 110\n";
|
||||||
|
else if (version == 21)
|
||||||
|
glsl_header = "#version 120\n";
|
||||||
|
else if (version == 30)
|
||||||
|
glsl_header = "#version 130\n";
|
||||||
|
else if (version == 31)
|
||||||
|
glsl_header = "#version 140\n";
|
||||||
|
else if (version == 32)
|
||||||
|
glsl_header = "#version 150\n";
|
||||||
|
else
|
||||||
|
glsl_header = "#version " + std::to_string(version * 10) + "\n";
|
||||||
|
|
||||||
|
// Desktop OpenGL doesn’t support precision qualifiers.
|
||||||
|
glsl_header += "#define mediump\n";
|
||||||
|
} else {
|
||||||
|
if (version == 20)
|
||||||
|
glsl_header = "#version 100\n";
|
||||||
|
else
|
||||||
|
glsl_header = "#version " + std::to_string(version * 10) + " es\n";
|
||||||
|
}
|
||||||
|
|
||||||
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
|
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
// Link shaders and get variable locations
|
// Link shaders and get variable locations
|
||||||
program_id = ShaderUtil::LoadShaders(GLShaders::g_vertex_shader, GLShaders::g_fragment_shader);
|
program_id = ShaderUtil::LoadShaders(glsl_header.c_str(), GLShaders::g_vertex_shader, GLShaders::g_fragment_shader);
|
||||||
uniform_modelview_matrix = glGetUniformLocation(program_id, "modelview_matrix");
|
uniform_modelview_matrix = glGetUniformLocation(program_id, "modelview_matrix");
|
||||||
uniform_color_texture = glGetUniformLocation(program_id, "color_texture");
|
uniform_color_texture = glGetUniformLocation(program_id, "color_texture");
|
||||||
attrib_position = glGetAttribLocation(program_id, "vert_position");
|
attrib_position = glGetAttribLocation(program_id, "vert_position");
|
||||||
@ -201,8 +228,8 @@ void RendererOpenGL::DrawScreens() {
|
|||||||
glUseProgram(program_id);
|
glUseProgram(program_id);
|
||||||
|
|
||||||
// Set projection matrix
|
// Set projection matrix
|
||||||
std::array<GLfloat, 3*2> ortho_matrix = MakeOrthographicMatrix((float)resolution_width, (float)resolution_height);
|
std::array<GLfloat, 3*3> ortho_matrix = MakeOrthographicMatrix((float)resolution_width, (float)resolution_height);
|
||||||
glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
|
glUniformMatrix3fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
|
||||||
|
|
||||||
// Bind texture in Texture Unit 0
|
// Bind texture in Texture Unit 0
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
Loading…
Reference in New Issue
Block a user