void DevState::createCleanState() { if (dwMyThread != 0) { ods("D3D9: CreateCleanState from other thread."); } Stash<DWORD> stashThread(&dwMyThread, GetCurrentThreadId()); if (pSB) pSB->Release(); pSB = NULL; IDirect3DStateBlock9* pStateBlock = NULL; dev->CreateStateBlock(D3DSBT_ALL, &pStateBlock); if (! pStateBlock) return; pStateBlock->Capture(); dev->CreateStateBlock(D3DSBT_ALL, &pSB); if (! pSB) { pStateBlock->Release(); return; } D3DVIEWPORT9 vp; dev->GetViewport(&vp); dev->SetVertexShader(NULL); dev->SetPixelShader(NULL); dev->SetFVF(D3DFVF_TLVERTEX); dev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); dev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // 0x16 dev->SetRenderState(D3DRS_WRAP0, FALSE); // 0x80 dev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); dev->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); dev->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); dev->SetRenderState(D3DRS_ZENABLE, FALSE); dev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); dev->SetRenderState(D3DRS_COLORVERTEX, FALSE); dev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); dev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); dev->SetRenderState(D3DRS_LIGHTING, FALSE); pSB->Capture(); pStateBlock->Apply(); pStateBlock->Release(); }
void CState::Save() { if( !m_StateBlock && m_D3DDev ) m_D3DDev->CreateStateBlock(D3DSBT_ALL, &m_StateBlock); if( m_StateBlock ) m_StateBlock->Capture(); }
static void doPresent(IDirect3DDevice9 *idd) { DevMapType::iterator it = devMap.find(idd); DevState *ds = it != devMap.end() ? it->second : NULL; if (ds && ds->pSB) { if (ds->dwMyThread != 0) { ods("D3D9: doPresent from other thread"); } Stash<DWORD> stashThread(&(ds->dwMyThread), GetCurrentThreadId()); IDirect3DSurface9 *pTarget = NULL; IDirect3DSurface9 *pRenderTarget = NULL; idd->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pTarget); idd->GetRenderTarget(0, &pRenderTarget); // Present is called for each frame. Thus, we do not want to always log here. #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("D3D9: doPresent BackB %p RenderT %p", pTarget, pRenderTarget); #endif IDirect3DStateBlock9* pStateBlock = NULL; idd->CreateStateBlock(D3DSBT_ALL, &pStateBlock); pStateBlock->Capture(); ds->pSB->Apply(); if (pTarget != pRenderTarget) idd->SetRenderTarget(0, pTarget); idd->BeginScene(); ds->draw(); idd->EndScene(); pStateBlock->Apply(); pStateBlock->Release(); pRenderTarget->Release(); pTarget->Release(); // ods("D3D9: Finished ref is %d %d", ds->myRefCount, ds->refCount); } }
static void doPresent(IDirect3DDevice9 *idd) { DevState *ds = devMap[idd]; if (ds && ds->pSB) { DWORD dwOldThread = ds->dwMyThread; if (dwOldThread) ods("doPresent from other thread"); ds->dwMyThread = GetCurrentThreadId(); IDirect3DSurface9 *pTarget = NULL; IDirect3DSurface9 *pRenderTarget = NULL; idd->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pTarget); idd->GetRenderTarget(0, &pRenderTarget); ods("D3D9: doPresent Back %p RenderT %p",pTarget,pRenderTarget); IDirect3DStateBlock9* pStateBlock = NULL; idd->CreateStateBlock(D3DSBT_ALL, &pStateBlock); pStateBlock->Capture(); ds->pSB->Apply(); if (pTarget != pRenderTarget) idd->SetRenderTarget(0, pTarget); idd->BeginScene(); ds->draw(); idd->EndScene(); pStateBlock->Apply(); pStateBlock->Release(); pRenderTarget->Release(); pTarget->Release(); // ods("Finished ref is %d %d", ds->myRefCount, ds->refCount); ds->dwMyThread = dwOldThread; } }
//-------------------------------------------------------------------------------- void System::OnRender(IDirect3DDevice9* pDevice) { //if(clock() - TheGameWorld->GetRendering() < 400) { IDirect3DStateBlock9* pStateBlock = NULL; pDevice->CreateStateBlock(D3DSBT_ALL, &pStateBlock); pStateBlock->Capture(); try { if(mUI && mPlatform) { Update(); mPlatform->getRenderManagerPtr()->drawOneFrame(); } } catch(...) { } pStateBlock->Apply(); pStateBlock->Release(); } }
STDMETHODIMP CDirect3DDevice8::CaptureStateBlock(THIS_ DWORD Token) { IDirect3DStateBlock9* pBlock = (IDirect3DStateBlock9*)Token; return pBlock->Capture(); }
/// Present the overlay. /// /// If called via IDirect3DDevice9::present() or IDirect3DDevice9Ex::present(), /// idd will be non-NULL and ids ill be NULL. /// /// If called via IDirect3DSwapChain9::present(), both idd and ids will be /// non-NULL. /// /// The doPresent function expects the following assumptions to be valid: /// /// - Only one swap chain used at the same time. /// - Windowed? IDirect3D9SwapChain::present() is used. ("Additional swap chain" is used) /// - Full screen? IDirect3D9Device::present() is used. (Implicit swap chain for IDirect3D9Device is used) /// /// It's either/or. /// /// If doPresent is called multiple times per frame (say, for different swap chains), /// the overlay will break badly when DevState::draw() is called. FPS counting will be off, /// different render targets with different sizes will cause a size-renegotiation with Mumble /// every frame, etc. static void doPresent(IDirect3DDevice9 *idd, IDirect3DSwapChain9 *ids) { DevMapType::iterator it = devMap.find(idd); DevState *ds = it != devMap.end() ? it->second : NULL; HRESULT hres; if (ds && ds->pSB) { if (ds->dwMyThread != 0) { ods("D3D9: doPresent from other thread"); } Stash<DWORD> stashThread(&(ds->dwMyThread), GetCurrentThreadId()); // Get the back buffer. // If we're called via IDirect3DSwapChain9, acquire it via the swap chain object. // Otherwise, acquire it via the device itself. IDirect3DSurface9 *pTarget = NULL; if (ids) { hres = ids->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pTarget); if (FAILED(hres)) { if (hres == D3DERR_INVALIDCALL) { ods("D3D9: IDirect3DSwapChain9::GetBackBuffer failed. BackBuffer index equals or exceeds the total number of back buffers"); } else { ods("D3D9: IDirect3DSwapChain9::GetBackBuffer failed"); } } } else { hres = idd->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pTarget); if (FAILED(hres)) { if (hres == D3DERR_INVALIDCALL) { ods("D3D9: IDirect3DDevice9::GetBackBuffer failed. BackBuffer index equals or exceeds the total number of back buffers"); } else { ods("D3D9: IDirect3DDevice9::GetBackBuffer failed"); } } } IDirect3DSurface9 *pRenderTarget = NULL; hres = idd->GetRenderTarget(0, &pRenderTarget); if (FAILED(hres)) { if (hres == D3DERR_NOTFOUND) { ods("D3D9: IDirect3DDevice9::GetRenderTarget failed. There is no render target with the specified index"); } else if (hres == D3DERR_INVALIDCALL) { ods("D3D9: IDirect3DDevice9::GetRenderTarget failed. One of the passed arguments was invalid"); } else { ods("D3D9: IDirect3DDevice9::GetRenderTarget failed"); } } // Present is called for each frame. Thus, we do not want to always log here. #ifdef EXTENDED_OVERLAY_DEBUGOUTPUT ods("D3D9: doPresent BackB %p RenderT %p", pTarget, pRenderTarget); #endif IDirect3DStateBlock9* pStateBlock = NULL; idd->CreateStateBlock(D3DSBT_ALL, &pStateBlock); pStateBlock->Capture(); ds->pSB->Apply(); if (pTarget != pRenderTarget) { hres = idd->SetRenderTarget(0, pTarget); if (FAILED(hres)) { ods("D3D9: IDirect3DDevice9::SetRenderTarget failed"); } } // If we're called via IDirect3DSwapChain9::present(), we have to // get the size of the back buffer and manually set the viewport size // to match it. // // Although the call to IDirect3DDevice9::SetRenderTarget() above is // documented as updating the device's viewport: // // "Setting a new render target will cause the viewport (see Viewports // and Clipping (Direct3D 9)) to be set to the full size of the new // render target." // // (via https://msdn.microsoft.com/en-us/library/windows/desktop/bb174455(v=vs.85).aspx) // // ...this doesn't happen. At least for some programs such as Final Fantasy XIV // and Battle.net Launcher. For these programs, we get a viewport of 1x1. // // The viewport we set here is used in the call below to DevState::draw() // as the full size of the screen/window. if (ids) { D3DPRESENT_PARAMETERS pp; hres = ids->GetPresentParameters(&pp); if (FAILED(hres)) { ods("D3D9: IDirect3DSwapChain9::GetPresentParameters failed"); } else { if (pp.BackBufferWidth != 0 && pp.BackBufferHeight != 0) { D3DVIEWPORT9 vp; vp.X = 0; vp.Y = 0; vp.Width = pp.BackBufferWidth; vp.Height = pp.BackBufferHeight; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; idd->SetViewport(&vp); } } } idd->BeginScene(); ds->draw(); idd->EndScene(); pStateBlock->Apply(); pStateBlock->Release(); pRenderTarget->Release(); pTarget->Release(); // ods("D3D9: Finished ref is %d %d", ds->myRefCount, ds->refCount); } }