libération de mémoire & organisation hiérarchique de classes

libération de mémoire & organisation hiérarchique de classes - C++ - Programmation

Marsh Posté le 24-09-2006 à 11:49:04    

Bonjour !
    J'ai actuellement un petit soucis avec un de mes programme : au moment où je veut libérer la mémoire utilisée j'ai mon programme qui ne répond plus... :( . J'ai trouvé une solution mais j'aimerais bien avoir une explication de pourquoi ça ne marchait pas.
Voilà mon code, j'espère que vous trouverez ça pas trop indigeste...

Code :
  1. bool MapManager::Memorise(std::string s)
  2. {
  3. if(MapModel.find(s) == MapModel.end())  //Regarde si le model est a deja ete charge
  4.  Load(s);
  5. if(MapModel[s].memorise)     //si il a ete charge a-t-il deja ete memorise
  6.  return true;
  7. MapModel[s].donnee_Array.reserve(MapModel[s].m_nbreMesh);  //on alloue la memoire necessaire dans le vector
  8. for(int i = 0 ; i < MapModel[s].m_nbreMesh ; i++)  //pour chacun des Mesh
  9. {
  10.  Mesh_a_afficher Array;
  11.  Array.VertexArray = new CVertex[MapModel[s].m_Meshes[i].m_numTriangles * 3]; //allocation de la memoire pour stocker les info a afficher
  12.  Array.TexArray = new CTexCoord[MapModel[s].m_Meshes[i].m_numTriangles * 3];
  13.  Array.NormalArray = new CNormal[MapModel[s].m_Meshes[i].m_numTriangles * 3];
  14.  for(int j = 0 ; j < MapModel[s].m_Meshes[i].m_numTriangles ; j++)  //pour tous les triangles
  15.  {
  16.   int triangleIndex = MapModel[s].m_Meshes[i].m_TrianglesIndices[j];
  17.   for(int k = 0 ; k < 3 ; k++)
  18.   {
  19.    int index = MapModel[s].m_Triangles[triangleIndex].m_VertexIndices[k];
  20.    try
  21.    {
  22.     Array.TexArray[3*j+k].u = MapModel[s].m_Triangles[triangleIndex].m_s[k]; //on remplit les tableaux qui vont etre donné
  23.     Array.TexArray[3*j+k].v = MapModel[s].m_Triangles[triangleIndex].m_t[k]; //à la carte graphique
  24.     Array.VertexArray[3*j+k].x = MapModel[s].m_vertices[index].m_position[0];
  25.     Array.VertexArray[3*j+k].y = MapModel[s].m_vertices[index].m_position[1];
  26.     Array.VertexArray[3*j+k].z = MapModel[s].m_vertices[index].m_position[2];
  27.     Array.NormalArray[3*j+k].x = MapModel[s].m_Triangles[triangleIndex].m_VertexNormal[k][0];
  28.     Array.NormalArray[3*j+k].y = MapModel[s].m_Triangles[triangleIndex].m_VertexNormal[k][1];
  29.     Array.NormalArray[3*j+k].z = MapModel[s].m_Triangles[triangleIndex].m_VertexNormal[k][2];
  30.    }
  31.    catch(std::out_of_range &e)
  32.    {
  33.     MessageBox(NULL,e.what(),"",MB_OK);
  34.    }
  35.   }
  36.  }
  37.  MapModel[s].donnee_Array.push_back(Array);  //on rajoute la mesh chargée dans le vector donne_array  
  38. }
  39. MapModel[s].memorise = true;      //Le model est alors chargé
  40. return true;
  41. }
  42. bool MapManager::Use(std::string s)
  43. {
  44. if(MapModel.find(s) == MapModel.end())    //le model a-t-il deja ete lu ?
  45.  Memorise(s);
  46. if(MapModel[s].donnee_Array.size() != MapModel[s].m_nbreMesh) //le model a-t-il deja ete mémorisé ?
  47.  Memorise(s);
  48. GLboolean texOn = glIsEnabled(GL_TEXTURE_2D);
  49. glEnable(GL_VERTEX_ARRAY);
  50. glEnable(GL_TEXTURE_COORD_ARRAY);
  51. glEnable(GL_NORMAL_ARRAY);
  52. for(int i = 0 ; i < MapModel[s].m_nbreMesh ; i++)    //on affiche chacune des mesh
  53. {
  54.  int materialIndex = MapModel[s].m_Meshes[i].m_MaterialIndex;
  55.  if(materialIndex >= 0)
  56.  {
  57.   glMaterialfv(GL_FRONT, GL_AMBIENT, MapModel[s].m_Materials[materialIndex].m_ambient);
  58.   glMaterialfv(GL_FRONT, GL_DIFFUSE, MapModel[s].m_Materials[materialIndex].m_diffuse);
  59.   glMaterialfv(GL_FRONT, GL_SPECULAR, MapModel[s].m_Materials[materialIndex].m_specular);
  60.   glMaterialfv(GL_FRONT, GL_EMISSION, MapModel[s].m_Materials[materialIndex].m_emissive);
  61.   glMaterialf(GL_FRONT, GL_SHININESS, MapModel[s].m_Materials[materialIndex].m_luminosite);
  62.   if(MapModel[s].m_Materials[materialIndex].m_NomTexture.length() > 0) //La mesh a-t-elle une texture ?
  63.   {
  64.    textureManager.Load(MapModel[s].m_Materials[materialIndex].m_NomTexture.data());
  65.    glEnable(GL_TEXTURE_2D);
  66.   }
  67.   else 
  68.    glDisable(GL_TEXTURE_2D);
  69.  }
  70.  else
  71.   glDisable(GL_TEXTURE_2D);
  72.  glVertexPointer(3, GL_FLOAT, 0, MapModel[s].donnee_Array[i].VertexArray); //on affiche la Mesh
  73.  glNormalPointer(GL_FLOAT, 0, MapModel[s].donnee_Array[i].NormalArray);
  74.  glTexCoordPointer(2, GL_FLOAT, 0, MapModel[s].donnee_Array[i].TexArray);
  75.  glDrawArrays(GL_TRIANGLES, 0, MapModel[s].m_Meshes[i].m_numTriangles * 3);
  76. }
  77. if(texOn)         //on reviens dans le mode d'affichage precedent
  78.  glEnable(GL_TEXTURE_2D);
  79. else
  80.  glDisable(GL_TEXTURE_2D);
  81. glDisable(GL_VERTEX_ARRAY);
  82. glDisable(GL_TEXTURE_COORD_ARRAY);
  83. glDisable(GL_NORMAL_ARRAY);
  84. return true;
  85. }
  86. void MapManager::Release(std::string s)
  87. {
  88. if(MapModel.find(s)!=MapModel.end()) //le model est-il existant ?
  89. {
  90.  std::vector<Mesh_a_afficher>::iterator it;
  91.  it = MapModel[s].donnee_Array.begin();
  92.  while(it != MapModel[s].donnee_Array.end())   //pour chacun des Mesh_a_afficher de donne_Array
  93.  {
  94.   delete[] (*it).NormalArray;     //on libère la mémoire
  95.   delete[] (*it).TexArray;
  96.   delete[] (*it).VertexArray;
  97.             it++;
  98.  }
  99.  MapModel[s].donnee_Array.clear();   //on supprime tous les Mesh_a_afficher
  100.  MapModel.erase(s);       //on supprime la Mesh désigné par s
  101. }
  102. }


 
Bon j'ai laissé la partie affichage, qui a l'air de bien marcher pour que vous puissiez voir pourquoi j'utilise pas un vector a la place de mes pointeurs sur les class CVertex, CTexCoord, CNormal
Bon pour l'info voilà a quoi ressemble ma class Mesh_a_afficher.  
 

Code :
  1. class Mesh_a_afficher
  2. {
  3. public:
  4. CVertex *VertexArray;
  5. CTexCoord *TexArray;
  6. CNormal *NormalArray;
  7. /*
  8. ~Mesh_a_afficher()
  9. {
  10.  delete[] VertexArray;
  11.  VertexArray = NULL;
  12.  delete[] TexArray;
  13.  TexArray = NULL;
  14.  delete[] NormalArray;
  15.  NormalArray = NULL;
  16. }*/
  17. };


Vous pouvez noter que j'avais voulu faire les désallocation dans le destructeur de Mesh_a_afficher... Normalement ça aurrait du marcher non ?
Avec mes mon utilisation d'itérateurs il n'y a pas de soucis, mais j'aurrais plutôt voulu mettre la désalocation dans le destructeur...
 
Voilà ! Merci a ceux qui se pencheront sur mon problème :)


Message édité par Amonchakai le 01-10-2006 à 19:15:49
Reply

Marsh Posté le 24-09-2006 à 11:49:04   

Reply

Marsh Posté le 24-09-2006 à 11:59:02    

Juste pour l'info, voilà ce que j'avais voulu faire :
 

Code :
  1. void MapManager::Release(std::string s)
  2. {
  3. if(MapModel.find(s)!=MapModel.end()) //le model est-il existant ?
  4. {
  5.  MapModel[s].donnee_Array.clear();   //on supprime tous les Mesh_a_afficher
  6.  MapModel.erase(s);       //on supprime la Mesh désigné par s
  7. }
  8. }


 
et j'avais les désalocations dans le destructeur...

Reply

Marsh Posté le 24-09-2006 à 15:53:30    

Citation :


Voilà mon code, j'espère que vous trouverez ça pas trop indigeste...  


Un poil quand même..

Citation :


les désalocations dans le destructeur...


c'est exactement ce qu'il faut faire.
 
Prends ton deboggeur, et suit le déroulement pas à pas pour trouver où se situe l'erreure.

Reply

Marsh Posté le 24-09-2006 à 17:55:55    

Ok, Merci Nargy !
 
J'ai réussit a trouver mon erreur :)  
Bon c'était une erreur de débutant :  
au moment du chargement je faisait ça :
 

Code :
  1. Mesh_a_afficher Array;
  2. Array.VertexArray = new CVertex[MapModel[s].m_Meshes[i].m_numTriangles * 3];
  3. Array.TexArray = new CTexCoord[MapModel[s].m_Meshes[i].m_numTriangles * 3];
  4. Array.NormalArray = new CNormal[MapModel[s].m_Meshes[i].m_numTriangles * 3];
  5. //plus remplissage...
  6. MapModel[s].donnee_Array.push_back(Array);  //et ensuite je le mettais dans le vector...


 
mais le truc c'est qu'avec mon destructeur qui me faisait automatiquement la désalocation de mémoire j'avais un problème a la sortie de la méthode Memorise() car il me libérait la mémoire que j'avais mis dans le vector... (en détruisant Array)
J'ai donc surchargé l'opérateur = pour gérer un compteur qui compte le nombre de copie et donc me permettre de désalouer la mémoire que quand toutes les copies sont sencé être détruites. Et ça MARCHE   :sol:  
 
 
Par contre j'aurrais une petite question au sujet du déboggeur :
Je n'arrive pas a le faire fonctionner : Je suis bien en mode Debug, je sélectionne les break point comme on peut le voir sur la capture :
http://img164.imageshack.us/img164/5179/question1kw2.th.jpg
mais quand je lance le déboggeur (F5) il me sort ça :
http://img78.imageshack.us/img78/2995/question2gk5.th.jpg
 
Quelqu'un aurrait une idée ?
Merci
 
ps : je tiens a dire que ma version de visual studio n'est pas une version piratée. Etant étudiant, Microsoft nous donne la possibilité de télécharger gratuitement quelques logiciels. Visual en faisant partie...

Reply

Marsh Posté le 24-09-2006 à 19:16:23    

utilise des vector<>, tu te simplifiera la vie !!!!
 

Reply

Marsh Posté le 24-09-2006 à 19:21:25    

et des counted_ptr :o

Reply

Marsh Posté le 24-09-2006 à 21:15:39    

bjone a écrit :

utilise des vector<>, tu te simplifiera la vie !!!!


Oui, je suis d'accord que c'est beaucoup plus simple. Mais on peut utiliser glVertexPointer() avec des vector ??? c'est par ce que je croyait que non,  que je suis passé par des pointeurs...
 

KangOl a écrit :

et des counted_ptr :o


Oui, c'est vrai que c'est une idée. Mais j'avais déjà eu un soucis avec les shared_array de boost pour une utilisation de ce type :
car j'arrivais pas a définir la taille de la mémoire allouée après avoir déclaré le pointeur...
Voilà un bout de code pour exprimer ce que je veut dire :

Code :
  1. boost::shared_array<int> tab(new int[32]); //donc ça, ça marche....  
  2. boost::shared_array<int> tab;  //déclaration dans la classe Mesh_a_afficher
  3. //traitement qui me permet de savoir la taille du tableau...
  4. tab = new int[32]; //ça c'est ce que j'aurrais aimé, mais ça marche pas... (normal puisque déjà shared_array est une classe...


Si vous savez comment on fait, ça m'intéresse.
 
Bon j'avoue que j'ai pas encore regardé counted_ptr mais ça ne saurrait tarder  ;)  
 
En tout cas merci de m'avoir proposé des trucs


Message édité par Amonchakai le 24-09-2006 à 21:17:26
Reply

Marsh Posté le 24-09-2006 à 21:20:31    

Citation :

Oui, je suis d'accord que c'est beaucoup plus simple. Mais on peut utiliser glVertexPointer() avec des vector ??? c'est par ce que je croyait que non,  que je suis passé par des pointeurs...


 
dans un vector<> tout est contigu, donc oui tu peux l'utiliser avec des fonctions nécessitant un pointeur.
 
tu peux par exemple:
vector<Vecteur3D> Position, Normale;
 
Position.push_back(...);
ou
Position.resize(num_vertexs);
Position[i].x=...
 
et faire un:
glMachin( &Position[0] ........

Reply

Marsh Posté le 24-09-2006 à 21:29:11    

Dans ce cas là on est d'accord. Mais le truc c'est que je voulais envoyer tout le tebleau d'un coup au lieu de l'envoyer vertex par vertex.
c'est pour ça que j'avais fait un glEnable(GL_VERTEX_ARRAY); et que j'envoyais tout le tableau d'un coup via glVertexPointer().

Reply

Marsh Posté le 24-09-2006 à 21:37:12    

oui
 
glVertexPointer(3, GL_FLOAT, 0, &Position[0] );    


Message édité par bjone le 24-09-2006 à 21:40:28
Reply

Marsh Posté le 24-09-2006 à 21:37:12   

Reply

Marsh Posté le 24-09-2006 à 21:40:59    

ha d'accord, autant pour moi... Bon bha reste plus qu'a corriger ce que j'ai fait. Merci :)

Reply

Marsh Posté le 24-09-2006 à 21:45:11    

d'ailleurs tu ferais mieux d'entrelacer position, normale et uv texture c'est plus amical avec le cache du GPU et régulier pour le fetch des données (quelles soient faites depuis la ram vidéo ou a travers l'agp ou le PCI/PCI-E)

Reply

Marsh Posté le 24-09-2006 à 21:55:41    

D'ailleurs tu devrais découpler le modèle du gestionnaire de modèles,
genre faire une classe Model, et une classe ModelCollection ou ModelManager.
 
Et une classe genre ModelInstance ou Entity qui fait référence à la classe Model par pointeur intelligent après l'avoir obtenue de la collection de modèles par string.
 
Comme ça, dans cette classe, tu stoques les etats style matrice de positionnement dans le monde, etc, etc...
 
Utiliser des "const std::string &s" comme paramètre a tes fonctions là aussi...

Reply

Marsh Posté le 25-09-2006 à 21:10:54    

Ok, bon pour ce qui est des "const std::string" je vais corriger.
 
Par contre quand tu dit : "d'ailleurs tu ferais mieux d'entrelacer position, normale et uv texture" tu me recommande d'utiliser un vertex Buffer et lors de ma déclaration de vertices de tout déclarer dans une même classe c'est ça ?
 
sinon j'ai un peu de mal a comprendre la shiérarchie que tu me recommande pour mes classe... Tu me recommanderai de faire un truc de ce genre la ?

Code :
  1. class Model : public ModelLoader
  2. {
  3.    std::vector<Mesh_a_afficher> donne;
  4.    Matrix3x3 rotation;
  5.    Matrix3x1 translation;
  6. public:
  7.    void Load();
  8.    void Affiche();
  9. };
  10. class ModelManager
  11. {
  12.    std::map<std::string, Model, std::less<std::string>> MapModel;
  13. public:
  14.    void AddNewModel(const std::string name);
  15.    void ReleaseModel(const std::string name);
  16.    Model &RetourneModel(const std::string name);
  17. };


Mais par contre je vois pas pourquoi tu veut que je passe par une classe ModelInstance qui utilise des smart Pointer.
 
En tout cas merci de m'aider a améliorer mon code :)

Reply

Marsh Posté le 25-09-2006 à 23:50:52    

Citation :

Par contre quand tu dit : "d'ailleurs tu ferais mieux d'entrelacer position, normale et uv texture" tu me recommande d'utiliser un vertex Buffer et lors de ma déclaration de vertices de tout déclarer dans une même classe c'est ça ?


 
Exactement.
 
un bête:
 
struct Vertex
{
    float x,y,z,
           nx,ny,nz,
           u,v;
};
 
Pour la structuration je verrais plus:

Code :
  1. class Model : boost::noncopyable
  2. {
  3. public:
  4.     vector<Vertex> VB_SystemMemory;
  5.     vector<qqchose pour les matériaux> Materials;
  6.     vector<qqchose pour packer les commandes> DrawBatches;
  7.     ....
  8.     ....
  9.     void Render();
  10. };
  11. class ModelCollection : public map< smart_ptr<Model>, string > // ou hashmap, un smart_ptr pour éviter de  
  12.                                                                                      // copier/détruire a gogo les modèles qui sont des objets lourds
  13.                                                                                      // avec peut-être des ressources OpenGl
  14. {
  15. public:
  16.     smart_ptr<Model> Get( const string &name );
  17.     ....
  18. };
  19. class ModelInstance
  20. {
  21. public:
  22.     smart_ptr<Model> Mdl;
  23.     Matrix4x4 World;
  24.     ....
  25.     ....
  26.     void Render(); // voir pourquoi pas virtual
  27. };
  28. class DynamicActor : public ModelInstance
  29. {
  30. public:
  31.     Vector3 speed, acceleration, angular_speed, angular_accelleration;
  32.     ....
  33. };
  34. class StaticActor : public ModelInstance
  35. {
  36. public:
  37.     bool destroyable;
  38.     .....
  39. };


 
faire le lookup par string en permance même au traçage ça pue: le lookup par string doit se faire qu'a la création de l'objet, au chargement de la scène (niveau/carte) ou lors d'un évenement de script.
 
il faut placer intelligemment des pointeurs intelligent: la classe qui maintiens la géométrie et autres infos d'un objet 3D est un objet lourd, qu'il vaux mieux considérer comme non-copiable. Une fois que tu aurais fait progressé l'implémentation OpenGl (genre a base VBO), il est hors de question de passer ça vie à copier et supprimmer des ressources OpenGl (ou Direct3D).
 
perso j'utilises boost::instrusive_ptr, et quand le décompte d'utilisation a arrive à 0 je flag le modèle comme étant purgeable (ou le mets dans un pool de modèles inutilisés), et je purges dans des situations déterministes (changement de niveau par exemple).  
Imagine le framerate si tu passes ta vie a charger/détruire un modèle 3D au fur et à mesure des évenements de ton monde 3D.
 
DynamicActor pouvant être une entitée pouvant être simulée mécaniquement (une trotinette), et StaticActor pouvant un truc statique genre un arbre...

Reply

Marsh Posté le 26-09-2006 à 20:53:31    

Ok, d'accord !
Bon je vais avoir du boulôt...  
 
Merci  :)

Reply

Marsh Posté le 01-10-2006 à 19:51:16    

Bonjour !  
   Bon, me voila de retour... Avec de nouveau une petite question d'organisation de mes classes. Je cherche maintenant a rendre mon code moins dépendant de l'API 3D utilisé. Je veut dire par la que je cherche a spécifier si j'utilise openGL ou DirectX qu'au dernier moment. Aussi j'ai créé ma class Render qui va dériver en OGLRender et DXRender.
voilà a quoi cela ressemble :
 
Render.h  

Code :
  1. class Render
  2. {
  3. protected:
  4. HDC hDC;
  5. HGLRC hRC;
  6. HWND hwnd;
  7. HINSTANCE hInstance;
  8. WNDCLASS wc;
  9. int xSize, ySize;   //info quant a l'affichage de la fenêtre...
  10. int nCmdShow;
  11. float clipping, distance, angleDeVue;
  12. std::vector<Lights> lumieres;
  13. bool fenetreEnCours;
  14. virtual void ResizeScene(int width, int height) = 0; //partie redimentionnement de la fenêtre
  15. virtual bool Initialise(HWND hwnd) = 0;     //lancement de l'API 3D...
  16. virtual void BeginScene() = 0; //partie affichage des objs
  17. virtual void EndScene() = 0;
  18. virtual void ConfigureEclairage(Lights &lampe) = 0;
  19. static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  20. bool CreeFenetre();     //partie création de la fenêtre
  21. void eclairage();
  22. void KillWindow();       //libération a la fin...
  23. public:
  24. Render(Screen &ecran, HINSTANCE hInst);
  25. virtual void LoadExtension(std::string s) = 0;  //partie chargement de pluggins
  26. virtual bool Init3D() = 0;   //initialisation des options de la fenêtre 3D
  27. virtual void Paint() = 0;   //méthode d'affichage...
  28. virtual void PaintMesh(boost::shared_ptr<Model> prt) = 0;
  29. void Run();
  30. };


 
OGLRender.h

Code :
  1. class OGLRender : public Render
  2. {
  3. protected:
  4. virtual void ResizeScene(int width, int height);
  5. virtual bool Initialise(HWND hwnd);
  6. virtual void BeginScene();
  7. virtual void EndScene();
  8. virtual void ConfigureEclairage(Lights &lampe);
  9. public:
  10. OGLRender(Screen &ecran, HINSTANCE hInst) : Render(ecran, hInst){};
  11. virtual void LoadExtension(std::string s);
  12. virtual void PaintMesh(boost::shared_ptr<Model> prt);
  13. virtual bool Init3D();
  14. virtual void Paint();
  15. };


 
Bon l'implémentation DirectX n'est pas encore faite...
 
Ma question c'est tout d'abord : Est-ce que vous trouvez que c'est bien comme ça que je dois m'y prendre ?
 
Et mon problème c'est d'aussi le lier avec ce que bjone m'avait donné. Ce que je pense faire ce serait un truc du type :

Code :
  1. template<class RenderChoisit>
  2. class MoteurGraphique : public RenderChoisit
  3. {
  4.     ModelLoader modeLoader;
  5.     ModelCollection collection;
  6.     std::vector<DynamicActor> objsDynamique;
  7.     std::vector<StaticActor> objsStatique;
  8. /* Le modelLoader me permettant de charger les éléments et les mettre dans la collection.
  9. Et ceux contenus dans les vectors étant ceux a afficher...*/
  10.     .....         //et là je m'occuperait de l'affichage de tous mes objs sans me soucier de l'API...
  11.    
  12. };


 
Voilà. Est-ce que celà vous parait correct ? (donc en gros je peut continuer dans cette voie ou trouvez vous que non...)
 
Merci :)


Message édité par Amonchakai le 01-10-2006 à 20:37:06
Reply

Marsh Posté le 01-10-2006 à 21:00:46    

remarque général de développement: évite le franglais.
 
dans un contexte de projet "sérieux", il vaux mieux tout mettre en anglais au niveau code, et mettre les commentaires en anglais ou dans ta langue maternelle si tu n'arrives pas exprimer ton commentaire en anglais.
 
de plus, il vaut mieux stoquer les instances type Actor via des pointeurs intelligents, afin de pas faire exploser le coût de modification des vector<>, et de pouvoir utiliser des référencements par pointeur intelligent dans d'autres traitrements/structures.


Message édité par bjone le 01-10-2006 à 21:01:05
Reply

Marsh Posté le 01-10-2006 à 21:06:55    

dans Render(), il manque un destructeur virtuel, et j'aurai envie de dire que les:
 
float clipping, distance, angleDeVue;
std::vector<Lights> lumieres;
 
seraient a mettre dans une class style RenderContext que tu passes au traçage ou un truc du genre, enfin après c'est toi qui choisit.
 
mais le "thème" des ressources Windows n'est pas le même que celui des états de rendu, et donc ça m'inciterait a faire des classes séparées.
 
ensuite ce que je t'ai donné n'est pas une bible a prendre à la lettre non plus.
 
(perso dans un premier temps je me focaliserait plus uniquement sur l'OpenGl ou le D3D, mais pas les deux à la fois - après faut voir)
 

Reply

Marsh Posté le 02-10-2006 à 20:01:07    

Ok, pour le franglais je vais faire des effort... Allez soyons fou, je vais passer en anglais :)
Sinon pour l'histoire des vectors, j'avais l'intention de passer par des pointeurs intelligent que j'aurrais stocké dans des vector pour simplifier l'utilisation... Comme ça il n'y a pas de problème non ?
Le destructeur de Render()... oops grosse erreur, je l'avais oublié.
 
Sinon tu as sûrement raison je vais me focaliser dans un premier temp sur openGL et je verrais DirectX ensuite. Bien que je pense que je vais continuer à organiser mes classes de manière à ne pas trop avoir de soucis pour ma futur implémentation de DirectX.
 
En tout cas Merci de m'avoir répondu !

Reply

Sujets relatifs:

Leave a Replay

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