Une classe Renderable pour afficher vos contenus 3D

test_remeshing

Intro :

Pour afficher rapidement du contenu 3D, il est laborieux de déclarer à chaque fois les vertex et index buffers, le shader associé, le Vertex Input Layout, la méthode d’affichage, etc…

Cette classe suivante vous permettra de restreindre ces difficultés.

Prérequis :

– Savoir utiliser la classe ShaderTechnique. Voir cet article.

– Savoir un peu utiliser DirectX 10.

Explications :

Voici le fichier Renderable.h :

#ifndef RENDERABLE_H
#define RENDERABLE_H

class ShaderTechnique;

class Renderable
{
public:
    enum DrawMethod
    {
        DRAW_NORMAL,
        DRAW_INDEXED
    };

    Renderable();
    virtual ~Renderable();

    virtual void Render(float fTimeSinceLastFrame);

    void SetShaderTechnique(ShaderTechnique* pShader);
    ShaderTechnique* GetShaderTechnique();

    void SetVertexType(VertexLayoutType vertexType);
    void SetDrawMethod(DrawMethod drawMethod);
    void SetTopology(D3D_PRIMITIVE_TOPOLOGY topology);

    void SetRenderableName(const std::string& sName);
    std::string GetRenderableName();

protected:
    void SetVertexBuffer(ID3D10Buffer* pBuffer);
    void SetIndexBuffer(ID3D10Buffer* pBuffer);

    ID3D10Buffer* GetVertexBuffer();
    ID3D10Buffer* GetIndexBuffer();

protected:
    unsigned int m_iVerticesCount;
    unsigned int m_iIndicesCount;

    ID3D10Buffer* m_pVertexBuffer;
    ID3D10Buffer* m_pIndexBuffer;

private:
    void Draw();
    void InitVertexBuffer();
    void InitIndexBuffer();

private:
    VertexLayoutType m_vertexType;
    DrawMethod m_drawMethod;
    D3D_PRIMITIVE_TOPOLOGY m_topology;

    ShaderTechnique* m_pShader;

    std::string m_sName;
};

#endif

 

Voici le fichier Renderale.cpp :

#include "Renderable.h"

Renderable::Renderable() :
m_pShader(nullptr),
m_vertexType(VertexLayoutType::PTN_VERTEX),
m_drawMethod(DrawMethod::DRAW_NORMAL),
m_topology(D3D_PRIMITIVE_TOPOLOGY::D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST),
m_iIndicesCount(0),
m_iVerticesCount(0),
m_pVertexBuffer(nullptr),
m_pIndexBuffer(nullptr)
{
}

Renderable::~Renderable()
{
    SAFE_RELEASE(m_pIndexBuffer);
    SAFE_RELEASE(m_pVertexBuffer);
}

void Renderable::SetShaderTechnique(ShaderTechnique* pShader)
{
    Assert(pShader);

    bool bSucess = pShader->Initialize();

    if (bSucess)
    {
        m_pShader = pShader;
    }
}

ShaderTechnique* Renderable::GetShaderTechnique()
{
    return m_pShader;
}

void Renderable::Render(float fTimeSinceLastFrame)
{
    if (m_pShader == nullptr)
    {
        return;
    }

    D3D10_RENDERER->GetDevice()->IASetInputLayout(m_pShader->GetVertexLayout());
    D3D10_RENDERER->GetDevice()->IASetPrimitiveTopology(m_topology);

    InitIndexBuffer();
    InitVertexBuffer();

    m_pShader->Update(fTimeSinceLastFrame);

    D3D10_TECHNIQUE_DESC techDesc;
    ID3D10EffectTechnique* pTechnique = m_pShader->GetShaderTechnique();

    pTechnique->GetDesc(&techDesc);

    for (unsigned int p = 0; p < techDesc.Passes; p++)
    {
        pTechnique->GetPassByIndex(p)->Apply(0);
        Draw();
    }
}

void Renderable::Draw()
{
    if (m_drawMethod == DrawMethod::DRAW_NORMAL)
    {
        D3D10_RENDERER->GetDevice()->Draw(m_iVerticesCount, 0);
    }
    else if (m_drawMethod == DrawMethod::DRAW_INDEXED)
    {
        D3D10_RENDERER->GetDevice()->DrawIndexed(m_iIndicesCount, 0, 0);
    }
}

void Renderable::InitVertexBuffer()
{
    if (m_pVertexBuffer)
    {
        UINT stride = D3D10_RENDERER->GetVertexBytesSize(m_vertexType);
        UINT offset = 0;

        D3D10_RENDERER->GetDevice()->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);
    }
}

void Renderable::InitIndexBuffer()
{
    if (m_pIndexBuffer)
    {
        D3D10_RENDERER->GetDevice()->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
    }
}

void Renderable::SetDrawMethod(DrawMethod drawMethod)
{
    m_drawMethod = drawMethod;
}

void Renderable::SetTopology(D3D_PRIMITIVE_TOPOLOGY topology)
{
    m_topology = topology;
}

void Renderable::SetVertexType(VertexLayoutType vertexType)
{
    m_vertexType = vertexType;
}

void Renderable::SetRenderableName(const std::string& sName)
{
    m_sName = sName;
}

std::string Renderable::GetRenderableName()
{
    return m_sName;
}

void Renderable::SetVertexBuffer(ID3D10Buffer* pBuffer)
{
    m_pVertexBuffer = pBuffer;
}

void Renderable::SetIndexBuffer(ID3D10Buffer* pBuffer)
{
    m_pIndexBuffer = pBuffer;
}

ID3D10Buffer* Renderable::GetVertexBuffer()
{
    return m_pVertexBuffer;
}

ID3D10Buffer* Renderable::GetIndexBuffer()
{
    return m_pIndexBuffer;
}

 

Résumé :

Cette classe pourra servir à être dérivée pour afficher vos contenus 3D : image, quad de post-effect, rendu 3D, etc..

Laisser un commentaire

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