
Intro :
Ceci constitue une introduction à la version 10 de DirectX.
DirectX est une interface entre le programmeur et la carte graphique.
Dans cette partie je vais vous apprendre à l’initialiser de manière rudimentaire.
Prérequis :
Savoir programmer en C++.
Première partie :
Création de la fenêtre de rendu.
Explications :
Pensez à configurer les chemins d’accès du SDK de DirectX dans VC++ ! Si vous ne savez pas comment faire : lire ce tutoriel.
On a besoin d’utiliser une fonction qui boucle à chaque fois que l’application reçoit
un message :
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Ensuite créez un fichier System.cpp et un fichier System.h où vous mettrez les fonctions que je vous énoncerai.
Voici le fichier System.h :
#ifndef SYSTEM_H
#define SYSTEM_H
#include "Defines.h"
#include "D3D10Renderer.h"
class System
{
public:
System();
virtual ~System();
bool Initialize();
void Shutdown();
bool Frame();
bool Run();
HRESULT SetupTheWindow();
void DestroyTheWindow();
private:
// Objet qui gère le rendu de DirectX
D3D10Renderer* m_pRenderer;
LPCWSTR m_sApplicationName;
HINSTANCE m_hInstance;
HWND m_Hwnd;
bool m_bFullScreen;
};
#endif
Dans le fichier System.cpp. On initialise d’abord une fenêtre Windows ; voici la fonction pour l’initialiser :
HRESULT System::SetupTheWindow()
{
// Détermine la résolution de l'écran.
unsigned int iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
unsigned int iScreenHeight = GetSystemMetrics(SM_CYSCREEN);
// Structure de la classe à configurer
WNDCLASSEX wcex;
// Taille de la structure WNDCLASSEX
wcex.cbSize = sizeof( WNDCLASSEX );
// Style de la classe
wcex.style = CS_HREDRAW | CS_VREDRAW;
// Pointeur de la fonction de boucle de fenêtre (Callback)
wcex.lpfnWndProc = WndProc;
// Inutile à comprendre
wcex.cbClsExtra = 0;
// Inutile à comprendre
wcex.cbWndExtra = 0;
// Obtention de l'instance de cette application
wcex.hInstance = m_hInstance;
// Icone de la fenêtre
wcex.hIcon = LoadIcon(NULL, IDI_WINLOGO);
// Icone du pointeur de la souris
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
// Inutile à comprendre
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
// Inutile à comprendre
wcex.lpszMenuName = NULL;
// Nom de la classe enregistrée
wcex.lpszClassName = m_sApplicationName;
wcex.hIconSm = wcex.hIcon;
DEVMODE dmScreenSettings;
if(m_bFullScreen)
{
ZeroMemory(&dmScreenSettings, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof (dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long) iScreenWidth;
dmScreenSettings.dmPelsHeight = (unsigned long) iScreenHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
}
if (!RegisterClassEx(&wcex))
return E_FAIL;
// Créé la fenêtre
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
m_Hwnd = CreateWindow(m_sApplicationName, m_sApplicationName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, m_hInstance,
NULL);
if (!m_Hwnd)
return E_FAIL;
ShowWindow(m_Hwnd, SW_SHOW);
SetForegroundWindow(m_Hwnd);
SetFocus(m_Hwnd);
return S_OK;
}
Toujours dans System.cpp, la fonction pour détruire la fenêtre :
void System::DestroyTheWindow()
{
// Change les paramètres d'affichage si l'on quitte le mode plein écran
if(m_bFullScreen)
{
ChangeDisplaySettings(NULL, 0);
}
// Détruit la fenêtre.
DestroyWindow(m_Hwnd);
m_Hwnd = NULL;
// Détruit l'instance de l'application
UnregisterClass(m_sApplicationName, m_hInstance);
m_hInstance = NULL;
}
La fonction pour initialiser la fenêtre et le Renderer de DirectX 10 :
bool System::Initialize()
{
SetupTheWindow();
m_pRenderer = new D3D10Renderer(m_Hwnd);
bool bSucess = m_pRenderer->Initialize(m_bFullScreen);
if (!bSucess)
{
MessageBoxA(NULL, "Erreur d'initialisation de DirectX !", "Erreur", MB_ICONHAND | MB_OK);
return false;
}
return true;
}
La fonction WinMain est dans le fichier Main.cpp et est implémentée de cette façon :
#include "D3D10Renderer.h"
#include "System.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
System* pSystem = new System();
bool bSucess = pSystem->Initialize();
if (bSucess)
{
pSystem->Run();
}
pSystem->Shutdown();
SAFE_DELETE(pSystem);
return 0;
}
Ensuite créez un fichier D3D10Renderer.cpp et un fichier D3D10Renderer.h où vous mettrez les fonctions que je vous énoncerai.
bool D3D10Renderer::Initialize(bool bFullScreen)
{
HRESULT hr = S_OK;;
RECT rc;
GetClientRect(m_hWnd, &rc);
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
// Une swap chain représente en fait le back buffer
// et le front buffer (principe nommé double buffering)
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = m_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = !bFullScreen;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
hr = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags,
D3D10_SDK_VERSION, &sd, &m_pSwapChain, &m_pd3dDevice);
if (FAILED(hr))
return false;
// Créé le back buffer
ID3D10Texture2D* pBackBuffer;
hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer);
if (FAILED(hr))
return false;
// Créé la render target
hr = m_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &m_pRenderTargetView);
pBackBuffer->Release();
if (FAILED(hr))
return false;
m_pd3dDevice->OMSetRenderTargets( 1, &m_pRenderTargetView, NULL );
// Création du viewport
D3D10_VIEWPORT vp;
vp.Width = width;
vp.Height = height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
m_pd3dDevice->RSSetViewports( 1, &vp );
return true;
}
La fonction pour afficher le rendu :
void D3D10Renderer::Render()
{
float afClearColor[4] = {0.0f, 0.125f, 0.3f, 1.0f};
m_pd3dDevice->ClearRenderTargetView(m_pRenderTargetView, afClearColor);
m_pSwapChain->Present(1, 0);
}
Résumé :
Nous avons affiché une fenêtre prête à recevoir le rendu de DirectX.
Voici l’archive du code complet pour cette partie : DirectX 10 Tutoriel – Partie 1.zip
Voilà le code et les explications pour initialiser la fenêtre de DirectX 10.
Il reste beaucoup de choses à intégrer pour faire un jeu mais vous saurez au moins comment intégrer DirectX 10.
Références :
– https://takinginitiative.wordpress.com/directx10-tutorials/
– http://www.rastertek.com/tutdx10.html
– DirectX SDK June 2010 Documentation Samples

