Merge branch 'arb_framebuffer' into GLSL-master

Conflicts:
	Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp
	Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp
	Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
	Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp
	Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp
This commit is contained in:
degasus 2013-01-09 11:00:26 +01:00
commit bff02b3b73
34 changed files with 300 additions and 431 deletions

View File

@ -102,7 +102,7 @@ if(NOT MSVC)
endif(NOT MSVC) endif(NOT MSVC)
# gcc uses some optimizations which might break stuff without this flag # gcc uses some optimizations which might break stuff without this flag
add_definitions(-fno-strict-aliasing -fno-exceptions) add_definitions(-fno-strict-aliasing -fno-exceptions -Wno-psabi)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)

View File

@ -158,7 +158,7 @@ public:
case MODE_READ: x = (wchar_t*)*ptr; break; case MODE_READ: x = (wchar_t*)*ptr; break;
case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break;
case MODE_MEASURE: break; case MODE_MEASURE: break;
case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break;
} }
(*ptr) += stringLen; (*ptr) += stringLen;
} }

View File

@ -1068,8 +1068,10 @@ void XEmitter::XOR (int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(t
void XEmitter::MOV (int bits, const OpArg &a1, const OpArg &a2) void XEmitter::MOV (int bits, const OpArg &a1, const OpArg &a2)
{ {
#ifdef _DEBUG #ifdef _DEBUG
#ifndef _M_X64
_assert_msg_(DYNA_REC, !a1.IsSimpleReg() || !a2.IsSimpleReg() || a1.GetSimpleReg() != a2.GetSimpleReg(), "Redundant MOV @ %p - bug in JIT?", _assert_msg_(DYNA_REC, !a1.IsSimpleReg() || !a2.IsSimpleReg() || a1.GetSimpleReg() != a2.GetSimpleReg(), "Redundant MOV @ %p - bug in JIT?",
code); code);
#endif
#endif #endif
WriteNormalOp(this, bits, nrmMOV, a1, a2); WriteNormalOp(this, bits, nrmMOV, a1, a2);
} }

View File

@ -218,13 +218,12 @@ void DSPJitRegCache::flushRegs(DSPJitRegCache &cache, bool emit)
do { do {
movcnt = 0; movcnt = 0;
for(i = 0; i <= DSP_REG_MAX_MEM_BACKED; i++) { for(i = 0; i <= DSP_REG_MAX_MEM_BACKED; i++) {
if (cache.regs[i].loc.GetSimpleReg() != X64Reg simple = regs[i].loc.GetSimpleReg();
regs[i].loc.GetSimpleReg() && X64Reg simple_cache = cache.regs[i].loc.GetSimpleReg();
xregs[cache.regs[i].loc.GetSimpleReg()].guest_reg == DSP_REG_NONE) if (simple_cache != simple
&& xregs[simple_cache].guest_reg == DSP_REG_NONE)
{ {
movToHostReg(i, movToHostReg(i, simple_cache, true);
cache.regs[i].loc.GetSimpleReg(),
true);
movcnt++; movcnt++;
} }
} }

View File

@ -290,7 +290,7 @@ bool CEXIETHERNET::IsWriteCommand(u32 const data)
return IsMXCommand(data) ? !!(data & (1 << 30)) : !!(data & (1 << 14)); return IsMXCommand(data) ? !!(data & (1 << 30)) : !!(data & (1 << 14));
} }
char const * const CEXIETHERNET::GetRegisterName() const const char* CEXIETHERNET::GetRegisterName() const
{ {
#define STR_RETURN(x) case x: return #x; #define STR_RETURN(x) case x: return #x;

View File

@ -297,7 +297,7 @@ public:
bool IsMXCommand(u32 const data); bool IsMXCommand(u32 const data);
bool IsWriteCommand(u32 const data); bool IsWriteCommand(u32 const data);
char const * const GetRegisterName() const; const char* GetRegisterName() const;
void MXHardReset(); void MXHardReset();
void MXCommandHandler(u32 data, u32 size); void MXCommandHandler(u32 data, u32 size);
void DirectFIFOWrite(u8 *data, u32 size); void DirectFIFOWrite(u8 *data, u32 size);

View File

@ -78,7 +78,7 @@ private:
virtual void TransferByte(u8 &_uByte); virtual void TransferByte(u8 &_uByte);
bool IsWriteCommand() const { return !!(m_uAddress & (1 << 31)); } bool IsWriteCommand() const { return !!(m_uAddress & (1 << 31)); }
u32 const CommandRegion() const { return (m_uAddress & ~(1 << 31)) >> 8; } const u32 CommandRegion() const { return (m_uAddress & ~(1 << 31)) >> 8; }
void LoadFileToIPL(std::string filename, u32 offset); void LoadFileToIPL(std::string filename, u32 offset);
}; };

View File

@ -132,14 +132,12 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
if(Movie::IsPlayingInput()) if(Movie::IsPlayingInput())
{ {
Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber); Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber);
if(!Movie::IsUsingWiimote(0)) Movie::InputUpdate();
Movie::InputUpdate();
} }
else if(Movie::IsRecordingInput()) else if(Movie::IsRecordingInput())
{ {
Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber);
if(!Movie::IsUsingWiimote(0)) Movie::InputUpdate();
Movie::InputUpdate();
} }
else else
Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber);

View File

@ -173,7 +173,7 @@ bool Wiimote::Read()
return true; return true;
} }
delete rpt.first; delete[] rpt.first;
return false; return false;
} }

View File

@ -387,7 +387,7 @@ void ExecuteCommand(u32 _Address)
INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)", INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), DeviceID, Mode); pDevice->GetDeviceName().c_str(), DeviceID, Mode);
if (Memory::Read_U32(_Address + 4) == DeviceID) if (Memory::Read_U32(_Address + 4) == (u32)DeviceID)
{ {
g_FdMap[DeviceID] = pDevice; g_FdMap[DeviceID] = pDevice;
} }

View File

