瀏覽代碼

Import texture testing project

DricomDragon 4 年之前
父節點
當前提交
f614eece6a

+ 73 - 0
textureTest/Caisse.cpp

@@ -0,0 +1,73 @@
+#include "Caisse.h"
+
+//Constructeur
+Caisse::Caisse(float taille, std::string const vertexShader, std::string const fragmentShader, std::string fichierImage)
+: Cube(taille, vertexShader, fragmentShader)
+{
+    // Chargement de la texture
+    m_texture.charger(fichierImage);
+
+    // Implémentation du tableau de coordonnées texture
+    float coordTextureTmp[] = {0, 0,   1, 0,   1, 1,     // Face 1
+                               0, 0,   0, 1,   1, 1,    // Face 1
+                               0, 0,   1, 0,   1, 1,     // Face 2
+                               0, 0,   0, 1,   1, 1,    // Face 2
+                               0, 0,   1, 0,   1, 1,     // Face 3
+                               0, 0,   0, 1,   1, 1,    // Face 3
+                               0, 0,   1, 0,   1, 1,     // Face 4
+                               0, 0,   0, 1,   1, 1,    // Face 4
+                               0, 0,   1, 0,   1, 1,     // Face 5
+                               0, 0,   0, 1,   1, 1,    // Face 5
+                               0, 0,   1, 0,   1, 1,     // Face 6
+                               0, 0,   0, 1,   1, 1};    // Face 6
+    for(int i (0); i < 72; i++)
+        m_coordTexture[i] = coordTextureTmp[i];
+
+}
+
+//Destructeur
+Caisse::~Caisse()
+{}
+
+void Caisse::afficher(glm::mat4 &projection, glm::mat4 &modelview)
+{
+    // Activation du shader
+    glUseProgram(m_shader.getProgramID());
+
+
+        // Envoi des vertices
+        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, m_vertices);
+        glEnableVertexAttribArray(0);
+
+
+        // Envoi des coordonnées de texture
+        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, m_coordTexture);
+        glEnableVertexAttribArray(2);
+
+
+        // Envoi des matrices
+        glUniformMatrix4fv(glGetUniformLocation(m_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));
+        glUniformMatrix4fv(glGetUniformLocation(m_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(modelview));
+
+
+        // Verrouillage de la texture
+        glBindTexture(GL_TEXTURE_2D, m_texture.getID());
+
+
+        // Rendu
+        glDrawArrays(GL_TRIANGLES, 0, 36);
+
+
+        // Déverrouillage de la texture
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+
+        // Désactivation des tableaux
+        glDisableVertexAttribArray(2);
+        glDisableVertexAttribArray(0);
+
+
+    // Désactivation du shader
+    glUseProgram(0);
+}
+

+ 25 - 0
textureTest/Caisse.h

@@ -0,0 +1,25 @@
+#ifndef CAISSE_H_INCLUDED
+#define CAISSE_H_INCLUDED
+
+// Includes
+#include <iostream>
+#include "Cube.h"
+#include "Texture.h"
+
+// Classe Caisse
+class Caisse : public Cube
+{
+    public:
+
+        Caisse(float taille, std::string const vertexShader, std::string const fragmentShader, std::string fichierImage);
+        ~Caisse();
+        void afficher(glm::mat4 &projection, glm::mat4 &modelview);
+
+    private:
+
+        Texture m_texture;
+        float m_coordTexture[72];
+
+};
+
+#endif // CAISSE_H_INCLUDED

+ 123 - 0
textureTest/Cube.cpp

@@ -0,0 +1,123 @@
+#include "Cube.h"
+
+
+// Permet d'éviter la ré-écriture du namespace glm::
+
+using namespace glm;
+
+
+// Constructeur et Destructeur
+
+Cube::Cube(float taille, std::string const vertexShader, std::string const fragmentShader) : m_shader(vertexShader, fragmentShader)
+{
+    // Chargement du shader
+
+    m_shader.charger();
+
+
+    // Division de la taille
+
+    taille /= 2;
+
+
+    // Vertices temporaires
+
+    float verticesTmp[] = {-taille, -taille, -taille,   taille, -taille, -taille,   taille, taille, -taille,     // Face 1
+                           -taille, -taille, -taille,   -taille, taille, -taille,   taille, taille, -taille,     // Face 1
+
+                           taille, -taille, taille,   taille, -taille, -taille,   taille, taille, -taille,       // Face 2
+                           taille, -taille, taille,   taille, taille, taille,   taille, taille, -taille,         // Face 2
+
+                           -taille, -taille, taille,   taille, -taille, taille,   taille, -taille, -taille,      // Face 3
+                           -taille, -taille, taille,   -taille, -taille, -taille,   taille, -taille, -taille,    // Face 3
+
+                           -taille, -taille, taille,   taille, -taille, taille,   taille, taille, taille,        // Face 4
+                           -taille, -taille, taille,   -taille, taille, taille,   taille, taille, taille,        // Face 4
+
+                           -taille, -taille, -taille,   -taille, -taille, taille,   -taille, taille, taille,     // Face 5
+                           -taille, -taille, -taille,   -taille, taille, -taille,   -taille, taille, taille,     // Face 5
+
+                           -taille, taille, taille,   taille, taille, taille,   taille, taille, -taille,         // Face 6
+                           -taille, taille, taille,   -taille, taille, -taille,   taille, taille, -taille};      // Face 6
+
+
+    // Couleurs temporaires
+
+    float couleursTmp[] = {1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,           // Face 1
+                           1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,           // Face 1
+
+                           0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,           // Face 2
+                           0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,           // Face 2
+
+                           0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,           // Face 3
+                           0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,           // Face 3
+
+                           1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,           // Face 4
+                           1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,           // Face 4
+
+                           0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,           // Face 5
+                           0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,           // Face 5
+
+                           0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,           // Face 6
+                           0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0};          // Face 6
+
+
+    // Copie des valeurs dans les tableaux finaux
+
+    for(int i(0); i < 108; i++)
+    {
+        m_vertices[i] = verticesTmp[i];
+        m_couleurs[i] = couleursTmp[i];
+    }
+}
+
+
+Cube::~Cube()
+{
+
+}
+
+
+// Méthodes
+
+void Cube::afficher(glm::mat4 &projection, glm::mat4 &modelview)
+{
+    // Activation du shader
+
+    glUseProgram(m_shader.getProgramID());
+
+
+        // Envoi des vertices
+
+        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, m_vertices);
+        glEnableVertexAttribArray(0);
+
+
+        // Envoi de la couleur
+
+        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, m_couleurs);
+        glEnableVertexAttribArray(1);
+
+
+        // Envoi des matrices
+
+        glUniformMatrix4fv(glGetUniformLocation(m_shader.getProgramID(), "projection"), 1, GL_FALSE, value_ptr(projection));
+        glUniformMatrix4fv(glGetUniformLocation(m_shader.getProgramID(), "modelview"), 1, GL_FALSE, value_ptr(modelview));
+
+
+        // Rendu
+
+        glDrawArrays(GL_TRIANGLES, 0, 36);
+
+
+        // Désactivation des tableaux
+
+        glDisableVertexAttribArray(1);
+        glDisableVertexAttribArray(0);
+
+
+    // Désactivation du shader
+
+    glUseProgram(0);
+}
+

+ 48 - 0
textureTest/Cube.h

@@ -0,0 +1,48 @@
+#ifndef DEF_CUBE
+#define DEF_CUBE
+
+
+// Includes OpenGL
+
+#ifdef WIN32
+#include <GL/glew.h>
+
+#else
+#define GL3_PROTOTYPES 1
+#include <GL3/gl3.h>
+
+#endif
+
+
+// Includes GLM
+
+#include <glm/glm.hpp>
+#include <glm/gtx/transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+
+// Includes
+
+#include "Shader.h"
+
+
+// Classe Cube
+
+class Cube
+{
+    public:
+
+    Cube(float taille, std::string const vertexShader, std::string const fragmentShader);
+    ~Cube();
+
+    void afficher(glm::mat4 &projection, glm::mat4 &modelview);
+
+
+    protected:
+
+    Shader m_shader;
+    float m_vertices[108];
+    float m_couleurs[108];
+};
+
+#endif

+ 178 - 0
textureTest/Input.cpp

@@ -0,0 +1,178 @@
+#include "Input.h"
+
+
+// Constructeur et Destructeur
+
+Input::Input() : m_x(0), m_y(0), m_xRel(0), m_yRel(0), m_terminer(false)
+{
+    // Initialisation du tableau m_touches[]
+
+    for(int i(0); i < SDL_NUM_SCANCODES; i++)
+        m_touches[i] = false;
+
+
+    // Initialisation du tableau m_boutonsSouris[]
+
+    for(int i(0); i < 8; i++)
+        m_boutonsSouris[i] = false;
+}
+
+
+Input::~Input()
+{
+
+}
+
+
+// Méthodes
+
+void Input::updateEvenements()
+{
+    // Pour éviter des mouvements fictifs de la souris, on réinitialise les coordonnées relatives
+
+    m_xRel = 0;
+    m_yRel = 0;
+
+
+    // Boucle d'évènements
+
+    while(SDL_PollEvent(&m_evenements))
+    {
+        // Switch sur le type d'évènement
+
+        switch(m_evenements.type)
+        {
+            // Cas d'une touche enfoncée
+
+            case SDL_KEYDOWN:
+                m_touches[m_evenements.key.keysym.scancode] = true;
+            break;
+
+
+            // Cas d'une touche relâchée
+
+            case SDL_KEYUP:
+                m_touches[m_evenements.key.keysym.scancode] = false;
+            break;
+
+
+            // Cas de pression sur un bouton de la souris
+
+            case SDL_MOUSEBUTTONDOWN:
+
+                m_boutonsSouris[m_evenements.button.button] = true;
+
+            break;
+
+
+            // Cas du relâchement d'un bouton de la souris
+
+            case SDL_MOUSEBUTTONUP:
+
+                m_boutonsSouris[m_evenements.button.button] = false;
+
+            break;
+
+
+            // Cas d'un mouvement de souris
+
+            case SDL_MOUSEMOTION:
+
+                m_x = m_evenements.motion.x;
+                m_y = m_evenements.motion.y;
+
+                m_xRel = m_evenements.motion.xrel;
+                m_yRel = m_evenements.motion.yrel;
+
+            break;
+
+
+            // Cas de la fermeture de la fenêtre
+
+            case SDL_WINDOWEVENT:
+
+                if(m_evenements.window.event == SDL_WINDOWEVENT_CLOSE)
+                    m_terminer = true;
+
+            break;
+
+
+            default:
+            break;
+        }
+    }
+}
+
+
+bool Input::terminer() const
+{
+    return m_terminer;
+}
+
+
+void Input::afficherPointeur(bool reponse) const
+{
+    if(reponse)
+        SDL_ShowCursor(SDL_ENABLE);
+
+    else
+        SDL_ShowCursor(SDL_DISABLE);
+}
+
+
+void Input::capturerPointeur(bool reponse) const
+{
+    if(reponse)
+        SDL_SetRelativeMouseMode(SDL_TRUE);
+
+    else
+        SDL_SetRelativeMouseMode(SDL_FALSE);
+}
+
+
+
+// Getters
+
+bool Input::getTouche(const SDL_Scancode touche) const
+{
+    return m_touches[touche];
+}
+
+
+bool Input::getBoutonSouris(const Uint8 bouton) const
+{
+    return m_boutonsSouris[bouton];
+}
+
+
+bool Input::mouvementSouris() const
+{
+    if(m_xRel == 0 && m_yRel == 0)
+        return false;
+
+    else
+        return true;
+}
+
+
+// Getters concernant la position du curseur
+
+int Input::getX() const
+{
+    return m_x;
+}
+
+int Input::getY() const
+{
+    return m_y;
+}
+
+int Input::getXRel() const
+{
+    return m_xRel;
+}
+
+int Input::getYRel() const
+{
+    return m_yRel;
+}

