Fichier source en cours : D3D10Renderer.cpp






Voici le code source cpp :




	#include "Framework.h"

using namespace fw;

#pragma comment(lib, "d3d10.lib")
#pragma comment(lib, "d3dx10.lib")
#pragma comment(lib, "dxerr.lib")

template<> D3D10Renderer* Singleton<D3D10Renderer>::ms_instance = nullptr;

D3D10Renderer::D3D10Renderer(HWND hWnd) : 
D3DRenderer(hWnd, DXVersion::D3D_10),
m_pd3dDevice(nullptr),
m_pSwapChain(nullptr),
m_pScreenRTTargetView(nullptr),
m_pDepthStencilTexture(nullptr),
m_pDSState(nullptr),
m_pDepthStencilView(nullptr),
m_pSprite(nullptr),
m_pFont(nullptr),
m_sTextInfo(L"D3D10 Renderer"),
m_bFSAA(false),
m_pPerformanceTimer(nullptr)
{
}

D3D10Renderer::~D3D10Renderer()
{
    if (m_pd3dDevice)
	{
		m_pd3dDevice->ClearState();
	}

	SAFE_RELEASE(m_pScreenRTTargetView);
	SAFE_RELEASE(m_pSwapChain);
	SAFE_RELEASE(m_pd3dDevice);

	SHADER_MANAGER->UnRegisterAllShaders();
	SCENE_MANAGER->DeleteAllNodes();
}

bool D3D10Renderer::Initialize(bool bFullscreen)
{ 
	m_bFullscreen = bFullscreen;

	// Variable pour stocker l'état erreur / succès
    HRESULT hr = S_OK;

	if (!CreateSwapChain())
	{
		return false;
	}

	if (!CreateRenderTarget())
	{
		return false;
	}

	if (!CreateDepthStencilView())
	{
		return false;
	}

	if (!CreateRasterizerState())
	{
		return false;
	}

	if (!CreateDepthStencilState())
	{
		return false;
	}

	CreateViewport();

	ShowCursor(false);

	SetupTextInfo();

	// Faire un gestionnaire de modules singletons
	new ShaderManager;
	new D3D10TextureManager;
	new SceneManager;
	new OBJFormatLoader;
	new ThreadsWrapper;

	SCENE_MANAGER->AddCamera(new FPSCamera("FPSCamera"));
	SCENE_MANAGER->SetActiveCamera("FPSCamera");

	//SHADER_MANAGER->RegisterShader(new ShaderTechnique_SkySphere, "SkySphere");
	//SHADER_MANAGER->RegisterShader(new ShaderTechnique_SimpleTexture, "SimpleTexture");
	//SHADER_MANAGER->RegisterShader(new ShaderTechnique_Vertex3DLines, "Vertex3DLines");

//	ShaderTechnique_SimpleTexture* pSimpleTextureShader =
	//	reinterpret_cast<ShaderTechnique_SimpleTexture*>(SHADER_MANAGER->GetShader("SimpleTexture"));

	LoadCustomCursor();

	D3D10MeshSceneNode* pWaterPlane = OBJ_LOADER_MANAGER->LoadMeshD3D10("water_plane.obj");


	ShaderTechnique::ShaderParameters param;
	param.SetParam(CUSTOM_SHADER_TEXTURE_NAME, "water.jpg");
	param.SetParam(CUSTOM_SHADER_TEXTURE_TILE_FACTOR, 50.0f);

	SCENE_MANAGER->AddMeshSceneNode(pWaterPlane);

	SCENE_MANAGER->EnableDebugLines(false);

	/*
	LoadMeshPrepared("oildrum2.obj",
		D3DXVECTOR3(0.0f, 10.0f, 0.0f),
		D3DXVECTOR3(0.0f, 0.0f, 0.0f),	
		D3DXVECTOR3(18.0f, 18.0f, 18.0f),
		pSimpleTextureShader, "Oildrum", "oildrum_col.jpg");
		*/
	m_pPerformanceTimer = new PerformanceTimer;

	return true;
}

