chargement de textures en openGL

chargement de textures en openGL - C++ - Programmation

Marsh Posté le 14-06-2006 à 14:08:03    

Bonjour, je poste car j'ai un problème avec la classe que j'ai crée pour le chargement de textures en openGL.
donc voilà déja le code :
 
textureManager.h

Code :
  1. #include "main.h"
  2. #include<IL\il.h>
  3. #include<IL\ilu.h>
  4. #include<IL\ilut.h>
  5. #define NBR_MAX_TEXTURES 10
  6. class TextureManager{
  7. GLuint Texture[NBR_MAX_TEXTURES];
  8. char *nomTextures[NBR_MAX_TEXTURES];
  9. short nbrInstanceTexture[NBR_MAX_TEXTURES];
  10. public:
  11. bool Init();
  12. int isTextureCharge(char *texture);
  13. void bindTexture(char *texture);
  14. void LoadTexture(char *texture);
  15. void Relase(int i);
  16. int PlaceMemoireLibre();
  17. int nbrTextureCharge();
  18. };


 
textureManager.cpp
 

Code :
  1. #include "textureManager.h"
  2. bool TextureManager::Init()
  3. {
  4. if(ilGetInteger(IL_VERSION_NUM) < IL_VERSION ||
  5.  ilGetInteger(ILU_VERSION_NUM) < ILU_VERSION ||
  6.  ilGetInteger(ILUT_VERSION_NUM) < ILUT_VERSION)
  7. {
  8.  MessageBox(NULL, "Erreur la version de DevIL installée est trop ancienne...", "Erreur :: DevIL",MB_OK);
  9.  return false;
  10. }
  11. ilInit();
  12. iluInit();
  13. glGenTextures(NBR_MAX_TEXTURES, Texture);
  14. for(int i = 0 ; i < NBR_MAX_TEXTURES ; i++)
  15.  nbrInstanceTexture[i] = 0;
  16. return true;
  17. }
  18. void TextureManager::LoadTexture(char *texture)
  19. {
  20. if(isTextureCharge(texture)==-1)
  21. {
  22.  int id = PlaceMemoireLibre();
  23.  if(id != -1)
  24.  {
  25.   if(!ilLoadImage(texture))
  26.    MessageBox(NULL, "image impossible a charger car non trouvée...", "Erreur dans DevIL", MB_OK);
  27.   nomTextures[id] = texture;
  28.   nbrInstanceTexture[id]++;
  29.    glBindTexture(GL_TEXTURE_2D, Texture[id]);
  30.             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  31.             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  32.             glTexImage2D(GL_TEXTURE_2D, 0, 3,
  33.                 ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
  34.                 0, GL_RGB, GL_UNSIGNED_BYTE, ilGetData());
  35.   ILenum error = ilGetError();
  36.   if(error != IL_NO_ERROR)
  37.    MessageBox(NULL, iluGetString(error), "Error", MB_OK);
  38.  }
  39.  else
  40.   MessageBox(NULL, "Erreur Place mémoire insuffisante pour charger la texture...", "Mémoire insuffisante",MB_OK);
  41. }
  42. int id = isTextureCharge(texture);
  43. glBindTexture(GL_TEXTURE_2D, Texture[id]);
  44. }
  45. int TextureManager::isTextureCharge(char *texture)
  46. {
  47. for(int i = 0 ; i < NBR_MAX_TEXTURES ; i++)
  48.  if(nomTextures[i] == texture)
  49.   return i;
  50. return -1;
  51. }
  52. void TextureManager::Relase(int i)
  53. {
  54. if(nbrInstanceTexture[i]>1)
  55.  --nbrInstanceTexture[i];
  56. else
  57. {
  58.  Texture[i]=0;
  59.  nomTextures[i]="";
  60.  nbrInstanceTexture[i] = 0;
  61. }
  62. }
  63. int TextureManager::PlaceMemoireLibre()
  64. {
  65. for(int i = 0 ; i < NBR_MAX_TEXTURES ; i++)
  66. {
  67.  if(nbrInstanceTexture[i] == 0)
  68.   return i;
  69. }
  70. return -1;
  71. }
  72. int TextureManager::nbrTextureCharge()
  73. {
  74. int n = 0;
  75. for(int i = 0 ; i < NBR_MAX_TEXTURES ; i++)
  76.  if(nbrInstanceTexture[i] != 0)
  77.   n++;
  78. return n;
  79. }
  80. void TextureManager::bindTexture(char *texture)
  81. {
  82. int id = isTextureCharge(texture);
  83. if(id == -1)
  84.  LoadTexture(texture);
  85. else
  86. {
  87.  glBindTexture(GL_TEXTURE_2D, Texture[id]);
  88. }
  89. }


 
comme vous pouvez le remarquer j'utilise DevIL...
Bon mon problème c'est que je n'arrive pas a changer de texture : seule la dernière chargée s'affiche...
pourtant l'appel a fonction bindTexture() aurrait du permettre d'en changer mais rien ne se passe et je conserve la même texture...
 
Merci :)

Reply

Marsh Posté le 14-06-2006 à 14:08:03   

Reply

Marsh Posté le 14-06-2006 à 14:55:40    

utilise des std::vector<> des std::string, et des hash_map<string, ... > pour faire la résolution d'une texture par son nom.
 
dans la classe qui maintient ton modèle 3D, vu le bindTexture() tu maintiens la texture par son nom (char *):  
 
évite ça, maintiens la dépendance à la texture par un entier ou un pointeur sur une structure via un boost::intrusive_ptr<>.
 
par exemple (ordre d'idée a pas prendre au pied de la lettre):
 
class Texture
{
public:
    GLuint Handle;
    std::string Name;
    int ref_count;
 
    Texture() : ref_count(0) {};
    ....
}
 
void intrusive_ptr_add_ref( Texture *ptr )
{
     ++ptr->ref_count;
}
 
void intrusive_ptr_release( Texture *ptr )
{
     --ptr->ref_count;
}
 
class TextureManager
{
    ???::hash_map<std::string, Texture*> TexturePool;
 
    // cherche la texture dans la hash_map<>, si y'a pas => charge la texture et la mets dans la hash_map
    intrusive_ptr<Texture> GetTexture( const std::string &TextureFile );  
 
    // balaye la collection de textures et détruit les textures inutilisées
    void GarbageUnusedTextures();
}
 
class Mesh
{
    boost::intrusive_ptr<Texture> DiffuseTexture, BumpTexture;
    int ref_count;
 
    ...
    ...
 
    bool Load( const std::string &File );
   void Render();
}
 
class MeshManager
{
   ???::hash_map<std::string, Mesh *>
 
   // idem
   intrusive_ptr<Texture> GetMesh( const std::string &MeshFile );
   
  // plop purgage
  void GarbageUnusedMeshes();
}
 
ce qui donne:
 
bool Mesh::Load(  const std::string &File )
{
    std::ifstream ifs( File.c_str() );
 
    ...
    ...
    DiffuseTexture=TextureMan->GetTexture( DiffStr );
    BumpTexture=TextureMan->GetTexture( BumpStr );
 
    ...    
}
 
void Mesh::Render()
{
   ...
   if( DiffuseTexture )
       glBindTexture(GL_TEXTURE_2D, DiffuseTexture->Handle );
   ...
   ...    
}
 
 
 
par exemple, à raffinner ou autre...
 
l'idée de ne pas détruire les instances automatiquement est nécessaire pour ne pas se tapper des chargement/destructions inutiles. (genre un vrai jeu ne détruit pas tout bêtement, mais par exemple au changement de niveau/scène)
 
(si ne maintiens les ressources que par la hash_map, attention a bien tout détruire par le destructeur)


Message édité par bjone le 14-06-2006 à 15:48:53
Reply

Marsh Posté le 14-06-2006 à 15:17:08    

tu peux même créer une méthode Bind() à la classe Texture pour te faciliter la vie (avec une variable membre qui stoque le GL_TEXTURE_2D et d'autres propriétées)

Reply

Marsh Posté le 14-06-2006 à 16:04:13    

Bon, d'accord Merci Bjone je vais faire ça...
 
mais je pense que mon problème lui restera car pour le moment ce que tu critique fonctionnait. C'était sûrement pas propre (et je vais l'améliorer en suivant tes conseils). Mais est ce que tu verrait au niveau de l'openGL où est mon erreur ?
 
et encore Merci  pour tes conseils :)

Reply

Marsh Posté le 14-06-2006 à 16:23:08    

le problèmes c'est les "char * texture", ça buggue, ça fuit:
 
 

Code :
  1. int TextureManager::isTextureCharge(char *texture)
  2. {
  3.     for(int i = 0 ; i < NBR_MAX_TEXTURES ; i++ )     
  4.         if(nomTextures[i] == texture)                   // strcmp() ici !!!!!
  5.             return i;
  6.     return -1;
  7. }


 

Code :
  1. void TextureManager::LoadTexture(char *texture)
  2. {
  3.     if(isTextureCharge(texture)==-1)
  4.     {
  5.         int id = PlaceMemoireLibre();
  6.         if(id != -1)
  7.         {
  8.             if(!ilLoadImage(texture))
  9.                 MessageBox(NULL, "image impossible a charger car non trouvée...", "Erreur dans DevIL", MB_OK);
  10.      
  11.        nomTextures[id] = texture;               //  sapu ==> strdup
  12.      
  13.              nbrInstanceTexture[id]++;
  14.              glBindTexture(GL_TEXTURE_2D, Texture[id]);
  15.              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  16.              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  17.            glTexImage2D(GL_TEXTURE_2D, 0, 3,
  18.                ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
  19.                0, GL_RGB, GL_UNSIGNED_BYTE, ilGetData());       
  20.             ILenum error = ilGetError();
  21.             if(error != IL_NO_ERROR)
  22.                 MessageBox(NULL, iluGetString(error), "Error", MB_OK);
  23.        }
  24.         else
  25.             MessageBox(NULL, "Erreur Place mémoire insuffisante pour charger la texture...", "Mémoire insuffisante",MB_OK);
  26.     }
  27.    
  28.     int id = isTextureCharge(texture);
  29.     glBindTexture(GL_TEXTURE_2D, Texture[id]);
  30. }


 
là devrait marcher, mais comme y'a pas les free() pour char * de mayrde, ça va fuire de partout => retour a ma première réponse (utilisation stl, boost)

Reply

Marsh Posté le 14-06-2006 à 16:25:36    

[:drapal]

Reply

Marsh Posté le 14-06-2006 à 17:24:52    

Bon d'accord a l'unanimité ce que j'ai fait est pourri...
mais le problème c'est que je ne connais ni STL ni BOOST  :fou:  
il me reste plus qu'a apprendre... je reviandrai poser des questions sur ces deux librairies (je commence par STL )

Reply

Marsh Posté le 14-06-2006 à 17:27:30    


 
I'll ba back

Reply

Marsh Posté le 14-06-2006 à 17:34:43    

hum effectivement elle est pas mal celle là

Reply

Marsh Posté le 14-06-2006 à 17:49:14    

Amonchakai a écrit :

Bon d'accord a l'unanimité ce que j'ai fait est pourri...
mais le problème c'est que je ne connais ni STL ni BOOST  :fou:  
il me reste plus qu'a apprendre... je reviandrai poser des questions sur ces deux librairies (je commence par STL )


 
c'est pas si pourri, ça pourrait presque marcher, en fuiyant à gauche à droite (quoique le code de référence que je t'ai mis est pas complet :D)
 
mais c'est sûr, je peux te garantir que tu gagneras a regarder la STL & Boost.

Reply

Marsh Posté le 14-06-2006 à 17:49:14   

Reply

Marsh Posté le 14-06-2006 à 19:57:37    

oublies pas aussi les exceptions pour géré les erreurs, c'est tres pratique

Reply

Marsh Posté le 15-06-2006 à 08:03:35    

Ok merci les gas...  :)


Message édité par Amonchakai le 15-06-2006 à 08:03:57
Reply

Sujets relatifs:

Leave a Replay

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