mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 21:30:19 -06:00
OpenGL: Fixed the screenshot function now that I found all the buffers
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3366 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -36,7 +36,7 @@ void Config::Load()
|
|||||||
|
|
||||||
// get resolution
|
// get resolution
|
||||||
iniFile.Get("Hardware", "WindowedRes", &temp, "640x480");
|
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
|
// apply this to the fullscreen resolution too
|
||||||
strncpy(iFSResolution, temp.c_str(), 16);
|
strncpy(iFSResolution, temp.c_str(), 16);
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ void Config::Save()
|
|||||||
{
|
{
|
||||||
IniFile iniFile;
|
IniFile iniFile;
|
||||||
iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini");
|
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", "FullscreenRes", iFSResolution);
|
||||||
iniFile.Set("Hardware", "Fullscreen", bFullscreen);
|
iniFile.Set("Hardware", "Fullscreen", bFullscreen);
|
||||||
iniFile.Set("Hardware", "VSync", bVSync);
|
iniFile.Set("Hardware", "VSync", bVSync);
|
||||||
|
@ -55,7 +55,7 @@ struct Config
|
|||||||
|
|
||||||
// Resolution control
|
// Resolution control
|
||||||
char iFSResolution[16];
|
char iFSResolution[16];
|
||||||
char iWindowedRes[16];
|
char iInternalRes[16];
|
||||||
|
|
||||||
bool bNativeResolution; // Should possibly be augmented with 2x, 4x native.
|
bool bNativeResolution; // Should possibly be augmented with 2x, 4x native.
|
||||||
bool bKeepAR43, bKeepAR169, bCrop; // Aspect ratio controls.
|
bool bKeepAR43, bKeepAR169, bCrop; // Aspect ratio controls.
|
||||||
|
@ -150,9 +150,9 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
|||||||
}
|
}
|
||||||
else // Going Windowed
|
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
|
else // No Window resolution set, fall back to default
|
||||||
{
|
{
|
||||||
|
@ -151,7 +151,7 @@ public:
|
|||||||
sscanf(g_Config.iFSResolution, "%dx%d",
|
sscanf(g_Config.iFSResolution, "%dx%d",
|
||||||
&currFullRes.x, &currFullRes.y);
|
&currFullRes.x, &currFullRes.y);
|
||||||
|
|
||||||
sscanf(g_Config.iWindowedRes, "%dx%d",
|
sscanf(g_Config.iInternalRes, "%dx%d",
|
||||||
&currWinRes.x, &currWinRes.y);
|
&currWinRes.x, &currWinRes.y);
|
||||||
|
|
||||||
SetProperty(OGL_FULLSCREEN, g_Config.bFullscreen);
|
SetProperty(OGL_FULLSCREEN, g_Config.bFullscreen);
|
||||||
|
@ -164,11 +164,11 @@ 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("Use native"), 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);
|
||||||
m_WindowResolutionCB->SetValue(wxString::FromAscii(g_Config.iWindowedRes));
|
m_WindowResolutionCB->SetValue(wxString::FromAscii(g_Config.iInternalRes));
|
||||||
|
|
||||||
// Aspect ratio / positioning controls
|
// Aspect ratio / positioning controls
|
||||||
wxStaticText *KeepARText = new wxStaticText(m_PageGeneral, wxID_ANY, wxT("Keep aspect ratio:"), wxDefaultPosition, wxDefaultSize, 0);
|
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(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 | 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(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);
|
||||||
@ -511,7 +511,7 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case ID_WINDOWRESOLUTIONCB:
|
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
|
// Apply this resolution as fullscreen resolution too
|
||||||
strcpy(g_Config.iFSResolution, m_WindowResolutionCB->GetValue().mb_str() );
|
strcpy(g_Config.iFSResolution, m_WindowResolutionCB->GetValue().mb_str() );
|
||||||
break;
|
break;
|
||||||
|
@ -404,8 +404,8 @@ void ToggleFullscreen(HWND hParent)
|
|||||||
g_Config.bFullscreen = false;
|
g_Config.bFullscreen = false;
|
||||||
RECT rc = {0, 0, w_fs, h_fs};
|
RECT rc = {0, 0, w_fs, h_fs};
|
||||||
|
|
||||||
if (strlen(g_Config.iWindowedRes) > 1)
|
if (strlen(g_Config.iInternalRes) > 1)
|
||||||
sscanf(g_Config.iWindowedRes, "%dx%d", &w_fs, &h_fs);
|
sscanf(g_Config.iInternalRes, "%dx%d", &w_fs, &h_fs);
|
||||||
// FullScreen -> Desktop
|
// FullScreen -> Desktop
|
||||||
ChangeDisplaySettings(NULL, 0);
|
ChangeDisplaySettings(NULL, 0);
|
||||||
|
|
||||||
|
@ -586,64 +586,6 @@ void Renderer::SetFramebuffer(GLuint fb)
|
|||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : s_uFramebuffer);
|
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()
|
void Renderer::ResetGLState()
|
||||||
{
|
{
|
||||||
// Gets us to a reasonably sane state where it's possible to do things like
|
// 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;
|
s_blendMode = newval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Apply AA if enabled
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
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
|
// Function: This function handles the OpenGL glScissor() function
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
@ -880,22 +885,6 @@ void Renderer::Swap(const TRectangle& rc)
|
|||||||
v_max = (float)GetTargetHeight();
|
v_max = (float)GetTargetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
|
||||||
// Save screenshot if AA and wireframe is off.
|
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
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
|
// Apply AA
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
@ -914,11 +903,11 @@ void Renderer::Swap(const TRectangle& rc)
|
|||||||
{
|
{
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer);
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer);
|
||||||
}
|
}
|
||||||
|
// Draw to the window buffer with bilinear filtering
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||||
glBlitFramebufferEXT(0, v_min, u_max, v_max,
|
glBlitFramebufferEXT(0, v_min, u_max, v_max,
|
||||||
back_rc.left, back_rc.top, back_rc.right, back_rc.bottom,
|
back_rc.left, back_rc.top, back_rc.right, back_rc.bottom,
|
||||||
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer, we'll draw debug text on top
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -976,18 +965,26 @@ void Renderer::Swap(const TRectangle& rc)
|
|||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Save screenshot if AA or wireframe is on.
|
// Save screenshot
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
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
|
// 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
|
// Reset settings
|
||||||
s_sScreenshotName = "";
|
s_sScreenshotName = "";
|
||||||
s_bScreenshot = false;
|
s_bScreenshot = false;
|
||||||
s_criticalScreenshot.Leave();
|
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)
|
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),
|
// The height seemed to often be one less than the setting (but sometimes not),
|
||||||
// perhaps a rounding error
|
// perhaps the source is the (bpmem.copyTexSrcWH.y + 1) in BPStructs.cpp that I'm guessing
|
||||||
if (H & 1)
|
// is there because of how some GL function works. But the buffer we are reading from here
|
||||||
H++;
|
// 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);
|
u8 *data = (u8 *)malloc(3 * W * H);
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
@ -1341,43 +1341,37 @@ bool Renderer::SaveRenderTarget(const char *filename, int W, int H, int YOffset)
|
|||||||
// Create wxImage
|
// Create wxImage
|
||||||
wxImage a(W, H, data);
|
wxImage a(W, H, data);
|
||||||
|
|
||||||
int nW, nH;
|
// ---------------------------------------------------------------------
|
||||||
|
// To get past the problem of non-4:3 and non-16:9 native resolution pictures (for example
|
||||||
// Resize the output to correctly use the Aspect ratio setting
|
// in RE1 some pictures have non-4:3 resolutions like 640 x 448 and 512 x 448 and such that
|
||||||
// This way, games are saved using the correct A/R scaling
|
// 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.
|
||||||
if ((g_Config.bKeepAR169 || g_Config.bKeepAR43) && s_MSAASamples == 1 && !g_Config.bWireFrame)
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
{
|
// We don't adjust non-native resolutions to avoid blurring the picture.
|
||||||
float Ratio = (float)W / (float)H;
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
float Ratio = (float)W / (float)(H), TargetRatio, TargetRatio1;
|
||||||
// Check if the height or width should be changed
|
if (g_Config.bNativeResolution && (g_Config.bKeepAR169 || g_Config.bKeepAR43)
|
||||||
if (Ratio != 4.0f/3.0f && 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)H * TargetRatio;
|
||||||
float fW = (float)W * 4.0/3.0;
|
W = (int)fW;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
if (Ratio != 16.0/9.0 && g_Config.bKeepAR169)
|
else
|
||||||
{
|
{
|
||||||
// Change the A/R to 16/9
|
float fH = (float)W * (1 / TargetRatio);
|
||||||
float fW = (float)W * 16.0/9.0;
|
H = (int)fH;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Rescale(W, H, wxIMAGE_QUALITY_HIGH);
|
a.Rescale(W, H, wxIMAGE_QUALITY_HIGH);
|
||||||
}
|
}
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
a.SaveFile(wxString::FromAscii(filename), wxBITMAP_TYPE_BMP);
|
a.SaveFile(wxString::FromAscii(filename), wxBITMAP_TYPE_BMP);
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
Reference in New Issue
Block a user