Camera.h #pragma once class CCamera { public: CCamera(); enum ECamMoveDir { eForward, eBack, eLeft, eRight }; void Reset(); void Move(ECamMoveDir dir); void Yaw(float angle); void Pitch(float angle); void Roll(float angle); void SetEye(const D3DVECTOR &eyePos) { eye = eyePos; } D3DVECTOR GetTarget(); D3DVECTOR GetEye() const { return eye; } D3DVECTOR GetCamForward() const { return forward; } D3DVECTOR GetCamUp() const { return up; } D3DVECTOR GetCamRight() const { return right; } private: D3DVECTOR right; D3DVECTOR up; D3DVECTOR forward; D3DVECTOR eye; };
Camera.cpp #include <d3d9.h> #include <d3dx9.h> #include "Camera.h" // Constructeur CCamera::CCamera() { Reset(); } // Place la camera sur les axes // Place l'oeil à -5 sur Z void CCamera::Reset() { right.x = 1.0f; right.y = 0.0f; right.z = 0.0f; up.x = 0.0f; up.y = 1.0f; up.z = 0.0f; forward.x = 0.0f; forward.y = 0.0f; forward.z = 1.0f; eye.x = 0.0f; eye.y = 0.0f; eye.z = -5.0f; } // Bouges la camera dans la direction "dir" void CCamera::Move(ECamMoveDir dir) { switch(dir) { case eForward: // Bouge devant eye.x += forward.x; eye.y += forward.y; eye.z += forward.z; break; case eBack: // Bouge derrière eye.x -= forward.x; eye.y -= forward.y; eye.z -= forward.z; break; case eLeft: // Bouge à gauche eye.x -= right.x; eye.y -= right.y; eye.z -= right.z; break; case eRight: // Bouge à droite eye.x += right.x; eye.y += right.y; eye.z += right.z; break; } } void CCamera::Yaw(float angle) { D3DXMATRIX matRotation; D3DXMatrixRotationAxis(&matRotation, (D3DXVECTOR3*)&up/*&D3DXVECTOR3(0,1,0)*/, angle); //D3DXVec3TransformCoord((D3DXVECTOR3*)&eye, (D3DXVECTOR3*)&eye, &matRotation); D3DXVec3TransformCoord((D3DXVECTOR3*)&forward, (D3DXVECTOR3*)&forward, &matRotation); } void CCamera::Pitch(float angle) { D3DXMATRIX matRotation; D3DXMatrixRotationAxis(&matRotation, (D3DXVECTOR3*)&right, angle); //D3DXVec3TransformCoord((D3DXVECTOR3*)&eye, (D3DXVECTOR3*)&eye, &matRotation); D3DXVec3TransformCoord((D3DXVECTOR3*)&forward, (D3DXVECTOR3*)&forward, &matRotation); } void CCamera::Roll(float angle) { } D3DVECTOR CCamera::GetTarget() { D3DVECTOR tmp; tmp.x = eye.x + forward.x; tmp.y = eye.y + forward.y; tmp.z = eye.z + forward.z; return tmp; }
Code principale #define WIN32_LEAN_AND_MEAN // Optimise la taille et la vitesse (non MFC) #define D3D_DEBUG_INFO // Informations complémentaires pour debug #include <d3d9.h> // Entête Direct3D #include <d3dx9.h> // Entête Extension D3D #include <windows.h> // Entête API Windows #include "DrawFPS.h" // Afficheur de FPS #include "Camera.h" // Camera //---------------------------------------------------- //-------------------- Macros ---------------------- //---------------------------------------------------- #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } //---------------------------------------------------- //-------------------- Globals --------------------- //---------------------------------------------------- HWND g_hWnd = NULL; // Handle pour la fenêtre LPDIRECT3D9 g_pD3D = NULL; // Pointer sur l'interface IDirect3D9 LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Pointer sur l'interface IDirect3DDevice9 D3DPRESENT_PARAMETERS g_d3dpp; // Paramètres D3D D3DDISPLAYMODE g_d3ddm; // Mode d'affichage LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Vertex Buffer LPDIRECT3DVERTEXBUFFER9 g_pGridVB = NULL;// Grid Vertex Buffer LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; // Index Buffer LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Texture CCamera * g_Camera; // Camera ID3DXFont* g_pFont_x = NULL; // Font pour x ID3DXFont* g_pFont_y = NULL; // Font pour y bool g_bFullScreen = false; // Plein écran ? bool g_bDrawFPS = true; // Affichage ou non des FPS int g_iwSx = 800; // Dimension de la fenêtre int g_iwSy = 600; // Dimension de la fenêtre bool g_bDeviceLost = false; // Perte du device POINT g_ptCurrentMousePos; // Position actuelle de la souris // Structure pour format de vertex struct CUSTOMVERTEX { D3DVECTOR points; // Position du vertex x,y,z D3DVECTOR normal; // Normale D3DCOLOR color; // Couleur float tu,tv; // Coordonnée texture }; // Le FVF (flexible vertex format), décrit la structure du vertex #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1) // Structure pour format de vertex struct GRIDVERTEX { D3DVECTOR points; // Position du vertex x,y,z D3DCOLOR color; // Couleur }; // Le FVF (flexible vertex format), décrit la structure du vertex #define D3DFVF_GRIDVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE) //---------------------------------------------------- //------------------- Prototypes ------------------- //---------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR CmdLine, int CmdShow); LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); HRESULT Init(void); void ShutDown(void); void ReleaseObject(void); void Render(void); void ToggleFullScreen(void); HRESULT InitVB(void); HRESULT InitGridVB(void); HRESULT InitView(void); HRESULT InitTransform(void); HRESULT LoadTextures(void); void SetView(void); void DrawCube(void); void DrawGrid(void); void CenterCursor(); //---------------------------------------------------- //----------- Point d'entrée du programme ---------- //---------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance, // Handle de l'instance de l'appli HINSTANCE hPrevInstance, // Obsolète, toujours NULL LPSTR CmdLine, // Paramètre (ligne de commande) int CmdShow) // Flag pour l'état de la fenêtre { MSG uMsg; // Message de la fenêtre WNDCLASSEX winClass; // Classe de la fenêtre (paramètres) winClass.cbSize = sizeof(WNDCLASSEX); // Taille de la structure winClass.style = CS_CLASSDC; // Style de la fenêtre winClass.lpfnWndProc = WindowProc; // Fonction de traitement des messages winClass.cbClsExtra = 0; // Nombre d'octets en plus pour la structure winClass.cbWndExtra = 0; // Nombre d'octets en plus pour l'instance winClass.hInstance = hInstance; // Handle de l'appli winClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Pas d'icone winClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Curseur standard winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // Fond, NULL pour D3D winClass.lpszMenuName = NULL; // Menu winClass.lpszClassName = "MY_WINDOWS_CLASS"; // Nom de la classe de la fenêtre winClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // Pas d'icone if(!RegisterClassEx(&winClass)) return E_FAIL; // Enregistre la fenêtre // Creation de la fenêtre g_hWnd = CreateWindowEx(NULL, // Styles étendus "MY_WINDOWS_CLASS", // Nom de la classe de la fenêtre "Plom 3D", // Titre de la fenêtre WS_OVERLAPPEDWINDOW | WS_VISIBLE, // Style de la fenêtre 0, 0, // x, y point d'origine g_iwSy, g_iwSy, // Taille NULL, // Handle fenêtre parent NULL, // Handle du menu hInstance, // Handle de l'appli NULL); // Paramètres supplémentaires if(g_hWnd == NULL) return E_FAIL; // Si la fenêtre n'est pas créée ShowWindow(g_hWnd, CmdShow); // Affiche la fenêtre hWnd suivant le paramètre CmdShow UpdateWindow(g_hWnd); // Mise à jour contenu fenêtre CenterCursor(); // Centre le curseur //ShowCursor(FALSE); // Cache le curseur ZeroMemory(&uMsg, sizeof(uMsg)); // Initialise à zéro les messages if(SUCCEEDED(Init())) // Initialise Direct3D { while(uMsg.message != WM_QUIT) // Tant que le message n'est pas QUIT { if(PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) // Dispatche les msg de la file { TranslateMessage(&uMsg); // Traduit le msg DispatchMessage(&uMsg); // Transmet à la fonction de traitement (WindowProc) } else { Render(); // Exécute le rendu 3D CenterCursor(); // Centre le curseur } } } ShutDown(); // Stoppe le rendu 3D et vide la mémoire UnregisterClass("MY_WINDOWS_CLASS", winClass.hInstance ); // Si on quitte, libère la fenêtre return uMsg.wParam; // Rentourne le wParam du message WM_QUIT } //---------------------------------------------------- //-------------- Gestion des messages -------------- //---------------------------------------------------- LRESULT CALLBACK WindowProc(HWND hWnd, // Handle de la fenêtre UINT uMsg, // Identifiant du message WPARAM wParam, // Premier paramètre du message LPARAM lParam) // deuxièe paramètre du message { switch( uMsg ) // Suivant le msg { case WM_KEYDOWN: // Si touche enfoncée { switch( wParam ) // Suivant le paramètre touche { case VK_F1: { g_bDrawFPS = !g_bDrawFPS; } break; case VK_UP: case 'Z': case 'z': { g_Camera->Move(CCamera::eForward); } break; case VK_DOWN: case 'S': case 's': { g_Camera->Move(CCamera::eBack); } break; case VK_RIGHT: case 'D': case 'd': { g_Camera->Move(CCamera::eRight); } break; case VK_LEFT: case 'Q': case 'q': { g_Camera->Move(CCamera::eLeft); } break; } } break; case WM_SYSKEYDOWN: { // ALT + ENTER if(wParam == VK_RETURN && (lParam & (1 << 29))) { ToggleFullScreen(); // Plein Ecran } // ALT + F4 if(wParam == VK_F4 && (lParam & (1 << 29))) { PostQuitMessage(0); // Quitte } } break; case WM_MOUSEMOVE: // Si la souris bouge { GetCursorPos(&g_ptCurrentMousePos); // Récupère la position du curseur ... ScreenToClient(g_hWnd, &g_ptCurrentMousePos); // ... par rapport à la fenêtre // Droite if(g_ptCurrentMousePos.x > g_iwSx/2 + 2) { float nXDiff = (1.0f - (float)(g_ptCurrentMousePos.x) / (float)g_iwSx) * 20; g_Camera->Yaw(D3DXToRadian(nXDiff)); } // Gauche if(g_ptCurrentMousePos.x < g_iwSx/2 - 2) { float nXDiff = (1.0f - (float)(g_ptCurrentMousePos.x) / (float)g_iwSx) * 20; g_Camera->Yaw(D3DXToRadian(-nXDiff)); } // Bas if(g_ptCurrentMousePos.y > g_iwSy/2 + 2) { float nYDiff = (1.0f - (float)(g_ptCurrentMousePos.y) / (float)g_iwSy) * 20; g_Camera->Pitch(D3DXToRadian(-nYDiff)); } // Haut if(g_ptCurrentMousePos.y < g_iwSy/2 - 2) { float nYDiff = (1.0f - (float)(g_ptCurrentMousePos.y) / (float)g_iwSy) * 20; g_Camera->Pitch(D3DXToRadian(nYDiff)); } } break; case WM_CLOSE: { // Ferme l'application en envoyant WM_QUIT PostQuitMessage(0); } case WM_DESTROY: { // Ferme l'application en envoyant WM_QUIT PostQuitMessage(0); } break; default: { // La fonction DefWindowProc() traitera les messages intraités return DefWindowProc( hWnd, uMsg, wParam, lParam ); } break; } return 0; } //---------------------------------------------------- //---------------- Centre le curseur --------------- //---------------------------------------------------- void CenterCursor() { POINT pt = { g_iwSx / 2, g_iwSy / 2 }; // Point central ... ClientToScreen(g_hWnd, &pt); // ... par rapport à la fenêtre SetCursorPos(pt.x, pt.y); // Place le curseur au centre de la fenêtre } //---------------------------------------------------- //------------ Initialisation Direct 3D ------------ //---------------------------------------------------- HRESULT Init(void) { g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); // Crée l'interface et renvoie un pointeur sur IDIRECT3D9 ZeroMemory(&g_d3ddm, sizeof(g_d3ddm)); // Met tout à zéro ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); // Met tout à zéro Sleep(100); g_d3dpp.hDeviceWindow = g_hWnd; // Handle sur la fenêtre g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // Remplitle back buffer de bruit g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // N'attend pas la V-Sync g_d3dpp.EnableAutoDepthStencil = TRUE; // Active le depth buffer g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // Format du depth buffer // En Plein Ecran if(g_bFullScreen) { g_d3ddm.Format = D3DFMT_X8R8G8B8; // Format du display g_d3ddm.Width = g_iwSx; // Taille du display g_d3ddm.Height = g_iwSy; // Taille du display g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &g_d3ddm); g_d3dpp.Windowed = FALSE; // Pas en fenêtré (pas nécessaire) g_d3dpp.BackBufferWidth = g_d3ddm.Width; // Taille back buffer g_d3dpp.BackBufferHeight = g_d3ddm.Height; // Taille back buffer g_d3dpp.BackBufferFormat g_d3ddm.Format; // Format back buffer format display } // En Fenêtré else if(!g_bFullScreen) { g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &g_d3ddm); g_d3dpp.Windowed = TRUE; // Fenêtré g_d3dpp.BackBufferFormat D3DFMT_UNKNOWN; // Format back buffer format bureau } if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, // Utilise l'affichage principal D3DDEVTYPE_HAL, // Utilise l'accélération matériel g_hWnd, // Handle sur la fenêtre D3DCREATE_HARDWARE_VERTEXPROCESSING, // Traitement de vertex (sommets) en hardware &g_d3dpp, // Pointeur sur les paramètres &g_pd3dDevice))) // Pointeur sur l'interface IDirect3DDevice9 { return E_FAIL; } g_Camera = new CCamera(); // Creation camera InitTimer(); // Initialisation des Timers (FPS) if FAILED(InitFont()) return E_FAIL; // Initialisation de la Font (FPS) if FAILED(InitVB()) return E_FAIL; // Initialisation du vertex buffer if FAILED(InitGridVB()) return E_FAIL; // Initialisation du vertex buffer if FAILED(InitTransform()) return E_FAIL; // Initialisation de la vue et de la perspective SetView(); // Initialise camera if FAILED(LoadTextures()) return E_FAIL;// Chargements des textures g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); // Désactive les lumières D3DXCreateFont(g_pd3dDevice, // Pointeur sur IDirect3DDevice9 20, // Hauteur des caractères 0, // Largeur des caractères FW_BOLD, // Type 0, // Nombre de niveaux de mipmap FALSE, // TRUE pour Italic DEFAULT_CHARSET, // Charset OUT_DEFAULT_PRECIS, // TrueType ou pas DEFAULT_QUALITY, // Qualité DEFAULT_PITCH | FF_DONTCARE, // Famille et pitch de la police TEXT("Arial"), // Nom de la police &g_pFont_x); // Pointeur sur Font D3DXCreateFont(g_pd3dDevice, // Pointeur sur IDirect3DDevice9 20, // Hauteur des caractères 0, // Largeur des caractères FW_BOLD, // Type 0, // Nombre de niveaux de mipmap FALSE, // TRUE pour Italic DEFAULT_CHARSET, // Charset OUT_DEFAULT_PRECIS, // TrueType ou pas DEFAULT_QUALITY, // Qualité DEFAULT_PITCH | FF_DONTCARE, // Famille et pitch de la police TEXT("Arial"), // Nom de la police &g_pFont_y); // Pointeur sur Font return S_OK; } //---------------------------------------------------- //--------------- Arrêt de Direct 3D --------------- //---------------------------------------------------- void ShutDown(void) { ReleaseObject(); // Libère la Font (FPS) SAFE_RELEASE(g_pVB); // Libère le vertex buffer SAFE_RELEASE(g_pIB); // Libère l'index buffer SAFE_RELEASE(g_pGridVB); // Libère le vertex buffer SAFE_RELEASE(g_pd3dDevice); // Libère le Device SAFE_RELEASE(g_pD3D); // Libère l'interface } //---------------------------------------------------- //--------------- Libère les objets ---------------- //---------------------------------------------------- void ReleaseObject(void) { ReleaseFont(); // Libère la Font (FPS) SAFE_RELEASE(g_pTexture); // Libère la texture SAFE_DELETE(g_Camera); // Libère la camera SAFE_RELEASE(g_pFont_x); // Libère la font du texte SAFE_RELEASE(g_pFont_y); // Libère la font du texte } //---------------------------------------------------- //---------- Initialise et remplit le VB ----------- //---------------------------------------------------- HRESULT InitVB(void) { // Liste des points D3DVECTOR P0 = { 1.0f, 1.0f, -1.0f}, P1 = { 1.0f, -1.0f, -1.0f}, P2 = {-1.0f, -1.0f, -1.0f}, P3 = {-1.0f, 1.0f, -1.0f}, P4 = {-1.0f, 1.0f, 1.0f}, P5 = {-1.0f, -1.0f, 1.0f}, P6 = { 1.0f, -1.0f, 1.0f}, P7 = { 1.0f, 1.0f, 1.0f}; // Liste des normales D3DVECTOR N0 = { 0.0f, 0.0f, -1.0f}, N1 = { -1.0f, 0.0f, 0.0f}, N2 = { 0.0f, 0.0f, 1.0f}, N3 = { 1.0f, 0.0f, 0.0f}, N4 = { 0.0f, -1.0f, 0.0f}, N5 = { 0.0f, 1.0f, 0.0f}; // Liste des couleurs D3DCOLOR C0 = D3DCOLOR_XRGB(255,0,0), C1 = D3DCOLOR_XRGB(255,255,0), C2 = D3DCOLOR_XRGB(255,0,255), C3 = D3DCOLOR_XRGB(255,128,128), C4 = D3DCOLOR_XRGB(0,255,255), C5 = D3DCOLOR_XRGB(128,128,128); // Liste des vertex CUSTOMVERTEX vertices[] = { {P0, N0, C0, 1.0f,0.0f}, {P1, N0, C0, 1.0f,1.0f}, {P3, N0, C0, 0.0f,0.0f}, {P2, N0, C0, 0.0f,1.0f}, // 1 face {P2, N1, C1, 1.0f,1.0f}, {P5, N1, C1, 0.0f,1.0f}, {P3, N1, C1, 1.0f,0.0f}, {P4, N1, C1, 0.0f,0.0f}, // 2 face {P4, N2, C2, 1.0f,0.0f}, {P5, N2, C2, 1.0f,1.0f}, {P7, N2, C2, 0.0f,0.0f}, {P6, N2, C2, 0.0f,1.0f}, // 3 face {P7, N3, C3, 1.0f,0.0f}, {P6, N3, C3, 1.0f,1.0f}, {P0, N3, C3, 0.0f,0.0f}, {P1, N3, C3, 0.0f,1.0f}, // 4 face {P6, N4, C4, 1.0f,1.0f}, {P5, N4, C4, 0.0f,1.0f}, {P1, N4, C4, 1.0f,0.0f}, {P2, N4, C4, 0.0f,0.0f}, // 5 face {P7, N5, C5, 1.0f,0.0f}, {P0, N5, C5, 1.0f,1.0f}, {P4, N5, C5, 0.0f,0.0f}, {P3, N5, C5, 0.0f,1.0f} // 6 face }; // Tableau d'indices short unsigned int index_vertices[] = { 0, 1, 2, 3, // Face 1 4, 5, 6, 7, // Face 2 8, 9,10,11, // Face 3 12,13,14,15, // Face 4 16,17,18,19, // Face 5 20,21,22,23 }; // Face 6 size_t verticesSize = sizeof(vertices); // Taille du tableau de sommets (vertex) size_t index_verticesSize = sizeof(index_vertices); // Taille du tableau d'index // Création d'un objet IDirect3DVertexBuffer9 (tableau de N sommets) g_pd3dDevice->CreateVertexBuffer(verticesSize, // Taille de mémoire à réserver 0, // 0 ou flag sur utilisation du buffer D3DFVF_CUSTOMVERTEX, // Format D3DPOOL_MANAGED, // Gestion mémoire &g_pVB, // Pointeur sur IDirect3DVertexBuffer9 NULL); // Toujours NULL // Vérouille l'objet (évite qu'il "bouge" en mémoire) VOID* pVertices; g_pVB->Lock(0, // Offset, décalage depuis le début du VertexBuffer verticesSize, // Taille à vérouiller &pVertices, // Adresse mémoire (temporaire) pour effectuer les opérations 0); // Type de verrou memcpy(pVertices, vertices, verticesSize); // Effectue la copie g_pVB->Unlock(); // Dévérouille // Création d'un Index Buffer g_pd3dDevice->CreateIndexBuffer(index_verticesSize, // Taille de méomire à réserver 0, // 0 ou flag D3DFMT_INDEX16, // Format D3DPOOL_MANAGED, // Gestion mémoire &g_pIB, // Pointeur sur l'IndexBuffer NULL); // Toujours NULL g_pIB->Lock(0, index_verticesSize, &pVertices, 0); memcpy(pVertices, index_vertices, index_verticesSize); g_pIB->Unlock(); return S_OK; } //---------------------------------------------------- //---------- Initialise et remplit le VB ----------- //---------------------------------------------------- HRESULT InitGridVB(void) { int i 0, j 0; D3DCOLOR Color = D3DCOLOR_XRGB(255,0,200); D3DVECTOR pos = { 0.0f, -2.0f, 0.0f }; GRIDVERTEX gridvertices[260]; for(i = -32; i <= 32; ++i) { gridvertices[j].color = Color; gridvertices[j].points.x = pos.x - 32; gridvertices[j].points.y = pos.y; gridvertices[j].points.z = pos.z + i; ++j; gridvertices[j].color = Color; gridvertices[j].points.x = pos.x + 32; gridvertices[j].points.y = pos.y; gridvertices[j].points.z = pos.z + i; ++j; gridvertices[j].color = Color; gridvertices[j].points.x = pos.x + i; gridvertices[j].points.y = pos.y; gridvertices[j].points.z = pos.z - 32; ++j; gridvertices[j].color = Color; gridvertices[j].points.x = pos.x + i; gridvertices[j].points.y = pos.y; gridvertices[j].points.z = pos.z + 32; ++j; } size_t verticesSize = sizeof(gridvertices); // Taille du tableau de sommets (vertex) // Création d'un objet IDirect3DVertexBuffer9 (tableau de N sommets) g_pd3dDevice->CreateVertexBuffer(verticesSize, // Taille de mémoire à réserver 0, // 0 ou flag sur utilisation du buffer D3DFVF_GRIDVERTEX, // Format D3DPOOL_MANAGED, // Gestion mémoire &g_pGridVB, // Pointeur sur IDirect3DVertexBuffer9 NULL); // Toujours NULL // Vérouille l'objet (évite qu'il "bouge" en mémoire) VOID* pVertices; g_pGridVB->Lock(0, // Offset, décalage depuis le début du VertexBuffer verticesSize, // Taille à vérouiller &pVertices, // Adresse mémoire (temporaire) pour effectuer les opérations 0); // Type de verrou memcpy(pVertices, gridvertices, verticesSize); // Effectue la copie g_pGridVB->Unlock(); // Dévérouille return S_OK; } //---------------------------------------------------- //------------ Initialise la perspective ----------- //---------------------------------------------------- HRESULT InitTransform(void) { D3DXMATRIX matProjection; // Déclaration des matrices // Défini le cône de vision (perspective) D3DXMatrixPerspectiveFovLH(&matProjection, // Matrice à créer D3DX_PI/3.f, // Largeur de champ de vision (radian) 640.0f / 480.0f, // Aspect ratio 1.0f, // z min visible 8192.0f); // z max visible g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProjection); return S_OK; } //---------------------------------------------------- //---------------- Initialise la vue --------------- //---------------------------------------------------- void SetView(void) { D3DXMATRIX matVue; // Déclaration matrice D3DXVECTOR3 Voeil = g_Camera->GetEye(), // Place l'oeil de la camera Vvers = g_Camera->GetTarget(), // Place la direction de la camera //Vdirhaut(0.0f, 1.0f, 0.0f); // Direction Vdirhaut = g_Camera->GetCamUp(); // Défini d'ou on regarde et dans quel direction D3DXMatrixLookAtLH(&matVue, // Matrice à créer &Voeil, // Là ou est notre oeil &Vvers, // Direction qu'il regarde &Vdirhaut); // Direction du haut g_pd3dDevice->SetTransform(D3DTS_VIEW, &matVue); } //---------------------------------------------------- //------------- Initialise les Textures ------------ //---------------------------------------------------- HRESULT LoadTextures(void) { D3DXCreateTextureFromFile(g_pd3dDevice, "rabbit.jpg", &g_pTexture); // Chargement de la texture dans g_pTexture g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); // Filtre bilinéaire pour zoom arrière g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); // Filtre bilinéaire pour zoom avant return S_OK; } //---------------------------------------------------- //------------- Passe en Plein Ecran --------------- //---------------------------------------------------- void ToggleFullScreen(void) { static RECT winRect = {0}; // Rectangle ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); // Efface les paramètres du device g_pd3dDevice->Reset(&g_d3dpp); // Reset du device if(!g_bFullScreen) GetWindowRect(g_hWnd, &winRect); // Recupère taille fenêtre g_bFullScreen = !g_bFullScreen; // Passe de l'un à l'autre // Si fenêtré, redimensionne la fenêtre if(!g_bFullScreen) SetWindowPos(g_hWnd, HWND_NOTOPMOST, winRect.left, winRect.top, winRect.right - winRect.left, winRect.bottom - winRect.top, SWP_SHOWWINDOW); Init(); // Réinitialise } //---------------------------------------------------- //--------------- Affichage du cube ---------------- //---------------------------------------------------- void DrawCube(void) { // Chargement de la texture g_pd3dDevice->SetTexture(0, g_pTexture); // Définit le FVF du Device g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); // Charge l'index g_pd3dDevice->SetIndices(g_pIB); // Charge les VertexBuffer dans le flux de sommets g_pd3dDevice->SetStreamSource(0, // Place dans le flux g_pVB, // Pointeur sur le VertexBuffer 0, // Offset dans le tableau de sommets sizeof(CUSTOMVERTEX)); // Taille de la structure // Affiche la primitive g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 24, 0, 2); // Première face g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 24, 4, 2); // Deuxième face (démarre indice 4) g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 24, 8, 2); // 3ème face (démarre indice 8) g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 24, 12, 2); // 4ème face g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 24, 16, 2); // Dessous g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 24, 20, 2); // Dessus } //---------------------------------------------------- //--------------- Affichage du cube ---------------- //---------------------------------------------------- void DrawGrid(void) { g_pd3dDevice->SetFVF(D3DFVF_GRIDVERTEX); // Charge les VertexBuffer dans le flux de sommets g_pd3dDevice->SetStreamSource(0, // Place dans le flux g_pGridVB, // Pointeur sur le VertexBuffer 0, // Offset dans le tableau de sommets sizeof(GRIDVERTEX)); // Taille de la structure // Affiche la primitive g_pd3dDevice->DrawPrimitive(D3DPT_LINELIST, 0, 130); // Première face } //---------------------------------------------------- //-------------------- Rendu 3D -------------------- //---------------------------------------------------- void Render(void) { HRESULT hr; if(g_bDeviceLost == true) // Si le device est lost { Sleep(100); // Laisse 100 milliseconds pour autres processus // Teste du cooperative level, on analyse l'erreur pour déterminé que faire if(FAILED(hr = g_pd3dDevice->TestCooperativeLevel())) { // Le device est perdu, on ne pas encore rien faire que attendre if(hr == D3DERR_DEVICELOST) return; // Le device est perdu mais on peut lancer un reset if(hr == D3DERR_DEVICENOTRESET) { ReleaseObject(); // On stope tous les objets // On lance un reset, seule methode qui peut être utilise pendant un lost hr = g_pd3dDevice->Reset(&g_d3dpp); if(FAILED(hr)) return; Init(); // On réinitialise tout } return; } g_bDeviceLost = false; } g_pd3dDevice->Clear(0, // Nombre de rectangle dans le tableau (voir param suivant) NULL, // Pointeur sur tableau de D3DRECT D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, // Surface à effacer D3DCOLOR_COLORVALUE(0.0f,0.0f,1.0f,1.0f),// Efface la surface par une couleur (bleu) 1.0f, // Nouvelle valeur du depth buffer 0); // Nouvelle valeur du stencil buffer g_pd3dDevice->BeginScene(); // Démarrage du rendu //------------------------- if(g_bDrawFPS == true) drawFPS(); RECT rc_x; SetRect(&rc_x, 2, 30, 0, 0); RECT rc_y; SetRect(&rc_y, 2, 50, 0, 0); char str_x[80] = "souris x :"; char str_y[80] = "souris y :"; sprintf(str_x, "souris x : %.2lf\n", cur_fps); sprintf(str_y, "souris y : %.2lf\n", cur_fps); g_pFont_x->DrawText(NULL, str_x, -1, &rc_x, DT_NOCLIP, D3DCOLOR_XRGB(255, 255, 255)); g_pFont_y->DrawText(NULL, str_y, -1, &rc_y, DT_NOCLIP, D3DCOLOR_XRGB(255, 255, 255)); SetView(); DrawCube(); DrawGrid(); //------------------------- g_pd3dDevice->EndScene(); // Arrêt du rendu hr = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); // Donne au back buffer la scène à afficher (ici rien pour vider) // Present renvoie une erreur si le device est lost if(hr D3DERR_DEVICELOST) g_bDeviceLost true; }
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question