123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #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;
- }
|