+ 49 - 0
textureTest/Input.h

@@ -0,0 +1,49 @@
+#ifndef DEF_INPUT
+#define DEF_INPUT
+
+// Include
+
+#include <SDL2/SDL.h>
+
+
+// Classe
+
+class Input
+{
+    public:
+
+    Input();
+    ~Input();
+
+    void updateEvenements();
+    bool terminer() const;
+    void afficherPointeur(bool reponse) const;
+    void capturerPointeur(bool reponse) const;
+
+    bool getTouche(const SDL_Scancode touche) const;
+    bool getBoutonSouris(const Uint8 bouton) const;
+    bool mouvementSouris() const;
+
+    int getX() const;
+    int getY() const;
+
+    int getXRel() const;
+    int getYRel() const;
+
+
+    private:
+
+    SDL_Event m_evenements;
+    bool m_touches[SDL_NUM_SCANCODES];
+    bool m_boutonsSouris[8];
+
+    int m_x;
+    int m_y;
+    int m_xRel;
+    int m_yRel;
+
+    bool m_terminer;
+};
+
+#endif
+

+ 159 - 0
textureTest/SceneOpenGL.cpp

@@ -0,0 +1,159 @@
+#include "SceneOpenGL.h"
+
+SceneOpenGL::SceneOpenGL(std::string titre, int largeur, int hauteur)
+: m_titreFenetre(titre), m_largeurFenetre(largeur), m_hauteurFenetre(hauteur), m_fenetre(0), m_contexteOpenGL(0)
+{
+
+}
+
+SceneOpenGL::~SceneOpenGL()
+{
+    SDL_GL_DeleteContext(m_contexteOpenGL);
+    SDL_DestroyWindow(m_fenetre);
+    SDL_Quit();
+}
+
+bool SceneOpenGL::initialiserFenetre()
+{
+    // Initialisation de la SDL
+    if(SDL_Init(SDL_INIT_VIDEO) < 0)
+    {
+        std::cout << "Erreur lors de l'initialisation de la SDL : " << SDL_GetError() << std::endl;
+        SDL_Quit();
+
+        return false;
+    }
+
+
+    // Version d'OpenGL
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
+
+
+    // Double Buffer
+    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+
+
+    // Création de la fenêtre
+    m_fenetre = SDL_CreateWindow(m_titreFenetre.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+                                 m_largeurFenetre, m_hauteurFenetre, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
+    if(m_fenetre == 0)
+    {
+        std::cout << "Erreur lors de la creation de la fenetre : " << SDL_GetError() << std::endl;
+        SDL_Quit();
+
+        return false;
+    }
+
+
+    // Création du contexte OpenGL
+    m_contexteOpenGL = SDL_GL_CreateContext(m_fenetre);
+    if(m_contexteOpenGL == 0)
+    {
+        std::cout << SDL_GetError() << std::endl;
+        SDL_DestroyWindow(m_fenetre);
+        SDL_Quit();
+
+        return false;
+    }
+
+    return true;
+}
+
+bool SceneOpenGL::initGL()
+{
+    glEnable(GL_DEPTH_TEST);
+    return true;
+}
+
+void SceneOpenGL::bouclePrincipale()
+{
+    /// Variables
+    //Gestion du temps
+    unsigned int frameRate (1000 / 50);//50fps
+    Uint32 debutBoucle(0), finBoucle(0), tempsEcoule(0);
+    //Objets
+    Caisse monoCube(2.2,"Shaders/texture.vert","Shaders/texture.frag","Textures/planks.bmp");
+    //Matrices
+    glm::mat4 projection;
+    glm::mat4 modelView(1.0);
+    glm::mat4 originSave(1.0);
+    glm::mat4 sauvegarde(1.0);//Pour sauvegarder modelView
+    float rotation(0.0);
+    float acceleration(0.0);
+    //Vecteurs
+    glm::vec3 posYeux(5.0,5.0,5.0);
+    glm::vec3 focus(0.0,0.0,0.0);
+    glm::vec3 axeY(0.0,1.0,0.0);
+    glm::vec3 axeZ(0.0,0.0,1.0);
+
+
+    ///Texture
+    Surface3D sol(15.0, 15.0, "Shaders/texture.vert", "Shaders/texture.frag", "Textures/stonebrick.bmp",4.0);
+
+    ///Initialisation
+    projection = glm::perspective(70.0, (double) m_largeurFenetre / m_hauteurFenetre, 1.0, 100.0);
+
+    /// Boucle principale
+    bool terminer(false);
+    while(!m_input.terminer() && !terminer)
+    {
+        // Amorce boucle
+        debutBoucle = SDL_GetTicks();
+
+        // Gestion des évènements
+        m_input.updateEvenements();
+        terminer = m_input.getTouche(SDL_SCANCODE_ESCAPE);
+        if (m_input.getTouche(SDL_SCANCODE_RIGHT))
+            acceleration+=0.05;
+        if (m_input.getTouche(SDL_SCANCODE_LEFT))
+            acceleration-=0.05;
+        rotation+=acceleration;
+        acceleration*=0.99;
+        if (rotation>=360.0)
+            rotation-=360.0;
+
+        // Nettoyage
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        originSave = modelView = glm::lookAt(posYeux,focus,axeY);
+
+        //Rotation générale
+        modelView = glm::rotate(modelView, rotation, axeY);
+        ///Cube 1
+            //Save
+            sauvegarde = modelView;
+            //Transformations
+            modelView = glm::translate(modelView, glm::vec3(-2.5,0.0,0.0));
+            modelView = glm::rotate(modelView, rotation, axeZ);
+            modelView = glm::rotate(modelView, 2*rotation, axeY);
+            //Afficher
+            monoCube.afficher(projection,modelView);
+            //Restauration
+            modelView = sauvegarde;
+        ///Cube 2
+            //Transformations
+            modelView = glm::translate(modelView, glm::vec3(2.5,0.0,0.0));
+            modelView = glm::rotate(modelView, 2*rotation, axeY);
+            //Afficher
+            monoCube.afficher(projection,modelView);
+        ///Texture
+            //Config initiale
+            modelView = originSave;
+            modelView = glm::translate(modelView, glm::vec3(0.0,-1.1,0.0));
+            modelView = glm::rotate(modelView, -rotation, axeY);
+            sol.afficher(projection,modelView);
+
+        // Actualisation de la fenêtre
+        SDL_GL_SwapWindow(m_fenetre);
+
+        /// Temps
+        // Calcul du temps écoulé
+        finBoucle = SDL_GetTicks();
+        tempsEcoule = finBoucle - debutBoucle;
+        // Si nécessaire, on met en pause le programme
+        if(tempsEcoule < frameRate)
+            SDL_Delay(frameRate - tempsEcoule);
+    }
+}
+

+ 48 - 0
textureTest/SceneOpenGL.h

@@ -0,0 +1,48 @@
+#ifndef SCENEOPENGL_H_INCLUDED
+#define SCENEOPENGL_H_INCLUDED
+
+// Includes GLM
+#include <glm/glm.hpp>
+#include <glm/gtx/transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+// Includes OpenGL
+#include <SDL2/SDL.h>
+#define GL3_PROTOTYPES 1
+#include <GL3/gl3.h>
+
+//Includes de base
+#include <string>
+#include <iostream>
+
+//Autres includes
+#include "Shader.h"
+#include "Caisse.h"
+#include "Input.h"
+#include "Texture.h"
+#include "Surface3D.h"
+
+class SceneOpenGL
+{
+    public:
+
+    SceneOpenGL(std::string titre, int largeur, int hauteur);
+    ~SceneOpenGL();
+
+    bool initialiserFenetre();
+    bool initGL();
+    void bouclePrincipale();
+
+
+    private:
+
+    std::string m_titreFenetre;
+    int m_largeurFenetre;
+    int m_hauteurFenetre;
+
+    SDL_Window* m_fenetre;
+    SDL_GLContext m_contexteOpenGL;
+    Input m_input;
+};
+
+#endif // SCENEOPENGL_H_INCLUDED

+ 273 - 0
textureTest/Shader.cpp

@@ -0,0 +1,273 @@
+#include "Shader.h"
+
+// Constructeurs et Destructeur
+
+Shader::Shader() : m_vertexID(0), m_fragmentID(0), m_programID(0), m_vertexSource(), m_fragmentSource()
+{
+}
+
+
+Shader::Shader(Shader const &shaderACopier)
+{
+    // Copie des fichiers sources
+
+    m_vertexSource = shaderACopier.m_vertexSource;
+    m_fragmentSource = shaderACopier.m_fragmentSource;
+
+
+    // Chargement du nouveau shader
+
+    charger();
+}
+
+
+Shader::Shader(std::string vertexSource, std::string fragmentSource) : m_vertexID(0), m_fragmentID(0), m_programID(0),
+                                                                       m_vertexSource(vertexSource), m_fragmentSource(fragmentSource)
+{
+}
+
+
+Shader::~Shader()
+{
+    // Destruction du shader
+
+    glDeleteShader(m_vertexID);
+    glDeleteShader(m_fragmentID);
+    glDeleteProgram(m_programID);
+}
+
+
+// Méthodes
+
+Shader& Shader::operator=(Shader const &shaderACopier)
+{
+    // Copie des fichiers sources
+
+    m_vertexSource = shaderACopier.m_vertexSource;
+    m_fragmentSource = shaderACopier.m_fragmentSource;
+
+
+    // Chargement du nouveau shader
+
+    charger();
+
+
+    // Retour du pointeur this
+
+    return *this;
+}
+
+
+bool Shader::charger()
+{
+    // Destruction d'un éventuel ancien Shader
+
+    if(glIsShader(m_vertexID) == GL_TRUE)
+        glDeleteShader(m_vertexID);
+
+    if(glIsShader(m_fragmentID) == GL_TRUE)
+        glDeleteShader(m_fragmentID);
+
+    if(glIsProgram(m_programID) == GL_TRUE)
+        glDeleteProgram(m_programID);
+
+
+    // Compilation des shaders
+
+    if(!compilerShader(m_vertexID, GL_VERTEX_SHADER, m_vertexSource))
+        return false;
+
+    if(!compilerShader(m_fragmentID, GL_FRAGMENT_SHADER, m_fragmentSource))
+        return false;
+
+
+    // Création du programme
+
+    m_programID = glCreateProgram();
+
+
+    // Association des shaders
+
+    glAttachShader(m_programID, m_vertexID);
+    glAttachShader(m_programID, m_fragmentID);
+
+
+    // Verrouillage des entrées shader
+
+    glBindAttribLocation(m_programID, 0, "in_Vertex");
+    glBindAttribLocation(m_programID, 1, "in_Color");
+    glBindAttribLocation(m_programID, 2, "in_TexCoord0");
+
+
+    // Linkage du programme
+
+    glLinkProgram(m_programID);
+
+
+    // Vérification du linkage
+
+    GLint erreurLink(0);
+    glGetProgramiv(m_programID, GL_LINK_STATUS, &erreurLink);
+
+
+    // S'il y a eu une erreur
+
+    if(erreurLink != GL_TRUE)
+    {
+        // Récupération de la taille de l'erreur
+
+        GLint tailleErreur(0);
+        glGetProgramiv(m_programID, GL_INFO_LOG_LENGTH, &tailleErreur);
+
+
+        // Allocation de mémoire
+
+        char *erreur = new char[tailleErreur + 1];
+
+
+        // Récupération de l'erreur
+
+        glGetShaderInfoLog(m_programID, tailleErreur, &tailleErreur, erreur);
+        erreur[tailleErreur] = '\0';
+
+
+        // Affichage de l'erreur
+
+        std::cout << erreur << std::endl;
+
+
+        // Libération de la mémoire et retour du booléen false
+
+        delete[] erreur;
+        glDeleteProgram(m_programID);
+
+        return false;
+    }
+
+
+
+    // Sinon c'est que tout s'est bien passé
+
+    else
+        return true;
+}
+
+
+bool Shader::compilerShader(GLuint &shader, GLenum type, std::string const &fichierSource)
+{
+    // Création du shader
+
+    shader = glCreateShader(type);
+
+
+    // Vérification du shader
+
+    if(shader == 0)
+    {
+        std::cout << "Erreur, le type de shader (" << type << ") n'existe pas" << std::endl;
+        return false;
+    }
+
+
+    // Flux de lecture
+
+    std::ifstream fichier(fichierSource.c_str());
+
+
+    // Test d'ouverture
+
+    if(!fichier)
+    {
+        std::cout << "Erreur le fichier " << fichierSource << " est introuvable" << std::endl;
+        glDeleteShader(shader);
+
+        return false;
+    }
+
+
+    // Strings permettant de lire le code source
+
+    std::string ligne;
+    std::string codeSource;
+
+
+    // Lecture
+
+    while(getline(fichier, ligne))
+        codeSource += ligne + '\n';
+
+
+    // Fermeture du fichier
+
+    fichier.close();
+
+
+    // Récupération de la chaine C du code source
+
+    const GLchar* chaineCodeSource = codeSource.c_str();
+
+
+    // Envoi du code source au shader
+
+    glShaderSource(shader, 1, &chaineCodeSource, 0);
+
+
+    // Compilation du shader
+
+    glCompileShader(shader);
+
+
+    // Vérification de la compilation
+
+    GLint erreurCompilation(0);
+    glGetShaderiv(shader, GL_COMPILE_STATUS, &erreurCompilation);
+
+
+    // S'il y a eu une erreur
+
+    if(erreurCompilation != GL_TRUE)
+    {
+        // Récupération de la taille de l'erreur
+
+        GLint tailleErreur(0);
+        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &tailleErreur);
+
+
+        // Allocation de mémoire
+
+        char *erreur = new char[tailleErreur + 1];
+
+
+        // Récupération de l'erreur
+
+        glGetShaderInfoLog(shader, tailleErreur, &tailleErreur, erreur);
+        erreur[tailleErreur] = '\0';
+
+
+        // Affichage de l'erreur
+
+        std::cout << erreur << std::endl;
+
+
+        // Libération de la mémoire et retour du booléen false
+
+        delete[] erreur;
+        glDeleteShader(shader);
+
+        return false;
+    }
+
+
+    // Sinon c'est que tout s'est bien passé
+
+    else
+        return true;
+}
+
+
+// Getter
+
+GLuint Shader::getProgramID() const
+{
+    return m_programID;
+}

+ 62 - 0
textureTest/Shader.h

@@ -0,0 +1,62 @@
+#ifndef DEF_SHADER
+#define DEF_SHADER
+
+
+// Include Windows
+
+#ifdef WIN32
+#include <GL/glew.h>
+
+
+// Include Mac
+
+#elif __APPLE__
+#define GL3_PROTOTYPES 1
+#include <OpenGL/gl3.h>
+
+
+// Include UNIX/Linux
+
+#else
+#define GL3_PROTOTYPES 1
+#include <GL3/gl3.h>
+
+#endif
+
+
+// Includes communs
+
+#include <iostream>
+#include <string>
+#include <fstream>
+
+
+// Classe Shader
+
+class Shader
+{
+    public:
+
+    Shader();
+    Shader(Shader const &shaderACopier);
+    Shader(std::string vertexSource, std::string fragmentSource);
+    ~Shader();
+
+    Shader& operator=(Shader const &shaderACopier);
+
+    bool charger();
+    bool compilerShader(GLuint &shader, GLenum type, std::string const &fichierSource);
+    GLuint getProgramID() const;
+
+
+    private:
+
+    GLuint m_vertexID;
+    GLuint m_fragmentID;
+    GLuint m_programID;
+
+    std::string m_vertexSource;
+    std::string m_fragmentSource;
+};
+
+#endif

