diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h index 117c64d88f..60f6703689 100644 --- a/Source/Core/Common/Src/Common.h +++ b/Source/Core/Common/Src/Common.h @@ -118,4 +118,10 @@ namespace #define GC_ALIGNED64_DECL(x) __attribute((aligned(64))) x #endif // WIN32 +// A macro to disallow the copy constructor and operator= functions +// This should be used in the private: declarations for a class +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + #endif // COMMON_H diff --git a/Source/Core/VideoCommon/Src/NativeVertexFormat.h b/Source/Core/VideoCommon/Src/NativeVertexFormat.h index 96bd65ea57..dd7e622d73 100644 --- a/Source/Core/VideoCommon/Src/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/Src/NativeVertexFormat.h @@ -89,9 +89,6 @@ struct PortableVertexDeclaration // all the data loading code must always be made compatible. class NativeVertexFormat { -protected: - NativeVertexFormat() {} - public: virtual ~NativeVertexFormat() {} @@ -103,6 +100,13 @@ public: // TODO: move these in under private: u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present. + +protected: + // Let subclasses construct. + NativeVertexFormat() {} + +private: + DISALLOW_COPY_AND_ASSIGN(NativeVertexFormat); }; #endif // _NATIVEVERTEXFORMAT_H diff --git a/Source/Core/VideoCommon/Src/VertexLoader.h b/Source/Core/VideoCommon/Src/VertexLoader.h index b3224f0ce1..f7c74177e8 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.h +++ b/Source/Core/VideoCommon/Src/VertexLoader.h @@ -23,6 +23,8 @@ #include +#include "Common.h" + #include "CPMemory.h" #include "DataReader.h" #include "NativeVertexFormat.h" @@ -103,6 +105,8 @@ private: void WriteGetVariable(int bits, Gen::OpArg dest, void *address); void WriteSetVariable(int bits, void *address, Gen::OpArg dest); + + DISALLOW_COPY_AND_ASSIGN(VertexLoader); }; #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp index bf62289542..f225e24951 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp @@ -37,7 +37,6 @@ #include "XFB.h" #include "main.h" - // --------------------------------------------------------------------------------------- // State translation lookup tables // ------------- @@ -383,8 +382,8 @@ void BPWritten(int addr, int changes, int newval) (int)((bpmem.copyTexSrcXY.x + bpmem.copyTexSrcWH.x + 1)), (int)((bpmem.copyTexSrcXY.y + bpmem.copyTexSrcWH.y + 1)) }; - float MValueX = OpenGL_GetXmax(); - float MValueY = OpenGL_GetYmax(); + float MValueX = Renderer::GetTargetScaleX(); + float MValueY = Renderer::GetTargetScaleY(); // Need another rc here to get it to scale. // Here the bottom right is the out of the rectangle. TRectangle multirc = { @@ -407,9 +406,9 @@ void BPWritten(int addr, int changes, int newval) if (g_Config.bEFBCopyDisable) { /* We already have this in Render.cpp that we call when (PE_copy.clear) is true. But we need a separate one - here because UpdateViewport() is not run when this otion is set? */ - glViewport(rc.left,rc.bottom, rc.right,rc.top); - glScissor(rc.left,rc.bottom, rc.right,rc.top); + here because UpdateViewport() is not run when this option is set? */ + glViewport(rc.left, rc.bottom, rc.right,rc.top); + glScissor(rc.left, rc.bottom, rc.right,rc.top); // Logging GLScissorX = rc.left; GLScissorY = rc.bottom; @@ -560,7 +559,7 @@ void BPWritten(int addr, int changes, int newval) break; default: - switch(addr & 0xFC) //texture sampler filter + switch (addr & 0xFC) //texture sampler filter { case 0x28: // tevorder 0-3 case 0x2C: // tevorder 4-7 @@ -571,7 +570,6 @@ void BPWritten(int addr, int changes, int newval) PixelShaderManager::SetTevOrderChanged(addr - 0x28); } break; - case 0x80: // TEX MODE 0 case 0xA0: if (changes) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp index 26ba6f8956..a8d556639d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Config.cpp @@ -40,17 +40,15 @@ void Config::Load() iniFile.Get("Hardware", "FullscreenRes", &temp, "640x480"); strncpy(iFSResolution, temp.c_str(), 16); - iniFile.Get("Settings", "Backend", &temp, ""); - strncpy(iBackend, temp.c_str(), 16); - iniFile.Get("Hardware", "Fullscreen", &bFullscreen, 0); // Hardware iniFile.Get("Hardware", "RenderToMainframe", &renderToMainframe, false); - iniFile.Get("Settings", "StretchToFit", &bStretchToFit, true); + iniFile.Get("Settings", "StretchToFit", &bNativeResolution, true); iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false); iniFile.Get("Settings", "KeepAR_16_9", &bKeepAR169, false); iniFile.Get("Settings", "Crop", &bCrop, false); iniFile.Get("Settings", "HideCursor", &bHideCursor, false); - + iniFile.Get("Settings", "UseXFB", &bUseXFB, 0); + iniFile.Get("Settings", "AutoScale", &bAutoScale, true); iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings @@ -69,12 +67,11 @@ void Config::Load() strcpy(texDumpPath, s.c_str()); else { strncpy(texDumpPath, s.c_str(), sizeof(texDumpPath)-1); - texDumpPath[sizeof(texDumpPath)-1] = 0; + texDumpPath[sizeof(texDumpPath) - 1] = 0; } iniFile.Get("Settings", "TexFmtOverlayEnable", &bTexFmtOverlayEnable, 0); iniFile.Get("Settings", "TexFmtOverlayCenter", &bTexFmtOverlayCenter, 0); - iniFile.Get("Settings", "UseXFB", &bUseXFB, 0); iniFile.Get("Settings", "WireFrame", &bWireFrame, 0); iniFile.Get("Settings", "DisableLighting", &bDisableLighting, 0); iniFile.Get("Settings", "DisableTexturing", &bDisableTexturing, 0); @@ -97,13 +94,13 @@ void Config::Save() iniFile.Set("Hardware", "FullscreenRes", iFSResolution); iniFile.Set("Hardware", "Fullscreen", bFullscreen); iniFile.Set("Hardware", "RenderToMainframe", renderToMainframe); - iniFile.Set("Settings", "StretchToFit", bStretchToFit); + iniFile.Set("Settings", "StretchToFit", bNativeResolution); iniFile.Set("Settings", "KeepAR_4_3", bKeepAR43); iniFile.Set("Settings", "KeepAR_16_9", bKeepAR169); iniFile.Set("Settings", "Crop", bCrop); iniFile.Set("Settings", "HideCursor", bHideCursor); - iniFile.Set("Settings", "Backend", iBackend); - + iniFile.Set("Settings", "UseXFB", bUseXFB); + iniFile.Set("Settings", "AutoScale", bAutoScale); iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache); iniFile.Set("Settings", "ShowFPS", bShowFPS); @@ -117,7 +114,6 @@ void Config::Save() iniFile.Set("Settings", "TexDumpPath", texDumpPath); iniFile.Set("Settings", "TexFmtOverlayEnable", bTexFmtOverlayEnable); iniFile.Set("Settings", "TexFmtOverlayCenter", bTexFmtOverlayCenter); - iniFile.Set("Settings", "UseXFB", bUseXFB); iniFile.Set("Settings", "Wireframe", bWireFrame); iniFile.Set("Settings", "DisableLighting", bDisableLighting); iniFile.Set("Settings", "DisableTexturing", bDisableTexturing); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Config.h b/Source/Plugins/Plugin_VideoOGL/Src/Config.h index c3c988bdca..0ad4801bf7 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Config.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Config.h @@ -18,6 +18,8 @@ #ifndef _CONFIG_H #define _CONFIG_H +#include "Common.h" + // Log in two categories, and save three other options in the same byte #define CONF_LOG 1 #define CONF_PRIMLOG 2 @@ -25,6 +27,7 @@ #define CONF_SAVETARGETS 8 #define CONF_SAVESHADERS 16 +// NEVER inherit from this class. struct Config { Config(); @@ -33,17 +36,17 @@ struct Config // General bool bFullscreen; - bool renderToMainframe; - char iFSResolution[16]; - char iWindowedRes[16]; - char iBackend[16]; - - // stretch to fit should be split into two options, I think - one for low resolution backbuffer, - // one for ignore aspect ratio. I guess KeepAR sort of does that. Anyway, these should be rethought. - bool bStretchToFit; - bool bKeepAR43, bKeepAR169, bCrop; bool bHideCursor; - bool bSafeTextureCache; + bool renderToMainframe; + + // Resolution control + char iFSResolution[16]; + char iWindowedRes[16]; + + bool bNativeResolution; // Should possibly be augmented with 2x, 4x native. + bool bKeepAR43, bKeepAR169, bCrop; // Aspect ratio controls. + bool bUseXFB; + bool bAutoScale; // Removes annoying borders without using XFB. Doesn't always work perfectly. // Enhancements int iMultisampleMode; @@ -59,7 +62,6 @@ struct Config bool bTexFmtOverlayCenter; // Render - bool bUseXFB; bool bWireFrame; bool bDisableLighting; bool bDisableTexturing; @@ -74,6 +76,7 @@ struct Config bool bProjectionHax1; bool bProjectionHax2; bool bCopyEFBToRAM; + bool bSafeTextureCache; int iLog; // CONF_ bits int iSaveTargetId; @@ -81,6 +84,9 @@ struct Config //currently unused: int iCompileDLsLevel; bool bShowShaderErrors; + +private: + DISALLOW_COPY_AND_ASSIGN(Config); }; extern Config g_Config; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 01603d1f22..3422fa3d09 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -37,18 +37,17 @@ struct RECT // Handles OpenGL and the window -// externals -int nBackbufferWidth, nBackbufferHeight; // screen width -int nXoff, nYoff; // screen offset -float MValueX, MValueY; +// Window dimensions. +static int s_backbuffer_width; +static int s_backbuffer_height; #ifndef _WIN32 GLWindow GLWin; #endif #if defined(_WIN32) -static HDC hDC = NULL; // Private GDI Device Context -static HGLRC hRC = NULL; // Permanent Rendering Context +static HDC hDC = NULL; // Private GDI Device Context +static HGLRC hRC = NULL; // Permanent Rendering Context extern HINSTANCE g_hInstance; #endif @@ -67,36 +66,14 @@ void OpenGL_SwapBuffers() #endif } -float OpenGL_GetXmax() { - return MValueX; +u32 OpenGL_GetBackbufferWidth() { + return s_backbuffer_width; } -float OpenGL_GetYmax() { - return MValueY; +u32 OpenGL_GetBackbufferHeight() { + return s_backbuffer_height; } -int OpenGL_GetXoff() { - return nXoff; -} - -int OpenGL_GetYoff() { - return nYoff; -} - -u32 OpenGL_GetWidth() { - return nBackbufferWidth; -} - -u32 OpenGL_GetHeight() { - return nBackbufferHeight; -} - -void OpenGL_SetSize(u32 width, u32 height) { - nBackbufferWidth = width; - nBackbufferHeight = height; -} - - void OpenGL_SetWindowText(const char *text) { #if USE_SDL @@ -123,7 +100,7 @@ void OpenGL_SetWindowText(const char *text) unsigned int Callback_PeekMessages() { #ifdef _WIN32 - //TODO: peekmessage + // TODO: peekmessage MSG msg; while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { @@ -137,6 +114,7 @@ unsigned int Callback_PeekMessages() return FALSE; #endif } + // Show the current FPS void UpdateFPSDisplay(const char *text) { @@ -187,40 +165,17 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight #endif // ---------------------------- - // --------------------------------------------------------------------------------------- // Control window size and picture scaling // ------------------ - // nBackbufferWidth and nBackbufferHeight = Screen resolution from ini, or 640x480 - // See OpenGL_Update() for documentation of the other variables - // ------------------ - nBackbufferWidth = _twidth; - nBackbufferHeight = _theight; - - float FactorW = 640.0f / (float)nBackbufferWidth; - float FactorH = 480.0f / (float)nBackbufferHeight; - float Max = (FactorW < FactorH) ? FactorH : FactorW; - - if (g_Config.bStretchToFit) - { - MValueX = 1.0f / FactorW; - MValueY = 1.0f / FactorH; - nXoff = 0; - nYoff = 0; - } - else - { - MValueX = 1.0f / Max; - MValueY = 1.0f / Max; - nXoff = (int)((nBackbufferWidth - (640 * MValueX)) / 2); - nYoff = (int)((nBackbufferHeight - (480 * MValueY)) / 2); - } + s_backbuffer_width = _twidth; + s_backbuffer_height = _theight; g_VideoInitialize.pPeekMessages = &Callback_PeekMessages; g_VideoInitialize.pUpdateFPSDisplay = &UpdateFPSDisplay; //char buff[100]; - //sprintf(buff, "%i %i %d %d %d", nBackbufferWidth, nBackbufferHeight, Max, MValueX, MValueY); + //sprintf(buff, "%i %i %d %d %d", s_backbuffer_width, s_backbuffer_height, Max, MValueX, MValueY); //MessageBox(0, buff, "", 0); #if USE_SDL @@ -234,8 +189,8 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight //setup ogl to use double buffering SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #elif defined(HAVE_COCOA) && HAVE_COCOA - GLWin.width = nBackbufferWidth; - GLWin.height = nBackbufferHeight; + GLWin.width = s_backbuffer_width; + GLWin.height = s_backbuffer_height; GLWin.cocoaWin = cocoaGLCreateWindow(GLWin.width, GLWin.height); GLWin.cocoaCtx = cocoaGLInit(g_Config.iMultisampleMode); #elif defined(USE_WX) && USE_WX @@ -290,14 +245,14 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight GetWindowRect(GetDesktopWindow(), &rcdesktop); if (g_Config.bFullscreen) { - //nBackbufferWidth = rcdesktop.right - rcdesktop.left; - //nBackbufferHeight = rcdesktop.bottom - rcdesktop.top; + //s_backbuffer_width = rcdesktop.right - rcdesktop.left; + //s_backbuffer_height = rcdesktop.bottom - rcdesktop.top; DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); dmScreenSettings.dmSize=sizeof(dmScreenSettings); - dmScreenSettings.dmPelsWidth = nBackbufferWidth; - dmScreenSettings.dmPelsHeight = nBackbufferHeight; + dmScreenSettings.dmPelsWidth = s_backbuffer_width; + dmScreenSettings.dmPelsHeight = s_backbuffer_height; dmScreenSettings.dmBitsPerPel = 32; dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; @@ -329,7 +284,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight RECT rc; rc.left = 0; rc.top = 0; - rc.right = nBackbufferWidth; rc.bottom = nBackbufferHeight; + rc.right = s_backbuffer_width; rc.bottom = s_backbuffer_height; AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle); int X = (rcdesktop.right-rcdesktop.left)/2 - (rc.right-rc.left)/2; int Y = (rcdesktop.bottom-rcdesktop.top)/2 - (rc.bottom-rc.top)/2; @@ -540,8 +495,8 @@ bool OpenGL_MakeCurrent() | ( g_Config.bFullscreen ? SDL_FULLSCREEN : 0); // Set vide mode. // TODO: Can we use this field or is a separate field needed? - int _twidth = nBackbufferWidth; - int _theight = nBackbufferHeight; + int _twidth = s_backbuffer_width; + int _theight = s_backbuffer_height; SDL_Surface *screen = SDL_SetVideoMode(_twidth, _theight, 0, videoFlags); if (!screen) { //TODO : Display an error message @@ -587,37 +542,36 @@ void OpenGL_Update() { #if USE_SDL SDL_Surface *surface = SDL_GetVideoSurface(); - RECT rcWindow; - if (!surface) return; - nBackbufferWidth = surface->w; - nBackbufferHeight = surface->h; + RECT rcWindow = {0}; + if (!surface) + return; + s_backbuffer_width = surface->w; + s_backbuffer_height = surface->h; rcWindow.right = surface->w; rcWindow.bottom = surface->h; #elif defined(HAVE_COCOA) && HAVE_COCOA - RECT rcWindow; + RECT rcWindow = {0}; rcWindow.right = GLWin.width; rcWindow.bottom = GLWin.height; #elif defined(USE_WX) && USE_WX - RECT rcWindow; + RECT rcWindow = {0}; rcWindow.right = GLWin.width; rcWindow.bottom = GLWin.height; // TODO fill in #elif defined(_WIN32) RECT rcWindow; - // If we are not rendering to a child window if (!EmuWindow::GetParentWnd()) { - // return if we don't stretch the picture - if (!g_Config.bStretchToFit) return; - GetWindowRect(EmuWindow::GetWnd(), &rcWindow); - rcWindow.top += 25; + // We are not rendering to a child window - use client size. + GetClientRect(EmuWindow::GetWnd(), &rcWindow); } else { + // We are rendering to a child window - use parent size. GetWindowRect(EmuWindow::GetParentWnd(), &rcWindow); } @@ -633,8 +587,8 @@ void OpenGL_Update() if (EmuWindow::GetParentWnd() != 0) ::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); - nBackbufferWidth = width; - nBackbufferHeight = height; + s_backbuffer_width = width; + s_backbuffer_height = height; #elif defined(HAVE_X11) && HAVE_X11 // We just check all of our events here @@ -684,8 +638,8 @@ void OpenGL_Update() unsigned int borderDummy; XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth); - nBackbufferWidth = GLWin.width; - nBackbufferHeight = GLWin.height; + s_backbuffer_width = GLWin.width; + s_backbuffer_height = GLWin.height; rcWindow.left = 0; rcWindow.top = 0; rcWindow.right = GLWin.width; @@ -705,37 +659,6 @@ void OpenGL_Update() } return; #endif - - // --------------------------------------------------------------------------------------- - // Get the new window width and height - /* ------------------ - nBackbufferWidth and nBackbufferHeight: Now the actual rendering window size - Max: The highest of w and h - nXoff and nYoff: Controls the picture's position inside the rendering window - MValueX and MValueY: Used for the picture resolution-change rescaling - // ------------------ - MValueX and MValueY: Used for the picture resolution-change rescaling. It will be used in - TextureMngr and VertexShaderManager: Rescale textures on resolution changes - BPStructs.cpp: Control glScissor() - // ------------------ */ - float FactorW = 640.0f / (float)nBackbufferWidth; - float FactorH = 480.0f / (float)nBackbufferHeight; - float Max = (FactorW < FactorH) ? FactorH : FactorW; - - if (g_Config.bStretchToFit) - { - MValueX = 1; - MValueY = 1; - nXoff = 0; - nYoff = 0; - } - else - { - MValueX = 1.0f / Max; - MValueY = 1.0f / Max; - nXoff = (int)((nBackbufferWidth - (640 * MValueX)) / 2); - nYoff = (int)((nBackbufferHeight - (480 * MValueY)) / 2); - } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h index 483f50f66e..e112789011 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h @@ -119,16 +119,8 @@ extern GLWindow GLWin; #endif -float OpenGL_GetXmax(); -float OpenGL_GetYmax(); -int OpenGL_GetXoff(); -int OpenGL_GetYoff(); -u32 OpenGL_GetWidth(); -u32 OpenGL_GetHeight(); -void OpenGL_SetSize(u32 width, u32 height); -// yeah yeah, these should be hidden -//extern int nBackbufferWidth, nBackbufferHeight; -//extern int nXoff, nYoff; +u32 OpenGL_GetBackbufferWidth(); +u32 OpenGL_GetBackbufferHeight(); bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _width, int _height); bool OpenGL_MakeCurrent(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp index 760dcbdaa8..b088423d9e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp @@ -30,11 +30,12 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog) EVT_CHECKBOX(ID_RENDERTOMAINWINDOW, ConfigDialog::GeneralSettingsChanged) EVT_COMBOBOX(ID_FULLSCREENCB, ConfigDialog::GeneralSettingsChanged) EVT_COMBOBOX(ID_WINDOWRESOLUTIONCB, ConfigDialog::GeneralSettingsChanged) - EVT_COMBOBOX(ID_RENDERBACKEND, ConfigDialog::GeneralSettingsChanged) EVT_COMBOBOX(ID_ALIASMODECB, ConfigDialog::GeneralSettingsChanged) EVT_CHOICE(ID_MAXANISOTROPY, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_FORCEFILTERING, ConfigDialog::GeneralSettingsChanged) - EVT_CHECKBOX(ID_STRETCHTOFIT, ConfigDialog::GeneralSettingsChanged) + EVT_CHECKBOX(ID_NATIVERESOLUTION, ConfigDialog::GeneralSettingsChanged) + EVT_CHECKBOX(ID_USEXFB, ConfigDialog::GeneralSettingsChanged) + EVT_CHECKBOX(ID_AUTOSCALE, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_KEEPAR_4_3, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_KEEPAR_16_9, ConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(ID_CROP, ConfigDialog::GeneralSettingsChanged) @@ -49,7 +50,6 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog) EVT_CHECKBOX(ID_SHADERERRORS, ConfigDialog::AdvancedSettingsChanged) EVT_CHECKBOX(ID_TEXFMTOVERLAY, ConfigDialog::AdvancedSettingsChanged) EVT_CHECKBOX(ID_TEXFMTCENTER, ConfigDialog::AdvancedSettingsChanged) - EVT_CHECKBOX(ID_USEXFB, ConfigDialog::AdvancedSettingsChanged) EVT_CHECKBOX(ID_DUMPTEXTURES, ConfigDialog::AdvancedSettingsChanged) EVT_CHECKBOX(ID_DISABLELIGHTING, ConfigDialog::AdvancedSettingsChanged) EVT_CHECKBOX(ID_DISABLETEXTURING, ConfigDialog::AdvancedSettingsChanged) @@ -120,11 +120,6 @@ void ConfigDialog::AddWindowReso(char *reso) arrayStringFor_WindowResolutionCB.Add(wxString::FromAscii(reso)); } -void ConfigDialog::AddRenderBackend(const char *backend) -{ - m_RenderBackend->Append(wxString::FromAscii(backend)); -} - void ConfigDialog::AddAAMode(int mode) { wxString tmp; @@ -168,16 +163,21 @@ void ConfigDialog::CreateGUIControls() m_Fullscreen->SetValue(g_Config.bFullscreen); m_RenderToMainWindow = new wxCheckBox(m_PageGeneral, ID_RENDERTOMAINWINDOW, wxT("Render to main window"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_RenderToMainWindow->SetValue(g_Config.renderToMainframe); - m_StretchToFit = new wxCheckBox(m_PageGeneral, ID_STRETCHTOFIT, wxT("Stretch to fit"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_NativeResolution = new wxCheckBox(m_PageGeneral, ID_NATIVERESOLUTION, wxT("Native resolution"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + + // Aspect ratio / positioning controls m_KeepAR43 = new wxCheckBox(m_PageGeneral, ID_KEEPAR_4_3, wxT("Keep 4:3 aspect ratio"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_KeepAR169 = new wxCheckBox(m_PageGeneral, ID_KEEPAR_16_9, wxT("Keep 16:9 aspect ratio"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Crop = new wxCheckBox(m_PageGeneral, ID_CROP, wxT("Crop"), 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); - // Default values - m_StretchToFit->SetValue(g_Config.bStretchToFit); + m_NativeResolution->SetValue(g_Config.bNativeResolution); m_KeepAR43->SetValue(g_Config.bKeepAR43); m_KeepAR169->SetValue(g_Config.bKeepAR169); m_Crop->SetValue(g_Config.bCrop); + m_UseXFB->SetValue(g_Config.bUseXFB); + m_AutoScale->SetValue(g_Config.bAutoScale); #ifndef _WIN32 m_HideCursor = new wxCheckBox(m_PageGeneral, ID_HIDECURSOR, wxT("Hide mouse cursor"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); @@ -192,17 +192,13 @@ void ConfigDialog::CreateGUIControls() 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)); - wxStaticText *BEText = new wxStaticText(m_PageGeneral, ID_BETEXT, wxT("Rendering backend:"), wxDefaultPosition, wxDefaultSize, 0); - m_RenderBackend = new wxComboBox(m_PageGeneral, ID_RENDERBACKEND, wxEmptyString, wxDefaultPosition, wxDefaultSize, arrayStringFor_RenderBackend, 0, wxDefaultValidator); - m_RenderBackend->SetValue(wxString::FromAscii(g_Config.iBackend)); - // Tool tips m_Fullscreen->SetToolTip(wxT( "This option use a separate rendering window and can only be used when" " 'Render to main window' is unchecked. The only way to exit this mode\n" " is with Alt + F4 (that also close Dolphin)." )); - m_StretchToFit->SetToolTip(wxT( + m_NativeResolution->SetToolTip(wxT( "This will use the game's native resolution and stretch it to fill the" "\nwindow instead of changing the internal display resolution. It" "\nmay result in a slightly blurrier image, but it may also give a higher" @@ -242,12 +238,15 @@ void ConfigDialog::CreateGUIControls() sBasic = new wxGridBagSizer(0, 0); sBasic->Add(m_Fullscreen, wxGBPosition(0, 0), wxGBSpan(1, 3), wxALL, 5); sBasic->Add(m_RenderToMainWindow, wxGBPosition(1, 0), wxGBSpan(1, 3), wxALL, 5); - sBasic->Add(m_StretchToFit, wxGBPosition(2, 0), wxGBSpan(1, 3), wxALL, 5); - sBasic->Add(m_KeepAR43, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALL, 5); - sBasic->Add(m_KeepAR169, wxGBPosition(3, 1), wxGBSpan(1, 1), wxALL, 5); - sBasic->Add(m_Crop, wxGBPosition(3, 2), wxGBSpan(1, 1), wxALL, 5); + sBasic->Add(m_AutoScale, wxGBPosition(2, 0), wxGBSpan(1, 3), wxALL, 5); + sBasic->Add(m_NativeResolution, wxGBPosition(3, 0), wxGBSpan(1, 3), wxALL, 5); + sBasic->Add(m_UseXFB, wxGBPosition(4, 0), wxGBSpan(1, 3), wxALL, 5); + sBasic->Add(m_KeepAR43, wxGBPosition(5, 0), wxGBSpan(1, 1), wxALL, 5); + sBasic->Add(m_KeepAR169, wxGBPosition(5, 1), wxGBSpan(1, 1), wxALL, 5); + sBasic->Add(m_Crop, wxGBPosition(5, 2), wxGBSpan(1, 1), wxALL, 5); + // Because of the ifdef here we need this variable for the row number - int Row = 4; + int Row = 6; #ifndef _WIN32 sBasic->Add(m_HideCursor, wxGBPosition(Row++, 0), wxGBSpan(1, 3), wxALL, 5); #endif @@ -255,8 +254,6 @@ void ConfigDialog::CreateGUIControls() sBasic->Add(m_FullscreenCB, wxGBPosition(Row++, 1), wxGBSpan(1, 1), wxALL, 5); sBasic->Add(WMText, wxGBPosition(Row, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5); sBasic->Add(m_WindowResolutionCB, wxGBPosition(Row++, 1), wxGBSpan(1, 1), wxALL, 5); - sBasic->Add(BEText, wxGBPosition(Row, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5); - sBasic->Add(m_RenderBackend, wxGBPosition(Row++, 1), wxGBSpan(1, 1), wxALL, 5); sbBasic->Add(sBasic); sGeneral->Add(sbBasic, 0, wxEXPAND|wxALL, 5); @@ -293,8 +290,6 @@ void ConfigDialog::CreateGUIControls() // Render sbRendering = new wxStaticBoxSizer(wxVERTICAL, m_PageAdvanced, wxT("Rendering")); - m_UseXFB = new wxCheckBox(m_PageAdvanced, ID_USEXFB, wxT("Use External Framebuffer (XFB)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_UseXFB->SetValue(g_Config.bUseXFB); m_Wireframe = new wxCheckBox(m_PageAdvanced, ID_WIREFRAME, wxT("Enable Wireframe"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Wireframe->SetValue(g_Config.bWireFrame); m_Wireframe->Enable(true); @@ -378,10 +373,9 @@ void ConfigDialog::CreateGUIControls() wxBoxSizer *sRenderBoxRow1 = new wxBoxSizer(wxHORIZONTAL); sRendering = new wxGridBagSizer(0, 0); - sRendering->Add(m_UseXFB, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALL, 5); - sRendering->Add(m_Wireframe, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALL, 5); - sRendering->Add(m_DisableLighting, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALL, 5); - sRendering->Add(m_DisableTexturing, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALL, 5); + sRendering->Add(m_Wireframe, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALL, 5); + sRendering->Add(m_DisableLighting, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALL, 5); + sRendering->Add(m_DisableTexturing, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALL, 5); sRenderBoxRow1->Add(sRendering, 0, wxALL|wxEXPAND, 5); wxStaticBoxSizer *sSBox = new wxStaticBoxSizer(m_StaticBox_EFB, wxVERTICAL); wxBoxSizer *sStrip1 = new wxBoxSizer(wxHORIZONTAL); @@ -431,8 +425,15 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) case ID_RENDERTOMAINWINDOW: g_Config.renderToMainframe = m_RenderToMainWindow->IsChecked(); break; - case ID_STRETCHTOFIT: - g_Config.bStretchToFit = m_StretchToFit->IsChecked(); + case ID_NATIVERESOLUTION: + g_Config.bNativeResolution = m_NativeResolution->IsChecked(); + break; + + case ID_USEXFB: + g_Config.bUseXFB = m_UseXFB->IsChecked(); + break; + case ID_AUTOSCALE: + g_Config.bAutoScale = m_AutoScale->IsChecked(); break; case ID_KEEPAR_4_3: g_Config.bKeepAR43 = m_KeepAR43->IsChecked(); @@ -447,10 +448,11 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) case ID_CROP: g_Config.bCrop = m_Crop->IsChecked(); break; + #ifndef _WIN32 - case ID_HIDECURSOR: - g_Config.bHideCursor = m_HideCursor->IsChecked(); - break; + case ID_HIDECURSOR: + g_Config.bHideCursor = m_HideCursor->IsChecked(); + break; #endif case ID_FULLSCREENCB: strcpy(g_Config.iFSResolution, m_FullscreenCB->GetValue().mb_str() ); @@ -458,9 +460,6 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) case ID_WINDOWRESOLUTIONCB: strcpy(g_Config.iWindowedRes, m_WindowResolutionCB->GetValue().mb_str() ); break; - case ID_RENDERBACKEND: - strcpy(g_Config.iBackend, m_RenderBackend->GetValue().mb_str()); - break; case ID_FORCEFILTERING: g_Config.bForceFiltering = m_ForceFiltering->IsChecked(); break; @@ -498,9 +497,6 @@ void ConfigDialog::AdvancedSettingsChanged(wxCommandEvent& event) g_Config.bTexFmtOverlayCenter = m_TexFmtCenter->IsChecked(); TextureMngr::Invalidate(false); break; - case ID_USEXFB: - g_Config.bUseXFB = m_UseXFB->IsChecked(); - break; case ID_WIREFRAME: g_Config.bWireFrame = m_Wireframe->IsChecked(); break; @@ -532,12 +528,14 @@ void ConfigDialog::AdvancedSettingsChanged(wxCommandEvent& event) case ID_SAFETEXTURECACHE: g_Config.bSafeTextureCache = m_SafeTextureCache->IsChecked(); break; - // Extented frame buffer + + // External frame buffer case ID_RADIO_COPYEFBTORAM: TextureMngr::ClearRenderTargets(); g_Config.bCopyEFBToRAM = true; break; case ID_RADIO_COPYEFBTOGL: + TextureMngr::ClearRenderTargets(); g_Config.bCopyEFBToRAM = false; break; case ID_BLENDSTATS: @@ -563,11 +561,14 @@ void ConfigDialog::TexturePathChange(wxFileDirPickerEvent& event) void ConfigDialog::UpdateGUI() { - // This option is only compatible with the Strech To Fit option - m_KeepAR43->Enable(g_Config.bStretchToFit); - m_KeepAR169->Enable(g_Config.bStretchToFit); // This is only used together with the aspect ratio options - m_Crop->Enable(g_Config.bStretchToFit && (g_Config.bKeepAR43 || g_Config.bKeepAR169)); + m_Crop->Enable(g_Config.bKeepAR43 || g_Config.bKeepAR169); + if (g_Config.bUseXFB) { + // XFB looks much better if the copy comes from native resolution. + g_Config.bNativeResolution = true; + m_NativeResolution->SetValue(true); + } + m_AutoScale->Enable(!g_Config.bUseXFB); // These options are for the separate rendering window m_Fullscreen->Enable(!g_Config.renderToMainframe); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h index 27fdf71e73..882338059b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h @@ -45,7 +45,6 @@ class ConfigDialog : public wxDialog void AddFSReso(char *reso); void AddWindowReso(char *reso); - void AddRenderBackend(const char *backend); void AddAAMode(int mode); void CreateGUIControls(); @@ -77,16 +76,16 @@ class ConfigDialog : public wxDialog wxPanel *m_PageAdvanced; wxCheckBox *m_Fullscreen; wxCheckBox *m_RenderToMainWindow; - wxCheckBox *m_StretchToFit; + wxCheckBox *m_NativeResolution; wxCheckBox *m_KeepAR43, *m_KeepAR169, *m_Crop; + wxCheckBox *m_UseXFB; + wxCheckBox *m_AutoScale; #ifndef _WIN32 wxCheckBox *m_HideCursor; #endif wxComboBox *m_FullscreenCB; wxArrayString arrayStringFor_WindowResolutionCB; wxComboBox *m_WindowResolutionCB; - wxArrayString arrayStringFor_RenderBackend; - wxComboBox *m_RenderBackend; wxCheckBox *m_ForceFiltering; // advanced wxChoice *m_MaxAnisotropyCB; @@ -99,7 +98,6 @@ class ConfigDialog : public wxDialog wxCheckBox *m_ProjStats; wxCheckBox *m_TexFmtOverlay; wxCheckBox *m_TexFmtCenter; - wxCheckBox *m_UseXFB; wxCheckBox *m_Wireframe; wxCheckBox *m_DisableLighting; wxCheckBox *m_DisableTexturing; @@ -128,15 +126,16 @@ class ConfigDialog : public wxDialog ID_FULLSCREEN, ID_RENDERTOMAINWINDOW, - ID_STRETCHTOFIT, + ID_NATIVERESOLUTION, ID_KEEPAR_4_3, ID_KEEPAR_16_9, ID_CROP, + ID_USEXFB, + ID_AUTOSCALE, + ID_HIDECURSOR, ID_FSTEXT, ID_FULLSCREENCB, ID_WMTEXT, ID_WINDOWRESOLUTIONCB, - ID_BETEXT, - ID_RENDERBACKEND, ID_FORCEFILTERING, ID_MAXANISOTROPY, @@ -151,7 +150,6 @@ class ConfigDialog : public wxDialog ID_TEXFMTOVERLAY, ID_TEXFMTCENTER, - ID_USEXFB, ID_WIREFRAME, ID_DISABLELIGHTING, ID_DISABLETEXTURING, diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 7d24627f4a..3eb09b3eda 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -152,7 +152,7 @@ FRAGMENTSHADER* PixelShaderCache::GetShader() return pShaderLast; } -void PixelShaderCache::Cleanup() +void PixelShaderCache::ProgressiveCleanup() { PSCache::iterator iter = pshaders.begin(); while (iter != pshaders.end()) { @@ -168,14 +168,14 @@ void PixelShaderCache::Cleanup() else iter++; } - SETSTAT(stats.numPixelShadersAlive,(int)pshaders.size()); + SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size()); } bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram) { - char stropt[64]; + char stropt[128]; sprintf(stropt, "MaxLocalParams=32,NumInstructionSlots=%d", s_nMaxPixelInstructions); - const char* opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; + const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts); if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { ERROR_LOG(VIDEO, "Failed to create ps %s:\n", cgGetLastListing(g_cgcontext)); @@ -183,18 +183,20 @@ bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpr return false; } + // This looks evil - we modify the program through the const char * we got from cgGetProgramString! + // It SHOULD not have any nasty side effects though - but you never know... char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); char *plocal = strstr(pcompiledprog, "program.local"); while (plocal != NULL) { - const char* penv = " program.env"; + const char *penv = " program.env"; memcpy(plocal, penv, 13); plocal = strstr(plocal+13, "program.local"); } if (Renderer::IsUsingATIDrawBuffers()) { - // sometimes compilation can use ARB_draw_buffers, which would fail for ATI cards - // replace the three characters ARB with ATI. TODO - check whether this is fixed in modern ATI drivers. - char* poptions = strstr(pcompiledprog, "ARB_draw_buffers"); + // Sometimes compilation can use ARB_draw_buffers, which would fail for ATI cards. + // Replace the three characters ARB with ATI. TODO - check whether this is fixed in modern ATI drivers. + char *poptions = strstr(pcompiledprog, "ARB_draw_buffers"); if (poptions != NULL) { poptions[0] = 'A'; poptions[1] = 'T'; @@ -202,9 +204,9 @@ bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpr } } - glGenProgramsARB( 1, &ps.glprogid ); - glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, ps.glprogid ); - glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); + glGenProgramsARB(1, &ps.glprogid); + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ps.glprogid); + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); GLenum err = GL_NO_ERROR; GL_REPORT_ERROR(); @@ -214,7 +216,6 @@ bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpr } cgDestroyProgram(tempprog); - // printf("Compiled pixel shader %i\n", ps.glprogid); #if defined(_DEBUG) || defined(DEBUGFAST) ps.strprog = pstrprogram; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h index c1857117b1..0a544e1f84 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h @@ -53,7 +53,7 @@ class PixelShaderCache public: static void Init(); - static void Cleanup(); + static void ProgressiveCleanup(); static void Shutdown(); static FRAGMENTSHADER* GetShader(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 93ff2e97a5..d5ef947ca2 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -41,6 +41,8 @@ #include "VertexShaderGen.h" #include "PixelShaderCache.h" #include "PixelShaderManager.h" +#include "VertexShaderCache.h" +#include "VertexShaderManager.h" #include "VertexLoaderManager.h" #include "VertexLoader.h" #include "XFB.h" @@ -82,14 +84,23 @@ static GLuint s_ZBufferTarget = 0; static bool s_bATIDrawBuffers = false; static bool s_bHaveStencilBuffer = false; +static bool s_bHaveFramebufferBlit = false; -static bool s_bScreenshot = false; +static volatile bool s_bScreenshot = false; static Common::CriticalSection s_criticalScreenshot; static std::string s_sScreenshotName; static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal; bool g_bBlendSeparate = false; + int frameCount; +static int s_fps = 0; + +// These STAY CONSTANT during execution, no matter how much you resize the game window. +static int s_targetwidth; // Size of render buffer FBO. +static int s_targetheight; + +static u32 s_blendMode; void HandleCgError(CGcontext ctx, CGerror err, void *appdata); @@ -110,70 +121,70 @@ static const GLenum glDestFactors[8] = { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA }; -static u32 s_blendMode; - bool Renderer::Init() { bool bSuccess = true; - int numvertexattribs = 0; + s_blendMode = 0; + GLint numvertexattribs = 0; GLenum err = GL_NO_ERROR; g_cgcontext = cgCreateContext(); cgGetError(); cgSetErrorHandler(HandleCgError, NULL); - // fill the opengl extension map - const char* ptoken = (const char*)glGetString(GL_EXTENSIONS); - if (ptoken == NULL) return false; - + // Look for required extensions. + const char *ptoken = (const char*)glGetString(GL_EXTENSIONS); + if (!ptoken) + { + PanicAlert("Failed to get OpenGL extension string. Do you have OpenGL drivers installed?"); + return false; + } INFO_LOG(VIDEO, "Supported OpenGL Extensions:\n"); INFO_LOG(VIDEO, ptoken); // write to the log file INFO_LOG(VIDEO, "\n"); if (GLEW_EXT_blend_func_separate && GLEW_EXT_blend_equation_separate) g_bBlendSeparate = true; - - //Checks if it ONLY has the ATI_draw_buffers extension, some have both + // Checks if it ONLY has the ATI_draw_buffers extension, some have both if (GLEW_ATI_draw_buffers && !GLEW_ARB_draw_buffers) s_bATIDrawBuffers = true; s_bFullscreen = g_Config.bFullscreen; - if (glewInit() != GLEW_OK) { - ERROR_LOG(VIDEO, "glewInit() failed!\nDoes your video card support OpenGL 2.x?"); - return false; - } - - if (!GLEW_EXT_framebuffer_object) { - ERROR_LOG(VIDEO, "*********\nGPU: ERROR: Need GL_EXT_framebufer_object for multiple render targets\nGPU: *********\nDoes your video card support OpenGL 2.x?"); - bSuccess = false; - } - - if (!GLEW_EXT_secondary_color) { - ERROR_LOG(VIDEO, "*********\nGPU: OGL ERROR: Need GL_EXT_secondary_color\nGPU: *********\nDoes your video card support OpenGL 2.x?"); - bSuccess = false; - } - - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, (GLint *)&numvertexattribs); - + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &numvertexattribs); if (numvertexattribs < 11) { ERROR_LOG(VIDEO, "*********\nGPU: OGL ERROR: Number of attributes %d not enough\nGPU: *********\nDoes your video card support OpenGL 2.x?", numvertexattribs); bSuccess = false; } + // Init extension support. + if (glewInit() != GLEW_OK) { + ERROR_LOG(VIDEO, "glewInit() failed!\nDoes your video card support OpenGL 2.x?"); + return false; + } + if (!GLEW_EXT_framebuffer_object) { + ERROR_LOG(VIDEO, "*********\nGPU: ERROR: Need GL_EXT_framebufer_object for multiple render targets\nGPU: *********\nDoes your video card support OpenGL 2.x?"); + bSuccess = false; + } + if (!GLEW_EXT_secondary_color) { + ERROR_LOG(VIDEO, "*********\nGPU: OGL ERROR: Need GL_EXT_secondary_color\nGPU: *********\nDoes your video card support OpenGL 2.x?"); + bSuccess = false; + } + s_bHaveFramebufferBlit = GLEW_EXT_framebuffer_blit ? true : false; + if (!bSuccess) return false; #ifdef _WIN32 - if (WGLEW_EXT_swap_control) - wglSwapIntervalEXT(0); - else - ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)\nDoes your video card support OpenGL 2.x?"); + if (WGLEW_EXT_swap_control) + wglSwapIntervalEXT(0); + else + ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)\nDoes your video card support OpenGL 2.x?"); #elif defined(HAVE_X11) && HAVE_X11 - if (glXSwapIntervalSGI) - glXSwapIntervalSGI(0); - else - ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)\n"); + if (glXSwapIntervalSGI) + glXSwapIntervalSGI(0); + else + ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)\n"); #else //TODO @@ -186,7 +197,6 @@ bool Renderer::Init() if (max_texture_size < 1024) { ERROR_LOG(VIDEO, "GL_MAX_TEXTURE_SIZE too small at %i - must be at least 1024", max_texture_size); } - GL_REPORT_ERROR(); if (err != GL_NO_ERROR) bSuccess = false; @@ -204,16 +214,17 @@ bool Renderer::Init() // The size of the framebuffer targets should really NOT be the size of the OpenGL viewport. // The EFB is larger than 640x480 - in fact, it's 640x528, give or take a couple of lines. // So the below is wrong. - int nBackbufferWidth = (int)OpenGL_GetWidth(); - int nBackbufferHeight = (int)OpenGL_GetHeight(); - - // Create the framebuffer target + // This should really be grabbed from config rather than from OpenGL. + s_targetwidth = (int)OpenGL_GetBackbufferWidth(); + s_targetheight = (int)OpenGL_GetBackbufferHeight(); + + // Create the framebuffer target texture glGenTextures(1, (GLuint *)&s_RenderTarget); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget); // Setup the texture params // initialize to default - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, nBackbufferWidth, nBackbufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, s_targetwidth, s_targetheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (glGetError() != GL_NO_ERROR) { @@ -226,16 +237,14 @@ bool Renderer::Init() GL_REPORT_ERROR(); - int nMaxMRT = 0; - glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, (GLint *)&nMaxMRT); - + GLint nMaxMRT = 0; + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &nMaxMRT); if (nMaxMRT > 1) { - // create zbuffer target + // Create zbuffer target. glGenTextures(1, (GLuint *)&s_ZBufferTarget); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, nBackbufferWidth, nBackbufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, s_targetwidth, s_targetheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (glGetError() != GL_NO_ERROR) { @@ -248,13 +257,12 @@ bool Renderer::Init() } // create the depth buffer - glGenRenderbuffersEXT(1, (GLuint *)&s_DepthTarget); + glGenRenderbuffersEXT(1, &s_DepthTarget); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, nBackbufferWidth, nBackbufferHeight); - + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, s_targetwidth, s_targetheight); if (glGetError() != GL_NO_ERROR) { - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nBackbufferWidth, nBackbufferHeight); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, s_targetwidth, s_targetheight); s_bHaveStencilBuffer = false; } else @@ -264,7 +272,7 @@ bool Renderer::Init() GL_REPORT_ERROR(); - // set as render targets + // Select our render and depth targets as render targets. glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget, 0); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget); @@ -283,10 +291,7 @@ bool Renderer::Init() } if (s_ZBufferTarget == 0) - ERROR_LOG(VIDEO, "disabling ztarget mrt feature (max mrt=%d)\n", nMaxMRT); - - // Why is this left here? - //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget); + ERROR_LOG(VIDEO, "Disabling ztarget MRT feature (max MRT = %d)\n", nMaxMRT); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); nZBufferRender = 0; @@ -313,17 +318,17 @@ bool Renderer::Init() cgGLSetOptimalOptions(g_cgvProf); cgGLSetOptimalOptions(g_cgfProf); - //ERROR_LOG(VIDEO, "max buffer sizes: %d %d\n", cgGetProgramBufferMaxSize(g_cgvProf), cgGetProgramBufferMaxSize(g_cgfProf)); + INFO_LOG(VIDEO, "Max buffer sizes: %d %d\n", cgGetProgramBufferMaxSize(g_cgvProf), cgGetProgramBufferMaxSize(g_cgfProf)); int nenvvertparams, nenvfragparams, naddrregisters[2]; glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, (GLint *)&nenvvertparams); glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, (GLint *)&nenvfragparams); glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, (GLint *)&naddrregisters[0]); glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, (GLint *)&naddrregisters[1]); - DEBUG_LOG(VIDEO, "max program env parameters: vert=%d, frag=%d\n", nenvvertparams, nenvfragparams); - DEBUG_LOG(VIDEO, "max program address register parameters: vert=%d, frag=%d\n", naddrregisters[0], naddrregisters[1]); + DEBUG_LOG(VIDEO, "Max program env parameters: vert=%d, frag=%d\n", nenvvertparams, nenvfragparams); + DEBUG_LOG(VIDEO, "Max program address register parameters: vert=%d, frag=%d\n", naddrregisters[0], naddrregisters[1]); if (nenvvertparams < 238) - ERROR_LOG(VIDEO, "not enough vertex shader environment constants!!\n"); + ERROR_LOG(VIDEO, "Not enough vertex shader environment constants!!\n"); #ifndef _DEBUG cgGLSetDebugMode(GL_FALSE); @@ -342,6 +347,7 @@ bool Renderer::Init() XFB_Init(); return glGetError() == GL_NO_ERROR && bSuccess; } + void Renderer::Shutdown(void) { delete s_pfont; @@ -421,15 +427,25 @@ bool Renderer::InitializeGL() // ------------------------ int Renderer::GetTargetWidth() { - return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth()); + return (g_Config.bNativeResolution ? 640 : s_targetwidth); } int Renderer::GetTargetHeight() { - return (g_Config.bStretchToFit ? 480 : (int)OpenGL_GetHeight()); + return (g_Config.bNativeResolution ? 480 : s_targetheight); } -///////////////////////////// +float Renderer::GetTargetScaleX() +{ + return (float)GetTargetWidth() / 640.0f; +} + +float Renderer::GetTargetScaleY() +{ + return (float)GetTargetHeight() / 480.0f; +} + +///////////////////////////// void Renderer::SetRenderTarget(GLuint targ) { @@ -573,8 +589,8 @@ bool Renderer::SetScissorRect() { int xoff = bpmem.scissorOffset.x * 2 - 342; int yoff = bpmem.scissorOffset.y * 2 - 342; - float MValueX = OpenGL_GetXmax(); - float MValueY = OpenGL_GetYmax(); + float MValueX = GetTargetScaleX(); + float MValueY = GetTargetScaleY(); float rc_left = (float)bpmem.scissorTL.x - xoff - 342; // left = 0 rc_left *= MValueX; if (rc_left < 0) rc_left = 0; @@ -660,11 +676,11 @@ void Renderer::FlushZBufferAlphaToTarget() // TODO: This code should not have to bother with stretchtofit checking - // all necessary scale initialization should be done elsewhere. // TODO: Investigate BlitFramebufferEXT. - if (g_Config.bStretchToFit) + if (g_Config.bNativeResolution) { //TODO: Do Correctly in a bit - float FactorW = 640.f / (float)OpenGL_GetWidth(); - float FactorH = 480.f / (float)OpenGL_GetHeight(); + float FactorW = 640.f / (float)OpenGL_GetBackbufferWidth(); + float FactorH = 480.f / (float)OpenGL_GetBackbufferHeight(); float Max = (FactorW < FactorH) ? FactorH : FactorW; float Temp = 1.0f / Max; @@ -763,181 +779,48 @@ Renderer::RenderMode Renderer::GetRenderMode() return s_RenderMode; } - -////////////////////////////////////////////////////////////////////////////////////// -// This function has the final picture if the XFB functions are not used. We adjust the aspect ratio here. -// ---------------------- -void Renderer::Swap(const TRectangle& rc) +void ComputeBackbufferRectangle(TRectangle *rc) { - OpenGL_Update(); // just updates the render window position and the backbuffer size - - DVSTARTPROFILE(); - - Renderer::SetRenderMode(Renderer::RM_Normal); - -#if 0 - // Blit the FBO to do Anti-Aliasing - // Not working? - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); - glBlitFramebufferEXT(0, 0, 640, 480, 0, 0, OpenGL_GetWidth(), OpenGL_GetHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer); - -#else - // render to the real buffer now - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer - // ----------------------------------------------------------------------- // GLViewPort variables // ------------------ - /* Work with float values for the XFB supplement and aspect ratio functions. These are default - values that are used if the XFB supplement and the keep aspect ratio function are unused */ - float FloatGLWidth = (float)OpenGL_GetWidth(); - float FloatGLHeight = (float)OpenGL_GetHeight(); - float FloatXOffset = 0, FloatYOffset = 0; - // ------------------------------------- - - - // ----------------------------------------------------------------------- - // XFB supplement, fix the black borders problem - // ------------------ - /* I'm limiting it to the stretch to fit option because I don't know how the other mode works. The reason - I don't allow this option together with UseXFB is that they are supplements and the XFB function - should be able to produce the same result */ - if(g_Config.bStretchToFit && !g_Config.bUseXFB) - { - // The rendering window size - float WinWidth = (float)OpenGL_GetWidth(); - float WinHeight = (float)OpenGL_GetHeight(); - - // The fraction of the screen that the image occupies - // Rc.right and rc.bottom is the original picture pixel size - /* There is a +1 in Rc (earlier called multirc, the input to this function), but these - adjustments seems to work better without it. */ - float WidthRatio = (float)(rc.right - 1) / 640.0f; - float HeightRatio = (float)(rc.bottom - 1) / 480.0f; - - // The pixel size of the image on the screen, adjusted for the actual window size - float OldWidth = WidthRatio * (float)WinWidth; - float OldHeight = HeightRatio * (float)WinHeight; - - // The adjusted width and height - FloatGLWidth = ceil((float)WinWidth / WidthRatio); - FloatGLHeight = ceil((float)WinHeight / HeightRatio); - - // The width and height deficit in actual pixels - float WidthDeficit = (float)WinWidth - OldWidth; - float HeightDeficit = (float)WinHeight - OldHeight; - - // The picture will be drawn from the bottom so we need this YOffset - // The X-axis needs no adjustment because the picture begins from the left - FloatYOffset = -HeightDeficit / HeightRatio; - - // ----------------------------------------------------------------------- - // Logging - // ------------------ - /* - Console::ClearScreen(); - Console::Print("Bpmem L:%i T:%i X:%i Y:%i\n", bpmem.copyTexSrcXY.x, bpmem.copyTexSrcXY.y, bpmem.copyTexSrcWH.x, bpmem.copyTexSrcWH.y); - Console::Print("Input Left:%i Top:%i Right:%i Bottom:%i\n", rc.left, rc.top, rc.right, rc.bottom); - Console::Print("Old picture: Width[%1.2f]:%4.0f Height[%1.2f]:%4.0f\n", WidthRatio, OldWidth, HeightRatio, OldHeight); - Console::Print("New picture: Width[%1.2f]:%4.0f Height[%1.2f]:%4.0f YOffset:%4.0f YDeficit:%4.0f\n", WidthRatio, WinWidth, HeightRatio, WinHeight, FloatYOffset, HeightDeficit); - Console::Print("----------------------------------------------------------------\n"); - */ - // ------------------------------ - } - // ------------------------------ - - - - // ----------------------------------------------------------------------- - /* Keep aspect ratio at 4:3. This may be interesting if you for example have a 5:4 screen but don't like - the stretching, and would rather have a letterbox. */ - // Output: GLWidth, GLHeight, XOffset, YOffset - // ------------------ + // Work with float values for the XFB supplement and aspect ratio functions. These are default + // values that are used if the XFB supplement and the keep aspect ratio function are unused. + float FloatGLWidth = (float)OpenGL_GetBackbufferWidth(); + float FloatGLHeight = (float)OpenGL_GetBackbufferHeight(); + float FloatXOffset = 0; + float FloatYOffset = 0; // The rendering window size - float WinWidth = (float)OpenGL_GetWidth(); - float WinHeight = (float)OpenGL_GetHeight(); - // The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio - float Ratio = WinWidth / WinHeight / (g_Config.bKeepAR43 ? (4.0f / 3.0f) : (16.0f / 9.0f)); - float wAdj, hAdj; - // Actual pixel size of the picture after adjustment - float PictureWidth = WinWidth, PictureHeight = WinHeight; + const float WinWidth = FloatGLWidth; + const float WinHeight = FloatGLHeight; - // This function currently only works together with the Stretch To Fit option - if ((g_Config.bKeepAR43 || g_Config.bKeepAR169) && g_Config.bStretchToFit) + // Handle aspect ratio. + if (g_Config.bKeepAR43 || g_Config.bKeepAR169) { + // The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio + float Ratio = (WinWidth / WinHeight) / (g_Config.bKeepAR43 ? (4.0f / 3.0f) : (16.0f / 9.0f)); // Check if height or width is the limiting factor. If ratio > 1 the picture is to wide and have to limit the width. if (Ratio > 1) { - // ------------------------------------------------ - // Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen - // ---------------- - wAdj = Ratio; - hAdj = 1.0; - FloatGLWidth = FloatGLWidth / wAdj; - FloatGLHeight = FloatGLHeight / hAdj; - // -------------------- - - // ------------------------------------------------ - // Calculate the new X offset - // ---------------- - // The picture width - PictureWidth = WinWidth / Ratio; - // Move the left of the picture to the middle of the screen - FloatXOffset = FloatXOffset + WinWidth / 2.0f; - // Then remove half the picture height to move it to the horizontal center - FloatXOffset = FloatXOffset - PictureWidth / 2.0f; - // -------------------- + // Scale down and center in the X direction. + FloatGLWidth /= Ratio; + FloatXOffset = (WinWidth - FloatGLWidth) / 2.0f; } - // The window is to high, we have to limit the height + // The window is too high, we have to limit the height else { - // ------------------------------------------------ - // Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen - // ---------------- - // Invert the ratio to make it > 1 - Ratio = 1.0f / Ratio; - wAdj = 1.0f; - hAdj = Ratio; - FloatGLWidth = FloatGLWidth / wAdj; - FloatGLHeight = FloatGLHeight / hAdj; - // -------------------- - - // ------------------------------------------------ - // Calculate the new Y offset - // ---------------- - // The picture height - PictureHeight = WinHeight / Ratio; - // Keep the picture on the bottom of the screen, this is needed because YOffset may not be 0 here - FloatYOffset = FloatYOffset / hAdj; - // Move the bottom of the picture to the middle of the screen - FloatYOffset = FloatYOffset + WinHeight / 2.0f; - // Then remove half the picture height to move it to the vertical center - FloatYOffset = FloatYOffset - PictureHeight / 2.0f; - // -------------------- + // Scale down and center in the Y direction. + FloatGLHeight *= Ratio; + FloatYOffset = FloatYOffset + (WinHeight - FloatGLHeight) / 2.0f; } - - // ----------------------------------------------------------------------- - // Logging - // ------------------ - /* - Console::Print("Screen Width:%4.0f Height:%4.0f Ratio:%1.2f\n", WinWidth, WinHeight, Ratio); - Console::Print("GL Width:%4.1f Height:%4.1f\n", FloatGLWidth, FloatGLHeight); - Console::Print("Picture Width:%4.1f Height:%4.1f YOffset:%4.0f\n", PictureWidth, PictureHeight, FloatYOffset); - Console::Print("----------------------------------------------------------------\n"); - */ - // ------------------------------ } - // ------------------------------------- - // ----------------------------------------------------------------------- /* Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10. */ // Output: FloatGLWidth, FloatGLHeight, FloatXOffset, FloatYOffset // ------------------ - if ((g_Config.bKeepAR43 || g_Config.bKeepAR169) && g_Config.bStretchToFit && g_Config.bCrop) + if ((g_Config.bKeepAR43 || g_Config.bKeepAR169) && g_Config.bCrop) { float Ratio = g_Config.bKeepAR43 ? ((4.0 / 3.0) / (5.0 / 4.0)) : (((16.0 / 9.0) / (16.0 / 10.0))); // The width and height we will add (calculate this before FloatGLWidth and FloatGLHeight is adjusted) @@ -946,47 +829,47 @@ void Renderer::Swap(const TRectangle& rc) // The new width and height FloatGLWidth = FloatGLWidth * Ratio; FloatGLHeight = FloatGLHeight * Ratio; - // Wee need this adjustment to, the -6 adjustment was needed to never show any pixels outside the actual picture + // We need this adjustment too, the -6 adjustment was needed to never show any pixels outside the actual picture // The result in offset in actual pixels is only around 1 or 2 pixels in a 1280 x 1024 resolution. In 1280 x 1024 the // picture is only about 2 to 4 pixels (1 up and 1 down for example) to big to produce a minimal margin // of error, while rather having a full screen and hiding one pixel, than having a one pixel black border. But it seems // to be just enough in all games I tried. - float WidthRatio = ((float)rc.right - 6.0) / 640.0; - float HeightRatio = ((float)rc.bottom - 6.0) / 480.0; + float WidthRatio = ((float)FloatGLWidth - 6.0) / 640.0; + float HeightRatio = ((float)FloatGLHeight - 6.0) / 480.0; // Adjust the X and Y offset FloatXOffset = FloatXOffset - (IncreasedWidth / 2.0 / WidthRatio / Ratio); FloatYOffset = FloatYOffset - (IncreasedHeight / 2.0 / HeightRatio / Ratio); //Console::Print("Crop Ratio:%1.2f IncreasedHeight:%3.0f YOffset:%3.0f\n", Ratio, IncreasedHeight, FloatYOffset); } - // ------------------------------------- + // Because there is no round() function we use round(float) = floor(float + 0.5) instead + int XOffset = floor(FloatXOffset + 0.5); + int YOffset = floor(FloatYOffset + 0.5); + rc->left = XOffset; + rc->top = YOffset; + rc->right = XOffset + ceil(FloatGLWidth); + rc->bottom = YOffset + ceil(FloatGLHeight); +} - // ----------------------------------------------------------------------- - /* Adjustments to - FloatGLWidth - FloatGLHeight - XOffset - YOffset - are done. Calculate the new new windows width and height. */ - // -------------------- - int GLx = OpenGL_GetXoff(); // These two are zero - int GLy = OpenGL_GetYoff(); - int GLWidth = ceil(FloatGLWidth); - int GLHeight = ceil(FloatGLHeight); +////////////////////////////////////////////////////////////////////////////////////// +// This function has the final picture if the XFB functions are not used. We adjust the aspect ratio here. +// ---------------------- +void Renderer::Swap(const TRectangle& rc) +{ + OpenGL_Update(); // just updates the render window position and the backbuffer size + DVSTARTPROFILE(); - // Because there is no round() function we use round(float) = floor(float + 0.5) instead - int YOffset = floor(FloatYOffset + 0.5); - int XOffset = floor(FloatXOffset+ 0.5); - // ------------------------------------- + Renderer::SetRenderMode(Renderer::RM_Normal); + // Blit the FBO to do Anti-Aliasing + // Not working? +// glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer); +// glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); +// glBlitFramebufferEXT(0, 0, 640, 480, 0, 0, OpenGL_GetWidth(), OpenGL_GetHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST); +// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer); - // Update GLViewPort - glViewport( - GLx + XOffset, - GLy + YOffset, - GLWidth, - GLHeight - ); + // render to the real buffer now + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer // ----------------------------------------------------------------------- // Show the finished picture @@ -1003,16 +886,40 @@ void Renderer::Swap(const TRectangle& rc) for (int i = 1; i < 8; ++i) TextureMngr::DisableStage(i); + TRectangle back_rc; + ComputeBackbufferRectangle(&back_rc); + + // Update GLViewPort + glViewport( + back_rc.left, + back_rc.top, + back_rc.right - back_rc.left, + back_rc.bottom - back_rc.top + ); + GL_REPORT_ERRORD(); - // Place the texture + // Copy the framebuffer to screen. + // TODO: Use glBlitFramebufferEXT. + + float u_max; + float v_min = 0.f; + float v_max; + if (g_Config.bAutoScale) { + u_max = (rc.right - rc.left); + v_min = (float)GetTargetHeight() - (rc.bottom - rc.top); + v_max = (float)GetTargetHeight(); + } else { + u_max = (float)GetTargetWidth(); + v_max = (float)GetTargetHeight(); // TODO - when we change the target height to 528, this will have to change. + } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(-1,-1); - glTexCoord2f(0, (float)GetTargetHeight()); glVertex2f(-1,1); - glTexCoord2f((float)GetTargetWidth(), (float)GetTargetHeight()); glVertex2f(1,1); - glTexCoord2f((float)GetTargetWidth(), 0); glVertex2f(1,-1); - glEnd(); + glBegin(GL_QUADS); + glTexCoord2f(0, v_min); glVertex2f(-1, -1); + glTexCoord2f(0, v_max); glVertex2f(-1, 1); + glTexCoord2f(u_max, v_max); glVertex2f( 1, 1); + glTexCoord2f(u_max, v_min); glVertex2f( 1, -1); + glEnd(); // Wireframe if (g_Config.bWireFrame) @@ -1022,68 +929,16 @@ void Renderer::Swap(const TRectangle& rc) TextureMngr::DisableStage(0); // ------------------------------------- - - // ----------------------------------------------------------------------- - /* Blacken out the borders in the 4:3 or 16:9 aspect ratio modes. Somewhere in BPStructs 0x52 or - elsewhere the area outside the actual picture, that we now show with the aspect ratio option - has been filled with either for example white, or have copies of old renderings on it. So we - replace that with blacknes. - - We are not supposed to need this with the Crop option and in full screen, but we can keep it for the - window mode, since the border can still be seen then - */ - // -------------------- - if(g_Config.bKeepAR43 || g_Config.bKeepAR169) - { - // Set current drawing color to black - glColor3f(0.0, 0.0, 0.0); - - /* This doesn't work - glRecti, glRectf( - (float)Left, - (float)Right, - (float)Top, - (float)Bottom); */ - - /* The glVertex3f() coordinates are: - Top: 1 to -1 from top to bottom - Left: 1 to -1 from right to left - Height and width is therefore 2.0, zero is the center of the screen - */ - // The fraction of the screen that the image occupies - /* It's hard to make a border that always exactly begin where the screen ends. The ( -1) here will - sometimes hide one pixel to many, but if we use (- 0) we will on the other hand sometimes show - one line of pixels that we should not show. But a -0.5 adjustment seemed just right, it never hid - one pixel to much, and never one to little. So I settle with a -0.5 adjustment here. */ - float HeightRatio = (((float)(rc.bottom)) - 0.5) / 480.0f; - - // Bottom border - float FLeft = 1.0, - FWidth = -2.0, - FHeight = 2.0 * (1.0 - HeightRatio), - FTop = -1.0 + FHeight; - - glBegin(GL_POLYGON); - glVertex3f (FLeft, FTop - FHeight, 0.0); - glVertex3f (FLeft + FWidth, FTop - FHeight, 0.0); - glVertex3f (FLeft + FWidth, FTop, 0.0); - glVertex3f (FLeft, FTop, 0.0); - glEnd(); - //Console::Print("Border Left:%1.3f Top:%1.3f Width:%1.3f Height:%1.3f\n", FLeft, FTop, FWidth, FHeight); - } - // ------------------------------------- - - // Take screenshot, if necessary - if(s_bScreenshot) { + // Take screenshot, if requested + if (s_bScreenshot) { s_criticalScreenshot.Enter(); - - if(SaveRenderTarget(s_sScreenshotName.c_str())) { + if (SaveRenderTarget(s_sScreenshotName.c_str(), OpenGL_GetBackbufferWidth(), OpenGL_GetBackbufferHeight())) { char msg[255]; sprintf(msg, "Saved %s\n", s_sScreenshotName.c_str()); OSD::AddMessage(msg, 2000); - } else - PanicAlert("Error while capturing screen"); - + } else { + PanicAlert("Error capturing or saving screenshot."); + } s_sScreenshotName = ""; s_bScreenshot = false; s_criticalScreenshot.Leave(); @@ -1093,42 +948,23 @@ void Renderer::Swap(const TRectangle& rc) SwapBuffers(); RestoreGLState(); -#endif - GL_REPORT_ERRORD(); + GL_REPORT_ERRORD(); g_Config.iSaveTargetId = 0; - - // for testing zbuffer targets - //Renderer::SetZBufferRender(); - //SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, GetTargetWidth(), GetTargetHeight()); + // For testing zbuffer targets. + // Renderer::SetZBufferRender(); + // SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, GetTargetWidth(), GetTargetHeight()); } //////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// We can now draw whatever we want on top of the picture. Then we copy the final picture to the output. -// ---------------------- -void Renderer::SwapBuffers() +void Renderer::DrawDebugText() { - // ----------------------------------------------------------------------- - /* Draw messages on the screen */ - // -------------------- - static int fpscount; - static int s_fps; - static unsigned long lasttime; + // Draw various messages on the screen, like FPS, statistics, etc. char debugtext_buffer[8192]; char *p = debugtext_buffer; p[0] = 0; - - ++fpscount; - if (timeGetTime() - lasttime > 1000) - { - lasttime = timeGetTime(); - s_fps = fpscount; - fpscount = 0; - } - if (g_Config.bShowFPS) { p+=sprintf(p, "FPS: %d\n", s_fps); @@ -1162,6 +998,7 @@ void Renderer::SwapBuffers() std::string text1; VertexLoaderManager::AppendListToString(&text1); + // TODO: Check for buffer overflow p+=sprintf(p,"%s",text1.c_str()); } @@ -1175,7 +1012,6 @@ void Renderer::SwapBuffers() p+=sprintf(p,"Alpha Update: %s\n", stats.alphaUpdate==1 ? "Enabled" : "Disabled"); p+=sprintf(p,"Dst Alpha Enabled: %s\n", stats.dstAlphaEnable==1 ? "Enabled" : "Disabled"); p+=sprintf(p,"Dst Alpha: %08x\n", stats.dstAlpha); - } if (g_Config.bOverlayProjStats) @@ -1202,11 +1038,29 @@ void Renderer::SwapBuffers() // Render a shadow, and then the text. Renderer::RenderText(debugtext_buffer, 21, 21, 0xDD000000); Renderer::RenderText(debugtext_buffer, 20, 20, 0xFF00FFFF); +} + +////////////////////////////////////////////////////////////////////////////////////// +// We can now draw whatever we want on top of the picture. Then we copy the final picture to the output. +// ---------------------- +void Renderer::SwapBuffers() +{ + // Count FPS. + static int fpscount = 0; + static unsigned long lasttime; + ++fpscount; + if (timeGetTime() - lasttime > 1000) + { + lasttime = timeGetTime(); + s_fps = fpscount; + fpscount = 0; + } + + DrawDebugText(); OSD::DrawMessages(); // ----------------------------- - #if defined(DVPROFILE) if (g_bWriteProfile) { //g_bWriteProfile = 0; @@ -1219,17 +1073,17 @@ void Renderer::SwapBuffers() } } #endif - // Copy the rendered frame to the real window OpenGL_SwapBuffers(); - glClearColor(0,0,0,0); + glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); GL_REPORT_ERRORD(); // Clean out old stuff from caches - PixelShaderCache::Cleanup(); + VertexShaderCache::ProgressiveCleanup(); + PixelShaderCache::ProgressiveCleanup(); TextureMngr::ProgressiveCleanup(); frameCount++; @@ -1239,7 +1093,6 @@ void Renderer::SwapBuffers() // Render to the framebuffer. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer); - if (nZBufferRender > 0) { if (--nZBufferRender == 0) { // turn off @@ -1253,8 +1106,8 @@ void Renderer::SwapBuffers() void Renderer::RenderText(const char* pstr, int left, int top, u32 color) { - int nBackbufferWidth = (int)OpenGL_GetWidth(); - int nBackbufferHeight = (int)OpenGL_GetHeight(); + int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth(); + int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight(); glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f, ((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f); s_pfont->printMultilineText(pstr, @@ -1268,51 +1121,35 @@ void Renderer::SetScreenshot(const char *filename) s_criticalScreenshot.Enter(); s_sScreenshotName = filename; s_bScreenshot = true; - s_criticalScreenshot.Leave(); } -bool Renderer::SaveRenderTarget(const char *filename) +bool Renderer::SaveRenderTarget(const char *filename, int w, int h) { - int w = (int)OpenGL_GetWidth(), h = (int)OpenGL_GetHeight(); - bool result = false; - - if(!filename) - return false; - u8 *data = (u8 *)malloc(3 * w * h); glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, data); - if (glGetError() != GL_NO_ERROR) return false; - - // Flip image - for(int y = 0; y < h / 2; y++) { - for(int x = 0; x < w; x++) { - std::swap(data[(y * w + x) * 3], - data[((h - 1 - y) * w + x) * 3]); - - std::swap(data[(y * w + x) * 3 + 1], - data[((h - 1 - y) * w + x) * 3 + 1]); - - std::swap(data[(y * w + x) * 3 + 2], - data[((h - 1 - y) * w + x) * 3 + 2]); + // Flip image upside down. Damn OpenGL. + for (int y = 0; y < h / 2; y++) + { + for(int x = 0; x < w; x++) + { + std::swap(data[(y * w + x) * 3], data[((h - 1 - y) * w + x) * 3]); + std::swap(data[(y * w + x) * 3 + 1], data[((h - 1 - y) * w + x) * 3 + 1]); + std::swap(data[(y * w + x) * 3 + 2], data[((h - 1 - y) * w + x) * 3 + 2]); } } #if defined(HAVE_WX) && HAVE_WX wxImage a(w, h, data); - a.SaveFile(wxString::FromAscii(filename), wxBITMAP_TYPE_BMP); - result = true; + bool result = true; #else - result = SaveTGA(filename, w, h, data); - + bool result = SaveTGA(filename, w, h, data); free(data); #endif - return result; } @@ -1339,60 +1176,29 @@ void UpdateViewport() (rawViewport[5] - rawViewport[2]) / 16777215.0f, rawViewport[5] / 16777215.0f);*/ // -------------------------- - - // ----------------------------------------------------------------------- - // GLViewPort variables - // ------------------ - int GLWidth, GLHeight, GLx, GLy; - float FloatGLWidth = fabs(2 * xfregs.rawViewport[0]); - float FloatGLHeight = fabs(2 * xfregs.rawViewport[1]); - - // rawViewport[0] = 320, rawViewport[1] = -240 int scissorXOff = bpmem.scissorOffset.x * 2 - 342; int scissorYOff = bpmem.scissorOffset.y * 2 - 342; // ------------------------------------- - - // ----------------------------------------------------------------------- - // Stretch picture while keeping the native resolution - // ------------------ - if (g_Config.bStretchToFit) - { - GLx = (int)(xfregs.rawViewport[3] - xfregs.rawViewport[0] - 342 - scissorXOff); - GLy = Renderer::GetTargetHeight() - ((int)(xfregs.rawViewport[4] - xfregs.rawViewport[1] - 342 - scissorYOff)); - // Round up to the nearest integer - GLWidth = (int)ceil(FloatGLWidth); - GLHeight = (int)ceil(FloatGLHeight); - } + float MValueX = Renderer::GetTargetScaleX(); + float MValueY = Renderer::GetTargetScaleY(); // ----------------------------------------------------------------------- // Stretch picture with increased internal resolution // ------------------ - else - { - float MValueX = OpenGL_GetXmax(); - float MValueY = OpenGL_GetYmax(); - - GLx = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - 342 - scissorXOff) * MValueX); - GLy = (int)ceil(Renderer::GetTargetHeight() - ((int)(xfregs.rawViewport[4] - xfregs.rawViewport[1] - 342 - scissorYOff)) * MValueY); - GLWidth = (int)ceil(abs((int)(2 * xfregs.rawViewport[0])) * MValueX); - GLHeight = (int)ceil(abs((int)(2 * xfregs.rawViewport[1])) * MValueY); - } + int GLx = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - 342 - scissorXOff) * MValueX); + int GLy = (int)ceil(Renderer::GetTargetHeight() - ((int)(xfregs.rawViewport[4] - xfregs.rawViewport[1] - 342 - scissorYOff)) * MValueY); + int GLWidth = (int)ceil(abs((int)(2 * xfregs.rawViewport[0])) * MValueX); + int GLHeight = (int)ceil(abs((int)(2 * xfregs.rawViewport[1])) * MValueY); // ------------------------------------- - // Update the view port - glViewport( - GLx, GLy, - GLWidth, GLHeight - ); + glViewport(GLx, GLy, GLWidth, GLHeight); - - // ----------------------------------------------------------------------- - // GLDepthRange - // ------------------ + // GLDepthRange - this could be a source of trouble - see the viewport hacks. double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777215.0f; double GLFar = xfregs.rawViewport[5] / 16777215.0f; glDepthRange(GLNear, GLFar); + // ------------------------------------- // Logging diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h index 4915c141a7..f9efacc1fa 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h @@ -116,6 +116,10 @@ public: static int GetTargetWidth(); static int GetTargetHeight(); + // Multiply any 0-640 / 0-480 coordinates by these when rendering. + static float GetTargetScaleX(); + static float GetTargetScaleY(); + static void SetFramebuffer(GLuint fb); static void SetZBufferRender(); // sets rendering of the zbuffer using MRTs static void SetRenderTarget(GLuint targ); // if targ is 0, sets to original render target @@ -126,11 +130,14 @@ public: // Random utilities static void RenderText(const char* pstr, int left, int top, u32 color); + static void DrawDebugText(); static void SetScreenshot(const char *filename); - static bool SaveRenderTarget(const char *filename); + static bool SaveRenderTarget(const char *filename, int w, int h); // Finish up the current frame, print some stats static void Swap(const TRectangle& rc); }; +void ComputeBackbufferRectangle(TRectangle *rc); + #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index 28cdff276c..98d0851013 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -177,7 +177,7 @@ void EncodeToRam(GLuint srcTexture, const TRectangle& sourceRc, glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture); - if(linearFilter) + if (linearFilter) { glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -198,6 +198,7 @@ void EncodeToRam(GLuint srcTexture, const TRectangle& sourceRc, glEnable(GL_FRAGMENT_PROGRAM_ARB); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader.glprogid); + // Draw... glBegin(GL_QUADS); glTexCoord2f((float)sourceRc.left, (float)sourceRc.top); glVertex2f(-1,-1); glTexCoord2f((float)sourceRc.left, (float)sourceRc.bottom); glVertex2f(-1,1); @@ -206,6 +207,7 @@ void EncodeToRam(GLuint srcTexture, const TRectangle& sourceRc, glEnd(); GL_REPORT_ERRORD(); + // .. and then readback the results. // TODO: make this less slow. glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr); GL_REPORT_ERRORD(); @@ -245,7 +247,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf u8* ptr = Memory_GetPtr(address); - u32 target = bFromZBuffer?Renderer::GetZBufferTarget():Renderer::GetRenderTarget(); + u32 target = bFromZBuffer ? Renderer::GetZBufferTarget() : Renderer::GetRenderTarget(); s32 width = source.right - source.left; s32 height = source.bottom - source.top; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index c1892a9975..4a5d3e07a9 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -660,12 +660,12 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool GL_REPORT_ERRORD(); glBegin(GL_QUADS); - float MValueX = OpenGL_GetXmax(); - float MValueY = OpenGL_GetYmax(); - glTexCoord2f((float)source->left * MValueX, Renderer::GetTargetHeight()-(float)source->bottom * MValueY); glVertex2f(-1,1); - glTexCoord2f((float)source->left * MValueX, Renderer::GetTargetHeight()-(float)source->top * MValueY); glVertex2f(-1,-1); - glTexCoord2f((float)source->right * MValueX, Renderer::GetTargetHeight()-(float)source->top * MValueY); glVertex2f(1,-1); - glTexCoord2f((float)source->right * MValueX, Renderer::GetTargetHeight()-(float)source->bottom * MValueY); glVertex2f(1,1); + float MValueX = Renderer::GetTargetScaleX(); + float MValueY = Renderer::GetTargetScaleY(); + glTexCoord2f((float)source->left * MValueX, Renderer::GetTargetHeight()-(float)source->bottom * MValueY); glVertex2f(-1, 1); + glTexCoord2f((float)source->left * MValueX, Renderer::GetTargetHeight()-(float)source->top * MValueY); glVertex2f(-1, -1); + glTexCoord2f((float)source->right * MValueX, Renderer::GetTargetHeight()-(float)source->top * MValueY); glVertex2f( 1, -1); + glTexCoord2f((float)source->right * MValueX, Renderer::GetTargetHeight()-(float)source->bottom * MValueY); glVertex2f( 1, 1); glEnd(); GL_REPORT_ERRORD(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index dec9d24657..5fc33e515f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -299,7 +299,7 @@ void Flush() if (g_Config.iLog & CONF_SAVETARGETS) { char str[128]; sprintf(str, "%sframes/targ%.3d.tga", FULL_DUMP_DIR, g_Config.iSaveTargetId); - Renderer::SaveRenderTarget(str); + Renderer::SaveRenderTarget(str, Renderer::GetTargetWidth(), Renderer::GetTargetHeight()); } #endif g_Config.iSaveTargetId++; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index c0a3af5037..902655fe22 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -109,7 +109,7 @@ VERTEXSHADER* VertexShaderCache::GetShader(u32 components) return pShaderLast; } -void VertexShaderCache::Cleanup() +void VertexShaderCache::ProgressiveCleanup() { VSCache::iterator iter = vshaders.begin(); while (iter != vshaders.end()) { @@ -142,18 +142,15 @@ bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrpr return false; } - //ERROR_LOG(VIDEO, pstrprogram); - //ERROR_LOG(VIDEO, "id: %d\n", g_Config.iSaveTargetId); - - char* pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); - char* plocal = strstr(pcompiledprog, "program.local"); - + // This looks evil - we modify the program through the const char * we got from cgGetProgramString! + // It SHOULD not have any nasty side effects though - but you never know... + char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); + char *plocal = strstr(pcompiledprog, "program.local"); while (plocal != NULL) { const char* penv = " program.env"; memcpy(plocal, penv, 13); - plocal = strstr(plocal+13, "program.local"); + plocal = strstr(plocal + 13, "program.local"); } - glGenProgramsARB(1, &vs.glprogid); glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vs.glprogid); glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); @@ -166,7 +163,6 @@ bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrpr } cgDestroyProgram(tempprog); - // printf("Compiled vertex shader %i\n", vs.glprogid); #if defined(_DEBUG) || defined(DEBUGFAST) vs.strprog = pstrprogram; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h index 266407829c..5d0ed09837 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h @@ -51,7 +51,7 @@ class VertexShaderCache public: static void Init(); - static void Cleanup(); + static void ProgressiveCleanup(); static void Shutdown(); static VERTEXSHADER* GetShader(u32 components); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp b/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp index a3c645f203..962b1bd6b8 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp @@ -59,7 +59,6 @@ static struct void XFB_SetUpdateArgs(u8* _pXFB, u32 _dwWidth, u32 _dwHeight, s32 _dwYOffset); - void XFB_Init() { glGenTextures(1, &xfb_decoded_texture); @@ -81,23 +80,22 @@ int XFB_isInit() void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt) { - u32 nBackbufferHeight = OpenGL_GetHeight(); TRectangle renderSrcRc; renderSrcRc.left = sourceRc.left; renderSrcRc.right = sourceRc.right; - renderSrcRc.top = nBackbufferHeight - sourceRc.top; - renderSrcRc.bottom = nBackbufferHeight - sourceRc.bottom; + // OpenGL upside down as usual... + renderSrcRc.top = Renderer::GetTargetHeight() - sourceRc.top; + renderSrcRc.bottom = Renderer::GetTargetHeight() - sourceRc.bottom; TextureConverter::EncodeToRamYUYV(Renderer::GetRenderTarget(), renderSrcRc, xfb_in_ram, dstWd, dstHt); } +// Draw the XFB straight to the OpenGL backbuffer. void XFB_Draw(u8 *xfb_in_ram, u32 width, u32 height, s32 yOffset) { TextureConverter::DecodeToTexture(xfb_in_ram, width, height, xfb_decoded_texture); OpenGL_Update(); // just updates the render window position and the backbuffer size - Renderer::ResetGLState(); - TextureMngr::EnableTexRECT(0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer @@ -105,8 +103,10 @@ void XFB_Draw(u8 *xfb_in_ram, u32 width, u32 height, s32 yOffset) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, xfb_decoded_texture); - glViewport(OpenGL_GetXoff(), OpenGL_GetYoff(), - (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight()); + TRectangle back_rc; + ComputeBackbufferRectangle(&back_rc); + + glViewport(back_rc.left, back_rc.top, back_rc.right - back_rc.left, back_rc.bottom - back_rc.top); GL_REPORT_ERRORD(); float w = (float)width; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/rasterfont.cpp b/Source/Plugins/Plugin_VideoOGL/Src/rasterfont.cpp index 0fd5b7c0cf..ebeaa31050 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/rasterfont.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/rasterfont.cpp @@ -136,91 +136,82 @@ GLubyte rasters[][13] = { RasterFont::RasterFont() { - // set GL modes - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - // create the raster font - fontOffset = glGenLists (128); - for (int i = 32; i < 127; i++) { - glNewList(i+fontOffset, GL_COMPILE); - glBitmap(8, 13, 0.0f, 2.0f, 10.0f, 0.0f, rasters[i-32]); - glEndList(); - } + // set GL modes + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + // create the raster font + fontOffset = glGenLists(128); + for (int i = 32; i < 127; i++) { + glNewList(i + fontOffset, GL_COMPILE); + glBitmap(8, 13, 0.0f, 2.0f, 10.0f, 0.0f, rasters[i - 32]); + glEndList(); + } } RasterFont::~RasterFont() { - glDeleteLists(fontOffset, 128); + glDeleteLists(fontOffset, 128); } void RasterFont::printString(const char *s, double x, double y, double z) { - // go to the right spot - glRasterPos3d(x, y, z); - - glPushAttrib (GL_LIST_BIT); - glListBase(fontOffset); - glCallLists((GLsizei)strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); - glPopAttrib (); + // go to the right spot + glRasterPos3d(x, y, z); + + glPushAttrib (GL_LIST_BIT); + glListBase(fontOffset); + glCallLists((GLsizei)strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); + glPopAttrib (); } void RasterFont::printCenteredString(const char *s, double y, int screen_width, double z) { - int length = (int)strlen(s); - int x = int(screen_width/2.0 - (length/2.0)*char_width); - - printString(s, x, y, z); + int length = (int)strlen(s); + int x = (int)(screen_width/2.0 - (length/2.0)*char_width); + printString(s, x, y, z); } void RasterFont::printMultilineText(const char *text, double start_x, double start_y, double z, int bbWidth, int bbHeight) { - double x=start_x; - double y=start_y; - + double x = start_x; + double y = start_y; static char temp[1024]; - char* t = temp; - - while(*text) + char *t = temp; + while (*text) { - if(*text=='\n') + if (*text == '\n') { - *t=0; - printString(temp,x,y,z); - y-=char_height * 2.0f / bbHeight; - x=start_x; - t=temp; + *t = 0; + printString(temp, x, y, z); + y -= char_height * 2.0f / bbHeight; + x = start_x; + t = temp; } - else if(*text=='\r') + else if (*text == '\r') { - t=temp; + t = temp; } - else if(*text=='\t') + else if (*text == '\t') { //todo: add tabs every something like 4*char_width - *t=0; - + *t = 0; int cpos = (int)strlen(temp); - - int newpos = (cpos+4)&(~3); - - - printString(temp,x,y,z); - - x =start_x + (char_width*newpos) * 2.0f / bbWidth; - - t=temp; - - *(t++)=' '; + int newpos = (cpos + 4) & (~3); + printString(temp, x, y, z); + x = start_x + (char_width*newpos) * 2.0f / bbWidth; + t = temp; + *t++ = ' '; } else { - *(t++)=*text; + *t++ = *text; } text++; } - if(t!=text) + + // ???? + if (t != text) { - *t=0; - printString(temp,x,y,z); + *t = 0; + printString(temp, x, y, z); } } diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index 756c5039a8..267bbfb2fd 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -100,9 +100,9 @@ void GetMousePos(float& x, float& y) // Calculate the new X offset // ---------------- // Move the left of the picture to the middle of the screen - XOffset = XOffset + WinWidth / 2.0; + XOffset = XOffset + WinWidth / 2.0f; // Then remove half the picture height to move it to the horizontal center - XOffset = XOffset - PictureWidth / 2.0; + XOffset = XOffset - PictureWidth / 2.0f; // -------------------- } // The window is to high, we have to limit the height @@ -112,7 +112,7 @@ void GetMousePos(float& x, float& y) // Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen // ---------------- // Invert the ratio to make it > 1 - Ratio = 1.0 / Ratio; + Ratio = 1.0f / Ratio; PictureHeight = WinHeight / Ratio; // -------------------- @@ -120,9 +120,9 @@ void GetMousePos(float& x, float& y) // Calculate the new Y offset // ---------------- // Move the top of the picture to the middle of the screen - YOffset = YOffset + WinHeight / 2.0; + YOffset = YOffset + WinHeight / 2.0f; // Then remove half the picture height to move it to the vertical center - YOffset = YOffset - PictureHeight / 2.0; + YOffset = YOffset - PictureHeight / 2.0f; // -------------------- } // Logging @@ -141,11 +141,11 @@ void GetMousePos(float& x, float& y) // ------------------ if ((g_Config.bKeepAR43 || g_Config.bKeepAR169) && g_Config.bCrop) { - float Ratio = g_Config.bKeepAR43 ? ((4.0 / 3.0) / (5.0 / 4.0)) : (((16.0 / 9.0) / (16.0 / 10.0))); + float Ratio = g_Config.bKeepAR43 ? ((4.0f / 3.0f) / (5.0f / 4.0f)) : (((16.0f / 9.0f) / (16.0f / 10.0f))); // The width and height we will add (calculate this before PictureWidth and PictureHeight is adjusted) - float IncreasedWidth = (Ratio - 1.0) * PictureWidth; - float IncreasedHeight = (Ratio - 1.0) * PictureHeight; + float IncreasedWidth = (Ratio - 1.0f) * PictureWidth; + float IncreasedHeight = (Ratio - 1.0f) * PictureHeight; // The new width and height PictureWidth = PictureWidth * Ratio;