@ -196,7 +196,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
switch (Mode){ switch (Mode){
case 0: case 0:
{ {
if (SeekPosition >=0 && SeekPosition <= fileSize) if (SeekPosition <= fileSize)
{ {
m_SeekPos = SeekPosition; m_SeekPos = SeekPosition;
ReturnValue = m_SeekPos; ReturnValue = m_SeekPos;
@ -206,7 +206,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
case 1: case 1:
{ {
u32 wantedPos = SeekPosition+m_SeekPos; u32 wantedPos = SeekPosition+m_SeekPos;
if (wantedPos >=0 && wantedPos <= fileSize) if (wantedPos <= fileSize)
{ {
m_SeekPos = wantedPos; m_SeekPos = wantedPos;
ReturnValue = m_SeekPos; ReturnValue = m_SeekPos;
@ -216,7 +216,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
case 2: case 2:
{ {
u64 wantedPos = fileSize+m_SeekPos; u64 wantedPos = fileSize+m_SeekPos;
if (wantedPos >=0 && wantedPos <= fileSize) if (wantedPos <= fileSize)
{ {
m_SeekPos = wantedPos; m_SeekPos = wantedPos;
ReturnValue = m_SeekPos; ReturnValue = m_SeekPos;

View File

@ -789,8 +789,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{ {
static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer(); static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer();
bool* wiiMoteConnected = new bool[s_Usb->m_WiiMotes.size()]; bool* wiiMoteConnected = new bool[s_Usb->m_WiiMotes.size()];
for(unsigned int i = 0; i < s_Usb->m_WiiMotes.size(); for (unsigned int i = 0; i < s_Usb->m_WiiMotes.size(); i++)
i++) wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected(); wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
std::string tContentFile(m_ContentFile.c_str()); std::string tContentFile(m_ContentFile.c_str());
WII_IPC_HLE_Interface::Reset(true); WII_IPC_HLE_Interface::Reset(true);

View File

@ -31,7 +31,7 @@ struct NANDStat
}; };
enum { enum {
FS_RESULT_OK = 0, FS_RESULT_OK = 0,
FS_INVALID = -4, FS_INVALID = -4,
FS_DIRFILE_NOT_FOUND = -6, FS_DIRFILE_NOT_FOUND = -6,
FS_RESULT_FATAL = -101, FS_RESULT_FATAL = -101,

View File

@ -116,26 +116,26 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
p.Do(m_EventQueue); p.Do(m_EventQueue);
m_acl_pool.DoState(p); m_acl_pool.DoState(p);
for (unsigned int i = 0; i < 4; i++) for (unsigned int i = 0; i < 4; i++)
m_WiiMotes[i].DoState(p); m_WiiMotes[i].DoState(p);
// Reset the connection of real and hybrid wiimotes // Reset the connection of real and hybrid wiimotes
if (p.GetMode() == PointerWrap::MODE_READ && SConfig::GetInstance().m_WiimoteReconnectOnLoad) if (p.GetMode() == PointerWrap::MODE_READ && SConfig::GetInstance().m_WiimoteReconnectOnLoad)
{ {
for (unsigned int i = 0; i < 4; i++) for (unsigned int i = 0; i < 4; i++)
{ {
if (WIIMOTE_SRC_EMU == g_wiimote_sources[i] || WIIMOTE_SRC_NONE == g_wiimote_sources[i]) if (WIIMOTE_SRC_EMU == g_wiimote_sources[i] || WIIMOTE_SRC_NONE == g_wiimote_sources[i])
continue; continue;
// TODO: Selectively clear real wiimote messages if possible. Or create a real wiimote channel and reporting mode pre-setup to vacate the need for m_WiimoteReconnectOnLoad. // TODO: Selectively clear real wiimote messages if possible. Or create a real wiimote channel and reporting mode pre-setup to vacate the need for m_WiimoteReconnectOnLoad.
m_EventQueue.clear(); m_EventQueue.clear();
if (!m_WiiMotes[i].IsInactive()) if (!m_WiiMotes[i].IsInactive())
{ {
m_WiiMotes[i].Activate(false); m_WiiMotes[i].Activate(false);
m_WiiMotes[i].Activate(true); m_WiiMotes[i].Activate(true);
} }
else else
m_WiiMotes[i].Activate(false); m_WiiMotes[i].Activate(false);
} }
} }
} }

View File

@ -36,6 +36,7 @@
#include "HW/DVDInterface.h" #include "HW/DVDInterface.h"
#include "../../Common/Src/NandPaths.h" #include "../../Common/Src/NandPaths.h"
#include "Crypto/md5.h" #include "Crypto/md5.h"
#include "scmrev.h"
// The chunk to allocate movie data in multiples of. // The chunk to allocate movie data in multiples of.
#define DTM_BASE_LENGTH (1024) #define DTM_BASE_LENGTH (1024)
@ -72,6 +73,7 @@ std::string author = "";
u64 g_titleID = 0; u64 g_titleID = 0;
unsigned char MD5[16]; unsigned char MD5[16];
u8 bongos; u8 bongos;
u8 revision[20];
bool g_bRecordingFromSaveState = false; bool g_bRecordingFromSaveState = false;
bool g_bPolled = false; bool g_bPolled = false;
@ -687,6 +689,7 @@ void ReadHeader()
g_bClearSave = tmpHeader.bClearSave; g_bClearSave = tmpHeader.bClearSave;
bMemcard = tmpHeader.bMemcard; bMemcard = tmpHeader.bMemcard;
bongos = tmpHeader.bongos; bongos = tmpHeader.bongos;
memcpy(revision, tmpHeader.revision, ARRAYSIZE(revision));
} }
else else
{ {
@ -1132,6 +1135,7 @@ void SaveRecording(const char *filename)
strncpy((char *)header.author, author.c_str(),ARRAYSIZE(header.author)); strncpy((char *)header.author, author.c_str(),ARRAYSIZE(header.author));
memcpy(header.md5,MD5,16); memcpy(header.md5,MD5,16);
header.bongos = bongos; header.bongos = bongos;
memcpy(header.revision, revision, ARRAYSIZE(header.revision));
// TODO // TODO
header.uniqueID = 0; header.uniqueID = 0;
@ -1189,6 +1193,10 @@ void GetSettings()
if (!Core::g_CoreStartupParameter.bWii) if (!Core::g_CoreStartupParameter.bWii)
g_bClearSave = !File::Exists(SConfig::GetInstance().m_strMemoryCardA); g_bClearSave = !File::Exists(SConfig::GetInstance().m_strMemoryCardA);
bMemcard = SConfig::GetInstance().m_EXIDevice[0] == EXIDEVICE_MEMORYCARD; bMemcard = SConfig::GetInstance().m_EXIDevice[0] == EXIDEVICE_MEMORYCARD;
std::stringstream ss;
ss << std::hex << SCM_REV_STR;
ss >> revision;
} }
void CheckMD5() void CheckMD5()

View File

@ -121,7 +121,8 @@ struct DTMHeader {
u8 bongos; u8 bongos;
u8 reserved[15]; // Padding for any new config options u8 reserved[15]; // Padding for any new config options
u8 discChange[40]; // Name of iso file to switch to, for two disc games. u8 discChange[40]; // Name of iso file to switch to, for two disc games.
u8 reserved2[47]; // Make heading 256 bytes, just because we can u8 revision[20]; // Git hash
u8 reserved2[27]; // Make heading 256 bytes, just because we can
}; };
static_assert(sizeof(DTMHeader) == 256, "DTMHeader should be 256 bytes"); static_assert(sizeof(DTMHeader) == 256, "DTMHeader should be 256 bytes");

View File

@ -365,8 +365,6 @@ CFrame::CFrame(wxFrame* parent,
// --------------- // ---------------
// Manager // Manager
// wxAUI_MGR_LIVE_RESIZE does not exist in the wxWidgets 2.8.9 that comes with Ubuntu 9.04
// Could just check for wxWidgets version if it becomes a problem.
m_Mgr = new wxAuiManager(this, wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE); m_Mgr = new wxAuiManager(this, wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
m_Mgr->AddPane(m_Panel, wxAuiPaneInfo() m_Mgr->AddPane(m_Panel, wxAuiPaneInfo()

View File

@ -50,6 +50,7 @@ Core::GetWindowHandle().
#include "LogConfigWindow.h" #include "LogConfigWindow.h"
#include "FifoPlayerDlg.h" #include "FifoPlayerDlg.h"
#include "WxUtils.h" #include "WxUtils.h"
#include "Host.h"
#include "ConfigManager.h" // Core #include "ConfigManager.h" // Core
#include "Core.h" #include "Core.h"
@ -96,6 +97,8 @@ extern "C" {
#include "../resources/KDE.h" #include "../resources/KDE.h"
}; };
bool confirmStop = false;
// Create menu items // Create menu items
// --------------------- // ---------------------
void CFrame::CreateMenu() void CFrame::CreateMenu()
@ -1070,6 +1073,9 @@ void CFrame::DoPause()
// Stop the emulation // Stop the emulation
void CFrame::DoStop() void CFrame::DoStop()
{ {
if (confirmStop)
return;
m_bGameLoading = false; m_bGameLoading = false;
if (Core::GetState() != Core::CORE_UNINITIALIZED || if (Core::GetState() != Core::CORE_UNINITIALIZED ||
m_RenderParent != NULL) m_RenderParent != NULL)
@ -1082,17 +1088,23 @@ void CFrame::DoStop()
// Ask for confirmation in case the user accidentally clicked Stop / Escape // Ask for confirmation in case the user accidentally clicked Stop / Escape
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bConfirmStop) if (SConfig::GetInstance().m_LocalCoreStartupParameter.bConfirmStop)
{ {
wxMessageDialog *m_StopDlg = new wxMessageDialog( Core::EState state = Core::GetState();
confirmStop = true;
Core::SetState(Core::CORE_PAUSE);
wxMessageDialog m_StopDlg(
this, this,
_("Do you want to stop the current emulation?"), _("Do you want to stop the current emulation?"),
_("Please confirm..."), _("Please confirm..."),
wxYES_NO | wxSTAY_ON_TOP | wxICON_EXCLAMATION, wxYES_NO | wxSTAY_ON_TOP | wxICON_EXCLAMATION,
wxDefaultPosition); wxDefaultPosition);
int Ret = m_StopDlg->ShowModal(); int Ret = m_StopDlg.ShowModal();
m_StopDlg->Destroy(); confirmStop = false;
if (Ret != wxID_YES) if (Ret != wxID_YES)
{
Core::SetState(state);
return; return;
}
} }
// TODO: Show the author/description dialog here // TODO: Show the author/description dialog here
@ -1457,12 +1469,17 @@ void CFrame::ConnectWiimote(int wm_idx, bool connect)
wxString msg(wxString::Format(wxT("Wiimote %i %s"), wm_idx + 1, wxString msg(wxString::Format(wxT("Wiimote %i %s"), wm_idx + 1,
connect ? wxT("Connected") : wxT("Disconnected"))); connect ? wxT("Connected") : wxT("Disconnected")));
Core::DisplayMessage(msg.ToAscii(), 3000); Core::DisplayMessage(msg.ToAscii(), 3000);
// Wait for the wiimote to connect
while (GetUsbPointer()->AccessWiiMote(wm_idx | 0x100)->IsConnected() != connect)
{}
Host_UpdateMainFrame();
} }
} }
void CFrame::OnConnectWiimote(wxCommandEvent& event) void CFrame::OnConnectWiimote(wxCommandEvent& event)
{ {
ConnectWiimote(event.GetId() - IDM_CONNECT_WIIMOTE1, event.IsChecked()); ConnectWiimote(event.GetId() - IDM_CONNECT_WIIMOTE1, !GetUsbPointer()->AccessWiiMote((event.GetId() - IDM_CONNECT_WIIMOTE1) | 0x100)->IsConnected());
} }
// Toogle fullscreen. In Windows the fullscreen mode is accomplished by expanding the m_Panel to cover // Toogle fullscreen. In Windows the fullscreen mode is accomplished by expanding the m_Panel to cover

View File

@ -60,8 +60,6 @@ bool cInterfaceGLX::Create(void *&window_handle)
GLX_GREEN_SIZE, 8, GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8, GLX_BLUE_SIZE, 8,
GLX_DEPTH_SIZE, 24, GLX_DEPTH_SIZE, 24,
GLX_SAMPLE_BUFFERS_ARB, g_Config.iMultisampleMode != MULTISAMPLE_OFF?1:0,
GLX_SAMPLES_ARB, g_Config.iMultisampleMode != MULTISAMPLE_OFF?1:0,
None }; None };
int attrListDefault[] = { int attrListDefault[] = {

View File

@ -50,6 +50,7 @@ bool cInterfaceWX::Create(void *&window_handle)
GLWin.glCanvas->Show(true); GLWin.glCanvas->Show(true);
if (GLWin.glCtxt == NULL) // XXX dirty hack if (GLWin.glCtxt == NULL) // XXX dirty hack
GLWin.glCtxt = new wxGLContext(GLWin.glCanvas); GLWin.glCtxt = new wxGLContext(GLWin.glCanvas);
return true;
} }
bool cInterfaceWX::MakeCurrent() bool cInterfaceWX::MakeCurrent()

View File

@ -45,6 +45,10 @@
#include <wx/intl.h> #include <wx/intl.h>
#ifdef _WIN32
#include <shellapi.h>
#endif
// Nvidia drivers >= v302 will check if the application exports a global // Nvidia drivers >= v302 will check if the application exports a global
// variable named NvOptimusEnablement to know if it should run the app in high // variable named NvOptimusEnablement to know if it should run the app in high
// performance graphics mode or using the IGP. // performance graphics mode or using the IGP.
@ -264,6 +268,19 @@ bool DolphinApp::OnInit()
int w = SConfig::GetInstance().m_LocalCoreStartupParameter.iWidth; int w = SConfig::GetInstance().m_LocalCoreStartupParameter.iWidth;
int h = SConfig::GetInstance().m_LocalCoreStartupParameter.iHeight; int h = SConfig::GetInstance().m_LocalCoreStartupParameter.iHeight;
#ifdef _WIN32
if (File::Exists("www.dolphin-emulator.com.txt"))
{
File::Delete("www.dolphin-emulator.com.txt");
MessageBox(NULL,
L"This version of Dolphin was downloaded from a website stealing money from developers of the emulator. Please "
L"download Dolphin from the official website instead: http://dolphin-emu.org/",
L"Unofficial version detected", MB_OK | MB_ICONWARNING);
ShellExecute(NULL, L"open", L"http://dolphin-emu.org/?ref=badver", NULL, NULL, SW_SHOWDEFAULT);
exit(0);
}
#endif
// The following is not needed with X11, where window managers // The following is not needed with X11, where window managers
// do not allow windows to be created off the desktop. // do not allow windows to be created off the desktop.
#ifdef _WIN32 #ifdef _WIN32

View File

@ -405,6 +405,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
_3d_vision = CreateCheckBox(page_enh, _("3D Vision"), wxGetTranslation(_3d_vision_desc), vconfig.b3DVision); _3d_vision = CreateCheckBox(page_enh, _("3D Vision"), wxGetTranslation(_3d_vision_desc), vconfig.b3DVision);
_3d_vision->Show(vconfig.backend_info.bSupports3DVision); _3d_vision->Show(vconfig.backend_info.bSupports3DVision);
szr_enh->Add(_3d_vision); szr_enh->Add(_3d_vision);
szr_enh->Add(CreateCheckBox(page_enh, _("Widescreen Hack"), wxGetTranslation(ws_hack_desc), vconfig.bWidescreenHack));
// TODO: Add anaglyph 3d here // TODO: Add anaglyph 3d here
wxStaticBoxSizer* const group_enh = new wxStaticBoxSizer(wxVERTICAL, page_enh, _("Enhancements")); wxStaticBoxSizer* const group_enh = new wxStaticBoxSizer(wxVERTICAL, page_enh, _("Enhancements"));
@ -553,8 +554,6 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
szr_misc->Add(CreateCheckBox(page_advanced, _("Crop"), wxGetTranslation(crop_desc), vconfig.bCrop)); szr_misc->Add(CreateCheckBox(page_advanced, _("Crop"), wxGetTranslation(crop_desc), vconfig.bCrop));
szr_misc->Add(CreateCheckBox(page_advanced, _("Enable Hotkeys"), wxGetTranslation(hotkeys_desc), vconfig.bOSDHotKey)); szr_misc->Add(CreateCheckBox(page_advanced, _("Enable Hotkeys"), wxGetTranslation(hotkeys_desc), vconfig.bOSDHotKey));
szr_misc->Add(CreateCheckBox(page_advanced, _("Widescreen Hack"), wxGetTranslation(ws_hack_desc), vconfig.bWidescreenHack));
// Progressive Scan // Progressive Scan
{ {
wxCheckBox* const cb_prog_scan = new wxCheckBox(page_advanced, wxID_ANY, _("Enable Progressive Scan")); wxCheckBox* const cb_prog_scan = new wxCheckBox(page_advanced, wxID_ANY, _("Enable Progressive Scan"));

View File

@ -304,8 +304,7 @@ void PixelShaderManager::SetConstants()
float GC_ALIGNED16(material[4]); float GC_ALIGNED16(material[4]);
float NormalizationCoef = 1 / 255.0f; float NormalizationCoef = 1 / 255.0f;
// TODO: This code is wrong. i goes out of range for xfregs.ambColor. for (int i = 0; i < 2; ++i)
for (int i = 0; i < 4; ++i)
{ {
if (nMaterialsChanged & (1 << i)) if (nMaterialsChanged & (1 << i))
{ {
@ -319,6 +318,21 @@ void PixelShaderManager::SetConstants()
SetPSConstant4fv(C_PMATERIALS + i, material); SetPSConstant4fv(C_PMATERIALS + i, material);
} }
} }
for (int i = 0; i < 2; ++i)
{
if (nMaterialsChanged & (1 << (i + 2)))
{
u32 data = *(xfregs.matColor + i);
material[0] = ((data >> 24) & 0xFF) * NormalizationCoef;
material[1] = ((data >> 16) & 0xFF) * NormalizationCoef;
material[2] = ((data >> 8) & 0xFF) * NormalizationCoef;
material[3] = ( data & 0xFF) * NormalizationCoef;
SetPSConstant4fv(C_PMATERIALS + i + 2, material);
}
}
nMaterialsChanged = 0; nMaterialsChanged = 0;
} }

View File

@ -253,8 +253,7 @@ void VertexShaderManager::SetConstants()
float GC_ALIGNED16(material[4]); float GC_ALIGNED16(material[4]);
float NormalizationCoef = 1 / 255.0f; float NormalizationCoef = 1 / 255.0f;
// TODO: This code is wrong. i goes out of range for xfregs.ambColor. for (int i = 0; i < 2; ++i)
for (int i = 0; i < 4; ++i)
{ {
if (nMaterialsChanged & (1 << i)) if (nMaterialsChanged & (1 << i))
{ {
@ -268,6 +267,21 @@ void VertexShaderManager::SetConstants()
SetVSConstant4fv(C_MATERIALS + i, material); SetVSConstant4fv(C_MATERIALS + i, material);
} }
} }
for (int i = 0; i < 2; ++i)
{
if (nMaterialsChanged & (1 << (i + 2)))
{
u32 data = *(xfregs.matColor + i);
material[0] = ((data >> 24) & 0xFF) * NormalizationCoef;
material[1] = ((data >> 16) & 0xFF) * NormalizationCoef;
material[2] = ((data >> 8) & 0xFF) * NormalizationCoef;
material[3] = ( data & 0xFF) * NormalizationCoef;
SetVSConstant4fv(C_MATERIALS + i + 2, material);
}
}
nMaterialsChanged = 0; nMaterialsChanged = 0;
} }

View File

@ -44,17 +44,14 @@ enum
EFB_HEIGHT = 528, EFB_HEIGHT = 528,
}; };
enum // XFB width is decided by EFB copy operation. The VI can do horizontal
{ // scaling (TODO: emulate).
// XFB width is decided by EFB copy operation. The VI can do horizontal const u32 MAX_XFB_WIDTH = EFB_WIDTH;
// scaling (TODO: emulate).
MAX_XFB_WIDTH = EFB_WIDTH,
// Although EFB height is 528, 574-line XFB's can be created either with // Although EFB height is 528, 574-line XFB's can be created either with
// vertical scaling by the EFB copy operation or copying to multiple XFB's // vertical scaling by the EFB copy operation or copying to multiple XFB's
// that are next to each other in memory (TODO: handle that situation). // that are next to each other in memory (TODO: handle that situation).
MAX_XFB_HEIGHT = 574 const u32 MAX_XFB_HEIGHT = 574;
};
// Logging // Logging
// ---------- // ----------

View File

@ -26,13 +26,6 @@
namespace OGL namespace OGL
{ {
extern bool s_bHaveFramebufferBlit; // comes from Render.cpp. ugly.
static GLuint s_VBO = 0;
static GLuint s_VAO = 0;
static MathUtil::Rectangle<float> s_cached_sourcerc;
static MathUtil::Rectangle<float> s_cached_drawrc;
int FramebufferManager::m_targetWidth; int FramebufferManager::m_targetWidth;
int FramebufferManager::m_targetHeight; int FramebufferManager::m_targetHeight;
int FramebufferManager::m_msaaSamples; int FramebufferManager::m_msaaSamples;
@ -47,7 +40,7 @@ GLuint FramebufferManager::m_resolvedFramebuffer;
GLuint FramebufferManager::m_resolvedColorTexture; GLuint FramebufferManager::m_resolvedColorTexture;
GLuint FramebufferManager::m_resolvedDepthTexture; GLuint FramebufferManager::m_resolvedDepthTexture;
GLuint FramebufferManager::m_xfbFramebuffer; // Only used in MSAA mode GLuint FramebufferManager::m_xfbFramebuffer;
FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples) FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples)
{ {
@ -58,15 +51,6 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
m_resolvedColorTexture = 0; m_resolvedColorTexture = 0;
m_resolvedDepthTexture = 0; m_resolvedDepthTexture = 0;
m_xfbFramebuffer = 0; m_xfbFramebuffer = 0;
s_cached_sourcerc.bottom = -1;
s_cached_sourcerc.left = -1;
s_cached_sourcerc.right = -1;
s_cached_sourcerc.top = -1;
s_cached_drawrc.bottom = -1;
s_cached_drawrc.left = -1;
s_cached_drawrc.right = -1;
s_cached_drawrc.top = -1;
m_targetWidth = targetWidth; m_targetWidth = targetWidth;
m_targetHeight = targetHeight; m_targetHeight = targetHeight;
@ -87,7 +71,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
// Create EFB target. // Create EFB target.
glGenFramebuffersEXT(1, &m_efbFramebuffer); glGenFramebuffers(1, &m_efbFramebuffer);
if (m_msaaSamples <= 1) if (m_msaaSamples <= 1)
{ {
@ -98,20 +82,20 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
m_efbColor = glObj[0]; m_efbColor = glObj[0];
m_efbDepth = glObj[1]; m_efbDepth = glObj[1];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbColor); glBindTexture(GL_TEXTURE_RECTANGLE, m_efbColor);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbDepth); glBindTexture(GL_TEXTURE_RECTANGLE, m_efbDepth);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE, 0);
// Bind target textures to the EFB framebuffer. // Bind target textures to the EFB framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbColor, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, m_efbColor, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbDepth, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_RECTANGLE, m_efbDepth, 0);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
} }
@ -124,87 +108,66 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
// Create EFB target renderbuffers. // Create EFB target renderbuffers.
GLuint glObj[2]; GLuint glObj[2];
glGenRenderbuffersEXT(2, glObj); glGenRenderbuffers(2, glObj);
m_efbColor = glObj[0]; m_efbColor = glObj[0];
m_efbDepth = glObj[1]; m_efbDepth = glObj[1];
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbColor); glBindRenderbuffer(GL_RENDERBUFFER, m_efbColor);
if (m_msaaCoverageSamples) if (m_msaaCoverageSamples)
glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight); glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
else else
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight); glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbDepth); glBindRenderbuffer(GL_RENDERBUFFER, m_efbDepth);
if (m_msaaCoverageSamples) if (m_msaaCoverageSamples)
glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight); glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
else else
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight); glRenderbufferStorageMultisample(GL_RENDERBUFFER, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
// Bind target renderbuffers to EFB framebuffer. // Bind target renderbuffers to EFB framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_efbColor); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_efbColor);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_efbDepth); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_efbDepth);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
// Create resolved targets for transferring multisampled EFB to texture. // Create resolved targets for transferring multisampled EFB to texture.
glGenFramebuffersEXT(1, &m_resolvedFramebuffer); glGenFramebuffers(1, &m_resolvedFramebuffer);
glGenTextures(2, glObj); glGenTextures(2, glObj);
m_resolvedColorTexture = glObj[0]; m_resolvedColorTexture = glObj[0];
m_resolvedDepthTexture = glObj[1]; m_resolvedDepthTexture = glObj[1];
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture); glBindTexture(GL_TEXTURE_RECTANGLE, m_resolvedColorTexture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture); glBindTexture(GL_TEXTURE_RECTANGLE, m_resolvedDepthTexture);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE, 0);
// Bind resolved textures to resolved framebuffer. // Bind resolved textures to resolved framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_resolvedFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_resolvedFramebuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, m_resolvedColorTexture, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_RECTANGLE, m_resolvedDepthTexture, 0);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
// Return to EFB framebuffer. // Return to EFB framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
} }
// Create XFB framebuffer; targets will be created elsewhere. // Create XFB framebuffer; targets will be created elsewhere.
glGenFramebuffersEXT(1, &m_xfbFramebuffer); glGenFramebuffers(1, &m_xfbFramebuffer);
// Generate VBO & VAO - and initialize the VAO for "Draw"
glGenBuffers(1, &s_VBO);
glGenVertexArrays(1, &s_VAO);
glBindBuffer(GL_ARRAY_BUFFER, s_VBO);
glBindVertexArray(s_VAO);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 6*sizeof(GLfloat), NULL);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 6*sizeof(GLfloat), (GLfloat*)NULL+2);
glClientActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 6*sizeof(GLfloat), (GLfloat*)NULL+4);
// TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// EFB framebuffer is currently bound, make sure to clear its alpha value to 1.f // EFB framebuffer is currently bound, make sure to clear its alpha value to 1.f
glViewport(0, 0, m_targetWidth, m_targetHeight); glViewport(0, 0, m_targetWidth, m_targetHeight);
@ -216,9 +179,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms
FramebufferManager::~FramebufferManager() FramebufferManager::~FramebufferManager()
{ {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteBuffers(1, &s_VBO);
glDeleteVertexArrays(1, &s_VAO);
GLuint glObj[3]; GLuint glObj[3];
@ -227,7 +188,7 @@ FramebufferManager::~FramebufferManager()
glObj[0] = m_efbFramebuffer; glObj[0] = m_efbFramebuffer;
glObj[1] = m_resolvedFramebuffer; glObj[1] = m_resolvedFramebuffer;
glObj[2] = m_xfbFramebuffer; glObj[2] = m_xfbFramebuffer;
glDeleteFramebuffersEXT(3, glObj); glDeleteFramebuffers(3, glObj);
m_efbFramebuffer = 0; m_efbFramebuffer = 0;
m_xfbFramebuffer = 0; m_xfbFramebuffer = 0;
@ -242,7 +203,7 @@ FramebufferManager::~FramebufferManager()
if (m_msaaSamples <= 1) if (m_msaaSamples <= 1)
glDeleteTextures(2, glObj); glDeleteTextures(2, glObj);
else else
glDeleteRenderbuffersEXT(2, glObj); glDeleteRenderbuffers(2, glObj);
m_efbColor = 0; m_efbColor = 0;
m_efbDepth = 0; m_efbDepth = 0;
} }
@ -262,16 +223,16 @@ GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
// Resolve. // Resolve.
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_efbFramebuffer);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolvedFramebuffer);
glBlitFramebufferEXT( glBlitFramebuffer(
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
GL_COLOR_BUFFER_BIT, GL_NEAREST GL_COLOR_BUFFER_BIT, GL_NEAREST
); );
// Return to EFB. // Return to EFB.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
return m_resolvedColorTexture; return m_resolvedColorTexture;
} }
@ -292,16 +253,16 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc)
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
// Resolve. // Resolve.
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_efbFramebuffer);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_resolvedFramebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolvedFramebuffer);
glBlitFramebufferEXT( glBlitFramebuffer(
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
targetRc.left, targetRc.top, targetRc.right, targetRc.bottom, targetRc.left, targetRc.top, targetRc.right, targetRc.bottom,
GL_DEPTH_BUFFER_BIT, GL_NEAREST GL_DEPTH_BUFFER_BIT, GL_NEAREST
); );
// Return to EFB. // Return to EFB.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer);
return m_resolvedDepthTexture; return m_resolvedDepthTexture;
} }
@ -322,7 +283,7 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c
void FramebufferManager::SetFramebuffer(GLuint fb) void FramebufferManager::SetFramebuffer(GLuint fb)
{ {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : GetEFBFramebuffer()); glBindFramebuffer(GL_FRAMEBUFFER, fb != 0 ? fb : GetEFBFramebuffer());
} }
// Apply AA if enabled // Apply AA if enabled
@ -340,43 +301,11 @@ void XFBSource::Draw(const MathUtil::Rectangle<float> &sourcerc,
const MathUtil::Rectangle<float> &drawrc, int width, int height) const const MathUtil::Rectangle<float> &drawrc, int width, int height) const
{ {
// Texture map xfbSource->texture onto the main buffer // Texture map xfbSource->texture onto the main buffer
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, texture, 0);
glBlitFramebuffer(sourcerc.left, sourcerc.bottom, sourcerc.right, sourcerc.top,
drawrc.left, drawrc.bottom, drawrc.right, drawrc.top,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
if(!(s_cached_sourcerc == sourcerc) || !(s_cached_drawrc == drawrc)) {
GLfloat vertices[] = {
drawrc.left, drawrc.bottom,
sourcerc.left, sourcerc.bottom,
0.0f, 0.0f,
drawrc.left, drawrc.top,
sourcerc.left, sourcerc.top,
0.0f, 1.0f,
drawrc.right, drawrc.top,
sourcerc.right, sourcerc.top,
1.0f, 1.0f,
drawrc.right, drawrc.bottom,
sourcerc.right, sourcerc.bottom,
1.0f, 0.0f
};
glBindBuffer(GL_ARRAY_BUFFER, s_VBO);
glBufferData(GL_ARRAY_BUFFER, 2*4*3*sizeof(GLfloat), vertices, GL_STREAM_DRAW);
// TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
s_cached_sourcerc = sourcerc;
s_cached_drawrc = drawrc;
}
glBindVertexArray(s_VAO);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
} }
@ -388,46 +317,25 @@ void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
void XFBSource::CopyEFB(float Gamma) void XFBSource::CopyEFB(float Gamma)
{ {
// Copy EFB data to XFB and restore render target again // Copy EFB data to XFB and restore render target again
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetEFBFramebuffer());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());
#if 0 // Bind texture.
if (m_msaaSamples <= 1) glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, texture, 0);
#else GL_REPORT_FBO_ERROR();
if (!s_bHaveFramebufferBlit)
#endif
{
// Just copy the EFB directly.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer()); glBlitFramebuffer(
0, 0, texWidth, texHeight,
0, 0, texWidth, texHeight,
GL_COLOR_BUFFER_BIT, GL_NEAREST
);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); // Unbind texture.
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, 0, 0, texWidth, texHeight, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, 0, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); // Return to EFB.
} glBindFramebuffer(GL_FRAMEBUFFER, FramebufferManager::GetEFBFramebuffer());
else
{
// OpenGL cannot copy directly from a multisampled framebuffer, so use
// EXT_framebuffer_blit.
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer());
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, FramebufferManager::GetXFBFramebuffer());
// Bind texture.
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, texture, 0);
GL_REPORT_FBO_ERROR();
glBlitFramebufferEXT(
0, 0, texWidth, texHeight,
0, 0, texWidth, texHeight,
GL_COLOR_BUFFER_BIT, GL_NEAREST
);
// Unbind texture.
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
// Return to EFB.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferManager::GetEFBFramebuffer());
}
} }
XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height)
@ -436,20 +344,10 @@ XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, un
glGenTextures(1, &texture); glGenTextures(1, &texture);
#if 0// XXX: Some video drivers don't handle glCopyTexImage2D correctly, so use EXT_framebuffer_blit whenever possible. glBindTexture(GL_TEXTURE_RECTANGLE, texture);
if (m_msaaSamples > 1) glTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, target_width, target_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
#else
if (s_bHaveFramebufferBlit)
#endif
{
// In MSAA mode, allocate the texture image here. In non-MSAA mode,
// the image will be allocated by glCopyTexImage2D (later).
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); glBindTexture(GL_TEXTURE_RECTANGLE, 0);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, target_width, target_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
}
return new XFBSource(texture); return new XFBSource(texture);
} }

