OpenGL: Added 2x mode for pixel exact 2D together with high-res 3D

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3371 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson
2009-06-08 06:05:09 +00:00
parent 299c4f8f1b
commit d3ddfef93c
6 changed files with 48 additions and 21 deletions

View File

@ -44,6 +44,7 @@ void Config::Load()
iniFile.Get("Hardware", "VSync", &bVSync, 0); // Hardware iniFile.Get("Hardware", "VSync", &bVSync, 0); // Hardware
iniFile.Get("Hardware", "RenderToMainframe", &renderToMainframe, false); iniFile.Get("Hardware", "RenderToMainframe", &renderToMainframe, false);
iniFile.Get("Settings", "StretchToFit", &bNativeResolution, true); iniFile.Get("Settings", "StretchToFit", &bNativeResolution, true);
iniFile.Get("Settings", "2xResolution", &b2xResolution, false);
iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false); iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false);
iniFile.Get("Settings", "KeepAR_16_9", &bKeepAR169, false); iniFile.Get("Settings", "KeepAR_16_9", &bKeepAR169, false);
iniFile.Get("Settings", "Crop", &bCrop, false); iniFile.Get("Settings", "Crop", &bCrop, false);
@ -135,6 +136,7 @@ void Config::Save()
iniFile.Set("Hardware", "VSync", bVSync); iniFile.Set("Hardware", "VSync", bVSync);
iniFile.Set("Hardware", "RenderToMainframe", renderToMainframe); iniFile.Set("Hardware", "RenderToMainframe", renderToMainframe);
iniFile.Set("Settings", "StretchToFit", bNativeResolution); iniFile.Set("Settings", "StretchToFit", bNativeResolution);
iniFile.Set("Settings", "2xResolution", b2xResolution);
iniFile.Set("Settings", "KeepAR_4_3", bKeepAR43); iniFile.Set("Settings", "KeepAR_4_3", bKeepAR43);
iniFile.Set("Settings", "KeepAR_16_9", bKeepAR169); iniFile.Set("Settings", "KeepAR_16_9", bKeepAR169);
iniFile.Set("Settings", "Crop", bCrop); iniFile.Set("Settings", "Crop", bCrop);

View File

@ -57,7 +57,7 @@ struct Config
char iFSResolution[16]; char iFSResolution[16];
char iInternalRes[16]; char iInternalRes[16];
bool bNativeResolution; // Should possibly be augmented with 2x, 4x native. bool bNativeResolution, b2xResolution; // Should possibly be augmented with 2x, 4x native.
bool bKeepAR43, bKeepAR169, bCrop; // Aspect ratio controls. bool bKeepAR43, bKeepAR169, bCrop; // Aspect ratio controls.
bool bUseXFB; bool bUseXFB;
bool bAutoScale; // Removes annoying borders without using XFB. Doesn't always work perfectly. bool bAutoScale; // Removes annoying borders without using XFB. Doesn't always work perfectly.

View File

