mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #3632 from N00byKing/3dtv_botenable
Add Support for Stereoscopic 3D
This commit is contained in:
		
						commit
						574824a26c
					
				
					 10 changed files with 115 additions and 19 deletions
				
			
		|  | @ -108,6 +108,10 @@ void Config::ReadValues() { | |||
|     Settings::values.frame_limit = | ||||
|         static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); | ||||
| 
 | ||||
|     Settings::values.toggle_3d = sdl2_config->GetBoolean("Renderer", "toggle_3d", false); | ||||
|     Settings::values.factor_3d = | ||||
|         static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0)); | ||||
| 
 | ||||
|     Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 0.0); | ||||
|     Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0); | ||||
|     Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0); | ||||
|  |  | |||
|  | @ -116,6 +116,14 @@ bg_red = | |||
| bg_blue = | ||||
| bg_green = | ||||
| 
 | ||||
| # Toggles Stereoscopic 3D | ||||
| # 0 (default): Off, 1: On | ||||
| toggle_3d = | ||||
| 
 | ||||
| # Change 3D Intensity | ||||
| # 0 - 100: Intensity. 0 (default) | ||||
| factor_3d = | ||||
| 
 | ||||
| [Layout] | ||||
| # Layout for the screen inside the render window. | ||||
| # 0 (default): Default Top Bottom Screen, 1: Single Screen Only, 2: Large Screen Small Screen, 3: Side by Side | ||||
|  |  | |||
|  | @ -100,6 +100,8 @@ void Config::ReadValues() { | |||
|     qt_config->endGroup(); | ||||
| 
 | ||||
|     qt_config->beginGroup("Layout"); | ||||
|     Settings::values.toggle_3d = qt_config->value("toggle_3d", false).toBool(); | ||||
|     Settings::values.factor_3d = qt_config->value("factor_3d", 0).toInt(); | ||||
|     Settings::values.layout_option = | ||||
|         static_cast<Settings::LayoutOption>(qt_config->value("layout_option").toInt()); | ||||
|     Settings::values.swap_screen = qt_config->value("swap_screen", false).toBool(); | ||||
|  | @ -323,6 +325,8 @@ void Config::SaveValues() { | |||
|     qt_config->endGroup(); | ||||
| 
 | ||||
|     qt_config->beginGroup("Layout"); | ||||
|     qt_config->setValue("toggle_3d", Settings::values.toggle_3d); | ||||
|     qt_config->setValue("factor_3d", Settings::values.factor_3d); | ||||
|     qt_config->setValue("layout_option", static_cast<int>(Settings::values.layout_option)); | ||||
|     qt_config->setValue("swap_screen", Settings::values.swap_screen); | ||||
|     qt_config->setValue("custom_layout", Settings::values.custom_layout); | ||||
|  |  | |||
|  | @ -40,6 +40,8 @@ void ConfigureGraphics::setConfiguration() { | |||
|     ui->toggle_vsync->setChecked(Settings::values.use_vsync); | ||||
|     ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); | ||||
|     ui->frame_limit->setValue(Settings::values.frame_limit); | ||||
|     ui->factor_3d->setValue(Settings::values.factor_3d); | ||||
|     ui->toggle_3d->setChecked(Settings::values.toggle_3d); | ||||
|     ui->layout_combobox->setCurrentIndex(static_cast<int>(Settings::values.layout_option)); | ||||
|     ui->swap_screen->setChecked(Settings::values.swap_screen); | ||||
| } | ||||
|  | @ -55,6 +57,8 @@ void ConfigureGraphics::applyConfiguration() { | |||
|     Settings::values.use_vsync = ui->toggle_vsync->isChecked(); | ||||
|     Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked(); | ||||
|     Settings::values.frame_limit = ui->frame_limit->value(); | ||||
|     Settings::values.factor_3d = ui->factor_3d->value(); | ||||
|     Settings::values.toggle_3d = ui->toggle_3d->isChecked(); | ||||
|     Settings::values.layout_option = | ||||
|         static_cast<Settings::LayoutOption>(ui->layout_combobox->currentIndex()); | ||||
|     Settings::values.swap_screen = ui->swap_screen->isChecked(); | ||||
|  |  | |||
|  | @ -228,6 +228,33 @@ | |||
|       <string>Layout</string> | ||||
|      </property> | ||||
|      <layout class="QVBoxLayout" name="verticalLayout_3"> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="horizontalLayout_5"> | ||||
|         <item> | ||||
|          <widget class="QCheckBox" name="toggle_3d"> | ||||
|           <property name="text"> | ||||
|            <string>Enable Stereoscopic 3D</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QSpinBox" name="factor_3d"> | ||||
|           <property name="suffix"> | ||||
|            <string>%</string> | ||||
|           </property> | ||||
|           <property name="minimum"> | ||||
|            <number>0</number> | ||||
|           </property> | ||||
|           <property name="maximum"> | ||||
|            <number>100</number> | ||||
|           </property> | ||||
|           <property name="value"> | ||||
|            <number>0</number> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="horizontalLayout_4"> | ||||
|         <item> | ||||
|  |  | |||
|  | @ -60,9 +60,17 @@ EmuWindow::~EmuWindow() { | |||
|  */ | ||||
| static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x, | ||||
|                                 unsigned framebuffer_y) { | ||||
|     return ( | ||||
|         framebuffer_y >= layout.bottom_screen.top && framebuffer_y < layout.bottom_screen.bottom && | ||||
|         framebuffer_x >= layout.bottom_screen.left && framebuffer_x < layout.bottom_screen.right); | ||||
|     if (Settings::values.toggle_3d) { | ||||
|         return (framebuffer_y >= layout.bottom_screen.top && | ||||
|                 framebuffer_y < layout.bottom_screen.bottom && | ||||
|                 framebuffer_x >= layout.bottom_screen.left / 2 && | ||||
|                 framebuffer_x < layout.bottom_screen.right / 2); | ||||
|     } else { | ||||
|         return (framebuffer_y >= layout.bottom_screen.top && | ||||
|                 framebuffer_y < layout.bottom_screen.bottom && | ||||
|                 framebuffer_x >= layout.bottom_screen.left && | ||||
|                 framebuffer_x < layout.bottom_screen.right); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) { | ||||
|  | @ -80,9 +88,16 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | |||
|         return; | ||||
| 
 | ||||
|     std::lock_guard<std::mutex> guard(touch_state->mutex); | ||||
|     touch_state->touch_x = | ||||
|         static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left) / | ||||
|         (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); | ||||
|     if (Settings::values.toggle_3d) { | ||||
|         touch_state->touch_x = | ||||
|             static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) / | ||||
|             (framebuffer_layout.bottom_screen.right / 2 - | ||||
|              framebuffer_layout.bottom_screen.left / 2); | ||||
|     } else { | ||||
|         touch_state->touch_x = | ||||
|             static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left) / | ||||
|             (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); | ||||
|     } | ||||
|     touch_state->touch_y = | ||||
|         static_cast<float>(framebuffer_y - framebuffer_layout.bottom_screen.top) / | ||||
|         (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| #include "core/core_timing.h" | ||||
| #include "core/hle/service/ptm/ptm.h" | ||||
| #include "core/hle/shared_page.h" | ||||
| #include "core/settings.h" | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
|  | @ -83,6 +84,10 @@ void Init() { | |||
|     update_time_event = | ||||
|         CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback); | ||||
|     CoreTiming::ScheduleEvent(0, update_time_event); | ||||
| 
 | ||||
|     float slidestate = | ||||
|         Settings::values.toggle_3d ? (float_le)Settings::values.factor_3d / 100 : 0.0f; | ||||
|     shared_page.sliderstate_3d = slidestate; | ||||
| } | ||||
| 
 | ||||
| void SetMacAddress(const MacAddress& addr) { | ||||
|  |  | |||
|  | @ -132,6 +132,9 @@ struct Values { | |||
|     float bg_green; | ||||
|     float bg_blue; | ||||
| 
 | ||||
|     bool toggle_3d; | ||||
|     u8 factor_3d; | ||||
| 
 | ||||
|     // Audio
 | ||||
|     std::string sink_id; | ||||
|     bool enable_audio_stretching; | ||||
|  |  | |||
|  | @ -103,12 +103,13 @@ void RendererOpenGL::SwapBuffers() { | |||
|     OpenGLState prev_state = OpenGLState::GetCurState(); | ||||
|     state.Apply(); | ||||
| 
 | ||||
|     for (int i : {0, 1}) { | ||||
|         const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; | ||||
|     for (int i : {0, 1, 2}) { | ||||
|         int fb_id = i == 2 ? 1 : 0; | ||||
|         const auto& framebuffer = GPU::g_regs.framebuffer_config[fb_id]; | ||||
| 
 | ||||
|         // Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04
 | ||||
|         u32 lcd_color_addr = | ||||
|             (i == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom); | ||||
|             (fb_id == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom); | ||||
|         lcd_color_addr = HW::VADDR_LCD + 4 * lcd_color_addr; | ||||
|         LCD::Regs::ColorFill color_fill = {0}; | ||||
|         LCD::Read(color_fill.raw, lcd_color_addr); | ||||
|  | @ -129,7 +130,7 @@ void RendererOpenGL::SwapBuffers() { | |||
|                 // performance problem.
 | ||||
|                 ConfigureFramebufferTexture(screen_infos[i].texture, framebuffer); | ||||
|             } | ||||
|             LoadFBToScreenInfo(framebuffer, screen_infos[i]); | ||||
|             LoadFBToScreenInfo(framebuffer, screen_infos[i], i == 1); | ||||
| 
 | ||||
|             // Resize the texture in case the framebuffer size has changed
 | ||||
|             screen_infos[i].texture.width = framebuffer.width; | ||||
|  | @ -160,10 +161,15 @@ void RendererOpenGL::SwapBuffers() { | |||
|  * Loads framebuffer from emulated memory into the active OpenGL texture. | ||||
|  */ | ||||
| void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& framebuffer, | ||||
|                                         ScreenInfo& screen_info) { | ||||
|                                         ScreenInfo& screen_info, bool right_eye) { | ||||
| 
 | ||||
|     if (framebuffer.address_right1 == 0 || framebuffer.address_right2 == 0) | ||||
|         right_eye = false; | ||||
| 
 | ||||
|     const PAddr framebuffer_addr = | ||||
|         framebuffer.active_fb == 0 ? framebuffer.address_left1 : framebuffer.address_left2; | ||||
|         framebuffer.active_fb == 0 | ||||
|             ? (!right_eye ? framebuffer.address_left1 : framebuffer.address_right1) | ||||
|             : (!right_eye ? framebuffer.address_left2 : framebuffer.address_right2); | ||||
| 
 | ||||
|     LOG_TRACE(Render_OpenGL, "0x%08x bytes from 0x%08x(%dx%d), fmt %x", | ||||
|               framebuffer.stride * framebuffer.height, framebuffer_addr, (int)framebuffer.width, | ||||
|  | @ -395,13 +401,33 @@ void RendererOpenGL::DrawScreens() { | |||
|     glUniform1i(uniform_color_texture, 0); | ||||
| 
 | ||||
|     if (layout.top_screen_enabled) { | ||||
|         DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left, (float)top_screen.top, | ||||
|                                 (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); | ||||
|         if (!Settings::values.toggle_3d) { | ||||
|             DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left, (float)top_screen.top, | ||||
|                                     (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); | ||||
|         } else { | ||||
|             DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left / 2, | ||||
|                                     (float)top_screen.top, (float)top_screen.GetWidth() / 2, | ||||
|                                     (float)top_screen.GetHeight()); | ||||
|             DrawSingleScreenRotated(screen_infos[1], | ||||
|                                     ((float)top_screen.left / 2) + ((float)layout.width / 2), | ||||
|                                     (float)top_screen.top, (float)top_screen.GetWidth() / 2, | ||||
|                                     (float)top_screen.GetHeight()); | ||||
|         } | ||||
|     } | ||||
|     if (layout.bottom_screen_enabled) { | ||||
|         DrawSingleScreenRotated(screen_infos[1], (float)bottom_screen.left, | ||||
|                                 (float)bottom_screen.top, (float)bottom_screen.GetWidth(), | ||||
|                                 (float)bottom_screen.GetHeight()); | ||||
|         if (!Settings::values.toggle_3d) { | ||||
|             DrawSingleScreenRotated(screen_infos[2], (float)bottom_screen.left, | ||||
|                                     (float)bottom_screen.top, (float)bottom_screen.GetWidth(), | ||||
|                                     (float)bottom_screen.GetHeight()); | ||||
|         } else { | ||||
|             DrawSingleScreenRotated(screen_infos[2], (float)bottom_screen.left / 2, | ||||
|                                     (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, | ||||
|                                     (float)bottom_screen.GetHeight()); | ||||
|             DrawSingleScreenRotated(screen_infos[2], | ||||
|                                     ((float)bottom_screen.left / 2) + ((float)layout.width / 2), | ||||
|                                     (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, | ||||
|                                     (float)bottom_screen.GetHeight()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     m_current_frame++; | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ private: | |||
| 
 | ||||
|     // Loads framebuffer from emulated memory into the display information structure
 | ||||
|     void LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& framebuffer, | ||||
|                             ScreenInfo& screen_info); | ||||
|                             ScreenInfo& screen_info, bool right_eye); | ||||
|     // Fills active OpenGL texture with the given RGB color.
 | ||||
|     void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture); | ||||
| 
 | ||||
|  | @ -76,7 +76,7 @@ private: | |||
|     OGLProgram shader; | ||||
| 
 | ||||
|     /// Display information for top and bottom screens respectively
 | ||||
|     std::array<ScreenInfo, 2> screen_infos; | ||||
|     std::array<ScreenInfo, 3> screen_infos; | ||||
| 
 | ||||
|     // Shader uniform location indices
 | ||||
|     GLuint uniform_modelview_matrix; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue