GL plugin: VSync option, some renaming, a little bit of MSAA preparations (not there yet)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2563 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
02a4b49df1
commit
75390c55bd
|
@ -84,7 +84,7 @@ void BPWritten(int addr, int changes, int newval)
|
|||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(bpmem.genMode.cullmode == 2 ? GL_CCW : GL_CW);
|
||||
}
|
||||
else if (glIsEnabled(GL_CULL_FACE) == GL_TRUE)
|
||||
else
|
||||
glDisable(GL_CULL_FACE);
|
||||
PixelShaderManager::SetGenModeChanged();
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ void BPWritten(int addr, int changes, int newval)
|
|||
|
||||
case BPMEM_LINEPTWIDTH:
|
||||
{
|
||||
float fratio = xfregs.rawViewport[0] != 0 ? (float)Renderer::GetTargetWidth() / 640.0f : 1.0f;
|
||||
float fratio = xfregs.rawViewport[0] != 0 ? ((float)Renderer::GetTargetWidth() / EFB_WIDTH) : 1.0f;
|
||||
if (bpmem.lineptwidth.linesize > 0)
|
||||
glLineWidth((float)bpmem.lineptwidth.linesize * fratio / 6.0f); // scale by ratio of widths
|
||||
if (bpmem.lineptwidth.pointsize > 0)
|
||||
|
@ -243,13 +243,6 @@ void BPWritten(int addr, int changes, int newval)
|
|||
break;
|
||||
|
||||
case BPMEM_FOGRANGE:
|
||||
if (changes) {
|
||||
// TODO(XK): Fog range format
|
||||
//glFogi(GL_FOG_START, ...
|
||||
//glFogi(GL_FOG_END, ...
|
||||
}
|
||||
break;
|
||||
|
||||
case BPMEM_FOGPARAM0:
|
||||
case BPMEM_FOGBEXPONENT:
|
||||
case BPMEM_FOGBMAGNITUDE:
|
||||
|
@ -363,9 +356,9 @@ void BPWritten(int addr, int changes, int newval)
|
|||
case BPMEM_SETGPMETRIC: // Set gp metric?
|
||||
break;
|
||||
|
||||
// ===============================================================
|
||||
// This case writes to bpmem.triggerEFBCopy and may apparently prompt us to update glScissor()
|
||||
// ------------------------
|
||||
// EFB copy command. This copies a rectangle from the EFB to either RAM in a texture format or to XFB as YUYV.
|
||||
// It can also optionally clear the EFB while copying from it. To emulate this, we of course copy first and clear afterwards.
|
||||
case BPMEM_TRIGGER_EFB_COPY:
|
||||
{
|
||||
DVSTARTSUBPROFILE("LoadBPReg:swap");
|
||||
|
@ -395,33 +388,30 @@ void BPWritten(int addr, int changes, int newval)
|
|||
PE_copy.Hex = bpmem.triggerEFBCopy;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Check if we should copy the picture to XFB or not
|
||||
// Check to where we should copy the image data from the EFB.
|
||||
// --------------------------
|
||||
if (PE_copy.copy_to_xfb == 0)
|
||||
{
|
||||
// EFB to texture
|
||||
// for some reason it sets bpmem.zcontrol.pixel_format to PIXELFMT_Z24 every time a zbuffer format is given as a dest to GXSetTexCopyDst
|
||||
if (g_Config.bEFBCopyDisable)
|
||||
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 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;
|
||||
GLScissorW = rc.right;
|
||||
GLScissorH = rc.top;
|
||||
}
|
||||
else if (g_Config.bCopyEFBToRAM)
|
||||
{
|
||||
TextureConverter::EncodeToRam(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0,
|
||||
(PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureMngr::CopyRenderTargetToTexture(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0,
|
||||
(PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, &rc);
|
||||
if (g_Config.bCopyEFBToRAM)
|
||||
{
|
||||
TextureConverter::EncodeToRam(bpmem.copyTexDest<<5,
|
||||
bpmem.zcontrol.pixel_format==PIXELFMT_Z24,
|
||||
PE_copy.intensity_fmt > 0,
|
||||
(PE_copy.target_pixel_format/2) + ((PE_copy.target_pixel_format&1) * 8), // ??
|
||||
PE_copy.half_scale>0, rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureMngr::CopyRenderTargetToTexture(bpmem.copyTexDest<<5,
|
||||
bpmem.zcontrol.pixel_format==PIXELFMT_Z24,
|
||||
PE_copy.intensity_fmt > 0,
|
||||
(PE_copy.target_pixel_format/2) + ((PE_copy.target_pixel_format & 1)*8), // ??
|
||||
PE_copy.half_scale > 0, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -446,6 +436,8 @@ void BPWritten(int addr, int changes, int newval)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Hm, we need to compensate for the fact that the copy may be bigger than what is displayed.
|
||||
// Seen in Spartan Warrior. Not sure how to deal with it yet.
|
||||
Renderer::Swap(multirc);
|
||||
}
|
||||
g_VideoInitialize.pCopiedToXFB();
|
||||
|
@ -459,16 +451,12 @@ void BPWritten(int addr, int changes, int newval)
|
|||
// Clear color
|
||||
Renderer::SetRenderMode(Renderer::RM_Normal);
|
||||
// Clear Z-Buffer target
|
||||
u32 nRestoreZBufferTarget = Renderer::GetZBufferTarget();
|
||||
bool bRestoreZBufferTarget = Renderer::GetFakeZTarget() != 0;
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Update the view port for clearing the picture
|
||||
// -----------------------
|
||||
glViewport(0, 0, Renderer::GetTargetWidth(), Renderer::GetTargetHeight());
|
||||
|
||||
// Always set the scissor in case it was set by the game and has not been reset
|
||||
/* We will also do this at the end of this section, in SetScissorRect(), but that is for creating the new picture
|
||||
this is for clearing the picture */
|
||||
glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom),
|
||||
(multirc.right - multirc.left), (multirc.bottom - multirc.top));
|
||||
// ---------------------------
|
||||
|
@ -484,23 +472,23 @@ void BPWritten(int addr, int changes, int newval)
|
|||
{
|
||||
u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
glClearColor(((clearColor>>16) & 0xff)*(1/255.0f),
|
||||
((clearColor>>8 ) & 0xff)*(1/255.0f),
|
||||
((clearColor>>0 ) & 0xff)*(1/255.0f),
|
||||
((clearColor>>24) & 0xff)*(1/255.0f));
|
||||
((clearColor>>8 ) & 0xff)*(1/255.0f),
|
||||
((clearColor>>0 ) & 0xff)*(1/255.0f),
|
||||
((clearColor>>24) & 0xff)*(1/255.0f));
|
||||
bits |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
if (bpmem.zmode.updateenable)
|
||||
{
|
||||
glClearDepth((float)(bpmem.clearZValue&0xFFFFFF) / float(0xFFFFFF));
|
||||
glClearDepth((float)(bpmem.clearZValue & 0xFFFFFF) / float(0xFFFFFF));
|
||||
bits |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
if (nRestoreZBufferTarget )
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // don't clear ztarget here
|
||||
if (bRestoreZBufferTarget)
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // don't clear ztarget here
|
||||
glClear(bits);
|
||||
}
|
||||
|
||||
// Have to clear the target zbuffer
|
||||
if (bpmem.zmode.updateenable && nRestoreZBufferTarget)
|
||||
if (bpmem.zmode.updateenable && bRestoreZBufferTarget)
|
||||
{
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
|
||||
GL_REPORT_ERRORD();
|
||||
|
@ -515,16 +503,14 @@ void BPWritten(int addr, int changes, int newval)
|
|||
GL_REPORT_ERRORD();
|
||||
}
|
||||
|
||||
if (nRestoreZBufferTarget)
|
||||
if (bRestoreZBufferTarget)
|
||||
{
|
||||
// restore target
|
||||
GLenum s_drawbuffers[2] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
|
||||
glDrawBuffers(2, s_drawbuffers);
|
||||
}
|
||||
|
||||
Renderer::SetScissorRect(); // reset the scissor rectangle
|
||||
}
|
||||
// ------------------------------
|
||||
Renderer::RestoreGLState();
|
||||
}
|
||||
break;
|
||||
// ==================================
|
||||
|
@ -643,7 +629,7 @@ void BPWritten(int addr, int changes, int newval)
|
|||
break;
|
||||
|
||||
default:
|
||||
switch(addr&0xF0) {
|
||||
switch (addr&0xF0) {
|
||||
case 0x10: // tevindirect 0-15
|
||||
if (changes) {
|
||||
VertexManager::Flush();
|
||||
|
|
|
@ -41,6 +41,7 @@ void Config::Load()
|
|||
strncpy(iFSResolution, temp.c_str(), 16);
|
||||
|
||||
iniFile.Get("Hardware", "Fullscreen", &bFullscreen, 0); // Hardware
|
||||
iniFile.Get("Hardware", "VSync", &bVSync, 0); // Hardware
|
||||
iniFile.Get("Hardware", "RenderToMainframe", &renderToMainframe, false);
|
||||
iniFile.Get("Settings", "StretchToFit", &bNativeResolution, true);
|
||||
iniFile.Get("Settings", "KeepAR_4_3", &bKeepAR43, false);
|
||||
|
@ -93,6 +94,7 @@ void Config::Save()
|
|||
iniFile.Set("Hardware", "WindowedRes", iWindowedRes);
|
||||
iniFile.Set("Hardware", "FullscreenRes", iFSResolution);
|
||||
iniFile.Set("Hardware", "Fullscreen", bFullscreen);
|
||||
iniFile.Set("Hardware", "VSync", bVSync);
|
||||
iniFile.Set("Hardware", "RenderToMainframe", renderToMainframe);
|
||||
iniFile.Set("Settings", "StretchToFit", bNativeResolution);
|
||||
iniFile.Set("Settings", "KeepAR_4_3", bKeepAR43);
|
||||
|
|
|
@ -38,6 +38,7 @@ struct Config
|
|||
bool bFullscreen;
|
||||
bool bHideCursor;
|
||||
bool renderToMainframe;
|
||||
bool bVSync;
|
||||
|
||||
// Resolution control
|
||||
char iFSResolution[16];
|
||||
|
|
|
@ -27,6 +27,7 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
|
|||
EVT_BUTTON(ID_CLOSE, ConfigDialog::CloseClick)
|
||||
EVT_BUTTON(ID_ABOUTOGL, ConfigDialog::AboutClick)
|
||||
EVT_CHECKBOX(ID_FULLSCREEN, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_VSYNC, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_RENDERTOMAINWINDOW, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_COMBOBOX(ID_FULLSCREENCB, ConfigDialog::GeneralSettingsChanged)
|
||||
EVT_COMBOBOX(ID_WINDOWRESOLUTIONCB, ConfigDialog::GeneralSettingsChanged)
|
||||
|
@ -161,6 +162,8 @@ void ConfigDialog::CreateGUIControls()
|
|||
sbBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageGeneral, wxT("Basic Settings"));
|
||||
m_Fullscreen = new wxCheckBox(m_PageGeneral, ID_FULLSCREEN, wxT("Fullscreen"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_Fullscreen->SetValue(g_Config.bFullscreen);
|
||||
m_VSync = new wxCheckBox(m_PageGeneral, ID_VSYNC, wxT("VSync (req. restart)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_VSync->SetValue(g_Config.bVSync);
|
||||
m_RenderToMainWindow = new wxCheckBox(m_PageGeneral, ID_RENDERTOMAINWINDOW, wxT("Render to main window"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_RenderToMainWindow->SetValue(g_Config.renderToMainframe);
|
||||
m_NativeResolution = new wxCheckBox(m_PageGeneral, ID_NATIVERESOLUTION, wxT("Native resolution"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
|
@ -239,16 +242,17 @@ void ConfigDialog::CreateGUIControls()
|
|||
sGeneral = new wxBoxSizer(wxVERTICAL);
|
||||
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_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);
|
||||
sBasic->Add(m_VSync, wxGBPosition(1, 0), wxGBSpan(1, 3), wxALL, 5);
|
||||
sBasic->Add(m_RenderToMainWindow, wxGBPosition(2, 0), wxGBSpan(1, 3), wxALL, 5);
|
||||
sBasic->Add(m_AutoScale, wxGBPosition(3, 0), wxGBSpan(1, 3), wxALL, 5);
|
||||
sBasic->Add(m_NativeResolution, wxGBPosition(4, 0), wxGBSpan(1, 3), wxALL, 5);
|
||||
sBasic->Add(m_UseXFB, wxGBPosition(5, 0), wxGBSpan(1, 3), wxALL, 5);
|
||||
sBasic->Add(m_KeepAR43, wxGBPosition(6, 0), wxGBSpan(1, 1), wxALL, 5);
|
||||
sBasic->Add(m_KeepAR169, wxGBPosition(6, 1), wxGBSpan(1, 1), wxALL, 5);
|
||||
sBasic->Add(m_Crop, wxGBPosition(6, 2), wxGBSpan(1, 1), wxALL, 5);
|
||||
|
||||
// Because of the ifdef here we need this variable for the row number
|
||||
int Row = 6;
|
||||
int Row = 7;
|
||||
#ifndef _WIN32
|
||||
sBasic->Add(m_HideCursor, wxGBPosition(Row++, 0), wxGBSpan(1, 3), wxALL, 5);
|
||||
#endif
|
||||
|
@ -430,7 +434,9 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
|
|||
case ID_NATIVERESOLUTION:
|
||||
g_Config.bNativeResolution = m_NativeResolution->IsChecked();
|
||||
break;
|
||||
|
||||
case ID_VSYNC:
|
||||
g_Config.bVSync = m_VSync->IsChecked();
|
||||
break;
|
||||
case ID_USEXFB:
|
||||
g_Config.bUseXFB = m_UseXFB->IsChecked();
|
||||
break;
|
||||
|
|
|
@ -75,6 +75,7 @@ class ConfigDialog : public wxDialog
|
|||
wxPanel *m_PageGeneral;
|
||||
wxPanel *m_PageAdvanced;
|
||||
wxCheckBox *m_Fullscreen;
|
||||
wxCheckBox *m_VSync;
|
||||
wxCheckBox *m_RenderToMainWindow;
|
||||
wxCheckBox *m_NativeResolution;
|
||||
wxCheckBox *m_KeepAR43, *m_KeepAR169, *m_Crop;
|
||||
|
@ -125,6 +126,7 @@ class ConfigDialog : public wxDialog
|
|||
ID_PAGEADVANCED,
|
||||
|
||||
ID_FULLSCREEN,
|
||||
ID_VSYNC,
|
||||
ID_RENDERTOMAINWINDOW,
|
||||
ID_NATIVERESOLUTION,
|
||||
ID_KEEPAR_4_3, ID_KEEPAR_16_9, ID_CROP,
|
||||
|
|
|
@ -63,7 +63,7 @@ bool LocalLogFile = true;
|
|||
#if LOGLEVEL > 0
|
||||
void __Log(const char *fmt, ...)
|
||||
{
|
||||
int len = strlen(fmt);
|
||||
size_t len = strlen(fmt);
|
||||
if (!len)
|
||||
return;
|
||||
char* Msg = (char*)alloca(len + 512);
|
||||
|
|
|
@ -109,7 +109,7 @@ FRAGMENTSHADER* PixelShaderCache::GetShader()
|
|||
{
|
||||
DVSTARTPROFILE();
|
||||
PIXELSHADERUID uid;
|
||||
u32 zbufrender = (Renderer::GetZBufferTarget() && bpmem.zmode.updateenable) ? 1 : 0;
|
||||
u32 zbufrender = (Renderer::GetFakeZTarget() && bpmem.zmode.updateenable) ? 1 : 0;
|
||||
u32 zBufRenderToCol0 = Renderer::GetRenderMode() != Renderer::RM_Normal;
|
||||
GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), zbufrender, zBufRenderToCol0);
|
||||
|
||||
|
@ -127,7 +127,7 @@ FRAGMENTSHADER* PixelShaderCache::GetShader()
|
|||
|
||||
PSCacheEntry& newentry = pshaders[uid];
|
||||
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(),
|
||||
Renderer::GetZBufferTarget() != 0,
|
||||
Renderer::GetFakeZTarget() != 0,
|
||||
Renderer::GetRenderMode() != Renderer::RM_Normal);
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
|
@ -63,7 +63,6 @@
|
|||
#else
|
||||
#endif
|
||||
|
||||
|
||||
CGcontext g_cgcontext;
|
||||
CGprofile g_cgvProf;
|
||||
CGprofile g_cgfProf;
|
||||
|
@ -72,15 +71,38 @@ RasterFont* s_pfont = NULL;
|
|||
|
||||
static bool s_bFullscreen = false;
|
||||
|
||||
static int nZBufferRender = 0; // if > 0, then use zbuffer render, and count down.
|
||||
static int nZBufferRender = 0; // if > 0, then use zbuffer render, and count down.
|
||||
|
||||
static bool MSAA = false;
|
||||
|
||||
// Normal Mode
|
||||
// s_RenderTarget is a texture_rect
|
||||
// s_DepthTarget is a Z renderbuffer
|
||||
// s_FakeZTarget is a texture_rect
|
||||
|
||||
// MSAA mode
|
||||
// s_uFramebuffer is a FBO
|
||||
// s_RenderTarget is a MSAA renderbuffer
|
||||
// s_FakeZBufferTarget is a MSAA renderbuffer
|
||||
// s_DepthTarget is a real MSAA z/stencilbuffer
|
||||
//
|
||||
// s_ResolvedFramebuffer is a FBO
|
||||
// s_ResolvedColorTarget is a texture
|
||||
// s_ResolvedFakeZTarget is a texture
|
||||
// s_ResolvedDepthTarget is a Z renderbuffer
|
||||
|
||||
// A framebuffer is a set of render targets: a color and a z buffer. They can be either RenderBuffers or Textures.
|
||||
static GLuint s_uFramebuffer = 0;
|
||||
|
||||
// The size of these should be a (not necessarily even) multiple of the EFB size, 640x528, but isn'.t
|
||||
// The size of these should be a (not necessarily even) multiple of the EFB size, 640x528, but isn't.
|
||||
// These are all texture IDs. Bind them as rect arb textures.
|
||||
static GLuint s_RenderTarget = 0;
|
||||
static GLuint s_DepthTarget = 0;
|
||||
static GLuint s_ZBufferTarget = 0;
|
||||
static GLuint s_FakeZTarget = 0;
|
||||
static GLuint s_DepthTarget = 0;
|
||||
|
||||
static GLuint s_ResolvedRenderTarget = 0;
|
||||
static GLuint s_ResolvedFakeZTarget = 0;
|
||||
static GLuint s_ResolvedDepthTarget = 0;
|
||||
|
||||
static bool s_bATIDrawBuffers = false;
|
||||
static bool s_bHaveStencilBuffer = false;
|
||||
|
@ -96,13 +118,16 @@ 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.
|
||||
// These STAY CONSTANT during execution, no matter how much you resize the game window.\
|
||||
// TODO: Add functionality to reinit all the render targets when the window is resized.
|
||||
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);
|
||||
extern void HandleCgError(CGcontext ctx, CGerror err, void *appdata);
|
||||
|
||||
namespace {
|
||||
|
||||
static const GLenum glSrcFactors[8] =
|
||||
{
|
||||
|
@ -121,6 +146,24 @@ static const GLenum glDestFactors[8] = {
|
|||
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA
|
||||
};
|
||||
|
||||
void SetDefaultRectTexParams()
|
||||
{
|
||||
// Set some standard texture filter modes.
|
||||
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) {
|
||||
GLenum err;
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
GL_REPORT_ERROR();
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
bool Renderer::Init()
|
||||
{
|
||||
bool bSuccess = true;
|
||||
|
@ -132,6 +175,7 @@ bool Renderer::Init()
|
|||
cgGetError();
|
||||
cgSetErrorHandler(HandleCgError, NULL);
|
||||
|
||||
|
||||
// Look for required extensions.
|
||||
const char *ptoken = (const char*)glGetString(GL_EXTENSIONS);
|
||||
if (!ptoken)
|
||||
|
@ -143,9 +187,10 @@ bool Renderer::Init()
|
|||
INFO_LOG(VIDEO, ptoken); // write to the log file
|
||||
INFO_LOG(VIDEO, "\n");
|
||||
|
||||
if (strstr(ptoken, "GL_EXT_blend_func_separate") != NULL && strstr(ptoken,
|
||||
"GL_EXT_blend_equation_separate") != NULL)
|
||||
if (strstr(ptoken, "GL_EXT_blend_func_separate") != NULL &&
|
||||
strstr(ptoken, "GL_EXT_blend_equation_separate") != NULL)
|
||||
g_bBlendSeparate = true;
|
||||
|
||||
// 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;
|
||||
|
@ -176,20 +221,17 @@ bool Renderer::Init()
|
|||
if (!bSuccess)
|
||||
return false;
|
||||
|
||||
// Handle VSync on/off
|
||||
#ifdef _WIN32
|
||||
if (WGLEW_EXT_swap_control)
|
||||
wglSwapIntervalEXT(0);
|
||||
wglSwapIntervalEXT(g_Config.bVSync ? 1 : 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);
|
||||
glXSwapIntervalSGI(g_Config.bVSync ? 1 : 0);
|
||||
else
|
||||
ERROR_LOG(VIDEO, "no support for SwapInterval (framerate clamped to monitor refresh rate)\n");
|
||||
#else
|
||||
|
||||
//TODO
|
||||
|
||||
#endif
|
||||
|
||||
// check the max texture width and height
|
||||
|
@ -229,83 +271,60 @@ bool Renderer::Init()
|
|||
if (s_targetheight < EFB_HEIGHT)
|
||||
s_targetheight = EFB_HEIGHT;
|
||||
|
||||
// Create the framebuffer target texture
|
||||
glGenTextures(1, (GLuint *)&s_RenderTarget);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
|
||||
if (!MSAA) {
|
||||
// Create the framebuffer target texture
|
||||
glGenTextures(1, (GLuint *)&s_RenderTarget);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
|
||||
// Create our main color render target as a texture rectangle of the desired size.
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, s_targetwidth, s_targetheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
SetDefaultRectTexParams();
|
||||
|
||||
// Setup the texture params
|
||||
// initialize to default
|
||||
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) {
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
GL_REPORT_ERROR();
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
GL_REPORT_ERROR();
|
||||
GLint nMaxMRT = 0;
|
||||
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &nMaxMRT);
|
||||
if (nMaxMRT > 1)
|
||||
{
|
||||
// There's MRT support. Create a color texture image to use as secondary render target.
|
||||
// We use MRT to render Z into this one, for various purposes (mostly copy Z to texture).
|
||||
glGenTextures(1, (GLuint *)&s_FakeZTarget);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, s_targetwidth, s_targetheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
SetDefaultRectTexParams();
|
||||
}
|
||||
|
||||
GLint nMaxMRT = 0;
|
||||
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &nMaxMRT);
|
||||
if (nMaxMRT > 1)
|
||||
{
|
||||
// Create zbuffer target.
|
||||
glGenTextures(1, (GLuint *)&s_ZBufferTarget);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget);
|
||||
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) {
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
GL_REPORT_ERROR();
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
// Create the real depth/stencil buffer. It's a renderbuffer, not a texture.
|
||||
glGenRenderbuffersEXT(1, &s_DepthTarget);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, s_targetwidth, s_targetheight);
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
// Our framebuffer object is still bound here. Attach the two render targets, color and Z/stencil, to the framebuffer object.
|
||||
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);
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
// create the depth buffer
|
||||
glGenRenderbuffersEXT(1, &s_DepthTarget);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, s_targetwidth, s_targetheight);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, s_targetwidth, s_targetheight);
|
||||
s_bHaveStencilBuffer = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_bHaveStencilBuffer = true;
|
||||
if (s_FakeZTarget != 0) {
|
||||
// We do a simple test to make sure that MRT works. I don't really know why - this is probably a workaround for
|
||||
// some terribly buggy ancient driver.
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget, 0);
|
||||
bool bFailed = glGetError() != GL_NO_ERROR || glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT;
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
||||
if (bFailed) {
|
||||
glDeleteTextures(1, (GLuint *)&s_FakeZTarget);
|
||||
s_FakeZTarget = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_FakeZTarget == 0)
|
||||
ERROR_LOG(VIDEO, "Disabling ztarget MRT feature (max MRT = %d)\n", nMaxMRT);
|
||||
} else {
|
||||
// TODO MSAA rendertarget init
|
||||
}
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
// 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);
|
||||
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
if (s_ZBufferTarget != 0) {
|
||||
// test to make sure it works
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, 0);
|
||||
bool bFailed = glGetError() != GL_NO_ERROR || glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT;
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
||||
|
||||
if (bFailed) {
|
||||
glDeleteTextures(1, (GLuint *)&s_ZBufferTarget);
|
||||
s_ZBufferTarget = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_ZBufferTarget == 0)
|
||||
ERROR_LOG(VIDEO, "Disabling ztarget MRT feature (max MRT = %d)\n", nMaxMRT);
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
nZBufferRender = 0;
|
||||
nZBufferRender = 0; // Initialize the Z render shutoff countdown. We only render Z if it's desired, to save GPU power.
|
||||
|
||||
GL_REPORT_ERROR();
|
||||
if (err != GL_NO_ERROR)
|
||||
|
@ -331,9 +350,9 @@ bool Renderer::Init()
|
|||
|
||||
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_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]);
|
||||
|
@ -344,14 +363,8 @@ bool Renderer::Init()
|
|||
#ifndef _DEBUG
|
||||
cgGLSetDebugMode(GL_FALSE);
|
||||
#endif
|
||||
|
||||
if (cgGetError() != CG_NO_ERROR) {
|
||||
ERROR_LOG(VIDEO, "cg error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_RenderMode = Renderer::RM_Normal;
|
||||
|
||||
if (!InitializeGL())
|
||||
return false;
|
||||
|
||||
|
@ -406,13 +419,13 @@ bool Renderer::InitializeGL()
|
|||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
|
||||
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // perspective correct interpolation of colors and tex coords
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
glHint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE); // Polygon smoothing is ancient junk that doesn't work anymore. MSAA is modern AA.
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// Do we really need to set this initial glScissor() value? Wont it be called all the time while the game is running?
|
||||
//glScissor(0, 0, (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight());
|
||||
|
||||
glScissor(0, 0, GetTargetWidth(), GetTargetHeight());
|
||||
glBlendColorEXT(0, 0, 0, 0.5f);
|
||||
glClearDepth(1.0f);
|
||||
|
||||
|
@ -438,12 +451,12 @@ bool Renderer::InitializeGL()
|
|||
// ------------------------
|
||||
int Renderer::GetTargetWidth()
|
||||
{
|
||||
return (g_Config.bNativeResolution ? EFB_WIDTH : s_targetwidth);
|
||||
return g_Config.bNativeResolution ? EFB_WIDTH : s_targetwidth;
|
||||
}
|
||||
|
||||
int Renderer::GetTargetHeight()
|
||||
{
|
||||
return (g_Config.bNativeResolution ? EFB_HEIGHT : s_targetheight);
|
||||
return g_Config.bNativeResolution ? EFB_HEIGHT : s_targetheight;
|
||||
}
|
||||
|
||||
float Renderer::GetTargetScaleX()
|
||||
|
@ -476,13 +489,21 @@ void Renderer::SetFramebuffer(GLuint fb)
|
|||
fb != 0 ? fb : s_uFramebuffer);
|
||||
}
|
||||
|
||||
GLuint Renderer::GetRenderTarget()
|
||||
GLuint Renderer::ResolveAndGetRenderTarget(const TRectangle &source_rect)
|
||||
{
|
||||
return s_RenderTarget;
|
||||
}
|
||||
GLuint Renderer::GetZBufferTarget()
|
||||
|
||||
GLuint Renderer::ResolveAndGetFakeZTarget(const TRectangle &source_rect)
|
||||
{
|
||||
return nZBufferRender > 0 ? s_ZBufferTarget : 0;
|
||||
// This logic should be moved elsewhere.
|
||||
return s_FakeZTarget;
|
||||
}
|
||||
|
||||
GLuint Renderer::GetFakeZTarget()
|
||||
{
|
||||
// This logic should be moved elsewhere.
|
||||
return nZBufferRender > 0 ? s_FakeZTarget : 0;
|
||||
}
|
||||
|
||||
void Renderer::ResetGLState()
|
||||
|
@ -503,16 +524,17 @@ void Renderer::ResetGLState()
|
|||
void Renderer::RestoreGLState()
|
||||
{
|
||||
// Gets us back into a more game-like state.
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
if (bpmem.genMode.cullmode > 0) glEnable(GL_CULL_FACE);
|
||||
if (bpmem.zmode.testenable) glEnable(GL_DEPTH_TEST);
|
||||
if (bpmem.zmode.updateenable) glDepthMask(GL_TRUE);
|
||||
if (bpmem.zmode.testenable) glEnable(GL_DEPTH_TEST);
|
||||
if (bpmem.zmode.updateenable) glDepthMask(GL_TRUE);
|
||||
|
||||
glEnable(GL_VERTEX_PROGRAM_ARB);
|
||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
SetScissorRect();
|
||||
SetColorMask();
|
||||
SetBlendMode(true);
|
||||
|
||||
glEnable(GL_VERTEX_PROGRAM_ARB);
|
||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
}
|
||||
|
||||
void Renderer::SetColorMask()
|
||||
|
@ -546,7 +568,6 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
|||
|
||||
if (bpmem.blendmode.blendenable) {
|
||||
newval |= 1;
|
||||
|
||||
if (bpmem.blendmode.subtract) {
|
||||
newval |= 0x0048; // src 1 dst 1
|
||||
} else {
|
||||
|
@ -560,7 +581,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
|||
u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode;
|
||||
|
||||
if (changes & 1) {
|
||||
newval & 1 ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||
(newval & 1) ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
bool dstAlphaEnable = g_bBlendSeparate && newval & 2;
|
||||
|
@ -635,8 +656,8 @@ bool Renderer::SetScissorRect()
|
|||
glScissor(
|
||||
(int)rc_left, // x = 0 for example
|
||||
Renderer::GetTargetHeight() - (int)(rc_bottom), // y = 0 for example
|
||||
(int)(rc_right-rc_left), // width = 640 for example
|
||||
(int)(rc_bottom-rc_top) // height = 480 for example
|
||||
(int)(rc_right - rc_left), // width = 640 for example
|
||||
(int)(rc_bottom - rc_top) // height = 480 for example
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -656,16 +677,18 @@ bool Renderer::HaveStencilBuffer()
|
|||
|
||||
void Renderer::SetZBufferRender()
|
||||
{
|
||||
nZBufferRender = 10; // give it 10 frames
|
||||
nZBufferRender = 10; // The game asked for Z. Give it 10 frames, then turn it off for speed.
|
||||
GLenum s_drawbuffers[2] = {
|
||||
GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_COLOR_ATTACHMENT1_EXT
|
||||
};
|
||||
glDrawBuffers(2, s_drawbuffers);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget, 0);
|
||||
_assert_(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
}
|
||||
|
||||
|
||||
// Does this function even work correctly???
|
||||
void Renderer::FlushZBufferAlphaToTarget()
|
||||
{
|
||||
ResetGLState();
|
||||
|
@ -673,12 +696,11 @@ void Renderer::FlushZBufferAlphaToTarget()
|
|||
SetRenderTarget(0);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
|
||||
glViewport(0, 0, GetTargetWidth(), GetTargetHeight());
|
||||
|
||||
// texture map s_RenderTargets[s_curtarget] onto the main buffer
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget);
|
||||
TextureMngr::EnableTexRECT(0);
|
||||
// disable all other stages
|
||||
for (int i = 1; i < 8; ++i)
|
||||
|
@ -691,7 +713,6 @@ 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.bNativeResolution)
|
||||
{
|
||||
//TODO: Do Correctly in a bit
|
||||
|
@ -748,7 +769,6 @@ void Renderer::SetRenderMode(RenderMode mode)
|
|||
else if (s_RenderMode == RM_Normal) {
|
||||
// setup buffers
|
||||
_assert_(GetZBufferTarget() && bpmem.zmode.updateenable);
|
||||
|
||||
if (mode == RM_ZBufferAlpha) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glClearStencil(0);
|
||||
|
@ -771,7 +791,7 @@ void Renderer::SetRenderMode(RenderMode mode)
|
|||
FlushZBufferAlphaToTarget();
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
SetRenderTarget(s_ZBufferTarget);
|
||||
SetRenderTarget(s_FakeZTarget);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
|
@ -797,11 +817,6 @@ Renderer::RenderMode Renderer::GetRenderMode()
|
|||
|
||||
void ComputeBackbufferRectangle(TRectangle *rc)
|
||||
{
|
||||
// -----------------------------------------------------------------------
|
||||
// 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_GetBackbufferWidth();
|
||||
float FloatGLHeight = (float)OpenGL_GetBackbufferHeight();
|
||||
float FloatXOffset = 0;
|
||||
|
@ -833,7 +848,7 @@ void ComputeBackbufferRectangle(TRectangle *rc)
|
|||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
/* Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10. */
|
||||
// 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.bCrop)
|
||||
|
@ -858,7 +873,7 @@ void ComputeBackbufferRectangle(TRectangle *rc)
|
|||
//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
|
||||
// round(float) = floor(float + 0.5)
|
||||
int XOffset = floor(FloatXOffset + 0.5);
|
||||
int YOffset = floor(FloatYOffset + 0.5);
|
||||
rc->left = XOffset;
|
||||
|
@ -885,12 +900,8 @@ void Renderer::Swap(const TRectangle& rc)
|
|||
// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
|
||||
|
||||
// render to the real buffer now
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Show the finished picture
|
||||
// --------------------
|
||||
// Reset GL state
|
||||
ResetGLState();
|
||||
|
||||
// Texture map s_RenderTargets[s_curtarget] onto the main buffer
|
||||
|
@ -901,7 +912,7 @@ void Renderer::Swap(const TRectangle& rc)
|
|||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
TextureMngr::EnableTexRECT(0);
|
||||
|
||||
// Disable all other stages
|
||||
// Disable all other stages.
|
||||
for (int i = 1; i < 8; ++i)
|
||||
TextureMngr::DisableStage(i);
|
||||
|
||||
|
@ -973,7 +984,7 @@ void Renderer::Swap(const TRectangle& rc)
|
|||
|
||||
// For testing zbuffer targets.
|
||||
// Renderer::SetZBufferRender();
|
||||
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_ZBufferTarget, GetTargetWidth(), GetTargetHeight());
|
||||
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget, GetTargetWidth(), GetTargetHeight());
|
||||
}
|
||||
////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -15,54 +15,14 @@
|
|||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
// How the non-true-XFB mode COULD work:
|
||||
//
|
||||
// The game renders to the EFB:
|
||||
//
|
||||
// ----------------------+
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | | efb_height
|
||||
// | |
|
||||
// | |
|
||||
// | - - - - - - - - - - |
|
||||
// | |
|
||||
// +---------------------+
|
||||
// efb_width
|
||||
//
|
||||
// At XFB blit time, the top 640-xxx X XXX part of the above buffer (size dotted below),
|
||||
// should be stretch blitted into the inner rectangle of the window:
|
||||
// +-----------------------------------------+
|
||||
// | | | |
|
||||
// | | . | |
|
||||
// | | | |
|
||||
// | | . | |
|
||||
// | | | |
|
||||
// | | . | | OpenGL_Height()
|
||||
// | | | |
|
||||
// | | . | |
|
||||
// | | - - - - - - - - - - | |
|
||||
// | | \ | |
|
||||
// +-------+---------------------------------+
|
||||
// OpenGL_Width()
|
||||
//
|
||||
//
|
||||
// efb_width and efb_height can even be adjusted so that the last blit will result
|
||||
// in a 1:1 rather than a stretch. That would require creating a bigger efb from the
|
||||
// start though.
|
||||
//
|
||||
// The above is not how it works today.
|
||||
|
||||
/*
|
||||
int win_w = OpenGL_Width();
|
||||
int win_h = OpenGL_Height();
|
||||
// GC graphics pipeline
|
||||
|
||||
int blit_w_640 = last_xfb_specified_width;
|
||||
int blit_h_640 = last_xfb_specified_height;
|
||||
*/
|
||||
// 3d commands are issued through the fifo. The gpu draws to the 2MB EFB.
|
||||
// The efb can be copied back into ram in two forms: as textures or as XFB.
|
||||
// The XFB is the region in RAM that the VI chip scans out to the television.
|
||||
// So, after all rendering to EFB is done, the image is copied into one of two XFBs in RAM.
|
||||
// Next frame, that one is scanned out and the other one gets the copy. = double buffering.
|
||||
|
||||
#ifndef GCOGL_RENDER
|
||||
#define GCOGL_RENDER
|
||||
|
@ -116,7 +76,7 @@ public:
|
|||
static int GetTargetWidth();
|
||||
static int GetTargetHeight();
|
||||
|
||||
// Multiply any 0-640 / 0-480 coordinates by these when rendering.
|
||||
// Multiply any 2D EFB coordinates by these when rendering.
|
||||
static float GetTargetScaleX();
|
||||
static float GetTargetScaleY();
|
||||
|
||||
|
@ -125,8 +85,14 @@ public:
|
|||
static void SetRenderTarget(GLuint targ); // if targ is 0, sets to original render target
|
||||
static void SetDepthTarget(GLuint targ);
|
||||
|
||||
static GLuint GetRenderTarget();
|
||||
static GLuint GetZBufferTarget();
|
||||
// If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID.
|
||||
// Thus, this call may be expensive. Don't repeat it unnecessarily.
|
||||
// If not in MSAA mode, will just return the render target texture ID.
|
||||
static GLuint ResolveAndGetRenderTarget(const TRectangle &rect);
|
||||
|
||||
// Same as above but for the FakeZ Target.
|
||||
static GLuint ResolveAndGetFakeZTarget(const TRectangle &rect);
|
||||
static GLuint GetFakeZTarget(); // This is used by some functions to check for Z target existence. Should be changed to a bool.
|
||||
|
||||
// Random utilities
|
||||
static void RenderText(const char* pstr, int left, int top, u32 color);
|
||||
|
|
|
@ -159,8 +159,8 @@ void Shutdown()
|
|||
s_texConvFrameBuffer = 0;
|
||||
}
|
||||
|
||||
void EncodeToRam(GLuint srcTexture, const TRectangle& sourceRc,
|
||||
u8* destAddr, int dstWidth, int dstHeight, bool linearFilter, FRAGMENTSHADER& shader)
|
||||
void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const TRectangle& sourceRc,
|
||||
u8* destAddr, int dstWidth, int dstHeight, bool linearFilter)
|
||||
{
|
||||
Renderer::SetRenderMode(Renderer::RM_Normal);
|
||||
|
||||
|
@ -241,20 +241,22 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
|||
format |= _GX_TF_CTF;
|
||||
}
|
||||
|
||||
FRAGMENTSHADER& fs = GetOrCreateEncodingShader(format);
|
||||
if (fs.glprogid == 0)
|
||||
FRAGMENTSHADER& texconv_shader = GetOrCreateEncodingShader(format);
|
||||
if (texconv_shader.glprogid == 0)
|
||||
return;
|
||||
|
||||
u8* ptr = Memory_GetPtr(address);
|
||||
|
||||
u32 target = bFromZBuffer ? Renderer::GetZBufferTarget() : Renderer::GetRenderTarget();
|
||||
|
||||
u32 source_texture = bFromZBuffer ? Renderer::ResolveAndGetFakeZTarget(source) : Renderer::ResolveAndGetRenderTarget(source);
|
||||
s32 width = source.right - source.left;
|
||||
s32 height = source.bottom - source.top;
|
||||
|
||||
if (bScaleByHalf)
|
||||
{
|
||||
// Hm. Shouldn't this only scale destination, not source?
|
||||
// The bloom in Beyond Good & Evil is a good test case - due to this problem,
|
||||
// it goes very wrong. Compare by switching back and forth between Copy textures to RAM and GL Texture.
|
||||
// This also affects the shadows in Burnout 2 badly.
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
|
@ -278,7 +280,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
|||
scaledSource.left = 0;
|
||||
scaledSource.right = expandedWidth / samples;
|
||||
|
||||
EncodeToRam(target, scaledSource, ptr, expandedWidth / samples, expandedHeight, bScaleByHalf, fs);
|
||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, ptr, expandedWidth / samples, expandedHeight, bScaleByHalf);
|
||||
|
||||
if (bFromZBuffer)
|
||||
Renderer::SetZBufferRender(); // notify for future settings
|
||||
|
@ -287,7 +289,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
|||
void EncodeToRamYUYV(GLuint srcTexture, const TRectangle& sourceRc,
|
||||
u8* destAddr, int dstWidth, int dstHeight)
|
||||
{
|
||||
EncodeToRam(srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, false, s_rgbToYuyvProgram);
|
||||
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, false);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -239,14 +239,12 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
|||
* The problem here was just the sparse hash on the texture. This texture is partly overwrited (what is needed only)
|
||||
* so lot's of remaning old text. Thin white chars on black bg too.
|
||||
*/
|
||||
|
||||
// TODO: - clean this up when ready to kill old "unsafe texture cache"
|
||||
// - fix the key index situation with CopyRenderTargetToTexture.
|
||||
// Could happen only for GX_TF_C4, GX_TF_C8 and GX_TF_C14X2 fmt.
|
||||
// Wonder if we can't use tex width&height to know if EFB might be copied to it...
|
||||
// raw idea: TOCHECK if addresses are aligned we have few bits left...
|
||||
|
||||
|
||||
if (address == 0)
|
||||
return NULL;
|
||||
|
||||
|
@ -259,19 +257,24 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
|||
u32 texID = address;
|
||||
if (g_Config.bSafeTextureCache)
|
||||
{
|
||||
hash_value = TexDecoder_GetSafeTextureHash(ptr, expandedWidth, height, format, 0); // remove last arg
|
||||
if ( (format == GX_TF_C4) || (format == GX_TF_C8) || (format == GX_TF_C14X2) )
|
||||
hash_value = TexDecoder_GetSafeTextureHash(ptr, expandedWidth, height, format, 0); // remove last arg
|
||||
if ((format == GX_TF_C4) || (format == GX_TF_C8) || (format == GX_TF_C14X2))
|
||||
{
|
||||
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
|
||||
// tlut size can be up to 32768B (GX_TF_C14X2) but Safer == Slower.
|
||||
//texID ^= TexDecoder_GetTlutHash(&texMem[tlutaddr], TexDecoder_GetPaletteSize(format));
|
||||
|
||||
// This trick (to change the texID depending on the TLUT addr) is a trick to get around
|
||||
// an issue with metroid prime's fonts, where it has multiple sets of fonts on top of
|
||||
// each other stored in a single texture, and uses the palette to make different characters
|
||||
// visible or invisible. Thus, unless we want to recreate the textures for every drawn character,
|
||||
// we must make sure that texture with different tluts get different IDs.
|
||||
texID ^= TexDecoder_GetTlutHash(&texMem[tlutaddr], (format == GX_TF_C4) ? 32 : 128);
|
||||
//DebugLog("addr: %08x | texID: %08x | texHash: %08x", address, texID, hash_value);
|
||||
}
|
||||
}
|
||||
|
||||
bool skip_texture_create = false;
|
||||
|
||||
TexCache::iterator iter = textures.find(texID);
|
||||
|
||||
if (iter != textures.end()) {
|
||||
|
@ -280,10 +283,12 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
|||
if (!g_Config.bSafeTextureCache)
|
||||
hash_value = ((u32 *)ptr)[entry.hashoffset];
|
||||
|
||||
if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash))) {
|
||||
if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash)))
|
||||
{
|
||||
entry.frameCount = frameCount;
|
||||
//glEnable(entry.isNonPow2?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D);
|
||||
glBindTexture(entry.isNonPow2 ? GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D, entry.texture);
|
||||
//glEnable(entry.isNonPow2?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D);
|
||||
// entry.isNonPow2 ? TextureMngr::EnableTex2D(texstage) : TextureMngr::EnableTexRECT(texstage);
|
||||
glBindTexture(entry.isNonPow2 ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture);
|
||||
if (entry.mode.hex != tm0.hex)
|
||||
entry.SetTextureParameters(tm0);
|
||||
//DebugLog("%cC addr: %08x | fmt: %i | e.hash: %08x | w:%04i h:%04i", g_Config.bSafeTextureCache ? 'S' : 'U'
|
||||
|
@ -406,7 +411,8 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
|||
return &entry;
|
||||
}
|
||||
|
||||
void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, TRectangle *source)
|
||||
|
||||
void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const TRectangle &source_rect)
|
||||
{
|
||||
DVSTARTPROFILE();
|
||||
GL_REPORT_ERRORD();
|
||||
|
@ -431,8 +437,8 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
|||
entry.frameCount = frameCount;
|
||||
|
||||
int mult = bScaleByHalf?2:1;
|
||||
int w = (abs(source->right-source->left)/mult);
|
||||
int h = (abs(source->bottom-source->top)/mult);
|
||||
int w = (abs(source_rect.GetWidth())/mult);
|
||||
int h = (abs(source_rect.GetHeight())/mult);
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
|
@ -600,7 +606,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
|||
Renderer::SetRenderMode(Renderer::RM_Normal); // set back to normal
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
// have to run a pixel shader
|
||||
// We have to run a pixel shader, for color conversion.
|
||||
|
||||
Renderer::ResetGLState(); // reset any game specific settings
|
||||
|
||||
|
@ -632,7 +638,11 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
|||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, bFromZBuffer?Renderer::GetZBufferTarget():Renderer::GetRenderTarget());
|
||||
if (bFromZBuffer) {
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, Renderer::ResolveAndGetFakeZTarget(source_rect));
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, Renderer::ResolveAndGetRenderTarget(source_rect));
|
||||
}
|
||||
TextureMngr::EnableTexRECT(0);
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
|
@ -645,10 +655,10 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
|||
glBegin(GL_QUADS);
|
||||
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);
|
||||
glTexCoord2f((float)source_rect.left * MValueX, Renderer::GetTargetHeight()-(float)source_rect.bottom * MValueY); glVertex2f(-1, 1);
|
||||
glTexCoord2f((float)source_rect.left * MValueX, Renderer::GetTargetHeight()-(float)source_rect.top * MValueY); glVertex2f(-1, -1);
|
||||
glTexCoord2f((float)source_rect.right * MValueX, Renderer::GetTargetHeight()-(float)source_rect.top * MValueY); glVertex2f( 1, -1);
|
||||
glTexCoord2f((float)source_rect.right * MValueX, Renderer::GetTargetHeight()-(float)source_rect.bottom * MValueY); glVertex2f( 1, 1);
|
||||
glEnd();
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
@ -669,14 +679,14 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
|||
|
||||
void TextureMngr::EnableTex2D(int stage)
|
||||
{
|
||||
if (!(nTex2DEnabled & (1<<stage))) {
|
||||
nTex2DEnabled |= (1<<stage);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
if (nTexRECTEnabled & (1<<stage)) {
|
||||
nTexRECTEnabled &= ~(1<<stage);
|
||||
glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
}
|
||||
if (!(nTex2DEnabled & (1<<stage))) {
|
||||
nTex2DEnabled |= (1<<stage);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureMngr::EnableTexRECT(int stage)
|
||||
|
@ -710,6 +720,6 @@ void TextureMngr::DisableStage(int stage)
|
|||
|
||||
void TextureMngr::ClearRenderTargets()
|
||||
{
|
||||
for (TexCache::iterator iter = textures.begin(); iter!=textures.end(); iter++)
|
||||
for (TexCache::iterator iter = textures.begin(); iter != textures.end(); iter++)
|
||||
iter->second.isRenderTarget = false;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
static void Shutdown();
|
||||
static void Invalidate(bool shutdown);
|
||||
static TCacheEntry* Load(int texstage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt);
|
||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, TRectangle *source);
|
||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const TRectangle &source);
|
||||
|
||||
static void EnableTex2D(int stage);
|
||||
static void EnableTexRECT(int stage);
|
||||
|
|
|
@ -242,7 +242,7 @@ void Flush()
|
|||
VERTEXSHADER* vs = VertexShaderCache::GetShader(g_nativeVertexFmt->m_components);
|
||||
|
||||
bool bRestoreBuffers = false;
|
||||
if (Renderer::GetZBufferTarget()) {
|
||||
if (Renderer::GetFakeZTarget()) {
|
||||
if (bpmem.zmode.updateenable) {
|
||||
if (!bpmem.blendmode.colorupdate) {
|
||||
Renderer::SetRenderMode(bpmem.blendmode.alphaupdate ? Renderer::RM_ZBufferAlpha : Renderer::RM_ZBufferOnly);
|
||||
|
|
|
@ -72,7 +72,7 @@ VERTEXSHADER* VertexShaderCache::GetShader(u32 components)
|
|||
{
|
||||
DVSTARTPROFILE();
|
||||
VERTEXSHADERUID uid;
|
||||
u32 zbufrender = (bpmem.ztex2.op == ZTEXTURE_ADD) || Renderer::GetZBufferTarget() != 0;
|
||||
u32 zbufrender = (bpmem.ztex2.op == ZTEXTURE_ADD) || Renderer::GetFakeZTarget() != 0;
|
||||
GetVertexShaderId(uid, components, zbufrender);
|
||||
|
||||
VSCache::iterator iter = vshaders.find(uid);
|
||||
|
@ -87,7 +87,7 @@ VERTEXSHADER* VertexShaderCache::GetShader(u32 components)
|
|||
}
|
||||
|
||||
VSCacheEntry& entry = vshaders[uid];
|
||||
const char *code = GenerateVertexShader(components, Renderer::GetZBufferTarget() != 0);
|
||||
const char *code = GenerateVertexShader(components, Renderer::GetFakeZTarget() != 0);
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
if (g_Config.iLog & CONF_SAVESHADERS && code) {
|
||||
|
|
|
@ -86,7 +86,7 @@ void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt)
|
|||
// 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);
|
||||
TextureConverter::EncodeToRamYUYV(Renderer::ResolveAndGetRenderTarget(sourceRc), renderSrcRc, xfb_in_ram, dstWd, dstHt);
|
||||
}
|
||||
|
||||
// Draw the XFB straight to the OpenGL backbuffer.
|
||||
|
@ -208,7 +208,7 @@ void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt)
|
|||
glEnd();
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
int width = sourceRc.right - sourceRc.left;
|
||||
int width = sourceRc.right - sourceRc.left;
|
||||
int height = sourceRc.bottom - sourceRc.top;
|
||||
glReadPixels(sourceRc.left, sourceRc.top, width, height, GL_RGBA, GL_UNSIGNED_BYTE, efb_buffer);
|
||||
GL_REPORT_ERRORD();
|
||||
|
|
|
@ -189,7 +189,7 @@ void DllConfig(HWND _hParent)
|
|||
{
|
||||
for (int i = 0; i < modeNum; i++)
|
||||
{
|
||||
if(px != modes[i]->hdisplay && py != modes[i]->vdisplay)
|
||||
if (px != modes[i]->hdisplay && py != modes[i]->vdisplay)
|
||||
{
|
||||
char temp[32];
|
||||
sprintf(temp,"%dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
|
||||
|
@ -219,8 +219,6 @@ void DllConfig(HWND _hParent)
|
|||
|
||||
void Initialize(void *init)
|
||||
{
|
||||
//Console::Open();
|
||||
|
||||
frameCount = 0;
|
||||
SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init;
|
||||
g_VideoInitialize = *(_pVideoInitialize); // Create a shortcut to _pVideoInitialize that can also update it
|
||||
|
@ -250,8 +248,6 @@ void DoState(unsigned char **ptr, int mode) {
|
|||
#endif
|
||||
// Clear all caches that touch RAM
|
||||
TextureMngr::Invalidate(false);
|
||||
// DisplayListManager::Invalidate();
|
||||
|
||||
VertexLoaderManager::MarkAllDirty();
|
||||
|
||||
PointerWrap p(ptr, mode);
|
||||
|
|
|
@ -22,7 +22,4 @@
|
|||
|
||||
extern SVideoInitialize g_VideoInitialize;
|
||||
|
||||
// Logging
|
||||
extern int GLScissorX, GLScissorY, GLScissorW, GLScissorH;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue