Une classe RenderTarget pour afficher un tampon d’image de rendu

rtt

Intro :

Nous avons parfois besoin de stocker le rendu 3D dans une texture que l’on pourra utiliser n’importe tout dans le programme !

Explications :

Voici le fichier RenderToTexture.h :

#ifndef RENDER_TO_TEXTURE_H
#define RENDER_TO_TEXTURE_H

#include <d3d10.h>
#include "Types.h"

class RenderTarget
{
public:
    RenderTarget();
    virtual ~RenderTarget();

    bool Initialize(uint32 iTextureWidth, uint32 iTextureHeight);

    void SetRenderTarget(ID3D10DepthStencilView* pDepthStencilView);
    void ClearRenderTarget(ID3D10DepthStencilView* pDepthStencilView);

    ID3D10ShaderResourceView* GetShaderResourceView();

private:
    ID3D10Texture2D* m_pRenderTargetTexture;
    ID3D10RenderTargetView* m_pRenderTargetView;
    ID3D10ShaderResourceView* m_pShaderResourceView;
};

#endif

 

Voici le fichier RenderToTexture.cpp :

#include "Defines.h"
#include "RenderTarget.h"
#include "D3D10Renderer.h"

RenderTarget::RenderTarget() :
m_pRenderTargetTexture(nullptr),
m_pRenderTargetView(nullptr),
m_pShaderResourceView(nullptr)
{
}

RenderTarget::~RenderTarget()
{
    SAFE_RELEASE(m_pRenderTargetTexture);
    SAFE_RELEASE(m_pRenderTargetView);
    SAFE_RELEASE(m_pShaderResourceView);
}

bool RenderTarget::Initialize(uint32 iTextureWidth, uint32 iTextureHeight)
{
    /* On créé les descriptions de texture 2D, de la render target et de la ressource du shader */
    D3D10_TEXTURE2D_DESC textureDesc;
    D3D10_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
    D3D10_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;

    HRESULT hr;
    // Initialize the render target texture description.
    ZeroMemory(&textureDesc, sizeof(textureDesc));

    // Setup the render target texture description.
    textureDesc.Width = iTextureWidth;
    textureDesc.Height = iTextureHeight;
    textureDesc.MipLevels = 1;
    textureDesc.ArraySize = 1;
    textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    textureDesc.SampleDesc.Count = 1;
    textureDesc.Usage = D3D10_USAGE_DEFAULT;
    textureDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
    textureDesc.CPUAccessFlags = 0;
    textureDesc.MiscFlags = 0;

    // Create the render target texture.
    hr = D3D10_RENDERER->GetDevice()->CreateTexture2D(&textureDesc, NULL, &m_pRenderTargetTexture);
    if (FAILED(hr))
    {
        return false;
    }

    // Setup the description of the render target view.
    renderTargetViewDesc.Format = textureDesc.Format;
    renderTargetViewDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
    renderTargetViewDesc.Texture2D.MipSlice = 0;

    // Create the render target view.
    hr = D3D10_RENDERER->GetDevice()->CreateRenderTargetView(m_pRenderTargetTexture, &renderTargetViewDesc, &m_pRenderTargetView);
    if (FAILED(hr))
    {
        return false;
    }

    // Setup the description of the shader resource view.
    shaderResourceViewDesc.Format = textureDesc.Format;
    shaderResourceViewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
    shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
    shaderResourceViewDesc.Texture2D.MipLevels = 1;

    // Create the shader resource view.
    hr = D3D10_RENDERER->GetDevice()->CreateShaderResourceView(m_pRenderTargetTexture, &shaderResourceViewDesc, &m_pShaderResourceView);
    if (FAILED(hr))
    {
        return false;
    }

    return true;
}

void RenderTarget::SetRenderTarget(ID3D10DepthStencilView* pDepthStencilView)
{
    D3D10_RENDERER->GetDevice()->OMSetRenderTargets(1, &m_pRenderTargetView, pDepthStencilView);
}

void RenderTarget::ClearRenderTarget(ID3D10DepthStencilView* pDepthStencilView)
{
    float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };

    // On efface le back buffer
    D3D10_RENDERER->GetDevice()->ClearRenderTargetView(m_pRenderTargetView, color);

    // On efface le depth buffer
    D3D10_RENDERER->GetDevice()->ClearDepthStencilView(pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0);
}

ID3D10ShaderResourceView* RenderTarget::GetShaderResourceView()
{
    return m_pShaderResourceView;
}

 

Comment l’utiliser ?

void D3D10Renderer::Render()
{
    [...]
    
    // Efface la surface de rendu
    m_pd3dDevice->ClearDepthStencilView(m_pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0 );
    m_pd3dDevice->ClearRenderTargetView(m_pRenderTargetView, afClearColor);

    SCENE_MANAGER->DrawAll(fTimeSinceLastFrame);

    RenderToTexture(fTimeSinceLastFrame);

    m_pQuad->OnRender(fTimeSinceLastFrame);

    m_pSwapChain->Present(0, 0);
}

void D3D10Renderer::RenderToTexture(float fTimeSinceLastFrame)
{
    // Set the render target to be the render to texture.
    m_pQuad->GetRT()->SetRenderTarget(m_pDepthStencilView);

    // Clear the render to texture.
    m_pQuad->GetRT()->ClearRenderTarget(m_pDepthStencilView);

    // Render the scene now and it will draw to the render to texture instead of the back buffer.
    SCENE_MANAGER->DrawAll(fTimeSinceLastFrame);

    // Reset the render target back to the original back buffer and not the render to texture anymore.
    m_pd3dDevice->OMSetRenderTargets(1, &m_pRenderTargetView, m_pDepthStencilView);
}

 

Résumé :

Nous avons présenter la façon la plus optimale possible d’utiliser une RenderTarget !

Références :

Laisser un commentaire

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