bool D3D10Renderer::CreateRenderTarget()
{
	HRESULT hr = S_OK;

	// Créé le back buffer
	ID3D10Texture2D* pBackBuffer;
	hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer);

	V_RETURN(hr);

	// Créé la render target
	hr = m_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &m_pScreenRTTargetView);
	pBackBuffer->Release();

	V_RETURN(hr);

	return true;
}

bool D3D10Renderer::Frame()
{
	Render();

	return true;
}

void D3D10Renderer::Render()
{
	m_pPerformanceTimer->Begin();

		float fTimeSinceLastFrame = m_pPerformanceTimer->GetTimeSinceLastFrame();

		static float afClearColor[4] = {0.5f, 0.5f, 0.5f, 1.0f };

		// Efface la surface de rendu
		m_pd3dDevice->ClearDepthStencilView(m_pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0 );
		m_pd3dDevice->ClearRenderTargetView(m_pScreenRTTargetView, afClearColor);

		SCENE_MANAGER->DrawAll(fTimeSinceLastFrame);

		fastprint(fTimeSinceLastFrame);

		DrawTextInfo();

		m_pSwapChain->Present(0, 0);

		SYSTEM->UpdateWindowTitle();

	m_pPerformanceTimer->End();
}

ID3D10Device* D3D10Renderer::GetDevice()
{
	return m_pd3dDevice;
}

size_t32 D3D10Renderer::GetViewportWidth()
{
    DXGI_SWAP_CHAIN_DESC swapChainDesc;
    ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));

	m_pSwapChain->GetDesc(&swapChainDesc);

	return swapChainDesc.BufferDesc.Width;
}

size_t32 D3D10Renderer::GetViewportHeight()
{
    DXGI_SWAP_CHAIN_DESC swapChainDesc;
    ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));

	m_pSwapChain->GetDesc(&swapChainDesc);

	return swapChainDesc.BufferDesc.Height;
}

void D3D10Renderer::EnableZBuffer(bool bEnable)
{
	D3D10_DEPTH_STENCIL_DESC pDesc;

	m_pDSState->GetDesc(&pDesc);
    pDesc.DepthEnable = bEnable;

	m_pd3dDevice->OMSetDepthStencilState(m_pDSState, 1);
}

void D3D10Renderer::CreateViewport()
{
    // Création du viewport
    D3D10_VIEWPORT vp;

	vp.Width = m_iWidth;
    vp.Height = m_iHeight;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;

    m_pd3dDevice->RSSetViewports(1, &vp);
}

bool D3D10Renderer::CreateSwapChain()
{
	// Rectangle 2D pour les dimensions de la fenêtre
    RECT rc;

	// On obtient les dimensions de la fenêtre courante
    GetClientRect(m_hWnd, &rc);
	// Largeur de la fenêtre
    m_iWidth = (size_t) (rc.right - rc.left);
	// Hauteur de la fenêtre
    m_iHeight = (size_t) (rc.bottom - rc.top);

	// Paramètres de création du device
    UINT createDeviceFlags = 0;

	// Permet d'afficher les éventuelles erreurs de la création du device
	//createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG | D3D10_CREATE_DEVICE_SINGLETHREADED;
	createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;

	// Création de la Swap Chain 
	// c'est-à-dire création du front buffer et du back buffer
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory(&sd, sizeof(sd));
    sd.BufferCount = 1;
	// Taille de la surface en pixels
    sd.BufferDesc.Width = m_iWidth;
    sd.BufferDesc.Height = m_iHeight;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	// Format des couleurs
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
	// L'hanbdle de la fenêtre que l'on va afficher dessus
    sd.OutputWindow = m_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = m_bFSAA ? m_iFSAALevel : 0;
	// Fenêtré ou non
	sd.Windowed = !m_bFullscreen;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	// On créé le device DirectX 10 et la Swap Chain 
	HRESULT hr = D3D10CreateDeviceAndSwapChain(nullptr, D3D10_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags,
                                               D3D10_SDK_VERSION, &sd, &m_pSwapChain, &m_pd3dDevice);
    if (FAILED(hr))
	{
		ShowMessageBoxDXError(hr);
        return false;
	}

	return true;
}