+ 18 - 0
textureTest/Shaders/basique2D.frag

@@ -0,0 +1,18 @@
+// Version du GLSL
+
+#version 150 core
+
+
+// Sortie Shader
+
+out vec4 out_Color;
+
+
+// Fonction main
+
+void main()
+{
+    // Couleur finale du pixel
+
+    out_Color = vec4(1.0, 1.0, 1.0, 1.0);
+}

+ 18 - 0
textureTest/Shaders/basique2D.vert

@@ -0,0 +1,18 @@
+// Version du GLSL
+
+#version 150 core
+
+
+// Entrée Shader
+
+in vec2 in_Vertex;
+
+
+// Fonction main
+
+void main()
+{
+    // Position finale du vertex
+
+    gl_Position = vec4(in_Vertex, 0.0, 1.0);
+}

+ 23 - 0
textureTest/Shaders/couleur2D.frag

@@ -0,0 +1,23 @@
+// Version du GLSL
+
+#version 150 core
+
+
+// Entrée
+
+in vec3 color;
+
+
+// Sortie 
+
+out vec4 out_Color;
+
+
+// Fonction main
+
+void main()
+{
+    // Couleur finale du pixel
+
+    out_Color = vec4(color, 1.0);
+}

+ 29 - 0
textureTest/Shaders/couleur2D.vert

