Un cube tout simple en 3D

cube

Intro :

Voici l’implémentation d’un cube tout simple par la définition de ses vertices et indices.

Il peut être utilisé pour faire des tests ou pour déboguer vos jeux.

Explications :

Dans le fichier Cube.h :

#ifndef CUBE_MESH_H
#define CUBE_MESH_H
 
#include <d3d10.h>
#include <d3dx10.h>

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

class Cube
{
public:
    struct PTNVertex
    {
        D3DXVECTOR3 position;
        D3DXVECTOR2 texture;
        D3DXVECTOR3 normal;
 
        PTNVertex()
        {
        }
 
        PTNVertex(D3DXVECTOR3 p, D3DXVECTOR2 t, D3DXVECTOR3 n)
        {
            position = p;
            texture = t;
            normal = n;
        }
    };
 
    Cube();
    virtual ~Cube();
 
    bool Initialize();
 
    void Render(float fTimeSinceLastFrame);
 
private:
    ID3DX10Mesh* m_pMesh;
 
    D3DXMATRIX m_worldMatrix;
    D3DXMATRIX m_viewMatrix;
    D3DXMATRIX m_projMatrix;

    ID3D10EffectMatrixVariable* m_pWorldVariable;
    ID3D10EffectMatrixVariable* m_pViewVariable;
    ID3D10EffectMatrixVariable* m_pProjVariable;

    ID3D10EffectShaderResourceVariable* m_pDiffuseVariable;
    ID3D10ShaderResourceView* m_pDiffuseMap;
     
    ID3D10Effect* m_pEffect;
    ID3D10EffectTechnique* m_pTechnique;
     
    ID3D10InputLayout* m_pVertexLayout;
};
 
#endif

 

Dans le fichier Cube.cpp :

#include "Cube.h"

