#include "Texture.h" // Constructeurs et Destructeur Texture::Texture() : m_id(0), m_fichierImage(""), m_largeur(0), m_hauteur(0), m_format(0), m_formatInterne(0), m_textureVide(true) { } Texture::Texture(std::string fichierImage) : m_id(0), m_fichierImage(fichierImage), m_largeur(0), m_hauteur(0), m_format(0), m_formatInterne(0), m_textureVide(false) { createTexture(); } Texture::Texture(int largeur, int hauteur, GLenum format, GLenum formatInterne, bool textureVide) : m_id(0), m_fichierImage(""), m_largeur(largeur), m_hauteur(hauteur), m_format(format), m_formatInterne(formatInterne), m_textureVide(textureVide) { if ( largeur > 0 && hauteur > 0 ) create(); } Texture::Texture(Texture const &autre) { *this = autre; } Texture::~Texture() { // Destruction de la texture if(glIsTexture(m_id) == GL_TRUE) glDeleteTextures(1, &m_id); } // Méthodes Texture& Texture::operator=(Texture const &autre) { // Copie des attributs m_fichierImage = autre.m_fichierImage; m_largeur = autre.m_largeur; m_hauteur = autre.m_hauteur; m_format = autre.m_format; m_formatInterne = autre.m_formatInterne; m_textureVide = autre.m_textureVide; // Si la texture est vide, alors on appelle la méthode create() if(m_textureVide && glIsTexture(autre.m_id) == GL_TRUE) create(); // Sinon, on appelle la méthode createTexture() par défaut else if(glIsTexture(autre.m_id) == GL_TRUE) createTexture(); // Retour du pointeur *this return *this; } bool Texture::createTexture() { // Chargement de l'image dans une surface SDL SDL_Surface *imageSDL = SDL_LoadBMP(m_fichierImage.c_str()); if( !imageSDL ) { std::cout << "Erreur : " << SDL_GetError() << std::endl; return false; } // Inversion de l'image SDL_Surface *imageInversee = inverserPixels(imageSDL); SDL_FreeSurface(imageSDL); // Détermination du format et du format interne pour les images à 3 composantes if(imageInversee->format->BytesPerPixel == 3) { // Format interne m_formatInterne = GL_RGB; // Format if(imageInversee->format->Rmask == 0xff) m_format = GL_RGB; else m_format = GL_RGB; // must be BGR } // Détermination du format et du format interne pour les images à 4 composantes else if(imageInversee->format->BytesPerPixel == 4) { // Format interne m_formatInterne = GL_RGBA; // Format m_format = GL_RGBA; } // Dans les autres cas, on arrête le chargement else { std::cout << "Erreur, format interne de l'image inconnu" << std::endl; SDL_FreeSurface(imageInversee); return false; } // On affecte les dimensions de notre image à celle de la texture m_hauteur = imageInversee->h; m_largeur = imageInversee->w; // Création OpenGL create( imageInversee->pixels ); // Fin de la méthode SDL_FreeSurface(imageInversee); return true; } void Texture::create( void* sampler ) { // Destruction d'une éventuelle ancienne texture if(glIsTexture(m_id) == GL_TRUE) glDeleteTextures(1, &m_id); // Génération de l'ID glGenTextures(1, &m_id); // Verrouillage glBindTexture(GL_TEXTURE_2D, m_id); // Définition des caractéristiques de la texture glTexImage2D(GL_TEXTURE_2D, 0, m_formatInterne, m_largeur, m_hauteur, 0, m_format, GL_UNSIGNED_BYTE, sampler); // Application des filtres glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Déverrouillage glBindTexture(GL_TEXTURE_2D, 0); } SDL_Surface* Texture::inverserPixels(SDL_Surface *imageSource) const { // Copie conforme de l'image source sans les pixels SDL_Surface *imageInversee = SDL_CreateRGBSurface(0, imageSource->w, imageSource->h, imageSource->format->BitsPerPixel, imageSource->format->Rmask, imageSource->format->Gmask, imageSource->format->Bmask, imageSource->format->Amask); // Tableau intermédiaires permettant de manipuler les pixels unsigned char* pixelsSources = (unsigned char*) imageSource->pixels; unsigned char* pixelsInverses = (unsigned char*) imageInversee->pixels; // Inversion des pixels for(int i = 0; i < imageSource->h; i++) { for(int j = 0; j < imageSource->w * imageSource->format->BytesPerPixel; j++) pixelsInverses[(imageSource->w * imageSource->format->BytesPerPixel * (imageSource->h - 1 - i)) + j] = pixelsSources[(imageSource->w * imageSource->format->BytesPerPixel * i) + j]; } // Retour de l'image inversée return imageInversee; } GLuint Texture::getID() const { return m_id; } void Texture::setFichierImage(const std::string &fichierImage) { m_fichierImage = fichierImage; m_textureVide = false; }