From 05dc633a8c35221ce8d6abe6ddf027f8b0bab6c2 Mon Sep 17 00:00:00 2001 From: tfarley Date: Mon, 18 May 2015 21:21:33 -0700 Subject: OpenGL renderer --- src/video_core/renderer_opengl/renderer_opengl.cpp | 61 +++++++++++++++++----- 1 file changed, 47 insertions(+), 14 deletions(-) (limited to 'src/video_core/renderer_opengl/renderer_opengl.cpp') diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 71ceb021..16cf92e2 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -53,6 +53,7 @@ static std::array MakeOrthographicMatrix(const float width, const /// RendererOpenGL constructor RendererOpenGL::RendererOpenGL() { + hw_rasterizer.reset(new RasterizerOpenGL()); resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; } @@ -63,7 +64,9 @@ RendererOpenGL::~RendererOpenGL() { /// Swap buffers (render frame) void RendererOpenGL::SwapBuffers() { - render_window->MakeCurrent(); + // Maintain the rasterizer's state as a priority + OpenGLState prev_state = OpenGLState::GetCurState(); + state.Apply(); for(int i : {0, 1}) { const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; @@ -110,7 +113,19 @@ void RendererOpenGL::SwapBuffers() { render_window->PollEvents(); render_window->SwapBuffers(); + prev_state.Apply(); + profiler.BeginFrame(); + + bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled; + if (Settings::values.use_hw_renderer != hw_renderer_enabled) { + // TODO: Save new setting value to config file for next startup + Settings::values.use_hw_renderer = hw_renderer_enabled; + + if (Settings::values.use_hw_renderer) { + hw_rasterizer->Reset(); + } + } } /** @@ -139,7 +154,11 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& // only allows rows to have a memory alignement of 4. ASSERT(pixel_stride % 4 == 0); - glBindTexture(GL_TEXTURE_2D, texture.handle); + state.texture_units[0].enabled_2d = true; + state.texture_units[0].texture_2d = texture.handle; + state.Apply(); + + glActiveTexture(GL_TEXTURE0); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride); // Update existing texture @@ -151,7 +170,6 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& texture.gl_format, texture.gl_type, framebuffer_data); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glBindTexture(GL_TEXTURE_2D, 0); } /** @@ -161,13 +179,15 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& */ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture) { - glBindTexture(GL_TEXTURE_2D, texture.handle); + state.texture_units[0].enabled_2d = true; + state.texture_units[0].texture_2d = texture.handle; + state.Apply(); + glActiveTexture(GL_TEXTURE0); u8 framebuffer_data[3] = { color_r, color_g, color_b }; // Update existing texture glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data); - glBindTexture(GL_TEXTURE_2D, 0); } /** @@ -175,7 +195,6 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color */ void RendererOpenGL::InitOpenGLObjects() { glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, 0.0f); - glDisable(GL_DEPTH_TEST); // Link shaders and get variable locations program_id = ShaderUtil::LoadShaders(GLShaders::g_vertex_shader, GLShaders::g_fragment_shader); @@ -189,10 +208,12 @@ void RendererOpenGL::InitOpenGLObjects() { // Generate VAO glGenVertexArrays(1, &vertex_array_handle); - glBindVertexArray(vertex_array_handle); + + state.draw.vertex_array = vertex_array_handle; + state.draw.vertex_buffer = vertex_buffer_handle; + state.Apply(); // Attach vertex data to VAO - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_handle); glBufferData(GL_ARRAY_BUFFER, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW); glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), (GLvoid*)offsetof(ScreenRectVertex, position)); glVertexAttribPointer(attrib_tex_coord, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), (GLvoid*)offsetof(ScreenRectVertex, tex_coord)); @@ -206,14 +227,19 @@ void RendererOpenGL::InitOpenGLObjects() { // Allocation of storage is deferred until the first frame, when we // know the framebuffer size. - glBindTexture(GL_TEXTURE_2D, texture.handle); + state.texture_units[0].enabled_2d = true; + state.texture_units[0].texture_2d = texture.handle; + state.Apply(); + + glActiveTexture(GL_TEXTURE0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } - glBindTexture(GL_TEXTURE_2D, 0); + + hw_rasterizer->InitObjects(); } void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, @@ -264,7 +290,11 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, UNIMPLEMENTED(); } - glBindTexture(GL_TEXTURE_2D, texture.handle); + state.texture_units[0].enabled_2d = true; + state.texture_units[0].texture_2d = texture.handle; + state.Apply(); + + glActiveTexture(GL_TEXTURE0); glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, texture.gl_format, texture.gl_type, nullptr); } @@ -280,8 +310,10 @@ void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x ScreenRectVertex(x+w, y+h, 0.f, 1.f), }; - glBindTexture(GL_TEXTURE_2D, texture.handle); - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_handle); + state.texture_units[0].enabled_2d = true; + state.texture_units[0].texture_2d = texture.handle; + state.Apply(); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data()); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -295,7 +327,8 @@ void RendererOpenGL::DrawScreens() { glViewport(0, 0, layout.width, layout.height); glClear(GL_COLOR_BUFFER_BIT); - glUseProgram(program_id); + state.draw.shader_program = program_id; + state.Apply(); // Set projection matrix std::array ortho_matrix = MakeOrthographicMatrix((float)layout.width, -- cgit v1.2.3