@@ -0,0 +1,29 @@
+// Version du GLSL
+
+#version 150 core
+
+
+// Entrées
+
+in vec2 in_Vertex;
+in vec3 in_Color;
+
+
+// Sortie
+
+out vec3 color;
+
+
+// Fonction main
+
+void main()
+{
+    // Position finale du vertex
+
+    gl_Position = vec4(in_Vertex, 0.0, 1.0);
+
+
+    // Envoi de la couleur au Fragment Shader
+
+    color = in_Color;
+}

+ 23 - 0
textureTest/Shaders/couleur3D.frag

@@ -0,0 +1,23 @@
+// Version du GLSL
+
+#version 150 core
+
+
+// Entrée
+
+in vec3 color;
+
+
+// Sortie 
+
+out vec4 out_Color;
+
+
+// Fonction main
+
+void main()
+{
+    // Couleur finale du pixel
+
+    out_Color = vec4(color, 0.5);
+}

+ 35 - 0
textureTest/Shaders/couleur3D.vert

@@ -0,0 +1,35 @@
+// Version du GLSL
+
+#version 150 core
+
+
+// Entrées
+
+in vec3 in_Vertex;
+in vec3 in_Color;
+
+
+// Uniform
+
+uniform mat4 projection;
+uniform mat4 modelview;
+
+
+// Sortie
+
+out vec3 color;
+
+
+// Fonction main
+
+void main()
+{
+    // Position finale du vertex en 3D
+
+    gl_Position = projection * modelview * vec4(in_Vertex, 1.0);
+
+
+    // Envoi de la couleur au Fragment Shader
+
+    color = in_Color;
+}

