Une classe MeshSceneNode pour représenter des meshes dans votre scène

mesh node

Intro :

Pour afficher vos entités / mesh dans la scène 3D, je vous présente une classe qui permettra de les initialiser rapidement.

Elle pourra construire facilement du contenu 3D à partir des méthodes suivantes :

// Construit et remplit le vertex buffer à partir d'un tableau de vertices
bool BuildVB(std::vector<T>& vertices)

// Construit et remplit l'index buffer à partir d'une tableau d'indices
bool BuildIB(std::vector<T>& indices)

// Construit un mesh à partir des tableaux de vertices et d'indices
bool Build(std::vector<T>& vertices, std::vector<unsigned short>& indices)

 

Prérequis :

– Savoir utiliser la classe SceneNode. Voir cet article.

– Savoir utiliser la classe Renderable. Voir cet article.

– Savoir un peu utiliser DirectX 10

– Comprendre la classe SceneNode

 

Explications :

Voici le fichier MeshSceneNode.h :

#ifndef MESH_SCENE_NODE_H
#define MESH_SCENE_NODE_H

class MeshSceneNode : public SceneNode, public Renderable
{
public:
    MeshSceneNode(SceneNode* pParent = nullptr,
        const D3DXVECTOR3& position = D3DXVECTOR3(0, 0, 0),
        const D3DXVECTOR3& rotation = D3DXVECTOR3(0, 0, 0),
        const D3DXVECTOR3& scale = D3DXVECTOR3(0, 0, 0));

    virtual ~MeshSceneNode();

    virtual bool Initialize() { return true; }

    template<class T>
    bool BuildVB(std::vector<T>& vertices)
    {
        unsigned int iVertexSize = sizeof(T);

        D3D10_BUFFER_DESC vertexBufferDesc;
        D3D10_SUBRESOURCE_DATA vertexData;
 
        m_iVerticesCount = vertices.size();

        vertexBufferDesc.Usage = D3D10_USAGE_DYNAMIC;

        vertexBufferDesc.ByteWidth = iVertexSize * m_iVerticesCount;

        vertexBufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
        vertexBufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
        vertexBufferDesc.MiscFlags = 0;

        vertexData.pSysMem = vertices.data();

        // Créé le vertex buffer
        HRESULT hr = D3D10_RENDERER->GetDevice()->CreateBuffer(&vertexBufferDesc, &vertexData, &m_pVertexBuffer);
 
        if (FAILED(hr))
        {
            ShowMessageBoxDXError(hr);

            return false;
        }

        return true;
    }

    template<class T>
    bool BuildIB(std::vector<T>& indices)
    {
        D3D10_BUFFER_DESC indexBufferDesc;
        D3D10_SUBRESOURCE_DATA indexData;

        HRESULT hr;
 
        m_iIndicesCount = indices.size();

        indexBufferDesc.Usage = D3D10_USAGE_DEFAULT;
        indexBufferDesc.ByteWidth = sizeof(T) * m_iIndicesCount;
        indexBufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
        indexBufferDesc.CPUAccessFlags = 0;
        indexBufferDesc.MiscFlags = 0;

        indexData.pSysMem = indices.data();
    
        // Créé l'index buffer
        hr = D3D10_RENDERER->GetDevice()->CreateBuffer(&indexBufferDesc, &indexData, &m_pIndexBuffer);
 
        if (FAILED(hr))
        {
            ShowMessageBoxDXError(hr);

            return false;
        }

        return true;
    }

    template<class T>
    bool Build(std::vector<T>& vertices, std::vector<unsigned short>& indices)
    {
        unsigned int iVertexSize = sizeof(T);

        D3D10_BUFFER_DESC vertexBufferDesc;
        D3D10_BUFFER_DESC indexBufferDesc;
 
        D3D10_SUBRESOURCE_DATA vertexData;
        D3D10_SUBRESOURCE_DATA indexData;
 
        HRESULT hr;
 
        m_iVerticesCount = vertices.size();
        m_iIndicesCount = indices.size();

        vertexBufferDesc.Usage = D3D10_USAGE_DYNAMIC;

        vertexBufferDesc.ByteWidth = iVertexSize * m_iVerticesCount;

        vertexBufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
        vertexBufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
        vertexBufferDesc.MiscFlags = 0;

        vertexData.pSysMem = vertices.data();

        // Créé le vertex buffer
        hr = D3D10_RENDERER->GetDevice()->CreateBuffer(&vertexBufferDesc, &vertexData, &m_pVertexBuffer);
 
        if (FAILED(hr))
        {
            ShowMessageBoxDXError(hr);

            return false;
        }
 
        indexBufferDesc.Usage = D3D10_USAGE_DEFAULT;
        indexBufferDesc.ByteWidth = sizeof(unsigned short) * m_iIndicesCount;
        indexBufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
        indexBufferDesc.CPUAccessFlags = 0;
        indexBufferDesc.MiscFlags = 0;

        indexData.pSysMem = indices.data();
    
        // Créé l'index buffer
        hr = D3D10_RENDERER->GetDevice()->CreateBuffer(&indexBufferDesc, &indexData, &m_pIndexBuffer);
 
        if (FAILED(hr))
        {
            ShowMessageBoxDXError(hr);

            return false;
        }

        return true;
    }

    template<class T>
    void UpdateVertices(const std::vector<T> vertices)
    {
        T* data = nullptr;

        m_pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&data);

        memcpy(data, vertices.data(), sizeof(T) * vertices.size());

        m_pVertexBuffer->Unmap();
    }
};

#endif

 

Resumé :

Nous avons présentée une classe qui permettra d’afficher du contenu 3D dans vos scène d’entités (SceneNode).

Laisser un commentaire

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