View File

@ -157,32 +157,26 @@ void OpenGL_ReportARBProgramError()
bool OpenGL_ReportFBOError(const char *function, const char *file, int line) bool OpenGL_ReportFBOError(const char *function, const char *file, int line)
{ {
#ifndef USE_GLES #ifndef USE_GLES
unsigned int fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); unsigned int fbo_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fbo_status != GL_FRAMEBUFFER_COMPLETE_EXT) if (fbo_status != GL_FRAMEBUFFER_COMPLETE)
{ {
const char *error = "-"; const char *error = "unknown error";
switch (fbo_status) switch (fbo_status)
{ {
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
error = "INCOMPLETE_ATTACHMENT_EXT"; error = "INCOMPLETE_ATTACHMENT";
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
error = "INCOMPLETE_MISSING_ATTACHMENT_EXT"; error = "INCOMPLETE_MISSING_ATTACHMENT";
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
error = "INCOMPLETE_DIMENSIONS_EXT"; error = "INCOMPLETE_DRAW_BUFFER";
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
error = "INCOMPLETE_FORMATS_EXT"; error = "INCOMPLETE_READ_BUFFER";
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: case GL_FRAMEBUFFER_UNSUPPORTED:
error = "INCOMPLETE_DRAW_BUFFER_EXT"; error = "UNSUPPORTED";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
error = "INCOMPLETE_READ_BUFFER_EXT";
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
error = "UNSUPPORTED_EXT";
break; break;
} }
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n", ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n",

View File

@ -196,8 +196,8 @@ RasterFont::RasterFont()
glVertexAttribPointer(glGetAttribLocation(shader_program, "texturePosition"), 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2); glVertexAttribPointer(glGetAttribLocation(shader_program, "texturePosition"), 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
// TODO: this after merging with graphic_update // TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
RasterFont::~RasterFont() RasterFont::~RasterFont()
@ -277,9 +277,6 @@ void RasterFont::printMultilineText(const char *text, double start_x, double sta
x += delta_x + border_x; x += delta_x + border_x;
} }
glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER);
// no printable char, so also nothing to do
if(!usage) return;
ProgramShaderCache::SetBothShaders(s_fragmentShader.glprogid, s_vertexShader.glprogid); ProgramShaderCache::SetBothShaders(s_fragmentShader.glprogid, s_vertexShader.glprogid);
@ -293,8 +290,10 @@ void RasterFont::printMultilineText(const char *text, double start_x, double sta
glDrawArrays(GL_TRIANGLES, 0, usage/4); glDrawArrays(GL_TRIANGLES, 0, usage/4);
// TODO: this after merging with graphic_update // TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
} }
} }

