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:
parent
11fd8062ad
commit
6dc4194767
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -53,7 +53,7 @@ class PixelShaderCache
|
|||
|
||||
public:
|
||||
static void Init();
|
||||
static void Cleanup();
|
||||
static void ProgressiveCleanup();
|
||||
static void Shutdown();
|
||||
|
||||
static FRAGMENTSHADER* GetShader();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -51,7 +51,7 @@ class VertexShaderCache
|
|||
|
||||
public:
|
||||
static void Init();
|
||||
static void Cleanup();
|
||||
static void ProgressiveCleanup();
|
||||
static void Shutdown();
|
||||
|
||||
static VERTEXSHADER* GetShader(u32 components);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue