FramebufferPtr Framebuffer::Create() { FramebufferPtr fb = FramebufferPtr(new Framebuffer); glGenFramebuffers(1, &fb->m_FBO); return fb; }
void CGSH_Direct3D9::SetupFramebuffer(uint64 frameReg, uint64 scissorReg) { if(frameReg == 0) return; auto frame = make_convertible<FRAME>(frameReg); auto scissor = make_convertible<SCISSOR>(scissorReg); { bool r = (frame.nMask & 0x000000FF) == 0; bool g = (frame.nMask & 0x0000FF00) == 0; bool b = (frame.nMask & 0x00FF0000) == 0; bool a = (frame.nMask & 0xFF000000) == 0; UINT colorMask = (r ? D3DCOLORWRITEENABLE_RED : 0) | (g ? D3DCOLORWRITEENABLE_GREEN : 0) | (b ? D3DCOLORWRITEENABLE_BLUE : 0) | (a ? D3DCOLORWRITEENABLE_ALPHA : 0); m_device->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); } bool newFramebuffer = false; auto framebuffer = FindFramebuffer(frameReg); if(!framebuffer) { framebuffer = FramebufferPtr(new CFramebuffer(m_device, frame.GetBasePtr(), frame.GetWidth(), 1024, frame.nPsm)); m_framebuffers.push_back(framebuffer); newFramebuffer = true; } //Any framebuffer selected at this point can be used as a texture framebuffer->m_canBeUsedAsTexture = true; float projWidth = static_cast<float>(framebuffer->m_width); float projHeight = static_cast<float>(framebuffer->m_height); HRESULT result = S_OK; Framework::Win32::CComPtr<IDirect3DSurface9> renderSurface; result = framebuffer->m_renderTarget->GetSurfaceLevel(0, &renderSurface); assert(SUCCEEDED(result)); result = m_device->SetRenderTarget(0, renderSurface); assert(SUCCEEDED(result)); if(newFramebuffer) { //TODO: Get actual contents from GS RAM m_device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); m_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); } RECT scissorRect = {}; scissorRect.left = scissor.scax0; scissorRect.top = scissor.scay0; scissorRect.right = scissor.scax1 + 1; scissorRect.bottom = scissor.scay1 + 1; m_device->SetScissorRect(&scissorRect); m_device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); SetReadCircuitMatrix(projWidth, projHeight); }
CGSH_Direct3D9::FramebufferPtr CGSH_Direct3D9::FindFramebuffer(uint64 frameReg) const { auto frame = make_convertible<FRAME>(frameReg); auto framebufferIterator = std::find_if(std::begin(m_framebuffers), std::end(m_framebuffers), [&] (const FramebufferPtr& framebuffer) { return (framebuffer->m_basePtr == frame.GetBasePtr()) && (framebuffer->m_width == frame.GetWidth()); } ); return (framebufferIterator != std::end(m_framebuffers)) ? *(framebufferIterator) : FramebufferPtr(); }
void CGSH_Direct3D9::SetupFramebuffer(uint64 frameReg) { if(frameReg == 0) return; auto frame = make_convertible<FRAME>(frameReg); { bool r = (frame.nMask & 0x000000FF) == 0; bool g = (frame.nMask & 0x0000FF00) == 0; bool b = (frame.nMask & 0x00FF0000) == 0; bool a = (frame.nMask & 0xFF000000) == 0; UINT colorMask = (r ? D3DCOLORWRITEENABLE_RED : 0) | (g ? D3DCOLORWRITEENABLE_GREEN : 0) | (b ? D3DCOLORWRITEENABLE_BLUE : 0) | (a ? D3DCOLORWRITEENABLE_ALPHA : 0); m_device->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); } auto framebuffer = FindFramebuffer(frameReg); if(!framebuffer) { framebuffer = FramebufferPtr(new CFramebuffer(m_device, frame.GetBasePtr(), frame.GetWidth(), 1024, frame.nPsm)); m_framebuffers.push_back(framebuffer); } //Any framebuffer selected at this point can be used as a texture framebuffer->m_canBeUsedAsTexture = true; float projWidth = static_cast<float>(framebuffer->m_width); float projHeight = static_cast<float>(framebuffer->m_height); HRESULT result = S_OK; Framework::Win32::CComPtr<IDirect3DSurface9> renderSurface; result = framebuffer->m_renderTarget->GetSurfaceLevel(0, &renderSurface); assert(SUCCEEDED(result)); result = m_device->SetRenderTarget(0, renderSurface); assert(SUCCEEDED(result)); SetReadCircuitMatrix(projWidth, projHeight); }