DirectX: déplacer la caméra en fonction de la souris

DirectX: déplacer la caméra en fonction de la souris - C++ - Programmation

Marsh Posté le 21-02-2006 à 14:03:26    

Bonjour à tous,
 
voilà quelques temps que je tente désespérement de tourner autour d'un objet en fonction des mouvements de la souris.
 
J'ai trouvé dans les exemples du SDK des projets qui utilisaient une classe CD3DArcBall. J'ai recopié du code depuis ces exemples, mes objets s'affichent, mais je n'arrive pas à tourner autour des objets.
 
Ca fait 2 jours que je cherche dans tous les sens, sans succès, alors je vous mets le code, parce que là je galère trop...
 
Fichier CPP

Code :
  1. #define STRICT
  2. #include <vcl.h>
  3. #include <Mmsystem.h>
  4. #pragma hdrstop
  5. #pragma package(smart_init)
  6. #include "CMyD3DApplication.h"
  7. //-----------------------------------------------------------------------------
  8. // Name: CMyD3DApplication()
  9. // Desc: Constructeur de la class. On peut y définir divers paramètres
  10. //   concernant la fenêtre.
  11. //-----------------------------------------------------------------------------
  12. CMyD3DApplication::CMyD3DApplication()
  13. : g_pyramid_count(6),g_cube_count(12)
  14. {
  15. // Définit le titre qui apparaîtra dans la barre des titres de la fenêtre
  16. m_strWindowTitle = _T("D3D Initialisation" );
  17. m_bUseDepthBuffer = TRUE;
  18.         m_pVB = NULL;
  19. }
  20. //-----------------------------------------------------------------------------
  21. // Name: OneTimeSceneInit()
  22. // Desc: Cette procédure est appelée avant la création de la fenêtre. Cette
  23. //   fonction n'est exécutée qu'une seule fois pour les initialisation de
  24. //   type permanent.
  25. //-----------------------------------------------------------------------------
  26. HRESULT CMyD3DApplication::OneTimeSceneInit()
  27. {
  28. m_pFont = new CD3DFont(_T("Arial" ), 12, D3DFONT_BOLD);
  29. return D3D_OK;
  30. }
  31. //-----------------------------------------------------------------------------
  32. // Name: FrameMove()
  33. // Desc: Cette fonction est appelée avant chaque rendu, pour l'animation des
  34. //   objets, de la scène et d'éventuels calculs.
  35. //-----------------------------------------------------------------------------
  36. HRESULT CMyD3DApplication::FrameMove()
  37. {
  38. // Setup world matrix
  39. D3DXMATRIXA16 matWorld;
  40. D3DXMatrixTranslation( &matWorld, -m_vObjectCenter.x,
  41.                               -m_vObjectCenter.y,
  42.                               -m_vObjectCenter.z );
  43. D3DXMatrixMultiply( &matWorld, &matWorld, m_ArcBall.GetRotationMatrix() );
  44. D3DXMatrixMultiply( &matWorld, &matWorld, m_ArcBall.GetTranslationMatrix() );
  45. m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  46. // Set up view matrix
  47. D3DXVECTOR3 vFrom( 0, 0,-5*m_fObjectRadius );
  48. D3DXVECTOR3 vAt( 0, 0, 0 );
  49. D3DXVECTOR3 vUp( 0, 1, 0 );
  50. D3DXMATRIXA16 matView;
  51. D3DXMatrixLookAtLH( &matView, &vFrom, &vAt, &vUp );
  52. m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  53. return S_OK;
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Name: Render()
  57. // Desc : Appelé une fois par frame, cette fonction sert au rendu de la scène,
  58. //    effacement de la scène...
  59. //-----------------------------------------------------------------------------
  60. HRESULT CMyD3DApplication::Render()
  61. {
  62. // Clear the viewport.
  63. m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0L );
  64. // Begin the scene.
  65. if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
  66. {
  67.         m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CUSTOMVERTEX) );
  68.         m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
  69.         D3DXMATRIXA16 matLocal, matWorldSaved;
  70.         m_pd3dDevice->GetTransform( D3DTS_WORLD, &matWorldSaved );
  71.         // Restore the modified render states
  72.         DrawPyramid();
  73.         DrawCube();
  74.         m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorldSaved );
  75.         // Output statistics
  76.         m_pd3dDevice->EndScene();
  77. }
  78. return S_OK;
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Name: InitDeviceObjects()
  82. // Desc: Cette fonction est appelée juste après la création du Device. On peut
  83. //   y configurer tous les paramètres de la scène : lumières, textures,
  84. //   matériaux, options de rendu, qualité du rendu...
  85. //-----------------------------------------------------------------------------
  86. HRESULT CMyD3DApplication::InitDeviceObjects()
  87. {
  88. m_pFont->InitDeviceObjects(m_pd3dDevice);
  89. m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
  90. // Set miscellaneous render states
  91. void *vb_vertices;
  92. HRESULT hr;
  93. hr = m_pd3dDevice->CreateVertexBuffer(sizeof(data),      //Length
  94.                                       D3DUSAGE_WRITEONLY,//Usage
  95.                                       D3DFVF_CUSTOMVERTEX,           //FVF
  96.                                       D3DPOOL_MANAGED,   //Pool
  97.                                       &m_pVB,        //ppVertexBuffer
  98.                                       NULL);             //Handle
  99. if(FAILED(hr))
  100. {
  101.         MessageBox(m_hWnd,"Error Creating vertex buffer",NULL,NULL);
  102.         return hr;
  103. }
  104. hr = m_pVB->Lock(0, //Offset
  105.                  0, //SizeToLock
  106.                  &vb_vertices, //Vertices
  107.                  0);  //Flags
  108. if(FAILED(hr))
  109. {
  110.         MessageBox(m_hWnd,"Error Locking vertex buffer",NULL,NULL);
  111.         return hr;
  112. }
  113. memcpy( vb_vertices, data,sizeof(data));
  114.     hr = D3DXComputeBoundingSphere((D3DXVECTOR3*)vb_vertices,
  115.                                    18,
  116.                                    D3DXGetFVFVertexSize(D3DFVF_CUSTOMVERTEX),
  117.                                    &m_vObjectCenter,
  118.                                    &m_fObjectRadius);
  119. m_pVB->Unlock();
  120. m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   TRUE );
  121. m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );
  122. m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,        TRUE );
  123. return S_OK;
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Name: RestoreDeviceObjects()
  127. // Desc: Méthode appelée pour la restauration des objets, des surfaces... après
  128. //   la création d'un périphérique ou un redimentionnement
  129. //-----------------------------------------------------------------------------
  130. HRESULT CMyD3DApplication::RestoreDeviceObjects()
  131. {
  132. // Setup the arcball parameters
  133. m_ArcBall.SetWindow( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 0.85f );
  134. m_ArcBall.SetRadius( m_fObjectRadius );
  135. // Setup the projection matrix
  136. D3DXMATRIXA16 matProj;
  137. FLOAT      fAspect = (FLOAT)m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
  138. D3DXMatrixPerspectiveFovLH(&matProj,
  139.                            D3DX_PI/4,
  140.                            fAspect,
  141.                            m_fObjectRadius/64.0f,
  142.                            m_fObjectRadius*200.0f );
  143.                          
  144. m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  145. return D3D_OK;
  146. }
  147. //-----------------------------------------------------------------------------
  148. // Name: InvalidateDeviceObjects()
  149. // Desc: Appelée quand les objets dépendants de dispositif sont sur le point
  150. //   d'être perdus.
  151. //-----------------------------------------------------------------------------
  152. HRESULT CMyD3DApplication::InvalidateDeviceObjects()
  153. {
  154. m_pFont->InvalidateDeviceObjects();
  155. SAFE_RELEASE( m_pVB );
  156. return S_OK;
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Name: DeleteDeviceObjects()
  160. // Desc: Appelée quand l'application se termine, ou que le périphérique est
  161. //   changé. Cette fonction supprime n'importe quels objets dépendants du
  162. //   périphérique.
  163. //-----------------------------------------------------------------------------
  164. HRESULT CMyD3DApplication::DeleteDeviceObjects()
  165. {
  166. m_pFont->DeleteDeviceObjects();
  167. return S_OK;
  168. }
  169. //-----------------------------------------------------------------------------
  170. // Name: FinalCleanup()
  171. // Desc: Appelée avant que l'application se termine, cette fonction donne la
  172. //   possibilité de nettoyer la mémoire de ses variables d'elle-même.
  173. //-----------------------------------------------------------------------------
  174. HRESULT CMyD3DApplication::FinalCleanup()
  175. {
  176. SAFE_DELETE(m_pFont);
  177. return S_OK;
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Name: ConfirmDevice()
  181. // Desc: Appelée pendant l'initialisation, ce code vérifie si les périphériques
  182. //   ont les capacités minimales requises.
  183. //-----------------------------------------------------------------------------
  184. HRESULT CMyD3DApplication::ConfirmDevice(D3DCAPS9* pCaps, DWORD dwBehavior, D3DFORMAT Format)
  185. {
  186. if( !(dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING) && !(pCaps->VertexShaderVersion >= D3DVS_VERSION(1, 0)) )
  187.         return E_FAIL;
  188. return S_OK;
  189. }
  190. //---------------------------------------------------------------------------
  191. //! Trace la pyramide
  192. void CMyD3DApplication::DrawPyramid()
  193. {
  194. D3DXMATRIX world_matrix;
  195. D3DXMATRIX rot_matrix;
  196. D3DXMATRIX trans_matrix;
  197. static float rot_triangle=0.0f;
  198. D3DXMatrixRotationY(&rot_matrix,rot_triangle);  //Rotate the pyramid
  199. D3DXMatrixTranslation(&trans_matrix,-2.0f,0,0); //Shift it 2 units to the left
  200. D3DXMatrixMultiply(&world_matrix,&rot_matrix,&trans_matrix);
  201. m_pd3dDevice->SetTransform(D3DTS_WORLD,&world_matrix);
  202. //Render from our Vertex Buffer
  203. m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, //PrimitiveType
  204.                             0,                  //StartVertex
  205.                             g_pyramid_count);   //PrimitiveCount
  206. rot_triangle+=0.003f;
  207. if(rot_triangle > D3DX_PI*2)
  208.         rot_triangle-=D3DX_PI*2;
  209. }
  210. //---------------------------------------------------------------------------
  211. //! Trace le cube
  212. void CMyD3DApplication::DrawCube()
  213. {
  214. D3DXMATRIX world_matrix;
  215. D3DXMATRIX rot_matrix;
  216. D3DXMATRIX trans_matrix;
  217. static float rot_cube=0.0f;
  218. int start_vertex;
  219. //Offset past the pyramid, offset is given as the number of vertices to be skipped
  220. start_vertex=g_pyramid_count * 3;
  221. D3DXMatrixRotationYawPitchRoll(&rot_matrix,0,rot_cube,rot_cube);  //Rotate the cube
  222. D3DXMatrixTranslation(&trans_matrix,2.0f,0,0); //Shift it 2 units to the right
  223. D3DXMatrixMultiply(&world_matrix,&rot_matrix,&trans_matrix);   //Rot & Trans
  224. m_pd3dDevice->SetTransform(D3DTS_WORLD,&world_matrix);
  225. //Render from our Vertex Buffer
  226. m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, //PrimitiveType
  227.                             start_vertex,       //StartVertex
  228.                             g_cube_count);      //PrimitiveCount
  229. rot_cube+=0.002f;
  230. if(rot_cube > D3DX_PI*2)
  231.         rot_cube-=D3DX_PI*2;
  232. }
  233. //---------------------------------------------------------------------------
  234. LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
  235.                                     LPARAM lParam )
  236. {
  237.     // Pass mouse messages to the ArcBall so it can build internal matrices
  238.     m_ArcBall.HandleMouseMessages( hWnd, uMsg, wParam, lParam );
  239. // Pass remaining messages to default handler
  240. return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
  241. }


 
Fichier H

Code :
  1. #ifndef CMyD3DApplicationH
  2. #define CMyD3DApplicationH
  3. #define sqrtf (float)sqrt
  4. #include <D3DX9.h>
  5. #include <DXUtil.h>
  6. #include <D3DEnumeration.h>
  7. #include <D3DSettings.h>
  8. #include <D3DApp.h>
  9. #include <D3DFile.h>
  10. #include <D3DFont.h>
  11. #include <D3DUtil.h>
  12. struct CUSTOMVERTEX
  13. {
  14.     float x, y, z; // The transformed position for the vertex.
  15.     DWORD color;        // The vertex color.
  16. };
  17. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
  18. CUSTOMVERTEX data[] =
  19. {
  20.    //Pyramid vertices
  21.    {-1.0f,-1.0f,-1.0f,0x0000FF00},{ 0.0f, 1.0f, 0.0f,0x0000FF00},{ 1.0f,-1.0f,-1.0f,0x0000FF00},
  22.    { 1.0f,-1.0f,-1.0f,0x000000FF},{ 0.0f, 1.0f, 0.0f,0x000000FF},{ 1.0f,-1.0f, 1.0f,0x000000FF},
  23.    { 1.0f,-1.0f, 1.0f,0x00FF0000},{ 0.0f, 1.0f, 0.0f,0x00FF0000},{-1.0f,-1.0f, 1.0f,0x00FF0000},
  24.    {-1.0f,-1.0f, 1.0f,0x00FFFF00},{ 0.0f, 1.0f, 0.0f,0x00FFFF00},{-1.0f,-1.0f,-1.0f,0x00FFFF00},
  25.    { 1.0f,-1.0f,-1.0f,0xFFFFFFFF},{ 1.0f,-1.0f, 1.0f,0xFFFFFFFF},{-1.0f,-1.0f, 1.0f,0xFFFFFFFF},
  26.    {-1.0f,-1.0f, 1.0f,0xFFFFFFFF},{-1.0f,-1.0f,-1.0f,0xFFFFFFFF},{ 1.0f,-1.0f,-1.0f,0xFFFFFFFF},
  27.    //Cube vertices
  28.       //Front face
  29.    {-1.0f,-1.0f,-1.0f,0xFF0000FF},{-1.0f, 1.0f,-1.0f,0xFF0000FF},{ 1.0f, 1.0f,-1.0f,0xFF0000FF},
  30.    { 1.0f, 1.0f,-1.0f,0xFF0000FF},{ 1.0f,-1.0f,-1.0f,0xFF0000FF},{-1.0f,-1.0f,-1.0f,0xFF0000FF},
  31.       //Back face
  32.    { 1.0f,-1.0f, 1.0f,0xFF0000FF},{ 1.0f, 1.0f, 1.0f,0xFF0000FF},{-1.0f, 1.0f, 1.0f,0xFF0000FF},
  33.    {-1.0f, 1.0f, 1.0f,0xFF0000FF},{-1.0f,-1.0f, 1.0f,0xFF0000FF},{ 1.0f,-1.0f, 1.0f,0xFF0000FF},
  34.       //Top face
  35.    {-1.0f, 1.0f,-1.0f,0xFFFF0000},{-1.0f, 1.0f, 1.0f,0xFFFF0000},{ 1.0f, 1.0f, 1.0f,0xFFFF0000},
  36.    { 1.0f, 1.0f, 1.0f,0xFFFF0000},{ 1.0f, 1.0f,-1.0f,0xFFFF0000},{-1.0f, 1.0f,-1.0f,0xFFFF0000},
  37.       //Bottom face
  38.    { 1.0f,-1.0f,-1.0f,0xFFFF0000},{ 1.0f,-1.0f, 1.0f,0xFFFF0000},{-1.0f,-1.0f, 1.0f,0xFFFF0000},
  39.    {-1.0f,-1.0f, 1.0f,0xFFFF0000},{-1.0f,-1.0f,-1.0f,0xFFFF0000},{ 1.0f,-1.0f,-1.0f,0xFFFF0000},
  40.       //Left face
  41.    {-1.0f,-1.0f, 1.0f,0xFF00FF00},{-1.0f, 1.0f, 1.0f,0xFF00FF00},{-1.0f, 1.0f,-1.0f,0xFF00FF00},
  42.    {-1.0f, 1.0f,-1.0f,0xFF00FF00},{-1.0f,-1.0f,-1.0f,0xFF00FF00},{-1.0f,-1.0f, 1.0f,0xFF00FF00},
  43.       //Right face
  44.    { 1.0f,-1.0f,-1.0f,0xFF00FF00},{ 1.0f, 1.0f,-1.0f,0xFF00FF00},{ 1.0f, 1.0f, 1.0f,0xFF00FF00},
  45.    { 1.0f, 1.0f, 1.0f,0xFF00FF00},{ 1.0f,-1.0f, 1.0f,0xFF00FF00},{ 1.0f,-1.0f,-1.0f,0xFF00FF00},
  46. };
  47. //-----------------------------------------------------------------------------
  48. // Name: class CMyD3DApplication
  49. // Desc: Application class. The base class (CD3DApplication) provides the  
  50. //       generic functionality needed in all Direct3D samples. CMyD3DApplication  
  51. //       adds functionality specific to this sample program.
  52. //-----------------------------------------------------------------------------
  53. class CMyD3DApplication : public CD3DApplication
  54. {
  55.         int g_list_count;
  56.         int g_pyramid_count;
  57.         int g_cube_count;
  58.        
  59.         LPDIRECT3DVERTEXBUFFER9 m_pVB;
  60.         CD3DArcBall         m_ArcBall;          // mouse rotation utility
  61.         D3DXVECTOR3         m_vObjectCenter;    // Center of bounding sphere of object
  62.         FLOAT               m_fObjectRadius;    // Radius of bounding sphere of object
  63. CD3DFont* m_pFont;
  64.         bool m_bUseDepthBuffer;
  65.        
  66. HRESULT ConfirmDevice(D3DCAPS9*, DWORD, D3DFORMAT);
  67.         void DrawPyramid();
  68.         void DrawCube();       
  69. protected:
  70. HRESULT OneTimeSceneInit();
  71. HRESULT InitDeviceObjects();
  72. HRESULT RestoreDeviceObjects();
  73. HRESULT InvalidateDeviceObjects();
  74. HRESULT DeleteDeviceObjects();
  75. HRESULT FinalCleanup();
  76. HRESULT Render();
  77. HRESULT FrameMove();
  78. public:
  79. CMyD3DApplication();
  80.         LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  81. };
  82. #endif


 