+ 28 - 0
textureTest/Shaders/texture.frag

@@ -0,0 +1,28 @@
+// Version du GLSL
+
+#version 150 core
+
+
+// Entrée
+
+in vec2 coordTexture;
+
+
+// Uniform
+
+uniform sampler2D texture;
+
+
+// Sortie 
+
+out vec4 out_Color;
+
+
+// Fonction main
+
+void main()
+{
+    // Couleur du pixel
+
+    out_Color = texture2D(texture, coordTexture);
+}

+ 35 - 0
textureTest/Shaders/texture.vert

@@ -0,0 +1,35 @@
+// Version du GLSL
+
+#version 150 core
+
+
+// Entrées
+
+in vec3 in_Vertex;
+in vec2 in_TexCoord0;
+
+
+// Uniform
+
+uniform mat4 projection;
+uniform mat4 modelview;
+
+
+// Sortie
+
+out vec2 coordTexture;
+
+
+// Fonction main
+
+void main()
+{
+    // Position finale du vertex en 3D
+
+    gl_Position = projection * modelview * vec4(in_Vertex, 1.0);
+
+
+    // Envoi des coordonnées de texture au Fragment Shader
+
+    coordTexture = in_TexCoord0;
+}

+ 68 - 0
textureTest/Surface3D.cpp

@@ -0,0 +1,68 @@
+#include "Surface3D.h"
+
+Surface3D::Surface3D(float tailleX, float tailleY, std::string const vertexShader, std::string const fragmentShader,
+                     std::string const fichierImage, float multi)
+:m_shader(vertexShader, fragmentShader)
+{
+    // Vertices
+    tailleX /= 2;
+    tailleY /= 2;
+    float vertices[] = {-tailleX, 0.0, -tailleY,   tailleX, 0.0, -tailleY,   tailleX, 0.0, tailleY,   // Triangle 1
+                        -tailleX, 0.0, -tailleY,   -tailleX, 0.0, tailleY,   tailleX, 0.0, tailleY};  // Triangle 2
+    for (int i(0); i<18; i++)
+        m_vertices[i] = vertices[i];
+
+    // Coordonnées de texture
+    if (multi == 0.0f)
+        multi = 1.0;
+    float multiX, multiY;
+    multiX = multiY = multi;
+    if (tailleX < tailleY)
+        multiX *= tailleX/tailleY;
+    else if (tailleY < tailleX)
+        multiY *= tailleY/tailleX;
+    float coordTexture[] = {0, 0,   multiX, 0,   multiX, multiY,     // Triangle 1
+                            0, 0,   0, multiY,   multiX, multiY};    // Triangle 2
+    for (int i(0); i<12; i++)
+        m_coordTexture[i] = coordTexture[i];
+
+    // Texture
+    m_texture.charger(fichierImage);
+
+    // Shader
+    if (!m_shader.charger())
+        std::cout << "Echec du chargement des shaders de texture." << std::endl;
+}
+
+Surface3D::~Surface3D()
+{
+
+}
+
+
+void Surface3D::afficher(glm::mat4 &projection, glm::mat4 &modelview)
+{
+    // Activation du shader
+    glUseProgram(m_shader.getProgramID());
+        // Envoi des vertices
+        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, m_vertices);
+        glEnableVertexAttribArray(0);
+        // Envoi des coordonnées de texture
+        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, m_coordTexture);
+        glEnableVertexAttribArray(2);
+        // Envoi des matrices
+        glUniformMatrix4fv(glGetUniformLocation(m_shader.getProgramID(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));
+        glUniformMatrix4fv(glGetUniformLocation(m_shader.getProgramID(), "modelview"), 1, GL_FALSE, glm::value_ptr(modelview));
+        // Verrouillage de la texture
+        glBindTexture(GL_TEXTURE_2D, m_texture.getID());
+        // Rendu
+        glDrawArrays(GL_TRIANGLES, 0, 6);
+        // Déverrouillage de la texture
+        glBindTexture(GL_TEXTURE_2D, 0);
+        // Désactivation des tableaux
+        glDisableVertexAttribArray(2);
+        glDisableVertexAttribArray(0);
+    // Désactivation du shader
+    glUseProgram(0);
+}
+

+ 41 - 0
textureTest/Surface3D.h

@@ -0,0 +1,41 @@
+#ifndef SURFACE3D_H_INCLUDED
+#define SURFACE3D_H_INCLUDED
+
+// Includes OpenGL
+#ifdef WIN32
+#include <GL/glew.h>
+
+#else
+#define GL3_PROTOTYPES 1
+#include <GL3/gl3.h>
+
+#endif
+
+// Includes GLM
+#include <glm/glm.hpp>
+#include <glm/gtx/transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+// Includes
+#include <iostream>
+#include "Shader.h"
+#include "Texture.h"
+
+class Surface3D
+{
+    public:
+
+        Surface3D(float tailleX, float tailleY, std::string const vertexShader, std::string const fragmentShader,
+                  std::string const fichierImage, float multi=0);
+        ~Surface3D();
+        void afficher(glm::mat4 &projection, glm::mat4 &modelview);
+
+    private:
+
+        Shader m_shader;
+        Texture m_texture;
+        float m_vertices[18];
+        float m_coordTexture[12];
+};
+
+#endif // SURFACE3D_H_INCLUDED