View File

@ -106,9 +106,6 @@ namespace OGL
static int s_fps = 0; static int s_fps = 0;
static GLuint s_ShowEFBCopyRegions_VBO = 0; static GLuint s_ShowEFBCopyRegions_VBO = 0;
static GLuint s_ShowEFBCopyRegions_VAO = 0; static GLuint s_ShowEFBCopyRegions_VAO = 0;
static GLuint s_Swap_VBO = 0;
static GLuint s_Swap_VAO[2];
static TargetRectangle s_cached_targetRc;
static RasterFont* s_pfont = NULL; static RasterFont* s_pfont = NULL;
@ -117,7 +114,6 @@ static int s_MSAASamples = 1;
static int s_MSAACoverageSamples = 0; static int s_MSAACoverageSamples = 0;
static int s_LastMultisampleMode = 0; static int s_LastMultisampleMode = 0;
bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp
static bool s_bHaveCoverageMSAA = false; static bool s_bHaveCoverageMSAA = false;
static u32 s_blendMode; static u32 s_blendMode;
@ -187,10 +183,6 @@ static const GLenum glLogicOpCodes[16] = {
int GetNumMSAASamples(int MSAAMode) int GetNumMSAASamples(int MSAAMode)
{ {
// required for MSAA
if (!s_bHaveFramebufferBlit)
return 1;
switch (MSAAMode) switch (MSAAMode)
{ {
case MULTISAMPLE_OFF: case MULTISAMPLE_OFF:
@ -242,16 +234,7 @@ Renderer::Renderer()
s_fps=0; s_fps=0;
s_ShowEFBCopyRegions_VBO = 0; s_ShowEFBCopyRegions_VBO = 0;
s_Swap_VBO = 0;
s_blendMode = 0; s_blendMode = 0;
// should be invalid, so there will be an upload on the first call
s_cached_targetRc.bottom = -1;
s_cached_targetRc.top = -1;
s_cached_targetRc.left = -1;
s_cached_targetRc.right = -1;
InitFPSCounter(); InitFPSCounter();
// Look for required extensions. // Look for required extensions.
@ -291,13 +274,6 @@ Renderer::Renderer()
return; // TODO: fail return; // TODO: fail
} }
if (!GLEW_EXT_framebuffer_object)
{
ERROR_LOG(VIDEO, "GPU: ERROR: Need GL_EXT_framebufer_object for multiple render targets.\n"
"GPU: Does your video card support OpenGL 2.x?");
bSuccess = false;
}
if (!GLEW_EXT_secondary_color) if (!GLEW_EXT_secondary_color)
{ {
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_EXT_secondary_color.\n" ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_EXT_secondary_color.\n"
@ -305,6 +281,13 @@ Renderer::Renderer()
bSuccess = false; bSuccess = false;
} }
if (!GLEW_ARB_framebuffer_object)
{
ERROR_LOG(VIDEO, "GPU: ERROR: Need GL_ARB_framebufer_object for multiple render targets.\n"
"GPU: Does your video card support OpenGL 3.0?");
bSuccess = false;
}
if (!GLEW_ARB_vertex_array_object) if (!GLEW_ARB_vertex_array_object)
{ {
ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n" ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n"
@ -312,7 +295,6 @@ Renderer::Renderer()
bSuccess = false; bSuccess = false;
} }
s_bHaveFramebufferBlit = strstr(ptoken, "GL_EXT_framebuffer_blit") != NULL;
s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL; s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL;
if (glewIsSupported("GL_ARB_blend_func_extended")) if (glewIsSupported("GL_ARB_blend_func_extended"))
@ -396,7 +378,7 @@ Renderer::Renderer()
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
s_MSAASamples, s_MSAACoverageSamples); s_MSAASamples, s_MSAACoverageSamples);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0);
if (GL_REPORT_ERROR() != GL_NO_ERROR) if (GL_REPORT_ERROR() != GL_NO_ERROR)
bSuccess = false; bSuccess = false;
@ -412,30 +394,10 @@ Renderer::Renderer()
glColorPointer (3, GL_FLOAT, sizeof(GLfloat)*5, (GLfloat*)NULL+2); glColorPointer (3, GL_FLOAT, sizeof(GLfloat)*5, (GLfloat*)NULL+2);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*5, NULL); glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*5, NULL);
glGenBuffers(1, &s_Swap_VBO);
glGenVertexArrays(2, s_Swap_VAO);
glBindBuffer(GL_ARRAY_BUFFER, s_Swap_VBO);
glBindVertexArray(s_Swap_VAO[0]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 7*sizeof(GLfloat), NULL);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+3);
glBindVertexArray(s_Swap_VAO[1]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 7*sizeof(GLfloat), NULL);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+3);
glClientActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+5);
// TODO: this after merging with graphic_update // TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glStencilFunc(GL_ALWAYS, 0, 0); glStencilFunc(GL_ALWAYS, 0, 0);
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
@ -455,7 +417,7 @@ Renderer::Renderer()
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, GetTargetWidth(), GetTargetHeight()); glScissor(0, 0, GetTargetWidth(), GetTargetHeight());
glBlendColorEXT(0, 0, 0, 0.5f); glBlendColor(0, 0, 0, 0.5f);
glClearDepth(1.0f); glClearDepth(1.0f);
// legacy multitexturing: select texture channel only. // legacy multitexturing: select texture channel only.
@ -476,8 +438,6 @@ Renderer::~Renderer()
glDeleteBuffers(1, &s_ShowEFBCopyRegions_VBO); glDeleteBuffers(1, &s_ShowEFBCopyRegions_VBO);
glDeleteVertexArrays(1, &s_ShowEFBCopyRegions_VAO); glDeleteVertexArrays(1, &s_ShowEFBCopyRegions_VAO);
glDeleteBuffers(1, &s_Swap_VBO);
glDeleteVertexArrays(2, s_Swap_VAO);
s_ShowEFBCopyRegions_VBO = 0; s_ShowEFBCopyRegions_VBO = 0;
delete s_pfont; delete s_pfont;
@ -627,8 +587,8 @@ void Renderer::DrawDebugInfo()
glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6); glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6);
// TODO: this after merging with graphic_update // TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Restore Line Size // Restore Line Size
glLineWidth(lSize); glLineWidth(lSize);
@ -789,7 +749,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
{ {
// Resolve our rectangle. // Resolve our rectangle.
FramebufferManager::GetEFBDepthTexture(efbPixelRc); FramebufferManager::GetEFBDepthTexture(efbPixelRc);
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer()); glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetResolvedFramebuffer());
} }
u32* depthMap = new u32[targetPixelRcWidth * targetPixelRcHeight]; u32* depthMap = new u32[targetPixelRcWidth * targetPixelRcHeight];
@ -838,7 +798,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
{ {
// Resolve our rectangle. // Resolve our rectangle.
FramebufferManager::GetEFBColorTexture(efbPixelRc); FramebufferManager::GetEFBColorTexture(efbPixelRc);
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer()); glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetResolvedFramebuffer());
} }
u32* colorMap = new u32[targetPixelRcWidth * targetPixelRcHeight]; u32* colorMap = new u32[targetPixelRcWidth * targetPixelRcHeight];
@ -1098,7 +1058,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// Textured triangles are necessary because of post-processing shaders // Textured triangles are necessary because of post-processing shaders
// Disable all other stages // Disable all other stages
for (int i = 1; i < 8; ++i) for (int i = 0; i < 8; ++i)
OGL::TextureCache::DisableStage(i); OGL::TextureCache::DisableStage(i);
// Update GLViewPort // Update GLViewPort
@ -1106,26 +1066,22 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
// Copy the framebuffer to screen.
// Texture map s_xfbTexture onto the main buffer
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
// Use linear filtering.
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// We must call ApplyShader here even if no post proc is selected - it takes // We must call ApplyShader here even if no post proc is selected - it takes
// care of disabling it in that case. It returns false in case of no post processing. // care of disabling it in that case. It returns false in case of no post processing.
bool applyShader = PostProcessing::ApplyShader(); //bool applyShader = PostProcessing::ApplyShader();
// degasus: disabled for blitting
// Copy the framebuffer to screen.
const XFBSourceBase* xfbSource = NULL; const XFBSourceBase* xfbSource = NULL;
if(g_ActiveConfig.bUseXFB) if(g_ActiveConfig.bUseXFB)
{ {
// draw each xfb source
// Render to the real buffer now. // Render to the real buffer now.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // switch to the window backbuffer
// draw each xfb source
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());
for (u32 i = 0; i < xfbCount; ++i) for (u32 i = 0; i < xfbCount; ++i)
{ {
@ -1135,10 +1091,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (g_ActiveConfig.bUseRealXFB) if (g_ActiveConfig.bUseRealXFB)
{ {
drawRc.top = 1; drawRc.top = flipped_trc.top;
drawRc.bottom = -1; drawRc.bottom = flipped_trc.bottom;
drawRc.left = -1; drawRc.left = flipped_trc.left;
drawRc.right = 1; drawRc.right = flipped_trc.right;
} }
else else
{ {
@ -1146,12 +1102,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
int xfbHeight = xfbSource->srcHeight; int xfbHeight = xfbSource->srcHeight;
int xfbWidth = xfbSource->srcWidth; int xfbWidth = xfbSource->srcWidth;
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
drawRc.top = 1.0f - (2.0f * (hOffset) / (float)fbHeight); drawRc.top = flipped_trc.bottom + (hOffset + xfbHeight) * flipped_trc.GetHeight() / fbHeight;
drawRc.bottom = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight); drawRc.bottom = flipped_trc.bottom + hOffset * flipped_trc.GetHeight() / fbHeight;
drawRc.left = -(xfbWidth / (float)fbWidth); drawRc.left = flipped_trc.left + (flipped_trc.GetWidth() - xfbWidth * flipped_trc.GetWidth() / fbWidth)/2;
drawRc.right = (xfbWidth / (float)fbWidth); drawRc.right = flipped_trc.left + (flipped_trc.GetWidth() + xfbWidth * flipped_trc.GetWidth() / fbWidth)/2;
// The following code disables auto stretch. Kept for reference. // The following code disables auto stretch. Kept for reference.
// scale draw area for a 1 to 1 pixel mapping with the draw target // scale draw area for a 1 to 1 pixel mapping with the draw target
//float vScale = (float)fbHeight / (float)flipped_trc.GetHeight(); //float vScale = (float)fbHeight / (float)flipped_trc.GetHeight();
@ -1171,64 +1127,28 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
sourceRc.bottom = xfbSource->sourceRc.bottom; sourceRc.bottom = xfbSource->sourceRc.bottom;
xfbSource->Draw(sourceRc, drawRc, 0, 0); xfbSource->Draw(sourceRc, drawRc, 0, 0);
// We must call ApplyShader here even if no post proc is selected.
// It takes care of disabling it in that case. It returns false in
// case of no post processing.
if (applyShader)
ProgramShaderCache::SetBothShaders(0, 0);
} }
} }
else else
{ {
TargetRectangle targetRc = ConvertEFBRectangle(rc); TargetRectangle targetRc = ConvertEFBRectangle(rc);
GLuint read_texture = FramebufferManager::ResolveAndGetRenderTarget(rc);
// Render to the real buffer now. // for msaa mode, we must resolve the efb content to non-msaa
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer FramebufferManager::ResolveAndGetRenderTarget(rc);
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); // Render to the real buffer now. (resolve have changed this in msaa mode)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
if(!( s_cached_targetRc == targetRc)) {
GLfloat vertices[] = { // always the non-msaa fbo
-1.0f, -1.0f, 1.0f, GLuint fb = s_MSAASamples>1?FramebufferManager::GetResolvedFramebuffer():FramebufferManager::GetEFBFramebuffer();
(GLfloat)targetRc.left, (GLfloat)targetRc.bottom,
0.0f, 0.0f,
-1.0f, 1.0f, 1.0f,
(GLfloat)targetRc.left, (GLfloat)targetRc.top,
0.0f, 1.0f,
1.0f, 1.0f, 1.0f,
(GLfloat)targetRc.right, (GLfloat)targetRc.top,
1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
(GLfloat)targetRc.right, (GLfloat)targetRc.bottom,
1.0f, 0.0f
};
glBindBuffer(GL_ARRAY_BUFFER, s_Swap_VBO); glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
glBufferData(GL_ARRAY_BUFFER, 4*7*sizeof(GLfloat), vertices, GL_STREAM_DRAW); glBlitFramebuffer(targetRc.left, targetRc.bottom, targetRc.right, targetRc.top,
flipped_trc.left, flipped_trc.bottom, flipped_trc.right, flipped_trc.top,
// TODO: this after merging with graphic_update GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBindBuffer(GL_ARRAY_BUFFER, 0);
s_cached_targetRc = targetRc;
}
glBindVertexArray(s_Swap_VAO[applyShader]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
if(applyShader)
ProgramShaderCache::SetBothShaders(0, 0);
} }
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
OGL::TextureCache::DisableStage(0);
// Save screenshot // Save screenshot
if (s_bScreenshot) if (s_bScreenshot)
@ -1389,7 +1309,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
delete g_framebuffer_manager; delete g_framebuffer_manager;
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
s_MSAASamples, s_MSAACoverageSamples); s_MSAASamples, s_MSAACoverageSamples);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0);
} }
} }