bool D3D10Renderer::CreateDepthStencilView()
{
	HRESULT hr = S_OK;

    D3D10_TEXTURE2D_DESC descDepth;
	ZeroMemory(&descDepth, sizeof(descDepth));

    descDepth.Width = m_iWidth;
    descDepth.Height = m_iHeight;
    descDepth.MipLevels = 1;
    descDepth.ArraySize = 1;
	/* Make it compatible with both DXGI_FORMAT_D32_FLOAT (stencil view) 
	   and DXGI_FORMAT_R32_FLOAT (resource view) */
    descDepth.Format = DXGI_FORMAT_D32_FLOAT;
	descDepth.SampleDesc.Count = m_bFSAA ? m_iFSAALevel : 1;
	descDepth.SampleDesc.Quality = 0;
    descDepth.Usage = D3D10_USAGE_DEFAULT;
    descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
    descDepth.CPUAccessFlags = 0;
    descDepth.MiscFlags = 0;

	hr = m_pd3dDevice->CreateTexture2D(&descDepth, nullptr, &m_pDepthStencilTexture);

    if (FAILED(hr))
	{
		ShowMessageBoxDXError(hr);
        return false;
	}
		
	D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;
    descDSV.Format = descDepth.Format;
    descDSV.ViewDimension = m_bFSAA ? D3D10_DSV_DIMENSION_TEXTURE2DMS : D3D10_DSV_DIMENSION_TEXTURE2D;
    descDSV.Texture2D.MipSlice = 0;

	hr = m_pd3dDevice->CreateDepthStencilView(m_pDepthStencilTexture, &descDSV, &m_pDepthStencilView);

	ResetDefaultRenderTarget();

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

	return true;
}

bool D3D10Renderer::CreateRasterizerState()
{
	D3D10_RASTERIZER_DESC rasterizerState;

	rasterizerState.CullMode = D3D10_CULL_BACK;
	rasterizerState.FillMode = D3D10_FILL_SOLID;
	rasterizerState.FrontCounterClockwise = false;
    rasterizerState.DepthBias = true;
    rasterizerState.DepthBiasClamp = 0;
    rasterizerState.SlopeScaledDepthBias = 0;
    rasterizerState.DepthClipEnable = false;
	rasterizerState.ScissorEnable = false;

    rasterizerState.MultisampleEnable = m_bFSAA ? true : false;
    rasterizerState.AntialiasedLineEnable = m_bFSAA ? true : false;

	HRESULT hr = m_pd3dDevice->CreateRasterizerState(&rasterizerState, &m_pRasterizerState);	

	m_pd3dDevice->RSSetState(m_pRasterizerState);

	V_RETURN(hr);

	return true;
}

bool D3D10Renderer::CreateDepthStencilState()
{
	D3D10_DEPTH_STENCIL_DESC pDesc;

	pDesc.DepthEnable = true;
	pDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
	pDesc.DepthFunc = D3D10_COMPARISON_LESS;

	pDesc.StencilEnable = true;
	pDesc.StencilReadMask = 0xFF;
	pDesc.StencilWriteMask = 0xFF;

	pDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
	pDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
	pDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
	pDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
	pDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
	pDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
	pDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
	pDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;

	HRESULT hr = m_pd3dDevice->CreateDepthStencilState(&pDesc, &m_pDSState);

	V_RETURN(hr);

	m_pd3dDevice->OMSetDepthStencilState(m_pDSState, 1);

	return true;
}


/*
A mettre dans FrameListener !
void D3D10Renderer::OnKeyPressed(const KeyEvent& arg)
{
	if (arg.keyCode == VK_ESCAPE)
	{
		SYSTEM->Quit();
	}
	else if (arg.keyCode == VK_F1)
	{
		FPSCamera* pCameraFPS = reinterpret_cast<FPSCamera*> (SCENE_MANAGER->GetActiveCamera());

		pCameraFPS->SetActive(!pCameraFPS->GetActive());
	}
}

void D3D10Renderer::OnKeyReleased(const KeyEvent& arg)
{
}
*/