+ 156 - 0
textureTest/Texture.cpp

@@ -0,0 +1,156 @@
+#include "Texture.h"
+
+// Constructeur
+Texture::Texture() : m_id(0)
+{
+
+}
+
+// Constructeur de copie
+Texture::Texture(Texture const &textureACopier)
+{
+    //Rechargement de la même texture
+    charger(textureACopier.m_chemin);
+}
+
+// Destructeur
+Texture::~Texture()
+{
+    glDeleteTextures(1, &m_id);
+}
+
+//Opérateur =
+Texture& Texture::operator=(Texture const &textureACopier)
+{
+    //Rechargement de la même texture
+    charger(textureACopier.m_chemin);
+
+    // Retour du pointeur *this
+    return *this;
+}
+
+// Méthodes
+bool Texture::charger(std::string fichierImage)
+{
+    //Attribution fichier image
+    m_chemin = fichierImage;
+
+    //Chargement
+    SDL_Surface* imageInversee = SDL_LoadBMP(fichierImage.c_str());
+    if(imageInversee == 0)
+    {
+        std::cout << "Erreur chargement texture : " << SDL_GetError() << std::endl;
+        return false;
+    }
+
+    //Mettre l'image à l'endroit
+    SDL_Surface* imageSDL = inverserPixels(imageInversee);
+    SDL_FreeSurface(imageInversee);
+    imageInversee = 0;
+
+    // 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);
+
+    // Format de l'image
+    GLenum formatInterne(0);
+    GLenum format(0);
+
+    // Détermination du format et du format interne pour les images à 3 composantes
+    std::cout << "Texture format interne|ordre : ";
+    if(imageSDL->format->BytesPerPixel == 3)
+    {
+        // Format interne
+        formatInterne = GL_RGB;
+        std::cout << "GL_RGB|";
+
+        // Format
+        if(imageSDL->format->Rmask == 0xff){
+            format = GL_RGB;
+            std::cout << "GL_RGB";
+        }
+        else{
+            format = GL_BGR;
+            std::cout << "GL_BGR";
+        }
+    }
+
+    // Détermination du format et du format interne pour les images à 4 composantes
+    else if(imageSDL->format->BytesPerPixel == 4)
+    {
+        // Format interne
+        formatInterne = GL_RGBA;
+        std::cout << "GL_RGBA|";
+
+        // Format
+        if(imageSDL->format->Rmask == 0xff){
+            format = GL_RGBA;
+            std::cout << "GL_RGBA";
+        }
+        else{
+            format = GL_BGRA;
+            std::cout << "GL_BGRA";
+        }
+    }
+
+
+    // Dans les autres cas, on arrête le chargement
+    else
+    {
+        std::cout << "Erreur, format interne de l'image inconnu" ;//<< std::endl;
+        SDL_FreeSurface(imageSDL);
+
+        return false;
+    }
+    std::cout << std::endl;
+
+    // Copie des pixels
+    glTexImage2D(GL_TEXTURE_2D, 0, formatInterne, imageSDL->w, imageSDL->h, 0, format, GL_UNSIGNED_BYTE, imageSDL->pixels);
+
+    // 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);
+
+    // Fin de la méthode
+    SDL_FreeSurface(imageSDL);
+    return true;
+}
+
+GLuint Texture::getID() const
+{
+    return m_id;
+}
+
+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;
+}
+

+ 37 - 0
textureTest/Texture.h

@@ -0,0 +1,37 @@
+#ifndef TEXTURE_H_INCLUDED
+#define TEXTURE_H_INCLUDED
+
+// Includes OpenGL + SDL
+#ifdef WIN32
+#include <GL/glew.h>
+#else
+#define GL3_PROTOTYPES 1
+#include <GL3/gl3.h>
+#endif
+
+#include <SDL2/SDL.h>
+
+// Basiques
+#include <iostream>
+
+// Classe Texture
+class Texture
+{
+    public:
+        Texture();
+        Texture(Texture const &textureACopier);
+        ~Texture();
+        Texture& operator=(Texture const &textureACopier);
+
+        bool charger(std::string fichierImage);
+        GLuint getID() const;
+        SDL_Surface* inverserPixels(SDL_Surface *imageSource) const;
+
+    private:
+        GLuint m_id;
+        std::string m_chemin;
+
+};
+
+
+#endif // TEXTURE_H_INCLUDED

二進制
textureTest/Textures/cobblestone.bmp


二進制
textureTest/Textures/epee.bmp


二進制
textureTest/Textures/planks.bmp


二進制
textureTest/Textures/stonebrick.bmp


+ 13 - 0
textureTest/main.cpp

@@ -0,0 +1,13 @@
+#include <iostream>
+#include "SceneOpenGL.h"
+
+int main(int argc, char **argv)
+{
+    SceneOpenGL plateau("Warfare",1366,768);
+    if (!plateau.initialiserFenetre() || !plateau.initGL())
+        return -1;
+
+    plateau.bouclePrincipale();
+
+    return 0;
+}