mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Added EFB Scale option to the OpenGL plug-in.
Renamed EFB Scale to Internal Resolution. Removed Auto Scale option (it is now always on). Added on-the-fly changing of the Internal Resolution in the OpenGL and Direct3D9 plug-ins. Further consolidated the code in the video plug-ins. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6240 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -94,6 +94,7 @@ static int s_MSAACoverageSamples = 0;
|
||||
bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp
|
||||
static bool s_bHaveCoverageMSAA = false;
|
||||
static u32 s_blendMode;
|
||||
static u32 s_LastEFBScale;
|
||||
|
||||
static volatile bool s_bScreenshot = false;
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
@ -105,6 +106,9 @@ static std::string s_sScreenshotName;
|
||||
int frameCount;
|
||||
|
||||
// The custom resolution
|
||||
static int s_Fulltarget_width;
|
||||
static int s_Fulltarget_height;
|
||||
|
||||
// TODO: Add functionality to reinit all the render targets when the window is resized.
|
||||
static int s_backbuffer_width;
|
||||
static int s_backbuffer_height;
|
||||
@ -348,29 +352,40 @@ bool Renderer::Init()
|
||||
TargetRectangle dst_rect;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
|
||||
if(!g_ActiveConfig.bNativeResolution)
|
||||
if(g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
if (g_ActiveConfig.b2xResolution)
|
||||
{
|
||||
xScale = 2.0f;
|
||||
yScale = 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||
}
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||
}
|
||||
|
||||
EFBxScale = ceilf(xScale);
|
||||
EFByScale = ceilf(yScale);
|
||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||
switch(s_LastEFBScale)
|
||||
{
|
||||
case 0:
|
||||
EFBxScale = xScale;
|
||||
EFByScale = yScale;
|
||||
break;
|
||||
case 1:
|
||||
EFBxScale = ceilf(xScale);
|
||||
EFByScale = ceilf(yScale);
|
||||
break;
|
||||
default:
|
||||
EFBxScale = g_ActiveConfig.iEFBScale - 1;
|
||||
EFByScale = EFBxScale;
|
||||
break;
|
||||
};
|
||||
|
||||
s_target_width = EFB_WIDTH * EFBxScale;
|
||||
s_target_height = EFB_HEIGHT * EFByScale;
|
||||
|
||||
s_Fulltarget_width = s_target_width;
|
||||
s_Fulltarget_height = s_target_height;
|
||||
|
||||
// Because of the fixed framebuffer size we need to disable the resolution
|
||||
// options while running
|
||||
g_Config.bRunning = true;
|
||||
@ -488,7 +503,7 @@ bool Renderer::Init()
|
||||
return GL_REPORT_ERROR() == GL_NO_ERROR && bSuccess;
|
||||
}
|
||||
|
||||
void Renderer::Shutdown(void)
|
||||
void Renderer::Shutdown()
|
||||
{
|
||||
g_Config.bRunning = false;
|
||||
UpdateActiveConfig();
|
||||
@ -530,15 +545,14 @@ int Renderer::GetTargetHeight()
|
||||
return s_target_height;
|
||||
}
|
||||
|
||||
// Return the custom resolution
|
||||
int Renderer::GetCustomWidth()
|
||||
int Renderer::GetFullTargetWidth()
|
||||
{
|
||||
return s_backbuffer_width;
|
||||
return s_Fulltarget_width;
|
||||
}
|
||||
|
||||
int Renderer::GetCustomHeight()
|
||||
int Renderer::GetFullTargetHeight()
|
||||
{
|
||||
return s_backbuffer_height;
|
||||
return s_Fulltarget_height;
|
||||
}
|
||||
|
||||
float Renderer::GetTargetScaleX()
|
||||
@ -561,17 +575,6 @@ float Renderer::GetXFBScaleY()
|
||||
return yScale;
|
||||
}
|
||||
|
||||
// Return the framebuffer size
|
||||
int Renderer::GetFrameBufferWidth()
|
||||
{
|
||||
return s_target_width;
|
||||
}
|
||||
|
||||
int Renderer::GetFrameBufferHeight()
|
||||
{
|
||||
return s_target_height;
|
||||
}
|
||||
|
||||
// Create On-Screen-Messages
|
||||
void Renderer::DrawDebugText()
|
||||
{
|
||||
@ -657,16 +660,26 @@ void Renderer::DrawDebugText()
|
||||
std::string T1 = "", T2 = "";
|
||||
std::vector<std::string> T0;
|
||||
|
||||
int W, H;
|
||||
W = OpenGL_GetBackbufferWidth();
|
||||
H = OpenGL_GetBackbufferHeight();
|
||||
std::string OSDM1;
|
||||
switch(g_ActiveConfig.iEFBScale)
|
||||
{
|
||||
case 0:
|
||||
OSDM1 = "Auto (fractional)";
|
||||
break;
|
||||
case 1:
|
||||
OSDM1 = "Auto (integral)";
|
||||
break;
|
||||
case 2:
|
||||
OSDM1 = "Native";
|
||||
break;
|
||||
case 3:
|
||||
OSDM1 = "2x";
|
||||
break;
|
||||
case 4:
|
||||
OSDM1 = "3x";
|
||||
break;
|
||||
}
|
||||
|
||||
std::string OSDM1 =
|
||||
g_ActiveConfig.bNativeResolution || g_ActiveConfig.b2xResolution ?
|
||||
(g_ActiveConfig.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;
|
||||
switch(g_ActiveConfig.iAspectRatio)
|
||||
{
|
||||
@ -740,7 +753,14 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
||||
|
||||
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||
{
|
||||
return g_framebufferManager.ConvertEFBRectangle(rc);
|
||||
TargetRectangle result;
|
||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||
result.left = (int)(rc.left * EFBxScale) + Xstride;
|
||||
result.top = (int)((EFB_HEIGHT - rc.top) * EFByScale) + Ystride;
|
||||
result.right = (int)(rc.right * EFBxScale) - (Xstride * 2);
|
||||
result.bottom = (int)((EFB_HEIGHT - rc.bottom) * EFByScale) - (Ystride * 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||
@ -778,39 +798,51 @@ bool Renderer::SetScissorRect()
|
||||
{
|
||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
||||
int yoff = bpmem.scissorOffset.y * 2 - 342;
|
||||
|
||||
float rc_left = (float)bpmem.scissorTL.x - xoff - 342; // left = 0
|
||||
if (rc_left < 0) rc_left = 0;
|
||||
|
||||
float rc_top = (float)bpmem.scissorTL.y - yoff - 342; // right = 0
|
||||
if (rc_top < 0) rc_top = 0;
|
||||
|
||||
float rc_right = (float)bpmem.scissorBR.x - xoff - 341; // right = 640
|
||||
if (rc_right > EFB_WIDTH) rc_right = EFB_WIDTH;
|
||||
|
||||
float rc_bottom = (float)bpmem.scissorBR.y - yoff - 341; // bottom = 480
|
||||
|
||||
// TODO: Sanity checks require further testing
|
||||
if (rc_left < 0) rc_left = 0;
|
||||
//if (rc_right < 0) rc_right = 0;
|
||||
//if (rc_left > EFB_WIDTH) rc_left = EFB_WIDTH;
|
||||
if (rc_right > EFB_WIDTH) rc_right = EFB_WIDTH;
|
||||
if (rc_top < 0) rc_top = 0;
|
||||
//if (rc_bottom < 0) rc_bottom = 0;
|
||||
//if (rc_top > EFB_HEIGHT) rc_top = EFB_HEIGHT;
|
||||
if (rc_bottom > EFB_HEIGHT) rc_bottom = EFB_HEIGHT;
|
||||
|
||||
if(rc_left > rc_right)
|
||||
if (rc_left > rc_right)
|
||||
{
|
||||
int temp = rc_right;
|
||||
rc_right = rc_left;
|
||||
rc_left = temp;
|
||||
}
|
||||
if(rc_top > rc_bottom)
|
||||
if (rc_top > rc_bottom)
|
||||
{
|
||||
int temp = rc_bottom;
|
||||
rc_bottom = rc_top;
|
||||
rc_top = temp;
|
||||
}
|
||||
|
||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||
|
||||
rc_left = (int)(rc_left * EFBxScale);// + Xstride;
|
||||
rc_top = (int)((rc_bottom - rc_top) * EFByScale);// + Ystride;
|
||||
rc_right = (int)((rc_right - rc_left) * EFBxScale);
|
||||
rc_bottom = (int)((EFB_HEIGHT - rc_bottom) * EFByScale); // -Ystride?
|
||||
|
||||
// Check that the coordinates are good
|
||||
if (rc_right != rc_left && rc_bottom != rc_top)
|
||||
{
|
||||
glScissor(
|
||||
(int)(rc_left * EFBxScale), // x = 0 for example
|
||||
(int)((EFB_HEIGHT - rc_bottom) * EFByScale), // y = 0 for example
|
||||
(int)((rc_right - rc_left)* EFBxScale), // width = 640 for example
|
||||
(int)((rc_bottom - rc_top) * EFByScale) // height = 480 for example
|
||||
(int)(rc_left), // x = 0 for example
|
||||
(int)(rc_bottom), // y = 0 for example
|
||||
(int)(rc_right), // width = 640 for example
|
||||
(int)(rc_top) // height = 480 for example
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@ -835,7 +867,7 @@ void Renderer::SetColorMask()
|
||||
|
||||
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||
{
|
||||
if(!g_ActiveConfig.bEFBAccessEnable)
|
||||
if (!g_ActiveConfig.bEFBAccessEnable)
|
||||
return 0;
|
||||
|
||||
// Get the rectangular target region covered by the EFB pixel
|
||||
@ -845,7 +877,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||
efbPixelRc.right = x + 1;
|
||||
efbPixelRc.bottom = y + 1;
|
||||
|
||||
TargetRectangle targetPixelRc = Renderer::ConvertEFBRectangle(efbPixelRc);
|
||||
TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc);
|
||||
|
||||
// TODO (FIX) : currently, AA path is broken/offset and doesn't return the correct pixel
|
||||
switch (type)
|
||||
@ -929,42 +961,44 @@ void UpdateViewport()
|
||||
// [3] = xorig + width/2 + 342
|
||||
// [4] = yorig + height/2 + 342
|
||||
// [5] = 16777215 * farz
|
||||
float scissorXOff = float(bpmem.scissorOffset.x) * 2.0f; // 342
|
||||
float scissorYOff = float(bpmem.scissorOffset.y) * 2.0f; // 342
|
||||
|
||||
int scissorXOff = bpmem.scissorOffset.x * 2;
|
||||
int scissorYOff = bpmem.scissorOffset.y * 2;
|
||||
|
||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||
|
||||
// Stretch picture with increased internal resolution
|
||||
int GLx = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - scissorXOff) *
|
||||
EFBxScale);
|
||||
int GLy = (int)ceil(
|
||||
(float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + scissorYOff) *
|
||||
EFByScale);
|
||||
int GLWidth = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
|
||||
int GLHeight = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
|
||||
int X = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - float(scissorXOff)) * EFBxScale);
|
||||
int Y = (int)ceil((float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + float(scissorYOff)) * EFByScale);
|
||||
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
|
||||
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
|
||||
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
|
||||
double GLFar = xfregs.rawViewport[5] / 16777216.0f;
|
||||
if(GLWidth < 0)
|
||||
if (Width < 0)
|
||||
{
|
||||
GLx += GLWidth;
|
||||
GLWidth*=-1;
|
||||
X += Width;
|
||||
Width*=-1;
|
||||
}
|
||||
if(GLHeight < 0)
|
||||
if (Height < 0)
|
||||
{
|
||||
GLy += GLHeight;
|
||||
GLHeight *= -1;
|
||||
Y += Height;
|
||||
Height *= -1;
|
||||
}
|
||||
// Update the view port
|
||||
glViewport(GLx, GLy, GLWidth, GLHeight);
|
||||
glViewport(X, Y, Width, Height);
|
||||
glDepthRange(GLNear, GLFar);
|
||||
}
|
||||
|
||||
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
||||
{
|
||||
// Update the view port for clearing the picture
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||
glViewport(targetRc.left, targetRc.bottom, targetRc.GetWidth(), targetRc.GetHeight());
|
||||
glScissor(targetRc.left, targetRc.bottom, targetRc.GetWidth(), targetRc.GetHeight());
|
||||
|
||||
|
||||
// Always set the scissor in case it was set by the game and has not been reset
|
||||
glScissor(targetRc.left, targetRc.bottom, targetRc.GetWidth(), targetRc.GetHeight());
|
||||
|
||||
VertexShaderManager::SetViewportChanged();
|
||||
|
||||
@ -1048,10 +1082,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
}
|
||||
|
||||
DVSTARTPROFILE();
|
||||
|
||||
ResetAPIState();
|
||||
TargetRectangle back_rc;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &back_rc);
|
||||
TargetRectangle dst_rect;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &dst_rect);
|
||||
|
||||
// Make sure that the wireframe setting doesn't screw up the screen copy.
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
@ -1063,7 +1096,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
TextureCache::DisableStage(i);
|
||||
|
||||
// Update GLViewPort
|
||||
glViewport(back_rc.left, back_rc.bottom, back_rc.GetWidth(), back_rc.GetHeight());
|
||||
glViewport(dst_rect.left, dst_rect.bottom, dst_rect.GetWidth(), dst_rect.GetHeight());
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
@ -1094,21 +1127,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
|
||||
TargetRectangle sourceRc;
|
||||
|
||||
if (g_ActiveConfig.bAutoScale || g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
sourceRc = xfbSource->sourceRc;
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceRc.left = 0;
|
||||
sourceRc.top = xfbSource->texHeight;
|
||||
sourceRc.right = xfbSource->texWidth;
|
||||
sourceRc.bottom = 0;
|
||||
}
|
||||
sourceRc = xfbSource->sourceRc;
|
||||
|
||||
MathUtil::Rectangle<float> drawRc;
|
||||
|
||||
if (g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||
if (!g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
// use virtual xfb with offset
|
||||
int xfbHeight = xfbSource->srcHeight;
|
||||
@ -1120,17 +1143,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
drawRc.left = -(xfbWidth / (float)fbWidth);
|
||||
drawRc.right = (xfbWidth / (float)fbWidth);
|
||||
|
||||
if (!g_ActiveConfig.bAutoScale)
|
||||
{
|
||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||
float vScale = (float)fbHeight / (float)back_rc.GetHeight();
|
||||
float hScale = (float)fbWidth / (float)back_rc.GetWidth();
|
||||
|
||||
drawRc.top *= vScale;
|
||||
drawRc.bottom *= vScale;
|
||||
drawRc.left *= hScale;
|
||||
drawRc.right *= hScale;
|
||||
}
|
||||
// The following code disables auto stretch. Kept for reference.
|
||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||
//float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
|
||||
//float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
|
||||
//drawRc.top *= vScale;
|
||||
//drawRc.bottom *= vScale;
|
||||
//drawRc.left *= hScale;
|
||||
//drawRc.right *= hScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1192,7 +1212,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
}
|
||||
else
|
||||
{
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||
GLuint read_texture = g_framebufferManager.ResolveAndGetRenderTarget(rc);
|
||||
// Render to the real buffer now.
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer
|
||||
@ -1234,12 +1254,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
glVertex2f( 1, -1);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
TextureCache::DisableStage(0);
|
||||
if(g_ActiveConfig.bAnaglyphStereo)
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
// Wireframe
|
||||
if (g_ActiveConfig.bWireFrame)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
@ -1249,7 +1268,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
// Save screenshot
|
||||
SaveRenderTarget(s_sScreenshotName.c_str(), back_rc);
|
||||
SaveRenderTarget(s_sScreenshotName.c_str(), dst_rect);
|
||||
// Reset settings
|
||||
s_sScreenshotName = "";
|
||||
s_bScreenshot = false;
|
||||
@ -1261,11 +1280,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
if (g_ActiveConfig.bDumpFrames)
|
||||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
int w = back_rc.GetWidth();
|
||||
int h = back_rc.GetHeight();
|
||||
int w = dst_rect.GetWidth();
|
||||
int h = dst_rect.GetHeight();
|
||||
u8 *data = (u8 *) malloc(3 * w * h);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(back_rc.left, back_rc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0)
|
||||
{
|
||||
if (!s_bLastFrameDumped)
|
||||
@ -1306,11 +1325,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
char movie_file_name[255];
|
||||
int w = back_rc.GetWidth();
|
||||
int h = back_rc.GetHeight();
|
||||
int w = dst_rect.GetWidth();
|
||||
int h = dst_rect.GetHeight();
|
||||
u8 *data = (u8 *) malloc(3 * w * h);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(back_rc.left, back_rc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
if (GL_REPORT_ERROR() == GL_NO_ERROR)
|
||||
{
|
||||
if (!s_bLastFrameDumped)
|
||||
@ -1348,6 +1367,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
s_bLastFrameDumped = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Finish up the current frame, print some stats
|
||||
OpenGL_Update(); // just updates the render window position and the backbuffer size
|
||||
bool xfbchanged = false;
|
||||
@ -1364,38 +1384,47 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
}
|
||||
|
||||
bool WindowResized = false;
|
||||
int W = (int)OpenGL_GetBackbufferWidth(), H = (int)OpenGL_GetBackbufferHeight();
|
||||
if (W != s_backbuffer_width || H != s_backbuffer_height)
|
||||
int W = (int)OpenGL_GetBackbufferWidth();
|
||||
int H = (int)OpenGL_GetBackbufferHeight();
|
||||
if (W != s_backbuffer_width || H != s_backbuffer_height || s_LastEFBScale != g_ActiveConfig.iEFBScale)
|
||||
{
|
||||
WindowResized = true;
|
||||
s_backbuffer_width = W;
|
||||
s_backbuffer_height = H;
|
||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||
}
|
||||
|
||||
if( xfbchanged || WindowResized)
|
||||
if (xfbchanged || WindowResized)
|
||||
{
|
||||
TargetRectangle dst_rect;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
|
||||
if(!g_ActiveConfig.bNativeResolution)
|
||||
if(g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
if (g_ActiveConfig.b2xResolution)
|
||||
{
|
||||
xScale = 2.0f;
|
||||
yScale = 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||
}
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||
}
|
||||
|
||||
EFBxScale = ceilf(xScale);
|
||||
EFByScale = ceilf(yScale);
|
||||
switch(s_LastEFBScale)
|
||||
{
|
||||
case 0:
|
||||
EFBxScale = xScale;
|
||||
EFByScale = yScale;
|
||||
break;
|
||||
case 1:
|
||||
EFBxScale = ceilf(xScale);
|
||||
EFByScale = ceilf(yScale);
|
||||
break;
|
||||
default:
|
||||
EFBxScale = g_ActiveConfig.iEFBScale - 1;
|
||||
EFByScale = EFBxScale;
|
||||
break;
|
||||
};
|
||||
|
||||
int m_newFrameBufferWidth = EFB_WIDTH * EFBxScale;
|
||||
int m_newFrameBufferHeight = EFB_HEIGHT * EFByScale;
|
||||
@ -1405,6 +1434,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
s_target_width = m_newFrameBufferWidth;
|
||||
s_target_height = m_newFrameBufferHeight;
|
||||
|
||||
s_Fulltarget_width = s_target_width;
|
||||
s_Fulltarget_height = s_target_height;
|
||||
|
||||
g_framebufferManager.Shutdown();
|
||||
g_framebufferManager.Init(s_target_width, s_target_height,
|
||||
s_MSAASamples, s_MSAACoverageSamples);
|
||||
@ -1617,23 +1649,6 @@ void Renderer::SetScreenshot(const char *filename)
|
||||
s_criticalScreenshot.Leave();
|
||||
}
|
||||
|
||||
// For the OSD menu's live resolution change
|
||||
bool Renderer::Allow2x()
|
||||
{
|
||||
if (GetFrameBufferWidth() >= 1280 && GetFrameBufferHeight() >= 960)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Renderer::AllowCustom()
|
||||
{
|
||||
if (GetCustomWidth() <= GetFrameBufferWidth() && GetCustomHeight() <= GetFrameBufferHeight())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Renderer::FlipImageData(u8 *data, int w, int h)
|
||||
{
|
||||
// Flip image upside down. Damn OpenGL.
|
||||
|
Reference in New Issue
Block a user