void D3D10Renderer::SetupTextInfo()
{
	// Il faut créer un objet ID3DX10Sprite
	D3DX10CreateSprite(m_pd3dDevice, 0, &m_pSprite);
 
	/* Détaille les attributs de cette police d'affichage */
	D3DX10_FONT_DESC fd;
 
	// Définit la hauteur d'un caractère de cette police
	fd.Height = 30;
	// Définit la largeur d'un caractère de cette police
	fd.Width = 13;
	fd.Weight = 3;
	fd.MipLevels = 0;
	// En italique ou non
	fd.Italic = false;
	fd.CharSet = OUT_DEFAULT_PRECIS;
	//fd.Quality = ANTIALIASED_QUALITY;
	fd.Quality = CLEARTYPE_QUALITY;
	fd.PitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
	// Définit le nom de la police à utiliser
	wcscpy_s(fd.FaceName, L"Corbel");
  
	D3DX10CreateFontIndirect(m_pd3dDevice, &fd, &m_pFont);
}

void D3D10Renderer::DrawTextInfo()
{
	DrawTextSprite(m_sTextInfo, D3DXVECTOR2(5, 100), Colours::White);
}

void D3D10Renderer::DrawTextSprite(const std::wstring& sText, const D3DXVECTOR2& position,
	const D3DXCOLOR& color)
{
	RECT rectangle;	
	rectangle.left = (uint32) position.x;
	rectangle.bottom = (uint32) position.y;
	rectangle.right = 0;
	rectangle.top = 0;

	EnableZBuffer(false);

		m_pSprite->Begin(D3DX10_SPRITE_SORT_TEXTURE);

			m_pFont->DrawText(m_pSprite, sText.c_str(), -1, &rectangle, DT_NOCLIP, color);

		m_pSprite->End();

	EnableZBuffer(true);
}

void D3D10Renderer::ResetDefaultRenderTarget()
{
	m_pd3dDevice->OMSetRenderTargets(1, &m_pScreenRTTargetView, m_pDepthStencilView);
}

ID3D10DepthStencilView* D3D10Renderer::GetDepthStencilView()
{
	return m_pDepthStencilView;
}

void D3D10Renderer::SetInfoText(const std::wstring& sText)
{
	m_sTextInfo = sText;
}

D3DMeshSceneNode<D3D10>* D3D10Renderer::LoadMeshOBJ(const std::string& sFileName)
{
	return OBJ_LOADER_MANAGER->LoadMesh<D3D10>(sFileName);
}

bool D3D10Renderer::SetSceneNodeData_Callback(const Callback::Parameter& param)
{
	D3DMeshSceneNode<D3D10>* pMeshNode = param.GetReturnValue<D3DMeshSceneNode<D3D10>*>();
	SceneManager::SceneNodeInfo* pMeshNodeInfo = 
		param.GetParameterAsPointer<SceneManager::SceneNodeInfo*>(CALL_BACK_SCENE_NODE_INFO);

	if (pMeshNode && pMeshNodeInfo)
	{
		if (pMeshNodeInfo->sName != NONE)
		{
			pMeshNode->SetName(pMeshNodeInfo->sName);
		}

		// Doit être appelée en priorité face à SetPosition, SetScale() !
		pMeshNode->CreateAABBLines(Colours::Red);

		pMeshNode->SetPosition(pMeshNodeInfo->position);
		pMeshNode->SetScale(pMeshNodeInfo->scale);
		pMeshNode->SetRotation(pMeshNodeInfo->rotation);

		pMeshNode->SetShaderTechnique(pMeshNodeInfo->pTechnique);

		if (pMeshNodeInfo->sTextureName != NONE)
		{
			ShaderTechnique::ShaderParameters param;
			param.SetParam(CUSTOM_SHADER_TEXTURE_NAME, pMeshNodeInfo->sTextureName);

			pMeshNode->PushCustomShaderParameter(param);
		}


		SCENE_MANAGER->AddMeshSceneNode(pMeshNode);

		return true;
	}
	else
	{
		return false;
	}
}

