Une classe TextureScreenQuad pour afficher vos effets shaders de Post-Traitement

fig-1-war-and-peace

Intro :

Dans un jeu, nous avons besoin d’afficher une texture / image qui prend la place de tout l’écran. Cette image peut être modifiée pour appliquer un rendu de post-effet avec un fichier shader .fx.

Explications :

Nous nous servons d’un tampon de vertices formant un carré ou d’un quad.

Voici le fichier TextureScreenQuad.h :

#ifndef TEXTURE_QUAD_H
#define TEXTURE_QUAD_H

#include <d3dx10.h>
#include <string>

#include "VertexDeclarations.h"
#include "Renderable.h"
#include "RenderTarget.h"
#include "MeshSceneNode.h"

class TextureScreenQuad : public MeshSceneNode
{
public:
    TextureScreenQuad();
    virtual ~TextureScreenQuad();

    bool Initialize();
    virtual void OnRender(float fTimeSinceLastFrame) override;

    void SetTransparency(float fValue);
    void SetColor(const D3DXCOLOR& color);
    void SetQuadSize(uint32 iWidth, uint32 iHeight);

    RenderTarget* GetRT();

    virtual bool SetShaderTechnique(ShaderTechnique* pShader) override;

protected:
    bool Update();

private:
    int m_iScreenWidth;
    int m_iScreenHeight;

    ID3D10ShaderResourceView* m_pTextureRessourceView;

    float m_fAlpha;

    PTVertex m_aQuadVertices[6];

    RenderTarget* m_pRT;
    D3DXCOLOR m_Color;
};

#endif

 

Voici le fichier TextureScreenQuad.cpp :

#include "TextureScreenQuad.h"
#include "Defines.h"
#include "D3D10Renderer.h"
#include "ShaderTechnique.h"
#include "ShaderTechnique_Declarations.h"

TextureScreenQuad::TextureScreenQuad() :
MeshSceneNode("TextureScreenQuad"),
m_fAlpha(1.0f),
m_pRT(nullptr)
{
    ZeroMemory(&m_aQuadVertices, sizeof(PTVertex) * 6);
    SetDrawMethod(DRAW_INDEXED);
    SetVertexType(VertexLayoutType::PT_VERTEX);
}

TextureScreenQuad::~TextureScreenQuad()
{
    SAFE_RELEASE(m_pTextureRessourceView);
}

bool TextureScreenQuad::Initialize()
{
    m_iScreenWidth = D3D10_RENDERER->GetViewportWidth();
    m_iScreenHeight = D3D10_RENDERER->GetViewportHeight();

    if (!Update())
    {
        MessageBoxA(nullptr, "Erreur d'initialisation d'un TextureScreenQuad !", "Erreur", MB_ICONHAND | MB_OK);
    }

    return true;
}

void TextureScreenQuad::SetTransparency(float fValue)
{
    m_Color.a = fValue;

    if (GetShaderTechnique() != nullptr)
    {
        GetShaderTechnique()->SetColor("Color", m_Color);
    }
}

void TextureScreenQuad::SetColor(const D3DXCOLOR& color)
{
    m_Color = color;
    
    if (GetShaderTechnique() != nullptr)
    {
        GetShaderTechnique()->SetColor("Color", m_Color);
    }
}

void TextureScreenQuad::OnRender(float fTimeSinceLastFrame)
{
    if (IsVisible())
    {
        D3D10_RENDERER->EnableZBuffer(false);

            Renderable::OnRender(fTimeSinceLastFrame);

        D3D10_RENDERER->EnableZBuffer(true);
    }
}

bool TextureScreenQuad::Update()
{
    float left, right, top, bottom;

    left = (float) -m_iScreenWidth / 2;
    right = left + (float) m_iScreenWidth;

    top = (float) -m_iScreenHeight / 2;
    bottom = top + (float) m_iScreenHeight;

    // Premier triangle
    m_aQuadVertices[0].pos = D3DXVECTOR3(left, top, 0.0f);  // Top left.
    m_aQuadVertices[0].texture = D3DXVECTOR2(0.0f, 0.0f);

    m_aQuadVertices[1].pos = D3DXVECTOR3(right, bottom, 0.0f);  // Bottom right.
    m_aQuadVertices[1].texture = D3DXVECTOR2(1.0f, 1.0f);

    m_aQuadVertices[2].pos = D3DXVECTOR3(left, bottom, 0.0f);  // Bottom left.
    m_aQuadVertices[2].texture = D3DXVECTOR2(0.0f, 1.0f);

    // Deuxième triangle
    m_aQuadVertices[3].pos = D3DXVECTOR3(left, top, 0.0f);  // Top left.
    m_aQuadVertices[3].texture = D3DXVECTOR2(0.0f, 0.0f);

    m_aQuadVertices[4].pos = D3DXVECTOR3(right, top, 0.0f);  // Top right.
    m_aQuadVertices[4].texture = D3DXVECTOR2(1.0f, 0.0f);

    m_aQuadVertices[5].pos = D3DXVECTOR3(right, bottom, 0.0f);  // Bottom right.
    m_aQuadVertices[5].texture = D3DXVECTOR2(1.0f, 1.0f);

    // On déclare les tableaux
    std::vector<PTVertex> vertices;
    // On reset les emplacements
    vertices.resize(6);
    // On affecte les valeurs
    std::copy(m_aQuadVertices, m_aQuadVertices + 6, vertices.begin());

    unsigned short i[6] = { 0, 1, 2, 3, 4, 5 };

    // On déclare les tableaux
    std::vector<unsigned short> indices;
    // On reset les emplacements
    indices.resize(6);
    // On affecte les valeurs
    std::copy(i, i + 6, indices.begin());

    BuildMesh(vertices, indices);

    return true;
}

void TextureScreenQuad::SetQuadSize(uint32 iWidth, uint32 iHeight)
{
    m_iScreenWidth = iWidth;
    m_iScreenHeight = iHeight;

    Update();
}

RenderTarget* TextureScreenQuad::GetRT()
{
    return m_pRT;
}

bool TextureScreenQuad::SetShaderTechnique(ShaderTechnique* pShader)
{
    bool bSuccess = Renderable::SetShaderTechnique(pShader);

    if (m_pRT == nullptr)
    {
        m_pRT = new RenderTarget();
        m_pRT->Initialize(m_iScreenWidth, m_iScreenHeight);

        ShaderTechnique_FXAA* pFXAA = dynamic_cast<ShaderTechnique_FXAA*> (GetShaderTechnique());
        pFXAA->SetRenderTarget(m_pRT);

        SetColor(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
    }

    return bSuccess;
}


Résumé :

Nous avons présenté une façon d’utiliser un Quad de de post-traitement afin de modifier les couleurs de rendu du front buffer.

Références :

– Stackoverflow.com

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *