voici les sources :
[code] 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;
};[/code]
[code]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]
[code]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;
}
[/code]
Merci