void D3D10Renderer::LoadMeshPrepared(const std::string& sFileName,
	const D3DXVECTOR3& pos, const D3DXVECTOR3& rot, const D3DXVECTOR3& scale,
	ShaderTechnique* pShaderTechnique, const std::string& sName, const std::string& sTextureName)
{
	Callback* pCallback = new Callback();
	pCallback->AddCallbackFunction(&D3D10Renderer::SetSceneNodeData_Callback, this);
	pCallback->AddCallbackFunction(&D3D10Renderer::LookAfterNodes_Callback, this);

	ThreadsWrapper::Thread* pT = nullptr;

	if (Utils::IsFileExtensionCorrect(sFileName, ".obj"))
	{
		pT = THREADS_WRAPPER->CreateThread("MeshLoaderOBJ",
				&D3D10Renderer::LoadMeshOBJ, this, sFileName);
	}

	if (pT)
	{
		SceneManager::SceneNodeInfo* pSceneNodeInfo = new SceneManager::SceneNodeInfo;

		pSceneNodeInfo->position = pos;
		pSceneNodeInfo->rotation = rot;
		pSceneNodeInfo->scale = scale;
		pSceneNodeInfo->pTechnique = pShaderTechnique;
		pSceneNodeInfo->sName = sName;
		pSceneNodeInfo->sTextureName = sTextureName;

		Callback::Parameter param;
		param.SetParam(CALL_BACK_SCENE_NODE_INFO, pSceneNodeInfo);

		pT->SetCallback(pCallback);
		pT->LinkParameters(param);

		std::thread::id id = THREADS_WRAPPER->LaunchThread(pT);
	}
}

void D3D10Renderer::LoadCustomCursor()
{
	HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
	HWND hwnd = SYSTEM->GetHwnd();

	HCURSOR WoWCursor = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR_ARROW));

	SetClassLong(hwnd, GCL_HCURSOR, (LONG)WoWCursor);
}

bool D3D10Renderer::LookAfterNodes_Callback(const Callback::Parameter& param)
{
	D3DMeshSceneNode<D3D10>* pMeshNode = param.GetReturnValue<D3DMeshSceneNode<D3D10>*>();
	SceneManager::SceneNodeInfo* pMeshNodeInfo =
		param.GetParameterAsPointer<SceneManager::SceneNodeInfo*>(CALL_BACK_SCENE_NODE_INFO);

	if (pMeshNodeInfo && pMeshNode)
	{
		std::string sNodeName = pMeshNodeInfo->sName;


		return true;
	}

	return false;
}

void D3D10Renderer::SetFSAAMaximumLevel()
{
	HRESULT hr = S_OK;
	UINT maxQualityLevel = 1;
	for (uint32 iSampleCount = 1; iSampleCount <= D3D10_MAX_MULTISAMPLE_SAMPLE_COUNT; iSampleCount++)
	{
		hr = m_pd3dDevice->CheckMultisampleQualityLevels(
			DXGI_FORMAT_R8G8B8A8_UNORM, iSampleCount, &maxQualityLevel);

		if (hr != S_OK)
		{
			fastprint(Utils::Formater(L"CheckMultisampleQualityLevels a échoué."));
		}

		if (maxQualityLevel > 0)
		{
			fastprint("MSAA " << iSampleCount << Utils::Formater(L"X supportée par la carte vidéo avec ") <<
				maxQualityLevel << Utils::Formater(L" niveau(x) de qualité."));
		}
	}
}

void D3D10Renderer::SetFullScreen()
{
	m_bFullscreen = !m_bFullscreen;

	if (m_bFullscreen)
	{
		ResizeSwapChain(m_iWidth, m_iHeight);
	}

	m_pSwapChain->SetFullscreenState(m_bFullscreen, nullptr);
}

void D3D10Renderer::SetWindowResolutionMode(uint32 iMode)
{
	// Largeur de la fenêtre
	uint32 iWidth = m_modes[iMode].Width;
	// Hauteur de la fenêtre
	uint32 iHeight = m_modes[iMode].Height;

	ResizeSwapChain(iWidth, iHeight);

	RECT rc;

	GetWindowRect(m_hWnd, &rc);

	SetWindowPos(m_hWnd, 0, rc.left, rc.top, iWidth, iHeight, SWP_SHOWWINDOW);
}

