diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 224 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 22 |
2 files changed, 115 insertions, 131 deletions
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index a57a564f7..bba16afaf 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -24,19 +24,21 @@ | |||
| 24 | 24 | ||
| 25 | namespace OpenGL { | 25 | namespace OpenGL { |
| 26 | 26 | ||
| 27 | static const char vertex_shader[] = R"( | 27 | namespace { |
| 28 | #version 150 core | ||
| 29 | 28 | ||
| 30 | in vec2 vert_position; | 29 | constexpr char vertex_shader[] = R"( |
| 31 | in vec2 vert_tex_coord; | 30 | #version 430 core |
| 32 | out vec2 frag_tex_coord; | 31 | |
| 32 | layout (location = 0) in vec2 vert_position; | ||
| 33 | layout (location = 1) in vec2 vert_tex_coord; | ||
| 34 | layout (location = 0) out vec2 frag_tex_coord; | ||
| 33 | 35 | ||
| 34 | // This is a truncated 3x3 matrix for 2D transformations: | 36 | // This is a truncated 3x3 matrix for 2D transformations: |
| 35 | // The upper-left 2x2 submatrix performs scaling/rotation/mirroring. | 37 | // The upper-left 2x2 submatrix performs scaling/rotation/mirroring. |
| 36 | // The third column performs translation. | 38 | // The third column performs translation. |
| 37 | // The third row could be used for projection, which we don't need in 2D. It hence is assumed to | 39 | // The third row could be used for projection, which we don't need in 2D. It hence is assumed to |
| 38 | // implicitly be [0, 0, 1] | 40 | // implicitly be [0, 0, 1] |
| 39 | uniform mat3x2 modelview_matrix; | 41 | layout (location = 0) uniform mat3x2 modelview_matrix; |
| 40 | 42 | ||
| 41 | void main() { | 43 | void main() { |
| 42 | // Multiply input position by the rotscale part of the matrix and then manually translate by | 44 | // Multiply input position by the rotscale part of the matrix and then manually translate by |
| @@ -47,34 +49,29 @@ void main() { | |||
| 47 | } | 49 | } |
| 48 | )"; | 50 | )"; |
| 49 | 51 | ||
| 50 | static const char fragment_shader[] = R"( | 52 | constexpr char fragment_shader[] = R"( |
| 51 | #version 150 core | 53 | #version 430 core |
| 52 | 54 | ||
| 53 | in vec2 frag_tex_coord; | 55 | layout (location = 0) in vec2 frag_tex_coord; |
| 54 | out vec4 color; | 56 | layout (location = 0) out vec4 color; |
| 55 | 57 | ||
| 56 | uniform sampler2D color_texture; | 58 | layout (binding = 0) uniform sampler2D color_texture; |
| 57 | 59 | ||
| 58 | void main() { | 60 | void main() { |
| 59 | // Swap RGBA -> ABGR so we don't have to do this on the CPU. This needs to change if we have to | ||
| 60 | // support more framebuffer pixel formats. | ||
| 61 | color = texture(color_texture, frag_tex_coord); | 61 | color = texture(color_texture, frag_tex_coord); |
| 62 | } | 62 | } |
| 63 | )"; | 63 | )"; |
| 64 | 64 | ||
| 65 | /** | 65 | constexpr GLint PositionLocation = 0; |
| 66 | * Vertex structure that the drawn screen rectangles are composed of. | 66 | constexpr GLint TexCoordLocation = 1; |
| 67 | */ | 67 | constexpr GLint ModelViewMatrixLocation = 0; |
| 68 | |||
| 68 | struct ScreenRectVertex { | 69 | struct ScreenRectVertex { |
| 69 | ScreenRectVertex(GLfloat x, GLfloat y, GLfloat u, GLfloat v) { | 70 | constexpr ScreenRectVertex(GLfloat x, GLfloat y, GLfloat u, GLfloat v) |
| 70 | position[0] = x; | 71 | : position{{x, y}}, tex_coord{{u, v}} {} |
| 71 | position[1] = y; | ||
| 72 | tex_coord[0] = u; | ||
| 73 | tex_coord[1] = v; | ||
| 74 | } | ||
| 75 | 72 | ||
| 76 | GLfloat position[2]; | 73 | std::array<GLfloat, 2> position; |
| 77 | GLfloat tex_coord[2]; | 74 | std::array<GLfloat, 2> tex_coord; |
| 78 | }; | 75 | }; |
| 79 | 76 | ||
| 80 | /** | 77 | /** |
| @@ -84,18 +81,82 @@ struct ScreenRectVertex { | |||
| 84 | * The projection part of the matrix is trivial, hence these operations are represented | 81 | * The projection part of the matrix is trivial, hence these operations are represented |
| 85 | * by a 3x2 matrix. | 82 | * by a 3x2 matrix. |
| 86 | */ | 83 | */ |
| 87 | static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, const float height) { | 84 | std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(float width, float height) { |
| 88 | std::array<GLfloat, 3 * 2> matrix; // Laid out in column-major order | 85 | std::array<GLfloat, 3 * 2> matrix; // Laid out in column-major order |
| 89 | 86 | ||
| 90 | // clang-format off | 87 | // clang-format off |
| 91 | matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f; | 88 | matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f; |
| 92 | matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f; | 89 | matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f; |
| 93 | // Last matrix row is implicitly assumed to be [0, 0, 1]. | 90 | // Last matrix row is implicitly assumed to be [0, 0, 1]. |
| 94 | // clang-format on | 91 | // clang-format on |
| 95 | 92 | ||
| 96 | return matrix; | 93 | return matrix; |
| 97 | } | 94 | } |
| 98 | 95 | ||
| 96 | const char* GetSource(GLenum source) { | ||
| 97 | switch (source) { | ||
| 98 | case GL_DEBUG_SOURCE_API: | ||
| 99 | return "API"; | ||
| 100 | case GL_DEBUG_SOURCE_WINDOW_SYSTEM: | ||
| 101 | return "WINDOW_SYSTEM"; | ||
| 102 | case GL_DEBUG_SOURCE_SHADER_COMPILER: | ||
| 103 | return "SHADER_COMPILER"; | ||
| 104 | case GL_DEBUG_SOURCE_THIRD_PARTY: | ||
| 105 | return "THIRD_PARTY"; | ||
| 106 | case GL_DEBUG_SOURCE_APPLICATION: | ||
| 107 | return "APPLICATION"; | ||
| 108 | case GL_DEBUG_SOURCE_OTHER: | ||
| 109 | return "OTHER"; | ||
| 110 | default: | ||
| 111 | UNREACHABLE(); | ||
| 112 | return "Unknown source"; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | const char* GetType(GLenum type) { | ||
| 117 | switch (type) { | ||
| 118 | case GL_DEBUG_TYPE_ERROR: | ||
| 119 | return "ERROR"; | ||
| 120 | case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: | ||
| 121 | return "DEPRECATED_BEHAVIOR"; | ||
| 122 | case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: | ||
| 123 | return "UNDEFINED_BEHAVIOR"; | ||
| 124 | case GL_DEBUG_TYPE_PORTABILITY: | ||
| 125 | return "PORTABILITY"; | ||
| 126 | case GL_DEBUG_TYPE_PERFORMANCE: | ||
| 127 | return "PERFORMANCE"; | ||
| 128 | case GL_DEBUG_TYPE_OTHER: | ||
| 129 | return "OTHER"; | ||
| 130 | case GL_DEBUG_TYPE_MARKER: | ||
| 131 | return "MARKER"; | ||
| 132 | default: | ||
| 133 | UNREACHABLE(); | ||
| 134 | return "Unknown type"; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, | ||
| 139 | const GLchar* message, const void* user_param) { | ||
| 140 | const char format[] = "{} {} {}: {}"; | ||
| 141 | const char* const str_source = GetSource(source); | ||
| 142 | const char* const str_type = GetType(type); | ||
| 143 | |||
| 144 | switch (severity) { | ||
| 145 | case GL_DEBUG_SEVERITY_HIGH: | ||
| 146 | LOG_CRITICAL(Render_OpenGL, format, str_source, str_type, id, message); | ||
| 147 | break; | ||
| 148 | case GL_DEBUG_SEVERITY_MEDIUM: | ||
| 149 | LOG_WARNING(Render_OpenGL, format, str_source, str_type, id, message); | ||
| 150 | break; | ||
| 151 | case GL_DEBUG_SEVERITY_NOTIFICATION: | ||
| 152 | case GL_DEBUG_SEVERITY_LOW: | ||
| 153 | LOG_DEBUG(Render_OpenGL, format, str_source, str_type, id, message); | ||
| 154 | break; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | } // Anonymous namespace | ||
| 159 | |||
| 99 | RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system) | 160 | RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system) |
| 100 | : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system} {} | 161 | : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system} {} |
| 101 | 162 | ||
| @@ -138,9 +199,6 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 138 | prev_state.Apply(); | 199 | prev_state.Apply(); |
| 139 | } | 200 | } |
| 140 | 201 | ||
| 141 | /** | ||
| 142 | * Loads framebuffer from emulated memory into the active OpenGL texture. | ||
| 143 | */ | ||
| 144 | void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer) { | 202 | void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer) { |
| 145 | // Framebuffer orientation handling | 203 | // Framebuffer orientation handling |
| 146 | framebuffer_transform_flags = framebuffer.transform_flags; | 204 | framebuffer_transform_flags = framebuffer.transform_flags; |
| @@ -181,19 +239,12 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf | |||
| 181 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | 239 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| 182 | } | 240 | } |
| 183 | 241 | ||
| 184 | /** | ||
| 185 | * Fills active OpenGL texture with the given RGB color. Since the color is solid, the texture can | ||
| 186 | * be 1x1 but will stretch across whatever it's rendered on. | ||
| 187 | */ | ||
| 188 | void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, | 242 | void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, |
| 189 | const TextureInfo& texture) { | 243 | const TextureInfo& texture) { |
| 190 | const u8 framebuffer_data[4] = {color_a, color_b, color_g, color_r}; | 244 | const u8 framebuffer_data[4] = {color_a, color_b, color_g, color_r}; |
| 191 | glClearTexImage(texture.resource.handle, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer_data); | 245 | glClearTexImage(texture.resource.handle, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer_data); |
| 192 | } | 246 | } |
| 193 | 247 | ||
| 194 | /** | ||
| 195 | * Initializes the OpenGL state and creates persistent objects. | ||
| 196 | */ | ||
| 197 | void RendererOpenGL::InitOpenGLObjects() { | 248 | void RendererOpenGL::InitOpenGLObjects() { |
| 198 | glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, | 249 | glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, |
| 199 | 0.0f); | 250 | 0.0f); |
| @@ -203,10 +254,6 @@ void RendererOpenGL::InitOpenGLObjects() { | |||
| 203 | state.draw.shader_program = shader.handle; | 254 | state.draw.shader_program = shader.handle; |
| 204 | state.AllDirty(); | 255 | state.AllDirty(); |
| 205 | state.Apply(); | 256 | state.Apply(); |
| 206 | uniform_modelview_matrix = glGetUniformLocation(shader.handle, "modelview_matrix"); | ||
| 207 | uniform_color_texture = glGetUniformLocation(shader.handle, "color_texture"); | ||
| 208 | attrib_position = glGetAttribLocation(shader.handle, "vert_position"); | ||
| 209 | attrib_tex_coord = glGetAttribLocation(shader.handle, "vert_tex_coord"); | ||
| 210 | 257 | ||
| 211 | // Generate VBO handle for drawing | 258 | // Generate VBO handle for drawing |
| 212 | vertex_buffer.Create(); | 259 | vertex_buffer.Create(); |
| @@ -217,14 +264,14 @@ void RendererOpenGL::InitOpenGLObjects() { | |||
| 217 | 264 | ||
| 218 | // Attach vertex data to VAO | 265 | // Attach vertex data to VAO |
| 219 | glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW); | 266 | glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW); |
| 220 | glVertexArrayAttribFormat(vertex_array.handle, attrib_position, 2, GL_FLOAT, GL_FALSE, | 267 | glVertexArrayAttribFormat(vertex_array.handle, PositionLocation, 2, GL_FLOAT, GL_FALSE, |
| 221 | offsetof(ScreenRectVertex, position)); | 268 | offsetof(ScreenRectVertex, position)); |
| 222 | glVertexArrayAttribFormat(vertex_array.handle, attrib_tex_coord, 2, GL_FLOAT, GL_FALSE, | 269 | glVertexArrayAttribFormat(vertex_array.handle, TexCoordLocation, 2, GL_FLOAT, GL_FALSE, |
| 223 | offsetof(ScreenRectVertex, tex_coord)); | 270 | offsetof(ScreenRectVertex, tex_coord)); |
| 224 | glVertexArrayAttribBinding(vertex_array.handle, attrib_position, 0); | 271 | glVertexArrayAttribBinding(vertex_array.handle, PositionLocation, 0); |
| 225 | glVertexArrayAttribBinding(vertex_array.handle, attrib_tex_coord, 0); | 272 | glVertexArrayAttribBinding(vertex_array.handle, TexCoordLocation, 0); |
| 226 | glEnableVertexArrayAttrib(vertex_array.handle, attrib_position); | 273 | glEnableVertexArrayAttrib(vertex_array.handle, PositionLocation); |
| 227 | glEnableVertexArrayAttrib(vertex_array.handle, attrib_tex_coord); | 274 | glEnableVertexArrayAttrib(vertex_array.handle, TexCoordLocation); |
| 228 | glVertexArrayVertexBuffer(vertex_array.handle, 0, vertex_buffer.handle, 0, | 275 | glVertexArrayVertexBuffer(vertex_array.handle, 0, vertex_buffer.handle, 0, |
| 229 | sizeof(ScreenRectVertex)); | 276 | sizeof(ScreenRectVertex)); |
| 230 | 277 | ||
| @@ -331,18 +378,18 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 331 | static_cast<f32>(screen_info.texture.height); | 378 | static_cast<f32>(screen_info.texture.height); |
| 332 | } | 379 | } |
| 333 | 380 | ||
| 334 | std::array<ScreenRectVertex, 4> vertices = {{ | 381 | const std::array vertices = { |
| 335 | ScreenRectVertex(x, y, texcoords.top * scale_u, left * scale_v), | 382 | ScreenRectVertex(x, y, texcoords.top * scale_u, left * scale_v), |
| 336 | ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left * scale_v), | 383 | ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left * scale_v), |
| 337 | ScreenRectVertex(x, y + h, texcoords.top * scale_u, right * scale_v), | 384 | ScreenRectVertex(x, y + h, texcoords.top * scale_u, right * scale_v), |
| 338 | ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v), | 385 | ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v), |
| 339 | }}; | 386 | }; |
| 340 | 387 | ||
| 341 | state.textures[0] = screen_info.display_texture; | 388 | state.textures[0] = screen_info.display_texture; |
| 342 | state.framebuffer_srgb.enabled = screen_info.display_srgb; | 389 | state.framebuffer_srgb.enabled = screen_info.display_srgb; |
| 343 | state.AllDirty(); | 390 | state.AllDirty(); |
| 344 | state.Apply(); | 391 | state.Apply(); |
| 345 | glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), vertices.data()); | 392 | glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); |
| 346 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 393 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 347 | // Restore default state | 394 | // Restore default state |
| 348 | state.framebuffer_srgb.enabled = false; | 395 | state.framebuffer_srgb.enabled = false; |
| @@ -351,9 +398,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 351 | state.Apply(); | 398 | state.Apply(); |
| 352 | } | 399 | } |
| 353 | 400 | ||
| 354 | /** | ||
| 355 | * Draws the emulated screens to the emulator window. | ||
| 356 | */ | ||
| 357 | void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | 401 | void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { |
| 358 | if (renderer_settings.set_background_color) { | 402 | if (renderer_settings.set_background_color) { |
| 359 | // Update background color before drawing | 403 | // Update background color before drawing |
| @@ -367,21 +411,17 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 367 | glClear(GL_COLOR_BUFFER_BIT); | 411 | glClear(GL_COLOR_BUFFER_BIT); |
| 368 | 412 | ||
| 369 | // Set projection matrix | 413 | // Set projection matrix |
| 370 | std::array<GLfloat, 3 * 2> ortho_matrix = | 414 | const std::array ortho_matrix = |
| 371 | MakeOrthographicMatrix((float)layout.width, (float)layout.height); | 415 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); |
| 372 | glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data()); | 416 | glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data()); |
| 373 | |||
| 374 | // Bind texture in Texture Unit 0 | ||
| 375 | glActiveTexture(GL_TEXTURE0); | ||
| 376 | glUniform1i(uniform_color_texture, 0); | ||
| 377 | 417 | ||
| 378 | DrawScreenTriangles(screen_info, (float)screen.left, (float)screen.top, | 418 | DrawScreenTriangles(screen_info, static_cast<float>(screen.left), |
| 379 | (float)screen.GetWidth(), (float)screen.GetHeight()); | 419 | static_cast<float>(screen.top), static_cast<float>(screen.GetWidth()), |
| 420 | static_cast<float>(screen.GetHeight())); | ||
| 380 | 421 | ||
| 381 | m_current_frame++; | 422 | m_current_frame++; |
| 382 | } | 423 | } |
| 383 | 424 | ||
| 384 | /// Updates the framerate | ||
| 385 | void RendererOpenGL::UpdateFramerate() {} | 425 | void RendererOpenGL::UpdateFramerate() {} |
| 386 | 426 | ||
| 387 | void RendererOpenGL::CaptureScreenshot() { | 427 | void RendererOpenGL::CaptureScreenshot() { |
| @@ -418,63 +458,6 @@ void RendererOpenGL::CaptureScreenshot() { | |||
| 418 | renderer_settings.screenshot_requested = false; | 458 | renderer_settings.screenshot_requested = false; |
| 419 | } | 459 | } |
| 420 | 460 | ||
| 421 | static const char* GetSource(GLenum source) { | ||
| 422 | #define RET(s) \ | ||
| 423 | case GL_DEBUG_SOURCE_##s: \ | ||
| 424 | return #s | ||
| 425 | switch (source) { | ||
| 426 | RET(API); | ||
| 427 | RET(WINDOW_SYSTEM); | ||
| 428 | RET(SHADER_COMPILER); | ||
| 429 | RET(THIRD_PARTY); | ||
| 430 | RET(APPLICATION); | ||
| 431 | RET(OTHER); | ||
| 432 | default: | ||
| 433 | UNREACHABLE(); | ||
| 434 | return "Unknown source"; | ||
| 435 | } | ||
| 436 | #undef RET | ||
| 437 | } | ||
| 438 | |||
| 439 | static const char* GetType(GLenum type) { | ||
| 440 | #define RET(t) \ | ||
| 441 | case GL_DEBUG_TYPE_##t: \ | ||
| 442 | return #t | ||
| 443 | switch (type) { | ||
| 444 | RET(ERROR); | ||
| 445 | RET(DEPRECATED_BEHAVIOR); | ||
| 446 | RET(UNDEFINED_BEHAVIOR); | ||
| 447 | RET(PORTABILITY); | ||
| 448 | RET(PERFORMANCE); | ||
| 449 | RET(OTHER); | ||
| 450 | RET(MARKER); | ||
| 451 | default: | ||
| 452 | UNREACHABLE(); | ||
| 453 | return "Unknown type"; | ||
| 454 | } | ||
| 455 | #undef RET | ||
| 456 | } | ||
| 457 | |||
| 458 | static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, | ||
| 459 | GLsizei length, const GLchar* message, const void* user_param) { | ||
| 460 | const char format[] = "{} {} {}: {}"; | ||
| 461 | const char* const str_source = GetSource(source); | ||
| 462 | const char* const str_type = GetType(type); | ||
| 463 | |||
| 464 | switch (severity) { | ||
| 465 | case GL_DEBUG_SEVERITY_HIGH: | ||
| 466 | LOG_CRITICAL(Render_OpenGL, format, str_source, str_type, id, message); | ||
| 467 | break; | ||
| 468 | case GL_DEBUG_SEVERITY_MEDIUM: | ||
| 469 | LOG_WARNING(Render_OpenGL, format, str_source, str_type, id, message); | ||
| 470 | break; | ||
| 471 | case GL_DEBUG_SEVERITY_NOTIFICATION: | ||
| 472 | case GL_DEBUG_SEVERITY_LOW: | ||
| 473 | LOG_DEBUG(Render_OpenGL, format, str_source, str_type, id, message); | ||
| 474 | break; | ||
| 475 | } | ||
| 476 | } | ||
| 477 | |||
| 478 | bool RendererOpenGL::Init() { | 461 | bool RendererOpenGL::Init() { |
| 479 | Core::Frontend::ScopeAcquireWindowContext acquire_context{render_window}; | 462 | Core::Frontend::ScopeAcquireWindowContext acquire_context{render_window}; |
| 480 | 463 | ||
| @@ -495,7 +478,6 @@ bool RendererOpenGL::Init() { | |||
| 495 | return true; | 478 | return true; |
| 496 | } | 479 | } |
| 497 | 480 | ||
| 498 | /// Shutdown the renderer | ||
| 499 | void RendererOpenGL::ShutDown() {} | 481 | void RendererOpenGL::ShutDown() {} |
| 500 | 482 | ||
| 501 | } // namespace OpenGL | 483 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index cf26628ca..b56328a7f 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -59,21 +59,31 @@ public: | |||
| 59 | void ShutDown() override; | 59 | void ShutDown() override; |
| 60 | 60 | ||
| 61 | private: | 61 | private: |
| 62 | /// Initializes the OpenGL state and creates persistent objects. | ||
| 62 | void InitOpenGLObjects(); | 63 | void InitOpenGLObjects(); |
| 64 | |||
| 63 | void AddTelemetryFields(); | 65 | void AddTelemetryFields(); |
| 66 | |||
| 64 | void CreateRasterizer(); | 67 | void CreateRasterizer(); |
| 65 | 68 | ||
| 66 | void ConfigureFramebufferTexture(TextureInfo& texture, | 69 | void ConfigureFramebufferTexture(TextureInfo& texture, |
| 67 | const Tegra::FramebufferConfig& framebuffer); | 70 | const Tegra::FramebufferConfig& framebuffer); |
| 71 | |||
| 72 | /// Draws the emulated screens to the emulator window. | ||
| 68 | void DrawScreen(const Layout::FramebufferLayout& layout); | 73 | void DrawScreen(const Layout::FramebufferLayout& layout); |
| 74 | |||
| 69 | void DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, float h); | 75 | void DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, float h); |
| 76 | |||
| 77 | /// Updates the framerate. | ||
| 70 | void UpdateFramerate(); | 78 | void UpdateFramerate(); |
| 71 | 79 | ||
| 72 | void CaptureScreenshot(); | 80 | void CaptureScreenshot(); |
| 73 | 81 | ||
| 74 | // Loads framebuffer from emulated memory into the display information structure | 82 | /// Loads framebuffer from emulated memory into the active OpenGL texture. |
| 75 | void LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer); | 83 | void LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer); |
| 76 | // Fills active OpenGL texture with the given RGBA color. | 84 | |
| 85 | /// Fills active OpenGL texture with the given RGB color.Since the color is solid, the texture | ||
| 86 | /// can be 1x1 but will stretch across whatever it's rendered on. | ||
| 77 | void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, | 87 | void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, |
| 78 | const TextureInfo& texture); | 88 | const TextureInfo& texture); |
| 79 | 89 | ||
| @@ -94,14 +104,6 @@ private: | |||
| 94 | /// OpenGL framebuffer data | 104 | /// OpenGL framebuffer data |
| 95 | std::vector<u8> gl_framebuffer_data; | 105 | std::vector<u8> gl_framebuffer_data; |
| 96 | 106 | ||
| 97 | // Shader uniform location indices | ||
| 98 | GLuint uniform_modelview_matrix; | ||
| 99 | GLuint uniform_color_texture; | ||
| 100 | |||
| 101 | // Shader attribute input indices | ||
| 102 | GLuint attrib_position; | ||
| 103 | GLuint attrib_tex_coord; | ||
| 104 | |||
| 105 | /// Used for transforming the framebuffer orientation | 107 | /// Used for transforming the framebuffer orientation |
| 106 | Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags; | 108 | Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags; |
| 107 | Common::Rectangle<int> framebuffer_crop_rect; | 109 | Common::Rectangle<int> framebuffer_crop_rect; |