Introduction à DirectX 10 – Rendu basique – partie 2

directx9c

Intro :

Dans cette deuxième partie, nous allons utiliser un shader basique pour afficher un triangle et afficher du texte à l’écran.

Prérequis :

Avoir suivi la première partie de ce tutoriel.
Savoir le fonctionnement d’un shader HLSL : pour cela il faut suivre le tutoriel sur le HLSL.

Deuxième partie :

Afficher un triangle et du texte à l’écran.

Explications :

Nous allons utiliser ce programme shader nommé Partie2.fx :


//----------------------------------------------------------
// Partie2.fx
//----------------------------------------------------------

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR0;
};

//----------------------------------------------------------
// Vertex Shader
//----------------------------------------------------------
VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR )
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    
    output.Pos = Pos;
    output.Color = Color;
    
    return output;    
}

//----------------------------------------------------------
// Pixel Shader
//----------------------------------------------------------
float4 PS( VS_OUTPUT input ) : SV_Target
{
    return input.Color;
}

//----------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

Si vous ne comprenez ce bout de code, voir l’article sur le HLSL.

Pensez à mettre ce fichier dans le répertoire de votre programme ! Vous aurez une erreur sinon.

Nous allons afficher un triangle à l’écran. Pour cela il faut que DirectX comprenne comment
sont agencés les vertices dans la mémoire vidéo.

Donc ici on déclare que toutes les vertices utilisées sont composées d’une variable position et d’une variable couleur. Cette structure suivante est utilisée par notre application.


struct SimpleVertex
{
    D3DXVECTOR3 Pos;
    D3DXVECTOR4 Color;
};

Et voilà un schéma des données vertices. Cette structure suivante est utilisée par DirectX.
Voir cet article pour mieux comprendre le mécanisme de cette structure.

D3D10_INPUT_ELEMENT_DESC layout[] =
{
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
    {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
};
UINT numElements = sizeof(layout) / sizeof(layout[0]);

 

On rajoute à la fonction Initialize du fichier D3D10Renderer.cpp donné dans la partie 1
du tutoriel :

/******************** Partie 2 ********************/

DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;

#if defined( DEBUG ) || defined( _DEBUG )
// Permet d'afficher les éventuelles erreurs de la compilation d'un shader
dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif

// Pour la création du shader, on le compile
hr = D3DX10CreateEffectFromFile(L"Partie2.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0, m_pd3dDevice, NULL,
                                NULL, &m_pEffect, NULL, NULL);
if (FAILED(hr))
    return false;

// On acquiert la technique du shader HLSL
m_pTechnique = m_pEffect->GetTechniqueByName("Render");

// On définit la structure d'un vertex
D3D10_INPUT_ELEMENT_DESC layout[] =
{
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
    {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
};
UINT numElements = sizeof(layout) / sizeof(layout[0]);

D3D10_PASS_DESC PassDesc;
m_pTechnique->GetPassByIndex(0)->GetDesc(&PassDesc);
hr = m_pd3dDevice->CreateInputLayout(layout, numElements, PassDesc.pIAInputSignature,
                                      PassDesc.IAInputSignatureSize, &m_pVertexLayout);
if(FAILED(hr))
    return false;

m_pd3dDevice->IASetInputLayout(m_pVertexLayout);

// On définit les vertices
SimpleVertex vertices[] =
{
    D3DXVECTOR3( 0.0f, 0.5f, 0.5f ), D3DXVECTOR4( 0.0f, 1.0f, 1.0f, 1.0f ),
    D3DXVECTOR3( 0.5f, -0.5f, 0.5f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ),
    D3DXVECTOR3( -0.5f, -0.5f, 0.5f ), D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f ),
};
// On implémente le vertex buffer
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = sizeof(SimpleVertex) * 6;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = vertices;
hr = m_pd3dDevice->CreateBuffer(&bd, &InitData, &m_pVertexBuffer);
if(FAILED(hr))
    return false;

// On définit le vertex buffer
UINT stride = sizeof(SimpleVertex);
// Décalage des informations du vertex buffer
UINT offset = 0;
m_pd3dDevice->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);

// On définit le type de primitive
m_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

/******** Font ********/

D3DX10CreateSprite(m_pd3dDevice, 0, &m_pSprite);

D3DX10_FONT_DESC fd;
fd.Height = 30;
fd.Width = 18;
fd.Weight = 0;
fd.MipLevels = 4;
fd.Italic = false;
fd.CharSet = OUT_DEFAULT_PRECIS;
fd.Quality = DEFAULT_QUALITY;
fd.PitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
wcscpy(fd.FaceName, L"Impact");

D3DX10CreateFontIndirect(m_pd3dDevice, &fd, &m_pFont);

 

La fonction de rendu va afficher un triangle et un texte comme convenu :

void D3D10Renderer::Render()
{
    static float afClearColor[4] = {0.0f, 0.125f, 0.3f, 1.0f}; 

    static D3DXCOLOR color(0.0f, 1.0f, 0.3f, 1.0f);
    static RECT rectangle = {10, 10, 0, 0};

    // Efface le backbuffer
    m_pd3dDevice->ClearRenderTargetView(m_pRenderTargetView, afClearColor);

    // Commence par afficher du texte
    m_pSprite->Begin(D3DX10_SPRITE_SAVE_STATE);
    m_pFont->DrawText(m_pSprite, L"Hello World!", -1, &rectangle, DT_NOCLIP, color);
    m_pSprite->End();
    
    // Rendu d'un triangle
    D3D10_TECHNIQUE_DESC techDesc;
    m_pTechnique->GetDesc(&techDesc);
    for (unsigned int p = 0; p < techDesc.Passes; ++p)
    {
        m_pTechnique->GetPassByIndex(p)->Apply(0);
        // On rend 3 vertex
        m_pd3dDevice->Draw(3, 0);
    }

    m_pSwapChain->Present(0, 0);
}

N’oubliez pas d’ajouter dans votre fichier System.h :

ID3DX10Font* m_pFont;
ID3DX10Sprite* m_pSprite;

Résumé :

Au final nous avons affiché un triangle multi-colorisé et affiché un petit texte :

triangle

Voici l’archive du code complet pour cette partie : DirectX 10 Tutoriel – Partie 2.zip

Laisser un commentaire

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