bool D3D10Renderer::ResizeSwapChain(const size_t32& iWidth, const size_t32& iHeight)
{
	/* On décharge les précédents objets de rendu */
	SAFE_RELEASE(m_pScreenRTTargetView);
	SAFE_RELEASE(m_pDepthStencilView);

	HRESULT hr = S_OK;
	hr = m_pSwapChain->ResizeBuffers(2, iWidth, iHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0);

	V_RETURN(hr);

	m_iWidth = iWidth;
	m_iHeight = iHeight;

	/* Puis on les recréer */
	CreateRenderTarget();
	CreateDepthStencilView();

	//m_pCube->SetLens()
	CreateViewport();

	return true;
}

bool D3D10Renderer::GetGPUInfo()
{
	HRESULT hr = S_OK;

	uint32 iNumModes;

	IDXGIFactory* pDXGIFactory = nullptr;
	IDXGIAdapter* pDXGIAdapter = nullptr;
	IDXGIOutput* pDXGIAdapterOutput = nullptr;

	DXGI_MODE_DESC* pDisplayModeList = nullptr;

	DXGI_ADAPTER_DESC adapterDesc;

	// Créée une interface métier "factory" DirectX
	hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&pDXGIFactory);

	V_RETURN(hr);

	// Utilise la "factory"
	hr = pDXGIFactory->EnumAdapters(0, &pDXGIAdapter);

	V_RETURN(hr);

	// Enumère l'adpatateur principal de l'écran
	hr = pDXGIAdapter->EnumOutputs(0, &pDXGIAdapterOutput);

	V_RETURN(hr);

	// Obtient le nombre de modes d'affichage qui corresppond à DXGI_FORMAT_R8G8B8A8_UNORM  
	hr = pDXGIAdapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &iNumModes, nullptr);

	V_RETURN(hr);

	/* Créé une liste qui détient tous les modes d'affichage possibles pour cette carte graphique et
	   le format d'affichage */
	pDisplayModeList = new DXGI_MODE_DESC[iNumModes];

	if (!pDisplayModeList)
	{
		return false;
	}

	// Remplie la précédente structure
	hr = pDXGIAdapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &iNumModes, pDisplayModeList);

	V_RETURN(hr);

	/* On parcourt tous les modes d'affichages possibles
	   et on trouve celui qui correspond à la taille spécifiée
	   en paramètre ; puis on enregistre le numérateur et le dénominateur
	   du taux de rafraichissement de l'écran
	*/
	for (uint32 i = 0; i < iNumModes; i++)
	{
		if (pDisplayModeList[i].Width == (uint32)m_iWidth)
		{
			if (pDisplayModeList[i].Height == (uint32)m_iHeight)
			{
				uint32 iNumerator = pDisplayModeList[i].RefreshRate.Numerator;
				uint32 iDenominator = pDisplayModeList[i].RefreshRate.Denominator;
			}
		}

		DXGI_MODE_DESC desc = pDisplayModeList[i];


		// On vérifie que ce mode n'a pas déjà été ajouté
		bool bAlreadyExist = false;
		for (uint32 i = 0; i < m_modes.size(); i++)
		{
			if (m_modes[i].Width == desc.Width &&
				m_modes[i].Height == desc.Height)
			{
				bAlreadyExist = true;
				break;
			}
		}

		if (!bAlreadyExist)
		{
			m_modes.push_back(desc);
		}
	}

	hr = pDXGIAdapter->GetDesc(&adapterDesc);

	V_RETURN(hr);

	// On enregistre la taille de la mémoire vidéo en mégabytes
	m_iVideoCardMemory = (adapterDesc.DedicatedVideoMemory / 1024 / 1024);

	size_t32 iStringLength = 0;
	// Convertie le nom la carte vidéo dans une chaîne de caractères
	uint32 iError = wcstombs_s(&iStringLength, m_sVideoCardDescription, 128, adapterDesc.Description, 128);

	if (iError != 0)
	{
		return false;
	}

	SAFE_DELETE_ARRAY(pDisplayModeList);

	SAFE_RELEASE(pDXGIAdapterOutput);
	SAFE_RELEASE(pDXGIAdapter);
	SAFE_RELEASE(pDXGIFactory);

	return true;
}

D3DDevice* D3D10Renderer::GetPureDevice() 
{ 
	return (D3DDevice*)m_pd3dDevice;
}