@ -35,6 +35,7 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
EVT_CHOICE(ID_MAXANISOTROPY, ConfigDialog::GeneralSettingsChanged) EVT_CHOICE(ID_MAXANISOTROPY, ConfigDialog::GeneralSettingsChanged)
EVT_CHOICE(ID_MSAAMODECB, ConfigDialog::GeneralSettingsChanged) EVT_CHOICE(ID_MSAAMODECB, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_NATIVERESOLUTION, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_NATIVERESOLUTION, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_2X_RESOLUTION, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_USEXFB, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_USEXFB, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_FORCEFILTERING, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_FORCEFILTERING, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_AUTOSCALE, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_AUTOSCALE, ConfigDialog::GeneralSettingsChanged)
@ -164,7 +165,8 @@ void ConfigDialog::CreateGUIControls()
sbBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageGeneral, wxT("Basic Display Settings")); 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 = new wxCheckBox(m_PageGeneral, ID_RENDERTOMAINWINDOW, wxT("Render to main window"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_RenderToMainWindow->SetValue(g_Config.renderToMainframe); 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("Native"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_2xResolution = new wxCheckBox(m_PageGeneral, ID_2X_RESOLUTION, wxT("2x"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
wxStaticText *IRText = new wxStaticText(m_PageGeneral, ID_IRTEXT, wxT("Internal resolution:"), wxDefaultPosition, wxDefaultSize, 0); 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 = new wxComboBox(m_PageGeneral, ID_WINDOWRESOLUTIONCB, arrayStringFor_WindowResolutionCB[0], wxDefaultPosition, wxDefaultSize, arrayStringFor_WindowResolutionCB, wxCB_READONLY, wxDefaultValidator);
@ -180,7 +182,9 @@ void ConfigDialog::CreateGUIControls()
m_UseXFB = new wxCheckBox(m_PageGeneral, ID_USEXFB, wxT("Use Real XFB"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_UseXFB = new wxCheckBox(m_PageGeneral, ID_USEXFB, wxT("Use Real XFB"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_AutoScale = new wxCheckBox(m_PageGeneral, ID_AUTOSCALE, wxT("Auto scale (try to remove borders)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_AutoScale = new wxCheckBox(m_PageGeneral, ID_AUTOSCALE, wxT("Auto scale (try to remove borders)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Default values
m_NativeResolution->SetValue(g_Config.bNativeResolution); m_NativeResolution->SetValue(g_Config.bNativeResolution);
m_2xResolution->SetValue(g_Config.b2xResolution);
m_KeepAR43->SetValue(g_Config.bKeepAR43); m_KeepAR43->SetValue(g_Config.bKeepAR43);
m_KeepAR169->SetValue(g_Config.bKeepAR169); m_KeepAR169->SetValue(g_Config.bKeepAR169);
m_Crop->SetValue(g_Config.bCrop); m_Crop->SetValue(g_Config.bCrop);
@ -220,24 +224,26 @@ void ConfigDialog::CreateGUIControls()
m_Fullscreen->SetToolTip(wxT( m_Fullscreen->SetToolTip(wxT(
"This will create a Fullscreen window using the chosen Fullscreen resolution." "This will create a Fullscreen window using the chosen Fullscreen resolution."
"\nPress Alt+Enter to switch between Fullscreen and Windowed mode." "\nPress Alt+Enter to switch between Fullscreen and Windowed mode."
"\n\nApplies instanty during gameplay: No")); "\n\nApplies instanty during gameplay: <No>"));
m_NativeResolution->SetToolTip(wxT( m_NativeResolution->SetToolTip(wxT(
"This will use the game's native resolution and stretch it to fill the" "This will use the game's native resolution and stretch it to fill the"
"\nwindow instead of changing the internal display resolution. It" "\nwindow instead of changing the internal display resolution. It"
"\nmay result in a blurrier image, but it may also give a higher" "\nmay result in a blurrier image, but it may also give a higher"
"\nFPS if you have a slow graphics card." "\nFPS if you have a slow graphics card."
"\n\nApplies instanty during gameplay: Yes")); "\n\nApplies instanty during gameplay: <Yes>"));
m_2xResolution->SetToolTip(wxT(
"Applies instanty during gameplay: <Yes>"));
m_Crop->SetToolTip(wxT( m_Crop->SetToolTip(wxT(
"Crop the picture instead of creating a letterbox. It will assume that your screen" "Crop the picture instead of creating a letterbox. It will assume that your screen"
"\nis of the 5:4 format if you have selected the 4:3 aspect ratio. It will assume" "\nis of the 5:4 format if you have selected the 4:3 aspect ratio. It will assume"
"\nthat your screen is of the 16:10 format if you have selected the 16:9 aspect ratio." "\nthat your screen is of the 16:10 format if you have selected the 16:9 aspect ratio."
"\n\nApplies instanty during gameplay: Yes")); "\n\nApplies instanty during gameplay: <Yes>"));
m_WindowResolutionCB->SetToolTip(wxT( m_WindowResolutionCB->SetToolTip(wxT(
"Select internal resolution for the separate rendering window. This resolution also applies" "Select internal resolution for the separate rendering window. This resolution also applies"
" to the fullscreen mode" " to the fullscreen mode"
"\n\nApplies instanty during gameplay: No")); "\n\nApplies instanty during gameplay: <No>"));
m_MSAAModeCB->SetToolTip(wxT( m_MSAAModeCB->SetToolTip(wxT(
"Applies instanty during gameplay: No")); "Applies instanty during gameplay: <No>"));
m_EFBCopyDisableHotKey->SetToolTip(wxT( m_EFBCopyDisableHotKey->SetToolTip(wxT(
"Enable OSD hotkeys '3', '4', '5', etc.")); "Enable OSD hotkeys '3', '4', '5', etc."));
@ -260,7 +266,8 @@ void ConfigDialog::CreateGUIControls()
sBasic->Add(IRText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5); 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_WindowResolutionCB, wxGBPosition(0, 1), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(m_NativeResolution, wxGBPosition(0, 2), wxGBSpan(1, 2), wxALIGN_CENTER_VERTICAL | wxALL, 5); sBasic->Add(m_NativeResolution, wxGBPosition(0, 2), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
sBasic->Add(m_2xResolution, wxGBPosition(0, 3), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
sBasic->Add(KeepARText, wxGBPosition(1, 0), wxGBSpan(1, 1), 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); sBasic->Add(m_KeepAR43, wxGBPosition(1, 1), wxGBSpan(1, 1), wxALL, 5);
@ -479,6 +486,9 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
case ID_NATIVERESOLUTION: case ID_NATIVERESOLUTION:
g_Config.bNativeResolution = m_NativeResolution->IsChecked(); g_Config.bNativeResolution = m_NativeResolution->IsChecked();
break; break;
case ID_2X_RESOLUTION:
g_Config.b2xResolution = m_2xResolution->IsChecked();
break;
case ID_VSYNC: case ID_VSYNC:
g_Config.bVSync = m_VSync->IsChecked(); g_Config.bVSync = m_VSync->IsChecked();
break; break;
@ -642,11 +652,10 @@ void ConfigDialog::UpdateGUI()
// These options are for the separate rendering window // These options are for the separate rendering window
m_Fullscreen->Enable(!g_Config.renderToMainframe); m_Fullscreen->Enable(!g_Config.renderToMainframe);
if (g_Config.renderToMainframe) if (g_Config.renderToMainframe) m_Fullscreen->SetValue(false);
m_Fullscreen->SetValue(false);
// Disable the internal resolution option if it's set to native // Disable the internal resolution option if it's set to native
m_WindowResolutionCB->Enable(!g_Config.bNativeResolution); m_WindowResolutionCB->Enable(!(g_Config.bNativeResolution || g_Config.b2xResolution));
} }

View File

@ -87,7 +87,7 @@ class ConfigDialog : public wxDialog
wxCheckBox *m_Fullscreen; wxCheckBox *m_Fullscreen;
wxCheckBox *m_VSync; wxCheckBox *m_VSync;
wxCheckBox *m_RenderToMainWindow; wxCheckBox *m_RenderToMainWindow;
wxCheckBox *m_NativeResolution; wxCheckBox *m_NativeResolution, *m_2xResolution;
wxCheckBox *m_ForceFiltering; wxCheckBox *m_ForceFiltering;
wxCheckBox *m_KeepAR43, *m_KeepAR169, *m_Crop; wxCheckBox *m_KeepAR43, *m_KeepAR169, *m_Crop;
wxCheckBox *m_UseXFB; wxCheckBox *m_UseXFB;
@ -143,7 +143,7 @@ class ConfigDialog : public wxDialog
ID_FULLSCREEN, ID_FULLSCREEN,
ID_VSYNC, ID_VSYNC,
ID_RENDERTOMAINWINDOW, ID_RENDERTOMAINWINDOW,
ID_NATIVERESOLUTION, ID_NATIVERESOLUTION, ID_2X_RESOLUTION,
ID_KEEPAR_4_3, ID_KEEPAR_16_9, ID_CROP, ID_KEEPAR_4_3, ID_KEEPAR_16_9, ID_CROP,
ID_USEXFB, ID_USEXFB,
ID_AUTOSCALE, ID_AUTOSCALE,

View File

@ -108,7 +108,12 @@ void OSDMenu(WPARAM wParam)
case '3': case '3':
OSDChoice = 1; OSDChoice = 1;
// Toggle native resolution // Toggle native resolution
g_Config.bNativeResolution = !g_Config.bNativeResolution; if (!(g_Config.bNativeResolution || g_Config.b2xResolution))
g_Config.bNativeResolution = true;
else if (g_Config.bNativeResolution)
{ g_Config.bNativeResolution = false; g_Config.b2xResolution = true; }
else
g_Config.b2xResolution = false;
break; break;
case '4': case '4':
OSDChoice = 2; OSDChoice = 2;

View File

@ -305,8 +305,9 @@ bool Renderer::Init()
// The EFB is larger than 640x480 - in fact, it's 640x528, give or take a couple of lines. // The EFB is larger than 640x480 - in fact, it's 640x528, give or take a couple of lines.
// So the below is wrong. // So the below is wrong.
// This should really be grabbed from config rather than from OpenGL. // This should really be grabbed from config rather than from OpenGL.
s_targetwidth = (int)OpenGL_GetBackbufferWidth(); // JP: Set these big enough to accomodate any potential 2x mode
s_targetheight = (int)OpenGL_GetBackbufferHeight(); s_targetwidth = 1280;
s_targetheight = 1024;
// Compensate height of render target for scaling, so that we get something close to the correct number of // Compensate height of render target for scaling, so that we get something close to the correct number of
// vertical pixels. // vertical pixels.
@ -467,6 +468,10 @@ bool Renderer::Init()
XFB_Init(); XFB_Init();
return glGetError() == GL_NO_ERROR && bSuccess; return glGetError() == GL_NO_ERROR && bSuccess;
// Now save the actual settings
s_targetwidth = (int)OpenGL_GetBackbufferWidth();
s_targetheight = (int)OpenGL_GetBackbufferHeight();
} }
void Renderer::Shutdown(void) void Renderer::Shutdown(void)
@ -551,12 +556,14 @@ bool Renderer::InitializeGL()
// ------------------------ // ------------------------
int Renderer::GetTargetWidth() int Renderer::GetTargetWidth()
{ {
return s_bNativeResolution ? EFB_WIDTH : s_targetwidth; return (s_bNativeResolution || g_Config.b2xResolution) ?
(s_bNativeResolution ? EFB_WIDTH : EFB_WIDTH * 2) : s_targetwidth;
} }
int Renderer::GetTargetHeight() int Renderer::GetTargetHeight()
{ {
return s_bNativeResolution ? EFB_HEIGHT : s_targetheight; return (s_bNativeResolution || g_Config.b2xResolution) ?
(s_bNativeResolution ? EFB_HEIGHT : EFB_HEIGHT * 2) : s_targetheight;
} }
float Renderer::GetTargetScaleX() float Renderer::GetTargetScaleX()
@ -1075,6 +1082,7 @@ void Renderer::Swap(const TRectangle& rc)
// Place messages on the picture, then copy it to the screen // Place messages on the picture, then copy it to the screen
SwapBuffers(); SwapBuffers();
// Why save this as s_bNativeResolution if we updated it all the time?
s_bNativeResolution = g_Config.bNativeResolution; s_bNativeResolution = g_Config.bNativeResolution;
RestoreGLState(); RestoreGLState();
@ -1304,8 +1312,11 @@ void Renderer::DrawDebugText()
sscanf(g_Config.iInternalRes, "%dx%d", &W, &H); sscanf(g_Config.iInternalRes, "%dx%d", &W, &H);
std::string OSDM1 = std::string OSDM1 =
g_Config.bNativeResolution ? StringFromFormat("%i x %i (native)", OSDInternalW, OSDInternalH) g_Config.bNativeResolution || g_Config.b2xResolution ?
: StringFromFormat("%i x %i", W, H); (g_Config.bNativeResolution ?
StringFromFormat("%i x %i (native)", OSDInternalW, OSDInternalH)
: StringFromFormat("%i x %i (2x)", OSDInternalW, OSDInternalH))
: StringFromFormat("%i x %i (custom)", W, H);
std::string OSDM21 = std::string OSDM21 =
!(g_Config.bKeepAR43 || g_Config.bKeepAR169) ? "-": (g_Config.bKeepAR43 ? "4:3" : "16:9"); !(g_Config.bKeepAR43 || g_Config.bKeepAR169) ? "-": (g_Config.bKeepAR43 ? "4:3" : "16:9");
std::string OSDM22 = std::string OSDM22 =
@ -1368,7 +1379,7 @@ bool Renderer::SaveRenderTarget(const char *filename, int W, int H, int YOffset)
// is there because of how some GL function works. But the buffer we are reading from here // 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 // seems to have the necessary pixels for a complete height so we use the complete height
// from the settings. // from the settings.
if (!g_Config.bNativeResolution) if (!(g_Config.bNativeResolution || g_Config.b2xResolution))
sscanf(g_Config.iInternalRes, "%dx%d", &W, &H); sscanf(g_Config.iInternalRes, "%dx%d", &W, &H);
u8 *data = (u8 *)malloc(3 * W * H); u8 *data = (u8 *)malloc(3 * W * H);