Cube::Cube() :
m_pMesh(nullptr),
m_pWorldVariable(nullptr),
m_pDiffuseVariable(nullptr),
m_pDiffuseMap(nullptr),
m_pTechnique(nullptr),
m_pEffect(nullptr),
m_pVertexLayout(nullptr)
{
    D3DXMatrixIdentity(&m_worldMatrix);

    D3DXVECTOR3 Eye(0.0f, 5.0f, -6.0f);
    D3DXVECTOR3 At(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 Up(0.0f, 1.0f, 0.0f);
 
    D3DXMatrixLookAtLH(&m_viewMatrix, &Eye, &At, &Up);
 
    D3DXMatrixPerspectiveFovLH(&m_projMatrix, D3DX_PI * 0.25f,
        (float) D3D10_RENDERER->GetViewportWidth() / (float)D3D10_RENDERER->GetViewportHeight(),
        0.1f, 100.0f);
}
 
Cube::~Cube()
{
    SAFE_RELEASE(m_pMesh);
}
 
bool Cube::Initialize()
{
    PTNVertex v[24];
     
    v[0] = PTNVertex( D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ), D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    v[1] = PTNVertex( D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ), D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    v[2] = PTNVertex( D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ), D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    v[3] = PTNVertex( D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ), D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
 
    v[4] = PTNVertex( D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ), D3DXVECTOR3( 0.0f, -1.0f, 0.0f ) );
    v[5] = PTNVertex( D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ), D3DXVECTOR3( 0.0f, -1.0f, 0.0f ) );
    v[6] = PTNVertex( D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ),  D3DXVECTOR3( 0.0f, -1.0f, 0.0f ) );
    v[7] = PTNVertex( D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ),  D3DXVECTOR3( 0.0f, -1.0f, 0.0f ));
 
    v[8] = PTNVertex( D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ),  D3DXVECTOR3( -1.0f, 0.0f, 0.0f ) );
    v[9] = PTNVertex( D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ), D3DXVECTOR3( -1.0f, 0.0f, 0.0f ) );
    v[10] = PTNVertex( D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ),  D3DXVECTOR3( -1.0f, 0.0f, 0.0f ) );
    v[11] = PTNVertex( D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ),  D3DXVECTOR3( -1.0f, 0.0f, 0.0f ) );
     
    v[12] = PTNVertex( D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ), D3DXVECTOR3( 1.0f, 0.0f, 0.0f ) );
    v[13] = PTNVertex( D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ), D3DXVECTOR3( 1.0f, 0.0f, 0.0f) );
    v[14] = PTNVertex( D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ), D3DXVECTOR3( 1.0f, 0.0f, 0.0f ) );
    v[15] = PTNVertex( D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ),    D3DXVECTOR3( 1.0f, 0.0f, 0.0f) );
 
    v[16] = PTNVertex( D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ), D3DXVECTOR3( 0.0f, 0.0f, -1.0f) );
    v[17] = PTNVertex( D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ),  D3DXVECTOR3( 0.0f, 0.0f, -1.0f) );
    v[18] = PTNVertex( D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ),  D3DXVECTOR3( 0.0f, 0.0f, -1.0f ) );
    v[19] = PTNVertex( D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 1.0f ),  D3DXVECTOR3( 0.0f, 0.0f, -1.0f ) );
 
    v[20] = PTNVertex( D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ), D3DXVECTOR3( 0.0f, 0.0f, 1.0f ) );
    v[21] = PTNVertex( D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 0.0f ), D3DXVECTOR3( 0.0f, 0.0f, 1.0f ) );
    v[22] = PTNVertex( D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ), D3DXVECTOR3( 0.0f, 0.0f, 1.0f) );
    v[23] = PTNVertex( D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ), D3DXVECTOR3( 0.0f, 0.0f, 1.0f ) );
     
    unsigned int i[36] = { 3,1,0,
                           2,1,3,
                           6,4,5,
                           7,4,6,
                           11,9,8,
                           10,9,11,
                           14,12,13,
                           15,12,14,
                           19,17,16,
                           18,17,19,
                           22,20,21,
                           23,20,22
                        };    
                         
     
    D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };

    HRESULT hr;
    hr = D3DX10CreateMesh(D3D10_RENDERER->GetDevice(), layout,  3, "POSITION", 24, 36/3, D3DX10_MESH_32_BIT, &m_pMesh);
 
    hr = m_pMesh->SetVertexData(0, v);
 
    if (FAILED(hr))
    {
        ShowMessageBoxDXError(hr);
        return false;
    }
 
    hr = m_pMesh->SetIndexData(i, 36);
 
    if (FAILED(hr))
    {
        ShowMessageBoxDXError(hr);
        return false;
    }
 
    hr = m_pMesh->CommitToDevice();
 
    if (FAILED(hr))
    {
        ShowMessageBoxDXError(hr);
        return false;
    }
 
    ID3D10Blob* pBlob = nullptr;
 
    hr = D3DX10CreateEffectFromFile(L"Cube.fx", nullptr, nullptr, "fx_4_0",
                                    D3D10_SHADER_ENABLE_STRICTNESS | D3D10_SHADER_DEBUG, 0,
                                    D3D10_RENDERER->GetDevice(), nullptr, nullptr, &m_pEffect, &pBlob, nullptr);
    if (FAILED(hr))
    {
        if (pBlob)
        {
            // Affiche l'erreur de compilation du shader
            MessageBoxA(nullptr, (PCSTR)pBlob->GetBufferPointer(), "Erreur dans le fichier shader", MB_ICONHAND | MB_OK);
        }
        else
        {
            ShowMessageBoxDXError(hr);
        }
 
        return false;
    }
 
    m_pTechnique = m_pEffect->GetTechniqueByName("Render");
 
    m_pWorldVariable = m_pEffect->GetVariableByName("World")->AsMatrix();
    m_pViewVariable = m_pEffect->GetVariableByName("View")->AsMatrix();
    m_pProjVariable = m_pEffect->GetVariableByName("Projection")->AsMatrix();
    m_pDiffuseVariable = m_pEffect->GetVariableByName("txDiffuse")->AsShaderResource();
 
    D3D10_PASS_DESC PassDesc;
    m_pTechnique->GetPassByIndex(0)->GetDesc(&PassDesc);
    hr = D3D10_RENDERER->GetDevice()->CreateInputLayout(layout, 3, PassDesc.pIAInputSignature,
                                         PassDesc.IAInputSignatureSize, &m_pVertexLayout);
    if (FAILED(hr))
    {
        ShowMessageBoxDXError(hr);
        return false;
    }

     // On charge la texture
    hr = D3DX10CreateShaderResourceViewFromFile(D3D10_RENDERER->GetDevice(), L"box.jpg", nullptr, nullptr, &m_pDiffuseMap, nullptr);

    if (FAILED(hr))
    {
        ShowMessageBoxDXError(hr);
        return false;
    }

    return true;
}
 
void Cube::Render(float fTimeSinceLastFrame)
{
    D3D10_RENDERER->GetDevice()->IASetInputLayout(m_pVertexLayout);

    // Pour faire tourner le cube autour de l'axe Y
    static float r = 0;
    D3DXMatrixRotationY(&m_worldMatrix, r);
    r += fTimeSinceLastFrame * 0.6f;

    m_pWorldVariable->SetMatrix((float*)&m_worldMatrix);
    m_pViewVariable->SetMatrix((float*)&m_viewMatrix);
    m_pProjVariable->SetMatrix((float*)&m_projMatrix);
    m_pDiffuseVariable->SetResource(m_pDiffuseMap);

    D3D10_TECHNIQUE_DESC techDesc;
    m_pTechnique->GetDesc(&techDesc);

    for(uint32 p = 0; p < techDesc.Passes; p++)
    {
        m_pTechnique->GetPassByIndex(p)->Apply(0);

        m_pMesh->DrawSubset(0);
    }
}

 

Résumé :

Nous avons implémenter le code pour afficher un petit cube.

Voici les fichiers sources : Simple Cube.zip.

Laisser un commentaire

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