//------------------------------------------------------------------------------
// Charge une image BMP 24 bits
//------------------------------------------------------------------------------

int LoadBMP(char *File, int nb)
 {
    unsigned char   *Data;
    FILE            *fichier;
    unsigned char   Header[0x36];
    GLuint          DataPos,DataSize;
    GLint           Components;
    GLsizei         Width,Height;
    GLenum          Format,Type;
    unsigned char t;
    int x;
    
    // Lit le fichier et son header
    fichier = fopen(File,"rb");if (!fichier) return -1;
    if (fread(Header,1,0x36,fichier)!=0x36) EXIT;
    if (Header[0]!='B' || Header[1]!='M')   EXIT;
    if (CTOI(Header[0x1E])!=0)              EXIT;
    if (CTOI(Header[0x1C])!=24)             EXIT;

    // Récupère les infos du fichier
    DataPos     = CTOI(Header[0x0A]);
    DataSize    = CTOI(Header[0x22]);
    
    // Récupère les infos de l'image
    Width   = CTOI(Header[0x12]);
    Height  = CTOI(Header[0x16]);    
    Type    = GL_UNSIGNED_BYTE;
    Format  = GL_RGB;
    Components = 3;
    
    // !!!!
    if (DataSize==0)    DataSize=Width*Height*Components;
    if (DataPos==0)     DataPos=0x36;

    // Charge l'image
    fseek(fichier,DataPos,0);
    Data = ( unsigned char * ) malloc ( DataSize * sizeof ( unsigned char ) );
    if (!Data)  EXIT;

    if (fread(Data,1,DataSize,fichier)!=DataSize) 
     {
        free ( Data ); EXIT;
     }
    
    fclose(fichier);

    // Inverse R et B
    for (x=0;x<Width*Height;x++)
     {
        t=Data[x*3];
        Data[x*3]=Data[x*3+2];
        Data[x*3+2]=t;
     }

    // Envoie la texture à OpenGL
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glGenTextures(nb, &Name[nb]);
    glBindTexture(GL_TEXTURE_2D, Name[nb]);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtered (ca lisser les textures mais moins ien que le TriLinear Filtering)
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtered
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

    glTexImage2D
     (     
        GL_TEXTURE_2D,                              //target
        0,                                          //mipmap level
        Components,                                 //nb couleurs
        Width,                                      //largeur
        Height,                                     //hauteur
        0,                                          //largeur du bord
        Format,                                     //type des couleurs
        Type,                                       //codage de chaque composante
        Data                                        //Image
     ); 

    return Name[nb];
 }

//------------------------------------------------------------------------------
// Charge une image TGA 32 bits non compressée
//------------------------------------------------------------------------------

int    LoadTGA(char *filename, int nb) // Loads A TGA File Into Memory
 {    
    GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};// Uncompressed TGA Header
    GLubyte TGAcompare[12];                         // Used To Compare TGA Header
    GLubyte header[6];                              // First 6 Useful Bytes From The Header
    int     imageSize;                              // Used To Store The Image Size When Setting Aside Ram
    int     type;                                   // Set The Default GL Mode To RBGA (32 BPP)
    GLubyte *imageData;                             // Données de l'image, jusqu'à 32 bits
    int     bpp;                                    // Bits Par Pixel de l'image
    int     Width, Height;                          // Taille de l'image
    int     t, i;
                                                    
    // Lit le fichier et son header
    FILE *fichier = fopen(filename, "rb");          // Open The TGA File                                                    
    if (fread(TGAcompare,1,sizeof(TGAcompare),fichier)!=sizeof(TGAcompare)) EXIT; // Are There 12 Bytes To Read?
    if (memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0)                  EXIT; // Does The Header Match What We Want?
    if (fread(header,1,sizeof(header),fichier)!=sizeof(header))             EXIT; // If So Read Next 6 Header Bytes

    // Récupère les infos de l'image
    Width  = header[1] * 256 + header[0];           // Determine The TGA Width    (highbyte*256+lowbyte)
    Height = header[3] * 256 + header[2];           // Determine The TGA Height    (highbyte*256+lowbyte)
    bpp = header[4];                                // Grab The TGA's Bits Per Pixel (24 or 32)
    if (bpp==24) type=GL_RGB;                       // If So Set The 'type' To GL_RGB
    else type=GL_RGBA;                              // If So Set The 'type' To GL_RGBA
    imageSize = Width*Height*bpp/8;                 // Calculate The Memory Required For The TGA Data

    // Charge l'image
    imageData=(GLubyte *)malloc(imageSize);         // Reserve Memory To Hold The TGA Data
    if (fread(imageData, 1, imageSize, fichier)!=imageSize) // Does The Image Size Match The Memory Reserved?
     {
        free ( imageData );
        EXIT;
     }

    fclose (fichier);                               // Close The File
    
    // Inverse R et B
    for(i=0; i<imageSize;i+=bpp/8)              // Loop Through The Image Data
     {                                              // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
        t=imageData[i];                             // Temporarily Store The Value At Image Data 'i'
        imageData[i]=imageData[i+2];                // Set The 1st Byte To The Value Of The 3rd Byte
        imageData[i+2]=t;                           // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
     }

    // Build A Texture From The Data
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    glGenTextures(nb, &Name[nb]);                   // Generate OpenGL texture IDs
                                             
    glBindTexture(GL_TEXTURE_2D, Name[nb]);         // Bind Our Texture
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtered (ca lisser les textures mais moins ien que le TriLinear Filtering)
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtered
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

    glTexImage2D(GL_TEXTURE_2D, 0, type, Width, Height, 0, type, GL_UNSIGNED_BYTE, imageData);

    return Name[nb];                                // Texture Building Went Ok, Return True
 }

//------------------------------------------------------------------------------
// Fin Du Fichier
//------------------------------------------------------------------------------