OGL plugin: +Autoscale option (attempts to remove borders, even without XFB). Lots of cleanup, especially around aspect ratio and similar stuff. MP2 scanner still broken, wonder when that happened?

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2470 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-02-28 16:33:59 +00:00
parent 11fd8062ad
commit 6dc4194767
22 changed files with 460 additions and 729 deletions

View File

@ -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

View File

@ -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

View File

@ -23,6 +23,8 @@
#include <string>
#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

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -53,7 +53,7 @@ class PixelShaderCache
public:
static void Init();
static void Cleanup();
static void ProgressiveCleanup();
static void Shutdown();
static FRAGMENTSHADER* GetShader();

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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++;

View File

@ -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;

View File

@ -51,7 +51,7 @@ class VertexShaderCache
public:
static void Init();
static void Cleanup();
static void ProgressiveCleanup();
static void Shutdown();
static VERTEXSHADER* GetShader(u32 components);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;