Merci d'avance :)

Reply

Marsh Posté le 21-02-2006 à 14:03:26   

Reply

Marsh Posté le 21-02-2006 à 14:17:42    

Personellement je crée deux classes :

  • Une premiere utilisant un device DirectInput pour acquérir les données du clavier
  • Une seconde utilisant aussi un device DirectInput mais pour acquérir les données de la souris


Chaque classe à une fonction ProcessInput(). Cette fonction est appelée a chaque frame rendue.
 
Le principe est simple :
 
A chaque appel du ProcessInput(), la classe de gestion de la souris récupère les nouvelles positions X, Y, boutons etc. (via CurrentMouseState), et bouge la caméra en fonction (avec des fonctions Sin, Cos,Tan...Mais y a surement moyen en agissant directement que la matrice View du Device Direct3D)
 
En esperant que ça t'aide...

Reply

Marsh Posté le 21-02-2006 à 14:34:15    

Euh... Pas vraiment ;)
 
Je n'ai pas besoin du clavier en fait. Je veux juste afficher une série de points, et tourner autour à l'aide de la caméra...

Reply

Marsh Posté le 21-02-2006 à 15:24:21    

Bah le systeme reste le meme :
 
Utiliser DirectInput pour obtenir les mouvements de la souris (variations en position X, Y)
Interpreter ces mouvements pour modifier la vue (soit avec des cosinus, sinus etc, soit en changeant la matrice View du DeviceD3D)

Reply

Marsh Posté le 21-02-2006 à 16:20:23    

Je me doute bien, mais j'avoue ne pas avoir pipé grand chose aux matrices.  
 
Du coup j'ai modifié les exemples du SDK pour utiliser la classe CD3DArcBall qui fait tout le boulot...
 
Bon sinon le souci vient des fonctions DrawPyramid et DrawCube. Je pense que c'est parce que je dois utiliser des matrices propres à chacun de ces objets au lieu d'utiliser la matrice World globale. Je testerai ça ce soir.
 
Pour le moment, je me contente juste de dessiner la pyramide, sans la faire tourner sur elle même, et j'arrive à faire tourner la caméra autour avec la souris, donc c'est un bon point déjà ;)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed