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