View File

@ -294,19 +294,19 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture) if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture)
{ {
if (s_TempFramebuffer == 0) if (s_TempFramebuffer == 0)
glGenFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer); glGenFramebuffers(1, (GLuint*)&s_TempFramebuffer);
FramebufferManager::SetFramebuffer(s_TempFramebuffer); FramebufferManager::SetFramebuffer(s_TempFramebuffer);
// Bind texture to temporary framebuffer // Bind texture to temporary framebuffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glDrawBuffer(GL_COLOR_ATTACHMENT0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE, read_texture);
glViewport(0, 0, virtual_width, virtual_height); glViewport(0, 0, virtual_width, virtual_height);
@ -357,9 +357,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
glBindBuffer(GL_ARRAY_BUFFER, vbo_it->second.vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo_it->second.vbo);
glBufferData(GL_ARRAY_BUFFER, 4*4*sizeof(GLfloat), vertices, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, 4*4*sizeof(GLfloat), vertices, GL_STREAM_DRAW);
// TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
vbo_it->second.targetSource = targetSource; vbo_it->second.targetSource = targetSource;
} }
@ -368,13 +365,14 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
// TODO: this after merging with graphic_update // TODO: this after merging with graphic_update
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
// Unbind texture from temporary framebuffer // Unbind texture from temporary framebuffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
} }
if (false == g_ActiveConfig.bCopyEFBToTexture) if (false == g_ActiveConfig.bCopyEFBToTexture)
@ -465,7 +463,7 @@ TextureCache::~TextureCache()
if (s_TempFramebuffer) if (s_TempFramebuffer)
{ {
glDeleteFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer); glDeleteFramebuffers(1, (GLuint*)&s_TempFramebuffer);
s_TempFramebuffer = 0; s_TempFramebuffer = 0;
} }
} }
@ -473,7 +471,8 @@ TextureCache::~TextureCache()
void TextureCache::DisableStage(unsigned int stage) void TextureCache::DisableStage(unsigned int stage)
{ {
glActiveTexture(GL_TEXTURE0 + stage); glActiveTexture(GL_TEXTURE0 + stage);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_RECTANGLE);
} }
} }

View File

@ -146,7 +146,7 @@ FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format)
void Init() void Init()
{ {
glGenFramebuffersEXT(1, &s_texConvFrameBuffer); glGenFramebuffers(1, &s_texConvFrameBuffer);
glGenBuffers(1, &s_encode_VBO ); glGenBuffers(1, &s_encode_VBO );
glGenVertexArrays(1, &s_encode_VAO ); glGenVertexArrays(1, &s_encode_VAO );
@ -175,13 +175,13 @@ void Init()
glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*4, (GLfloat*)NULL+2); glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
// TODO: this after merging with graphic_update // TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenRenderbuffersEXT(1, &s_dstRenderBuffer); glGenRenderbuffers(1, &s_dstRenderBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, s_dstRenderBuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, renderBufferWidth, renderBufferHeight); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, renderBufferWidth, renderBufferHeight);
s_srcTextureWidth = 0; s_srcTextureWidth = 0;
s_srcTextureHeight = 0; s_srcTextureHeight = 0;
@ -199,8 +199,8 @@ void Init()
void Shutdown() void Shutdown()
{ {
glDeleteTextures(1, &s_srcTexture); glDeleteTextures(1, &s_srcTexture);
glDeleteRenderbuffersEXT(1, &s_dstRenderBuffer); glDeleteRenderbuffers(1, &s_dstRenderBuffer);
glDeleteFramebuffersEXT(1, &s_texConvFrameBuffer); glDeleteFramebuffers(1, &s_texConvFrameBuffer);
glDeleteBuffers(1, &s_encode_VBO ); glDeleteBuffers(1, &s_encode_VBO );
glDeleteVertexArrays(1, &s_encode_VAO ); glDeleteVertexArrays(1, &s_encode_VAO );
glDeleteBuffers(1, &s_decode_VBO ); glDeleteBuffers(1, &s_decode_VBO );
@ -227,8 +227,8 @@ void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
// attach render buffer as color destination // attach render buffer as color destination
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer); FramebufferManager::SetFramebuffer(s_texConvFrameBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, s_dstRenderBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_dstRenderBuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, s_dstRenderBuffer);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
for (int i = 1; i < 8; ++i) for (int i = 1; i < 8; ++i)
@ -236,19 +236,19 @@ void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
// set source texture // set source texture
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, srcTexture); glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE, srcTexture);
if (linearFilter) if (linearFilter)
{ {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} }
else else
{ {
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
} }
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
@ -270,9 +270,6 @@ void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
glBindBuffer(GL_ARRAY_BUFFER, s_encode_VBO ); glBindBuffer(GL_ARRAY_BUFFER, s_encode_VBO );
glBufferData(GL_ARRAY_BUFFER, 4*4*sizeof(GLfloat), vertices, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, 4*4*sizeof(GLfloat), vertices, GL_STREAM_DRAW);
// TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
s_cached_sourceRc = sourceRc; s_cached_sourceRc = sourceRc;
} }
@ -281,6 +278,7 @@ void EncodeToRamUsingShader(GLuint srcTexture, const TargetRectangle& sourceRc,
// TODO: this after merging with graphic_update // TODO: this after merging with graphic_update
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
@ -412,7 +410,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
FramebufferManager::SetFramebuffer(s_texConvFrameBuffer); FramebufferManager::SetFramebuffer(s_texConvFrameBuffer);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, destTexture); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, destTexture);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, destTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, destTexture, 0);
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
@ -422,19 +420,19 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
// activate source texture // activate source texture
// set srcAddr as data for source texture // set srcAddr as data for source texture
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_srcTexture); glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE, s_srcTexture);
// TODO: make this less slow. (How?) // TODO: make this less slow. (How?)
if ((GLsizei)s_srcTextureWidth == (GLsizei)srcFmtWidth && (GLsizei)s_srcTextureHeight == (GLsizei)srcHeight) if ((GLsizei)s_srcTextureWidth == (GLsizei)srcFmtWidth && (GLsizei)s_srcTextureHeight == (GLsizei)srcHeight)
{ {
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0,0,0,s_srcTextureWidth, s_srcTextureHeight, glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0,0,0,s_srcTextureWidth, s_srcTextureHeight,
GL_BGRA, GL_UNSIGNED_BYTE, srcAddr); GL_BGRA, GL_UNSIGNED_BYTE, srcAddr);
} }
else else
{ {
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, (GLsizei)srcFmtWidth, (GLsizei)srcHeight, glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, (GLsizei)srcFmtWidth, (GLsizei)srcHeight,
0, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr); 0, GL_BGRA, GL_UNSIGNED_BYTE, srcAddr);
s_srcTextureWidth = (GLsizei)srcFmtWidth; s_srcTextureWidth = (GLsizei)srcFmtWidth;
s_srcTextureHeight = (GLsizei)srcHeight; s_srcTextureHeight = (GLsizei)srcHeight;
@ -460,9 +458,6 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
glBindBuffer(GL_ARRAY_BUFFER, s_decode_VBO ); glBindBuffer(GL_ARRAY_BUFFER, s_decode_VBO );
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*4*4, vertices, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*4*4, vertices, GL_STREAM_DRAW);
// TODO: this after merging with graphic_update
glBindBuffer(GL_ARRAY_BUFFER, 0);
s_cached_srcHeight = srcHeight; s_cached_srcHeight = srcHeight;
s_cached_srcWidth = srcWidth; s_cached_srcWidth = srcWidth;
} }
@ -472,12 +467,13 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
// TODO: this after merging with graphic_update // TODO: this after merging with graphic_update
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
// reset state // reset state
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, 0, 0);
TextureCache::DisableStage(0); TextureCache::DisableStage(0);
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();

