поэтому я написал класс Post Processing для какой-то старой игры с открытым исходным кодом,
У меня есть функция начала сцены, функция конца сцены, функция рендеринга и функция для создания отряда экрана и ресурсов.
bool CPostProcessingChain::BeginScene()
{
if (!m_lpSourceTexture || !m_lpLastPass || !m_lpTarget || !m_lpDepthStencilSurface)
{
if (!CreateResources())
{
return false;
}
}
STATEMANAGER.GetDevice()->GetRenderTarget(0, &m_lpBackupTargetSurface);
STATEMANAGER.GetDevice()->SetRenderTarget(0, m_lpSourceTextureSurface);
STATEMANAGER.GetDevice()->GetDepthStencilSurface(&m_lpDepthStencilBackup);
STATEMANAGER.GetDevice()->SetDepthStencilSurface(m_lpDepthStencilSurface);
return true;
}bool CPostProcessingChain::EndScene()
{
STATEMANAGER.GetDevice()->SetRenderTarget(0, m_lpBackupTargetSurface);
STATEMANAGER.GetDevice()->SetDepthStencilSurface(m_lpDepthStencilBackup);
m_lpDepthStencilBackup->Release();
m_lpDepthStencilBackup = nullptr;
m_lpBackupTargetSurface->Release();
m_lpBackupTargetSurface = nullptr;
D3DXMATRIX mWorld, mView, mProj, mIdentity;
D3DXMatrixIdentity(&mIdentity);
STATEMANAGER.GetDevice()->GetTransform(D3DTS_WORLD, &mWorld);
STATEMANAGER.GetDevice()->GetTransform(D3DTS_VIEW, &mView);
STATEMANAGER.GetDevice()->GetTransform(D3DTS_PROJECTION, &mProj);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_WORLD, &mIdentity);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_VIEW, &mIdentity);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_PROJECTION, &mIdentity);
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
STATEMANAGER.GetDevice()->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0.0f);
STATEMANAGER.GetDevice()->SetTexture(0, m_lpTarget);
STATEMANAGER.GetDevice()->SetPixelShader(nullptr);
STATEMANAGER.GetDevice()->SetVertexShader(nullptr);
STATEMANAGER.GetDevice()->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
STATEMANAGER.GetDevice()->SetStreamSource(0, m_lpScreenQuad, 0, sizeof(TRTTVertex));
STATEMANAGER.GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
STATEMANAGER.RestoreRenderState(D3DRS_MULTISAMPLEANTIALIAS);
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_WORLD, &mWorld);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_VIEW, &mView);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_PROJECTION, &mProj);
return true;
}bool CPostProcessingChain::Render()
{
D3DXMATRIX mWorld, mView, mProj, mIdentity;
D3DXMatrixIdentity(&mIdentity);
STATEMANAGER.GetDevice()->GetTransform(D3DTS_WORLD, &mWorld);
STATEMANAGER.GetDevice()->GetTransform(D3DTS_VIEW, &mView);
STATEMANAGER.GetDevice()->GetTransform(D3DTS_PROJECTION, &mProj);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_WORLD, &mIdentity);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_VIEW, &mIdentity);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_PROJECTION, &mIdentity);
STATEMANAGER.GetDevice()->SetRenderTarget(0, m_lpLastPassSurface);
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
STATEMANAGER.GetDevice()->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0.0f);
STATEMANAGER.GetDevice()->SetTexture(0, m_lpSourceTexture);
STATEMANAGER.GetDevice()->SetPixelShader(nullptr);
STATEMANAGER.GetDevice()->SetVertexShader(nullptr);
STATEMANAGER.GetDevice()->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
STATEMANAGER.GetDevice()->SetStreamSource(0, m_lpScreenQuad, 0, sizeof(TRTTVertex));
STATEMANAGER.GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
IDirect3DSurface9* pCurrentTarget = m_lpTargetSurface;
STATEMANAGER.GetDevice()->SetTexture(1, m_lpSourceTexture);
for (std::list<CPostProcessingEffect>::iterator it = m_kEffects.begin(); it != m_kEffects.end(); ++it)
{
D3DSURFACE_DESC kDesc;
pCurrentTarget->GetDesc(&kDesc);
D3DXVECTOR4 vScreenSize = D3DXVECTOR4(kDesc.Width, kDesc.Height, 0.0f, 0.0f);
(*it).GetConstants()->SetFloatArray(STATEMANAGER.GetDevice(), "ScreenSize", reinterpret_cast<float*>(&vScreenSize), 4);
if ((*it).Apply())
{
STATEMANAGER.GetDevice()->SetRenderTarget(0, pCurrentTarget);
STATEMANAGER.GetDevice()->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0.0f);
STATEMANAGER.GetDevice()->SetTexture(0, pCurrentTarget == m_lpLastPassSurface ? m_lpTarget : m_lpLastPass);
STATEMANAGER.GetDevice()->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
STATEMANAGER.GetDevice()->SetStreamSource(0, m_lpScreenQuad, 0, sizeof(TRTTVertex));
STATEMANAGER.GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
pCurrentTarget = pCurrentTarget == m_lpLastPassSurface ? m_lpTargetSurface : m_lpLastPassSurface;
}
}
STATEMANAGER.GetDevice()->SetTexture(1, nullptr);
if (pCurrentTarget == m_lpTargetSurface)
{
STATEMANAGER.GetDevice()->SetRenderTarget(0, m_lpTargetSurface);
STATEMANAGER.GetDevice()->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0.0f);
STATEMANAGER.GetDevice()->SetTexture(0, m_lpLastPass);
STATEMANAGER.GetDevice()->SetPixelShader(nullptr);
STATEMANAGER.GetDevice()->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
STATEMANAGER.GetDevice()->SetStreamSource(0, m_lpScreenQuad, 0, sizeof(TRTTVertex));
STATEMANAGER.GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
}
STATEMANAGER.RestoreRenderState(D3DRS_MULTISAMPLEANTIALIAS);
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_WORLD, &mWorld);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_VIEW, &mView);
STATEMANAGER.GetDevice()->SetTransform(D3DTS_PROJECTION, &mProj);
return true;
}
bool CPostProcessingChain::CreateResources()
{
ReleaseResources();
D3DSURFACE_DESC kDesc;
IDirect3DSurface9* pSurface;
STATEMANAGER.GetDevice()->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
pSurface->GetDesc(&kDesc);
pSurface->Release();
if (FAILED(STATEMANAGER.GetDevice()->CreateTexture(kDesc.Width, kDesc.Width, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &m_lpSourceTexture, nullptr)))
{
TraceError("CPostProcessingChain unable to create render target");
return false;
}
m_lpSourceTexture->GetSurfaceLevel(0, &m_lpSourceTextureSurface);
if (FAILED(STATEMANAGER.GetDevice()->CreateTexture(kDesc.Width, kDesc.Width, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &m_lpLastPass, nullptr)))
{
TraceError("CPostProcessingChain unable to create pass render target");
return false;
}
m_lpLastPass->GetSurfaceLevel(0, &m_lpLastPassSurface);
if (FAILED(STATEMANAGER.GetDevice()->CreateTexture(kDesc.Width, kDesc.Width, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &m_lpTarget, nullptr)))
{
TraceError("CPostProcessingChain unable to create final render target");
return false;
}
m_lpTarget->GetSurfaceLevel(0, &m_lpTargetSurface);
STATEMANAGER.GetDevice()->GetDepthStencilSurface(&pSurface);
pSurface->GetDesc(&kDesc);
pSurface->Release();
if (FAILED(STATEMANAGER.GetDevice()->CreateDepthStencilSurface(kDesc.Width, kDesc.Width, D3DFMT_D16, kDesc.MultiSampleType, kDesc.MultiSampleQuality, FALSE, &m_lpDepthStencilSurface, nullptr)))
{
TraceError("CPostProcessingChain unable to create depth surface");
return false;
}
if (FAILED(STATEMANAGER.GetDevice()->CreateVertexBuffer(sizeof(TRTTVertex)* 6, 0, D3DFVF_XYZRHW | D3DFVF_TEX1, D3DPOOL_MANAGED, &m_lpScreenQuad, nullptr)))
{
TraceError("CPostProcessingChain unable to create screen quad");
return false;
}
float fWidth = static_cast<float>(kDesc.Width) - 0.5f;
float fHeight = static_cast<float>(kDesc.Height) - 0.5f;
float fTexPos = fHeight / fWidth;
TRTTVertex* pVertices;
m_lpScreenQuad->Lock(0, 0, reinterpret_cast<void**>(&pVertices), 0);
pVertices[0].p = D3DXVECTOR4(-0.5f, -0.5f, 0.0f, 1.0f);
pVertices[0].t = D3DXVECTOR2(0.0f, 0.0f);
pVertices[1].p = D3DXVECTOR4(-0.5f, fHeight, 0.0f, 1.0f);
pVertices[1].t = D3DXVECTOR2(0.0f, 1.0f);
pVertices[2].p = D3DXVECTOR4(fWidth, fHeight, 0.0f, 1.0f);
pVertices[2].t = D3DXVECTOR2(1.0f, 1.0f);
pVertices[3].p = D3DXVECTOR4(-0.5f, -0.5f, 0.0f, 1.0f);
pVertices[3].t = D3DXVECTOR2(0.0f, 0.0f);
pVertices[4].p = D3DXVECTOR4(fWidth, fHeight, 0.0f, 1.0f);
pVertices[4].t = D3DXVECTOR2(1.0f, 1.0f);
pVertices[5].p = D3DXVECTOR4(fWidth, -0.5f, 0.0f, 1.0f);
pVertices[5].t = D3DXVECTOR2(1.0f, 0.0f);
m_lpScreenQuad->Unlock();
/*0, 0 | up left
0, height | down left
width, height | down right
0, 0 | up left
width, height | down right
width, 0 | up right*/
AddEffect("shaders/testshader.xml");
return true;
}
Этот код работает на графических картах AMD, но не работает на графических картах NVida,
Я уже пытался использовать текстуры зажима cl2p, но это не помогло, так что на данный момент у меня нет ни малейшего представления, почему он работает на AMD, а не на картах Nvidia
На Nvidia не вылетает, но экран черный
Если у вас есть идеи, пожалуйста, ответьте,
заранее спасибо
Задача ещё не решена.