1

so I wrote a Post Processing class for some old open source game,

I have a begin scene function a end scene function, a render function and a function for creating the screen squad and resources.

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;
}

This code works on AMD Graphic cards but is not working on NVida Graphic cards, I already tried to use cl2p clamp textures but that did not help so at the moment I have not the slightest idea why it is working on AMD but not on Nvidia Cards

It does not crash on Nvidia but the screen is black

If you have any ideas, please respond, Thanks in advance

iH8
  • 27,722
  • 4
  • 67
  • 76

0 Answers0