View File

@ -355,7 +355,7 @@ namespace EfbInterface
dstClr = (~srcClr) & dstClr; dstClr = (~srcClr) & dstClr;
break; break;
case 5: // noop case 5: // noop
dstClr = dstClr; // Do nothing
break; break;
case 6: // xor case 6: // xor
dstClr = srcClr ^ dstClr; dstClr = srcClr ^ dstClr;

View File

@ -62,7 +62,7 @@ namespace HwRasterizer
"}\n"; "}\n";
// Clear shader // Clear shader
static const char *fragclearText = static const char *fragclearText =
"uniform vec4 Color;\n" "uniform " PREC " vec4 Color;\n"
"void main() {\n" "void main() {\n"
" gl_FragColor = Color;\n" " gl_FragColor = Color;\n"
"}\n"; "}\n";

View File

@ -146,9 +146,6 @@ void SWRenderer::DrawTexture(u8 *texture, int width, int height)
glTexImage2D(TEX2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); glTexImage2D(TEX2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexParameteri(TEX2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(TEX2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(TEX2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(TEX2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
GLfloat u_max = (GLfloat)width;
GLfloat v_max = (GLfloat)glHeight;
static const GLfloat verts[4][2] = { static const GLfloat verts[4][2] = {
{ -1, -1}, // Left top { -1, -1}, // Left top
@ -158,6 +155,9 @@ void SWRenderer::DrawTexture(u8 *texture, int width, int height)
}; };
//Texture rectangle uses pixel coordinates //Texture rectangle uses pixel coordinates
#ifndef USE_GLES #ifndef USE_GLES
GLfloat u_max = (GLfloat)width;
GLfloat v_max = (GLfloat)height;
static const GLfloat texverts[4][2] = { static const GLfloat texverts[4][2] = {
{0, v_max}, {0, v_max},
{0, 0}, {0, 0},