diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp index ea5c61fac1..34e0fee833 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp @@ -36,7 +36,7 @@ void Config::Load() // get resolution iniFile.Get("Hardware", "WindowedRes", &temp, "640x480"); - strncpy(iWindowedRes, temp.c_str(), 16); + strncpy(iInternalRes, temp.c_str(), 16); // apply this to the fullscreen resolution too strncpy(iFSResolution, temp.c_str(), 16); @@ -129,7 +129,7 @@ void Config::Save() { IniFile iniFile; iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini"); - iniFile.Set("Hardware", "WindowedRes", iWindowedRes); + iniFile.Set("Hardware", "WindowedRes", iInternalRes); iniFile.Set("Hardware", "FullscreenRes", iFSResolution); iniFile.Set("Hardware", "Fullscreen", bFullscreen); iniFile.Set("Hardware", "VSync", bVSync); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Config.h b/Source/Plugins/Plugin_VideoOGL/Src/Config.h index e34f84eaf1..a6bddc2649 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Config.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Config.h @@ -55,7 +55,7 @@ struct Config // Resolution control char iFSResolution[16]; - char iWindowedRes[16]; + char iInternalRes[16]; bool bNativeResolution; // Should possibly be augmented with 2x, 4x native. bool bKeepAR43, bKeepAR169, bCrop; // Aspect ratio controls. diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 0fbf986208..579f6dddcc 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -150,9 +150,9 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight } else // Going Windowed { - if (strlen(g_Config.iWindowedRes) > 1) + if (strlen(g_Config.iInternalRes) > 1) { - sscanf(g_Config.iWindowedRes, "%dx%d", &_twidth, &_theight); + sscanf(g_Config.iInternalRes, "%dx%d", &_twidth, &_theight); } else // No Window resolution set, fall back to default { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h b/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h index 002757f906..c33abce4fd 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h @@ -151,7 +151,7 @@ public: sscanf(g_Config.iFSResolution, "%dx%d", &currFullRes.x, &currFullRes.y); - sscanf(g_Config.iWindowedRes, "%dx%d", + sscanf(g_Config.iInternalRes, "%dx%d", &currWinRes.x, &currWinRes.y); SetProperty(OGL_FULLSCREEN, g_Config.bFullscreen); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp index c5ddcc4705..29a356d409 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp @@ -164,11 +164,11 @@ void ConfigDialog::CreateGUIControls() sbBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageGeneral, wxT("Basic Display Settings")); m_RenderToMainWindow = new wxCheckBox(m_PageGeneral, ID_RENDERTOMAINWINDOW, wxT("Render to main window"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_RenderToMainWindow->SetValue(g_Config.renderToMainframe); - m_NativeResolution = new wxCheckBox(m_PageGeneral, ID_NATIVERESOLUTION, wxT("Use Native"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_NativeResolution = new wxCheckBox(m_PageGeneral, ID_NATIVERESOLUTION, wxT("Use native"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxStaticText *IRText = new wxStaticText(m_PageGeneral, ID_IRTEXT, wxT("Internal resolution:"), wxDefaultPosition, wxDefaultSize, 0); - wxStaticText *WMText = new wxStaticText(m_PageGeneral, ID_WMTEXT, wxT("Window Mode:"), wxDefaultPosition, wxDefaultSize , 0 ); + wxStaticText *WMText = new wxStaticText(m_PageGeneral, ID_WMTEXT, wxT("Window mode:"), wxDefaultPosition, wxDefaultSize , 0 ); m_WindowResolutionCB = new wxComboBox(m_PageGeneral, ID_WINDOWRESOLUTIONCB, arrayStringFor_WindowResolutionCB[0], wxDefaultPosition, wxDefaultSize, arrayStringFor_WindowResolutionCB, wxCB_READONLY, wxDefaultValidator); - m_WindowResolutionCB->SetValue(wxString::FromAscii(g_Config.iWindowedRes)); + m_WindowResolutionCB->SetValue(wxString::FromAscii(g_Config.iInternalRes)); // Aspect ratio / positioning controls wxStaticText *KeepARText = new wxStaticText(m_PageGeneral, wxID_ANY, wxT("Keep aspect ratio:"), wxDefaultPosition, wxDefaultSize, 0); @@ -251,7 +251,7 @@ void ConfigDialog::CreateGUIControls() sBasic->Add(IRText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5); sBasic->Add(m_WindowResolutionCB, wxGBPosition(0, 1), wxGBSpan(1, 1), wxALL, 5); - sBasic->Add(m_NativeResolution, wxGBPosition(0, 2), wxGBSpan(1, 2), wxALIGN_CENTER_VERTICAL | wxTOP, 0); + sBasic->Add(m_NativeResolution, wxGBPosition(0, 2), wxGBSpan(1, 2), wxALIGN_CENTER_VERTICAL | wxALL, 5); sBasic->Add(KeepARText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5); sBasic->Add(m_KeepAR43, wxGBPosition(1, 1), wxGBSpan(1, 1), wxALL, 5); @@ -511,7 +511,7 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) break; #endif case ID_WINDOWRESOLUTIONCB: - strcpy(g_Config.iWindowedRes, m_WindowResolutionCB->GetValue().mb_str() ); + strcpy(g_Config.iInternalRes, m_WindowResolutionCB->GetValue().mb_str() ); // Apply this resolution as fullscreen resolution too strcpy(g_Config.iFSResolution, m_WindowResolutionCB->GetValue().mb_str() ); break; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp index 3feb1103e8..90b033e862 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp @@ -404,8 +404,8 @@ void ToggleFullscreen(HWND hParent) g_Config.bFullscreen = false; RECT rc = {0, 0, w_fs, h_fs}; - if (strlen(g_Config.iWindowedRes) > 1) - sscanf(g_Config.iWindowedRes, "%dx%d", &w_fs, &h_fs); + if (strlen(g_Config.iInternalRes) > 1) + sscanf(g_Config.iInternalRes, "%dx%d", &w_fs, &h_fs); // FullScreen -> Desktop ChangeDisplaySettings(NULL, 0); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 5b0e090e69..dd603aa1aa 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -586,64 +586,6 @@ void Renderer::SetFramebuffer(GLuint fb) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : s_uFramebuffer); } -GLuint Renderer::ResolveAndGetRenderTarget(const TRectangle &source_rect) -{ - if (s_MSAASamples > 1) - { - // Flip the rectangle - TRectangle flipped_rect; - source_rect.FlipYPosition(GetTargetHeight(), &flipped_rect); - - flipped_rect.Clamp(0, 0, GetTargetWidth(), GetTargetHeight()); - // Do the resolve. - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, s_uResolvedFramebuffer); - glBlitFramebufferEXT(flipped_rect.left, flipped_rect.top, flipped_rect.right, flipped_rect.bottom, - flipped_rect.left, flipped_rect.top, flipped_rect.right, flipped_rect.bottom, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - - // Return the resolved target. - return s_ResolvedRenderTarget; - } - else - { - return s_RenderTarget; - } -} - -GLuint Renderer::ResolveAndGetDepthTarget(const TRectangle &source_rect) -{ - // This logic should be moved elsewhere. - if (s_MSAASamples > 1) - { - // Flip the rectangle - TRectangle flipped_rect; - //source_rect.FlipYPosition(GetTargetHeight(), &flipped_rect); - - // donkopunchstania - some bug causes the offsets to be ignored. driver bug? - flipped_rect.top = 0; - flipped_rect.bottom = GetTargetHeight(); - - flipped_rect.left = 0; - flipped_rect.right = GetTargetWidth(); - - flipped_rect.Clamp(0, 0, GetTargetWidth(), GetTargetHeight()); - // Do the resolve. - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, s_uResolvedFramebuffer); - glBlitFramebufferEXT(flipped_rect.left, flipped_rect.top, flipped_rect.right, flipped_rect.bottom, - flipped_rect.left, flipped_rect.top, flipped_rect.right, flipped_rect.bottom, - GL_DEPTH_BUFFER_BIT, GL_NEAREST); - - // Return the resolved target. - return s_ResolvedDepthTarget; - } - else - { - return s_DepthTarget; - } -} - void Renderer::ResetGLState() { // Gets us to a reasonably sane state where it's possible to do things like @@ -725,6 +667,69 @@ void Renderer::SetBlendMode(bool forceUpdate) s_blendMode = newval; } +////////////////////////////////////////////////////////////////////////////////////////// +// Apply AA if enabled +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +GLuint Renderer::ResolveAndGetRenderTarget(const TRectangle &source_rect) +{ + if (s_MSAASamples > 1) + { + // Flip the rectangle + TRectangle flipped_rect; + source_rect.FlipYPosition(GetTargetHeight(), &flipped_rect); + + flipped_rect.Clamp(0, 0, GetTargetWidth(), GetTargetHeight()); + // Do the resolve. + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, s_uResolvedFramebuffer); + glBlitFramebufferEXT(flipped_rect.left, flipped_rect.top, flipped_rect.right, flipped_rect.bottom, + flipped_rect.left, flipped_rect.top, flipped_rect.right, flipped_rect.bottom, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + // Return the resolved target. + return s_ResolvedRenderTarget; + } + else + { + return s_RenderTarget; + } +} + +GLuint Renderer::ResolveAndGetDepthTarget(const TRectangle &source_rect) +{ + // This logic should be moved elsewhere. + if (s_MSAASamples > 1) + { + // Flip the rectangle + TRectangle flipped_rect; + //source_rect.FlipYPosition(GetTargetHeight(), &flipped_rect); + + // donkopunchstania - some bug causes the offsets to be ignored. driver bug? + flipped_rect.top = 0; + flipped_rect.bottom = GetTargetHeight(); + + flipped_rect.left = 0; + flipped_rect.right = GetTargetWidth(); + + flipped_rect.Clamp(0, 0, GetTargetWidth(), GetTargetHeight()); + // Do the resolve. + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, s_uResolvedFramebuffer); + glBlitFramebufferEXT(flipped_rect.left, flipped_rect.top, flipped_rect.right, flipped_rect.bottom, + flipped_rect.left, flipped_rect.top, flipped_rect.right, flipped_rect.bottom, + GL_DEPTH_BUFFER_BIT, GL_NEAREST); + + // Return the resolved target. + return s_ResolvedDepthTarget; + } + else + { + return s_DepthTarget; + } +} +////////////////////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////////////////////// // Function: This function handles the OpenGL glScissor() function // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ @@ -880,22 +885,6 @@ void Renderer::Swap(const TRectangle& rc) v_max = (float)GetTargetHeight(); } - // --------------------------------------------------------------------- - // Save screenshot if AA and wireframe is off. - // ŻŻŻŻŻŻŻŻŻŻŻŻŻ - if (s_bScreenshot && s_MSAASamples == 1 && !g_Config.bWireFrame) - { - s_criticalScreenshot.Enter(); - - // Save screenshot - SaveRenderTarget(s_sScreenshotName.c_str(), rc.right, rc.bottom, (int)(v_min)); - // Reset settings - s_sScreenshotName = ""; - s_bScreenshot = false; - s_criticalScreenshot.Leave(); - } - // --------------------------------------------------------------------- - // --------------------------------------------------------------------- // Apply AA // ŻŻŻŻŻŻŻŻŻŻŻŻŻ @@ -914,11 +903,11 @@ void Renderer::Swap(const TRectangle& rc) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer); } + // Draw to the window buffer with bilinear filtering glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); glBlitFramebufferEXT(0, v_min, u_max, v_max, - back_rc.left, back_rc.top, back_rc.right, back_rc.bottom, - GL_COLOR_BUFFER_BIT, GL_LINEAR); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer, we'll draw debug text on top + back_rc.left, back_rc.top, back_rc.right, back_rc.bottom, + GL_COLOR_BUFFER_BIT, GL_LINEAR); } else { @@ -976,18 +965,26 @@ void Renderer::Swap(const TRectangle& rc) // --------------------------------------------------------------------- // --------------------------------------------------------------------- - // Save screenshot if AA or wireframe is on. + // Save screenshot // ŻŻŻŻŻŻŻŻŻŻŻŻŻ - if (s_bScreenshot && (s_MSAASamples > 1 || g_Config.bWireFrame)) + if (s_bScreenshot) { - s_criticalScreenshot.Enter(); + // Select source + if (s_MSAASamples > 1) + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uResolvedFramebuffer); + else + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer); + s_criticalScreenshot.Enter(); // Save screenshot - SaveRenderTarget(s_sScreenshotName.c_str(), OpenGL_GetBackbufferWidth(), OpenGL_GetBackbufferHeight(), 0); + SaveRenderTarget(s_sScreenshotName.c_str(), rc.right, rc.bottom, (int)(v_min)); // Reset settings s_sScreenshotName = ""; s_bScreenshot = false; s_criticalScreenshot.Leave(); + + // Switch to the window backbuffer, we'll draw debug text on top + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } // --------------------------------------------------------------------- @@ -1318,10 +1315,13 @@ void Renderer::SetScreenshot(const char *filename) bool Renderer::SaveRenderTarget(const char *filename, int W, int H, int YOffset) { - // The height seemed to be one less than the setting sometimes (and sometimes not), - // perhaps a rounding error - if (H & 1) - H++; + // The height seemed to often be one less than the setting (but sometimes not), + // perhaps the source is the (bpmem.copyTexSrcWH.y + 1) in BPStructs.cpp that I'm guessing + // is there because of how some GL function works. But the buffer we are reading from here + // seems to have the necessary pixels for a complete height so we use the complete height + // from the settings. + if (!g_Config.bNativeResolution) + sscanf(g_Config.iInternalRes, "%dx%d", &W, &H); u8 *data = (u8 *)malloc(3 * W * H); glPixelStorei(GL_PACK_ALIGNMENT, 1); @@ -1341,43 +1341,37 @@ bool Renderer::SaveRenderTarget(const char *filename, int W, int H, int YOffset) // Create wxImage wxImage a(W, H, data); - int nW, nH; - - // Resize the output to correctly use the Aspect ratio setting - // This way, games are saved using the correct A/R scaling - - if ((g_Config.bKeepAR169 || g_Config.bKeepAR43) && s_MSAASamples == 1 && !g_Config.bWireFrame) - { - float Ratio = (float)W / (float)H; - - // Check if the height or width should be changed - if (Ratio != 4.0f/3.0f && g_Config.bKeepAR43) + // --------------------------------------------------------------------- + // To get past the problem of non-4:3 and non-16:9 native resolution pictures (for example + // in RE1 some pictures have non-4:3 resolutions like 640 x 448 and 512 x 448 and such that + // are meant to be rescaled to 4:3, and most Wii games use 640 x 480 even for the 16:9 mode) + // we let the user use the keep aspect ratio functions to control the resulting aspect ratio. + // ŻŻŻŻŻŻŻŻŻŻŻŻŻ + // We don't adjust non-native resolutions to avoid blurring the picture. + // ŻŻŻŻŻŻŻŻŻŻŻŻŻ + float Ratio = (float)W / (float)(H), TargetRatio, TargetRatio1; + if (g_Config.bNativeResolution && (g_Config.bKeepAR169 || g_Config.bKeepAR43) + && Ratio != 4.0/3.0 && Ratio != 16.0/9.0) + { + if (g_Config.bKeepAR43) + TargetRatio = 4.0/3.0; + else + TargetRatio = 16.0/9.0; + // Check if the height or width should be changed (we only increase the picture size, not + // the other way around) + if (Ratio < TargetRatio) { - // Change the A/R to 4/3 - float fW = (float)W * 4.0/3.0; - nW = (int)floor(fW); - float fH = fW * 3.0/4.0; - nH = (int)floor(fH); - - // Then rescale the width - W = nW * H / nH; - H = nH * H / nH; + float fW = (float)H * TargetRatio; + W = (int)fW; } - if (Ratio != 16.0/9.0 && g_Config.bKeepAR169) + else { - // Change the A/R to 16/9 - float fW = (float)W * 16.0/9.0; - nW = (int)floor(fW); - float fH = fW * 9.0/16.0; - nH = (int)floor(fH); - - // Then rescale the height - W = nW * W / nW; - H = nH * W / nW; + float fH = (float)W * (1 / TargetRatio); + H = (int)fH; } - a.Rescale(W, H, wxIMAGE_QUALITY_HIGH); } + // --------------------------------------------------------------------- a.SaveFile(wxString::FromAscii(filename), wxBITMAP_TYPE_BMP); bool result = true;