diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index 3831bda0ba..2edca7312f 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.cpp +++ b/Source/Core/Core/Src/HW/VideoInterface.cpp @@ -502,7 +502,6 @@ void Update() { LastTime += (TicksPerFrame / LineCount); - // VerticalBeamPos++; if (VerticalBeamPos > LineCount) { @@ -517,19 +516,19 @@ void Update() if (NextXFBRender == 1) { NextXFBRender = LinesPerField; - // The & mask is a hack for mario kart - u32 addr = (VideoInterface::m_FrameBufferTop.Hex & 0xFFFFFFF) | 0x80000000; - if (addr >= 0x80000000 && - addr <= (0x81800000-640*480*2)) - xfbPtr = Memory::GetPointer(addr); + u32 addr = (VideoInterface::m_FrameBufferTop.Hex & 0xFFFFFFF); + if (VideoInterface::m_FrameBufferTop.Hex & 0x10000000) + addr = addr << 5; + xfbPtr = Memory::GetPointer(addr); } else { NextXFBRender = 1; - u32 addr = (VideoInterface::m_FrameBufferBottom.Hex & 0xFFFFFFF) | 0x80000000; - if (addr >= 0x80000000 && - addr <= (0x81800000-640*480*2)) - xfbPtr = Memory::GetPointer(addr); + u32 addr = (VideoInterface::m_FrameBufferBottom.Hex & 0xFFFFFFF); + // check the top buffer address not the bottom + if (VideoInterface::m_FrameBufferTop.Hex & 0x10000000) + addr = addr << 5; + xfbPtr = Memory::GetPointer(addr); yOffset = -1; } Common::PluginVideo* video = CPluginManager::GetInstance().GetVideo(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp index 8cc3ca914f..5d516b75d7 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp @@ -39,22 +39,7 @@ // --------------------------------------------------------------------------------------- // State translation lookup tables // ------------- -static const GLenum glSrcFactors[8] = -{ - GL_ZERO, - GL_ONE, - GL_DST_COLOR, - GL_ONE_MINUS_DST_COLOR, - GL_SRC_ALPHA, - GL_ONE_MINUS_SRC_ALPHA, - GL_DST_ALPHA, - GL_ONE_MINUS_DST_ALPHA -}; -static const GLenum glDestFactors[8] = { - GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, - GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA -}; static const GLenum glCmpFuncs[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS }; @@ -162,7 +147,7 @@ void BPWritten(int addr, int changes, int newval) VertexManager::Flush(); ((u32*)&bpmem)[addr] = newval; PRIM_LOG("constalpha: alp=%d, en=%d\n", bpmem.dstalpha.alpha, bpmem.dstalpha.enable); - PixelShaderManager::SetDestAlpha(bpmem.dstalpha); + Renderer::SetBlendMode(false); } break; @@ -191,14 +176,7 @@ void BPWritten(int addr, int changes, int newval) PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d\n", bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode); - - if (changes & 1) { - if (bpmem.blendmode.blendenable) { - glEnable(GL_BLEND); - - } - else glDisable(GL_BLEND); - } + if (changes & 2) { if (Renderer::CanBlendLogicOp()) { if (bpmem.blendmode.logicopenable) { @@ -251,22 +229,14 @@ void BPWritten(int addr, int changes, int newval) // } //} } - if (changes & 4) { + /*if (changes & 4) { // pointless //if (bpmem.blendmode.dither) glEnable(GL_DITHER); //else glDisable(GL_DITHER); } - if (changes & 0xFE0) { - if (!bpmem.blendmode.subtract) - glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]); - } - if (changes & 0x800) { - glBlendEquation(bpmem.blendmode.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD); - if (bpmem.blendmode.subtract) - glBlendFunc(GL_ONE, GL_ONE); - else - glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]); - } + */ + if (changes & 0xFE1) + Renderer::SetBlendMode(false); if (changes & 0x18) Renderer::SetColorMask(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 2c6c710f96..981008e946 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -102,11 +102,30 @@ static bool s_bHaveStencilBuffer = false; static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal; bool g_bBlendLogicOp = false; +bool g_bBlendSeparate = false; int frameCount; void HandleCgError(CGcontext ctx, CGerror err, void *appdata); ///////////////////////////// +static const GLenum glSrcFactors[8] = +{ + GL_ZERO, + GL_ONE, + GL_DST_COLOR, + GL_ONE_MINUS_DST_COLOR, + GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, + GL_DST_ALPHA, + GL_ONE_MINUS_DST_ALPHA +}; + +static const GLenum glDestFactors[8] = { + GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA +}; + +static u32 s_blendMode; bool Renderer::Init() { @@ -126,6 +145,8 @@ bool Renderer::Init() if (strstr(ptoken, "GL_EXT_blend_logic_op") != NULL) g_bBlendLogicOp = true; + if (strstr(ptoken, "GL_EXT_blend_func_separate") != NULL && strstr(ptoken, "GL_EXT_blend_equation_separate") != NULL) + g_bBlendSeparate = true; if (strstr(ptoken, "ATI_draw_buffers") != NULL && strstr(ptoken, "ARB_draw_buffers") == NULL) //Checks if it ONLY has the ATI_draw_buffers extension, some have both s_bATIDrawBuffers = true; @@ -556,12 +577,12 @@ void Renderer::RestoreGLState() if (bpmem.genMode.cullmode > 0) glEnable(GL_CULL_FACE); if (bpmem.zmode.testenable) glEnable(GL_DEPTH_TEST); - if (bpmem.blendmode.blendenable) glEnable(GL_BLEND); if (bpmem.zmode.updateenable) glDepthMask(GL_TRUE); glEnable(GL_VERTEX_PROGRAM_ARB); glEnable(GL_FRAGMENT_PROGRAM_ARB); SetColorMask(); + SetBlendMode(true); } void Renderer::SetColorMask() @@ -574,6 +595,68 @@ void Renderer::SetColorMask() glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); } +void Renderer::SetBlendMode(bool forceUpdate) +{ + // blend mode bit mask + // 0 - blend enable + // 1 - dst alpha enable + // 2 - reverse subtract enable (else add) + // 3-5 - srcRGB function + // 6-8 - dstRGB function + // 9-16 - dstAlpha + + u32 newval = bpmem.blendmode.subtract << 2; + + if (g_bBlendSeparate) { + newval |= bpmem.dstalpha.enable ? 3 : 0; + newval |= bpmem.dstalpha.alpha << 9; + } + + if (bpmem.blendmode.blendenable) { + newval |= 1; + + if (bpmem.blendmode.subtract) { + newval |= 0x0048; // src 1 dst 1 + } else { + newval |= bpmem.blendmode.srcfactor << 3; + newval |= bpmem.blendmode.dstfactor << 6; + } + } else { + newval |= 0x0008; // src 1 dst 0 + } + + u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode; + + if (changes & 1) { + newval & 1 ? glEnable(GL_BLEND) : glDisable(GL_BLEND); + } + + bool dstAlphaEnable = g_bBlendSeparate && newval & 2; + + if (changes & 6) { + // dst alpha enable or subtract enable change + if (dstAlphaEnable) + glBlendEquationSeparate(newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD, GL_FUNC_ADD); + else + glBlendEquation(newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD); + } + + if (changes & 0x1FA) { + // dst alpha enable or blend RGB change + if (dstAlphaEnable) + glBlendFuncSeparate(glSrcFactors[(newval >> 3) & 7], glDestFactors[(newval >> 6) & 7], GL_CONSTANT_ALPHA, GL_ZERO); + else + glBlendFunc(glSrcFactors[(newval >> 3) & 7], glDestFactors[(newval >> 6) & 7]); + } + + if (dstAlphaEnable && changes & 0x1FE00) { + // dst alpha color change + glBlendColor(0, 0, 0, (float)bpmem.dstalpha.alpha / 255.0f); + } + + s_blendMode = newval; +} + // Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg() // case 0x52 > SetScissorRect() // --------------- @@ -1133,4 +1216,4 @@ void UpdateViewport() } glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f); -} +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h index 9de2f3ee98..292bb72449 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h @@ -116,6 +116,7 @@ public: static GLuint GetZBufferTarget(); static void SetColorMask(); + static void SetBlendMode(bool forceUpdate); static bool SetScissorRect(); static void SetRenderMode(RenderMode mode);