Browse Source

Import arena sandbox project

DricomDragon 4 years ago
parent
commit
a45cb5080e
53 changed files with 54589 additions and 0 deletions
  1. BIN
      arena/2DModels/arc.bmp
  2. BIN
      arena/2DModels/epee.bmp
  3. BIN
      arena/2DModels/hache.bmp
  4. BIN
      arena/2DModels/sword_iron.bmp
  5. 43 0
      arena/3D/Modele3D.cpp
  6. 47 0
      arena/3D/Modele3D.h
  7. 166 0
      arena/3D/Mosaic.cpp
  8. 19 0
      arena/3D/Mosaic.h
  9. 156 0
      arena/3D/OBJ.cpp
  10. 16 0
      arena/3D/OBJ.h
  11. 16290 0
      arena/3DModels/AK47.obj
  12. 34784 0
      arena/3DModels/MPX.obj
  13. 57 0
      arena/3DModels/bateau.obj
  14. 60 0
      arena/3DModels/bazooka.obj
  15. 30 0
      arena/3DModels/kube.obj
  16. 11 0
      arena/3DModels/plan.obj
  17. 158 0
      arena/Caisse.cpp
  18. 32 0
      arena/Caisse.h
  19. 197 0
      arena/Camera.cpp
  20. 69 0
      arena/Camera.h
  21. 224 0
      arena/Cube.cpp
  22. 65 0
      arena/Cube.h
  23. 125 0
      arena/FrameBuffer.cpp
  24. 55 0
      arena/FrameBuffer.h
  25. 224 0
      arena/Input.cpp
  26. 68 0
      arena/Input.h
  27. 194 0
      arena/InputAndJoy.cpp
  28. 52 0
      arena/InputAndJoy.h
  29. 399 0
      arena/SceneOpenGL.cpp
  30. 69 0
      arena/SceneOpenGL.h
  31. 192 0
      arena/Shader.cpp
  32. 51 0
      arena/Shader.h
  33. 26 0
      arena/Shaders/gris.frag
  34. 67 0
      arena/Shaders/light.frag
  35. 33 0
      arena/Shaders/light.vert
  36. 18 0
      arena/Shaders/texture.frag
  37. 23 0
      arena/Shaders/texture.vert
  38. 148 0
      arena/Surface3D.cpp
  39. 48 0
      arena/Surface3D.h
  40. 59 0
      arena/TexturLoader.cpp
  41. 27 0
      arena/TexturLoader.h
  42. 184 0
      arena/Texture.cpp
  43. 58 0
      arena/Texture.h
  44. BIN
      arena/Textures/bleu_mur.bmp
  45. BIN
      arena/Textures/caisse_basic.bmp
  46. BIN
      arena/Textures/caisse_metal.bmp
  47. BIN
      arena/Textures/chantier.bmp
  48. BIN
      arena/Textures/pierres.bmp
  49. BIN
      arena/Textures/spectre.bmp
  50. BIN
      arena/Textures/test.bmp
  51. BIN
      arena/Textures/tireur.bmp
  52. 12 0
      arena/macro.h
  53. 33 0
      arena/main.cpp

BIN
arena/2DModels/arc.bmp


BIN
arena/2DModels/epee.bmp


BIN
arena/2DModels/hache.bmp


BIN
arena/2DModels/sword_iron.bmp


+ 43 - 0
arena/3D/Modele3D.cpp

@@ -0,0 +1,43 @@
+#include "Modele3D.h"
+
+Modele3D::Modele3D()
+:m_textID( 0 ), m_vertices(0x0), m_coordTexture(0x0), m_vboID(0), m_vaoID(0)
+{
+    //ctor
+}
+
+Modele3D::~Modele3D()
+{
+    // Destruction des tableaux de cordonnées
+    if ( m_vertices != 0x0 ) delete[] m_vertices;
+    if ( m_coordTexture != 0x0 ) delete[] m_coordTexture;
+
+    // Destruction du VBO
+    glDeleteBuffers(1, &m_vboID);
+
+    // Destruction du VAO
+    glDeleteVertexArrays(1, &m_vaoID);
+}
+
+
+void Modele3D::afficher(glm::mat4 pmv, glm::mat4 m, Shader* const shad)
+{
+    // Verouillage VAO
+    glBindVertexArray(m_vaoID);
+
+        // Envoi des matrices
+        glUniformMatrix4fv(glGetUniformLocation(shad->getProgramID(), "pmv"), 1, GL_FALSE, glm::value_ptr(pmv));
+        glUniformMatrix4fv(glGetUniformLocation(shad->getProgramID(), "m"), 1, GL_FALSE, glm::value_ptr(m));
+
+        // Verrouillage de la texture
+        glBindTexture(GL_TEXTURE_2D, m_textID);
+
+        // Rendu
+        glDrawArrays(GL_TRIANGLES, 0, m_nbVec);
+
+        // Déverrouillage de la texture
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+    // Déverrouillage du VAO
+    glBindVertexArray(0);
+}

+ 47 - 0
arena/3D/Modele3D.h

@@ -0,0 +1,47 @@
+#ifndef MODELE3D_H
+#define MODELE3D_H
+
+// Macro utile au VBO
+#ifndef BUFFER_OFFSET
+
+    #define BUFFER_OFFSET(offset) ((char*)NULL + (offset))
+
+#endif
+
+#include <iostream>
+#include <vector>
+#include <fstream>
+
+#include "../Shader.h"
+#include "../Texture.h"
+
+
+// Includes GLM
+#include <glm/glm.hpp>
+#include <glm/gtx/transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+class Modele3D
+{
+    public:
+        Modele3D();
+        virtual ~Modele3D();
+
+        void afficher(glm::mat4 pmv, glm::mat4 m, Shader* const shad);
+
+    protected:
+
+        GLuint m_textID;
+        GLuint m_nbVec;
+        float *m_vertices; // Tableau
+        float *m_coordTexture; // Tableau
+        float *m_normales; // Tableau
+
+        GLuint m_vboID;
+        int m_tailleVerticesBytes;
+        int m_tailleCoordTextureBytes;
+        int m_tailleNormalesBytes;
+        GLuint m_vaoID;
+};
+
+#endif // MODELE3D_H

+ 166 - 0
arena/3D/Mosaic.cpp

@@ -0,0 +1,166 @@
+#include "Mosaic.h"
+
+Mosaic::Mosaic() : m_text( 0x0 )
+{
+    //ctor
+}
+
+Mosaic::~Mosaic()
+{
+    if ( m_text ) delete m_text;
+}
+
+
+int Mosaic::charger( std::string const src, float vertMulti )
+{
+    /// Création des attributs
+    // Chargement du sprite
+    SDL_Surface* image = SDL_LoadBMP( src.c_str() );
+    if ( !image ) {
+        std::cout << "Erreur lors du chargement de " << src << std::endl;
+    }
+    unsigned char* pixels = (unsigned char*) image->pixels;
+    SDL_LockSurface(image);
+
+    // Création de la texture
+    m_text = new Texture(src);
+    m_textID = m_text->getID();
+
+    // Tableaux
+    std::vector<float> v_coord(0); // Coordonnées des vertices
+    std::vector<float> v_norm(0); // Normales
+    std::vector<float> v_text(0); // Coordonnées de texture des vertices
+
+    /// Attributions
+    // Tableaux
+    v_coord.push_back(-0.5f);//1
+    v_coord.push_back(0.5f);
+    v_coord.push_back(0.0f);
+    v_coord.push_back(-0.5f);//2
+    v_coord.push_back(-0.5f);
+    v_coord.push_back(0.0f);
+    v_coord.push_back(0.5f);//3
+    v_coord.push_back(0.5f);
+    v_coord.push_back(0.0f);
+    v_coord.push_back(0.5f);//4
+    v_coord.push_back(0.5f);
+    v_coord.push_back(0.0f);
+    v_coord.push_back(-0.5f);//5
+    v_coord.push_back(-0.5f);
+    v_coord.push_back(0.0f);
+    v_coord.push_back(0.5f);//6
+    v_coord.push_back(-0.5f);
+    v_coord.push_back(0.0f);
+
+    v_norm.push_back(0.0f);//1
+    v_norm.push_back(0.0f);
+    v_norm.push_back(1.0f);
+    v_norm.push_back(0.0f);//2
+    v_norm.push_back(0.0f);
+    v_norm.push_back(1.0f);
+    v_norm.push_back(0.0f);//3
+    v_norm.push_back(0.0f);
+    v_norm.push_back(1.0f);
+    v_norm.push_back(0.0f);//4
+    v_norm.push_back(0.0f);
+    v_norm.push_back(1.0f);
+    v_norm.push_back(0.0f);//5
+    v_norm.push_back(0.0f);
+    v_norm.push_back(1.0f);
+    v_norm.push_back(0.0f);//6
+    v_norm.push_back(0.0f);
+    v_norm.push_back(1.0f);
+
+    v_text.push_back(0.0f);//1
+    v_text.push_back(1.0f);
+    v_text.push_back(0.0f);//2
+    v_text.push_back(0.0f);
+    v_text.push_back(1.0f);//3
+    v_text.push_back(1.0f);
+    v_text.push_back(1.0f);//4
+    v_text.push_back(1.0f);
+    v_text.push_back(0.0f);//5
+    v_text.push_back(0.0f);
+    v_text.push_back(1.0f);//6
+    v_text.push_back(0.0f);
+
+    // Création des tableaux openGL
+    m_nbVec = v_coord.size() / 3;
+
+    m_tailleVerticesBytes = v_coord.size() * sizeof(float);
+    m_vertices = new float[v_coord.size()];
+
+    m_tailleNormalesBytes = v_norm.size() * sizeof(float);
+    m_normales = new float[v_norm.size()];
+
+    m_tailleCoordTextureBytes = v_text.size() * sizeof(float);
+    m_coordTexture = new float[v_text.size()];
+
+    // Remplissage des tableaux openGL
+    for ( uint32_t i; i < v_coord.size(); i++ )
+        m_vertices[i] = v_coord[i];
+    for ( uint32_t i; i < v_norm.size(); i++ )
+        m_vertices[i] = v_norm[i];
+    for ( uint32_t i; i < v_text.size(); i++ )
+        m_vertices[i] = v_text[i];
+
+    /// Destruction de l'image
+    SDL_FreeSurface( image );
+
+    /// Chargement Vertex Buffer Object
+    // Destruction d'un éventuel ancien VBO
+    if(glIsBuffer(m_vboID) == GL_TRUE)
+        glDeleteBuffers(1, &m_vboID);
+
+    // Génération de l'ID
+    glGenBuffers(1, &m_vboID);
+
+    // Verrouillage du VBO
+    glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+        // Allocation de la mémoire vidéo
+        glBufferData(GL_ARRAY_BUFFER, m_tailleVerticesBytes + m_tailleNormalesBytes + m_tailleCoordTextureBytes, 0, GL_STATIC_DRAW);
+
+        // Transfert des données
+        glBufferSubData(GL_ARRAY_BUFFER, 0, m_tailleVerticesBytes, m_vertices);
+        glBufferSubData(GL_ARRAY_BUFFER, m_tailleVerticesBytes, m_tailleNormalesBytes, m_normales);
+        glBufferSubData(GL_ARRAY_BUFFER, m_tailleVerticesBytes+m_tailleNormalesBytes, m_tailleCoordTextureBytes, m_coordTexture);
+
+    // Déverrouillage de l'objet
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    /// Chargement Vertex Array Object
+    // Destruction d'un éventuel ancien VAO
+    if(glIsVertexArray(m_vaoID) == GL_TRUE)
+        glDeleteVertexArrays(1, &m_vaoID);
+
+    // Génération de l'ID du VAO
+    glGenVertexArrays(1, &m_vaoID);
+
+    // Verrouillage du VAO
+    glBindVertexArray(m_vaoID);
+
+        // Verrouillage du VBO
+        glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+            // Accès aux vertices dans la mémoire vidéo
+            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
+            glEnableVertexAttribArray(0);
+
+            // Accès aux normales dans la mémoire vidéo
+            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_tailleVerticesBytes));
+            glEnableVertexAttribArray(1);
+
+            // Accès aux coordonnées de texture dans la mémoire vidéo
+            glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_tailleVerticesBytes+m_tailleNormalesBytes));
+            glEnableVertexAttribArray(2);
+
+        // Déverrouillage du VBO
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    // Déverrouillage du VAO
+    glBindVertexArray(0);
+
+    /// Fin
+    return 0;
+}

+ 19 - 0
arena/3D/Mosaic.h

@@ -0,0 +1,19 @@
+#ifndef MOSAIC_H
+#define MOSAIC_H
+
+#include "Modele3D.h"
+
+
+class Mosaic : public Modele3D
+{
+    public:
+        Mosaic();
+        virtual ~Mosaic();
+
+        int charger( std::string const src, float vertMulti = 1.0f );
+
+    protected:
+        Texture* m_text;
+};
+
+#endif // MOSAIC_H

+ 156 - 0
arena/3D/OBJ.cpp

@@ -0,0 +1,156 @@
+#include "OBJ.h"
+
+OBJ::OBJ()
+{
+    //ctor
+}
+
+OBJ::~OBJ()
+{
+    //destructor
+}
+
+void OBJ::charger( std::string const src, GLuint samplerID, float vertMulti, float textMulti )
+{
+    // Attribution texture
+    m_textID = samplerID;
+
+    /// Chargement du fichier obj
+    // Variables
+    std::vector<float> v_coord(0); // Coordonnées des vertices
+    std::vector<float> v_norm(0); // Normales
+    std::vector<float> v_text(0); // Coordonnées de texture des vertices
+    std::vector<uint32_t> v_face(0); // Stocke les faces
+
+    std::ifstream fichier( src.c_str() );
+    int taille;
+    float nb;
+    uint32_t id;
+    std::string mot;
+
+    // Test flux
+    if ( !fichier ) {
+        std::cout << "Erreur lors du chargement du fichier : " << src << std::endl;
+        return;
+    }
+
+    // Connaître la taille du fichier
+    fichier.seekg(0, std::ios::end);
+    taille = fichier.tellg();
+    fichier.seekg(0, std::ios::beg);
+
+    // Lecture du fichier
+    while ( fichier.tellg() < taille && fichier.tellg()!=-1 )
+    {
+        fichier >> mot;
+
+        if ( mot == "v" ) { // Coordonnées des vertices
+            for ( int i(0); i<3; i++ ) {
+                fichier >> nb;
+                v_coord.push_back(nb);
+            }
+        } else if ( mot == "vt" ) { // Coordonnées de texture des vertices
+            for ( int i(0); i<2; i++ ) {
+                fichier >> nb;
+                v_text.push_back( nb );
+            }
+        } else if ( mot == "vn" ) { // Coordonnées des normales
+            for ( int i(0); i<3; i++ ) {
+                fichier >> nb;
+                v_norm.push_back(nb);
+            }
+        } else if ( mot == "f" ) { // Réalisation d'une face
+            for ( int i(0); i<9; i++ ) {
+                fichier >> id;
+                v_face.push_back(id);
+            }
+        }
+        mot = "rien";
+    }
+
+    // Création des tableaux openGL
+    int nbFaces( v_face.size() / 9 ); // Contient le nombre de triangles
+    m_nbVec = nbFaces * 3; // Contient le nombre de vertices à afficher
+
+    uint32_t tailleVertices( nbFaces*3*3 ); // 3 vertices de 3 coordonnées par face
+    m_tailleVerticesBytes = tailleVertices * sizeof(float);
+    m_vertices = new float[tailleVertices];
+
+    uint32_t tailleNormales( nbFaces*3*3 ); // 3 normales de 3 coordonnées par face
+    m_tailleNormalesBytes = tailleNormales * sizeof(float);
+    m_normales = new float[tailleNormales];
+
+    uint32_t tailleCoordText( nbFaces*3*2 ); // 3 vertices de 2 coordonnées par face
+    m_tailleCoordTextureBytes = tailleCoordText * sizeof(float);
+    m_coordTexture = new float[tailleCoordText];
+
+    // Remplissage des tableaux openGL
+    uint32_t i(0), j(0), k(0);
+    for ( i = 0; i<v_face.size(); i+=3) // Remplissage des vertices
+    {
+        for ( j = 0; j<3; j++) {
+            m_vertices[i+j] = v_coord[ (v_face[i]-1)*3+j ] * vertMulti;
+            m_normales[i+j] = v_norm[ (v_face[i+2]-1)*3+j ];
+        }
+    }
+    for ( i = 1; i<v_face.size(); i+=3) // Remplissage des coordonnées de texture
+    {
+        for ( j = 0; j<2; j++)
+            m_coordTexture[k+j] = v_text[ (v_face[i]-1)*2+j ] * textMulti;
+        k += 2;
+    }
+
+    /// Chargement Vertex Buffer Object
+    // Destruction d'un éventuel ancien VBO
+    if(glIsBuffer(m_vboID) == GL_TRUE)
+        glDeleteBuffers(1, &m_vboID);
+
+    // Génération de l'ID
+    glGenBuffers(1, &m_vboID);
+
+    // Verrouillage du VBO
+    glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+        // Allocation de la mémoire vidéo
+        glBufferData(GL_ARRAY_BUFFER, m_tailleVerticesBytes + m_tailleNormalesBytes + m_tailleCoordTextureBytes, 0, GL_STATIC_DRAW);
+
+        // Transfert des données
+        glBufferSubData(GL_ARRAY_BUFFER, 0, m_tailleVerticesBytes, m_vertices);
+        glBufferSubData(GL_ARRAY_BUFFER, m_tailleVerticesBytes, m_tailleNormalesBytes, m_normales);
+        glBufferSubData(GL_ARRAY_BUFFER, m_tailleVerticesBytes+m_tailleNormalesBytes, m_tailleCoordTextureBytes, m_coordTexture);
+
+    // Déverrouillage de l'objet
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    /// Chargement Vertex Array Object
+    // Destruction d'un éventuel ancien VAO
+    if(glIsVertexArray(m_vaoID) == GL_TRUE)
+        glDeleteVertexArrays(1, &m_vaoID);
+
+    // Génération de l'ID du VAO
+    glGenVertexArrays(1, &m_vaoID);
+
+    // Verrouillage du VAO
+    glBindVertexArray(m_vaoID);
+
+        // Verrouillage du VBO
+        glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+            // Accès aux vertices dans la mémoire vidéo
+            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
+            glEnableVertexAttribArray(0);
+
+            // Accès aux normales dans la mémoire vidéo
+            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_tailleVerticesBytes));
+            glEnableVertexAttribArray(1);
+
+            // Accès aux coordonnées de texture dans la mémoire vidéo
+            glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_tailleVerticesBytes+m_tailleNormalesBytes));
+            glEnableVertexAttribArray(2);
+
+        // Déverrouillage du VBO
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    // Déverrouillage du VAO
+    glBindVertexArray(0);
+}

+ 16 - 0
arena/3D/OBJ.h

@@ -0,0 +1,16 @@
+#ifndef OBJ_H
+#define OBJ_H
+
+#include "Modele3D.h"
+
+
+class OBJ : public Modele3D
+{
+    public:
+        OBJ();
+        virtual ~OBJ();
+
+        void charger( std::string const src, GLuint samplerID, float vertMulti = 1.0f, float textMulti = 1.0f);
+};
+
+#endif // OBJ_H

File diff suppressed because it is too large
+ 16290 - 0
arena/3DModels/AK47.obj


File diff suppressed because it is too large
+ 34784 - 0
arena/3DModels/MPX.obj


+ 57 - 0
arena/3DModels/bateau.obj

@@ -0,0 +1,57 @@
+v 1.000000 -1.000000 -1.000000
+v 1.000000 -1.000000 1.000000
+v -1.000000 -1.000000 1.000000
+v -1.000000 -1.000000 -1.000000
+v 1.281085 0.933360 -0.904891
+v 0.411205 1.233186 1.250351
+v -0.978612 0.888814 1.772039
+v -1.152217 0.909492 -0.922449
+v -1.000000 1.000000 -2.079143
+v 1.000001 1.000000 -2.079142
+v -0.999999 -1.000000 -2.079143
+v 1.000000 -1.000000 -2.079143
+v 1.000001 2.065500 -2.079142
+v -1.000000 2.065500 -2.079143
+v -1.000000 2.065500 -1.000000
+v 1.000000 2.065500 -0.999999
+vn 0.000000 -1.000000 0.000000
+vn -0.105050 0.991845 -0.072172
+vn 0.978066 0.055589 0.200742
+vn 0.169860 -0.215150 0.961695
+vn -0.998416 -0.042606 0.036734
+vn -0.996887 -0.037438 -0.069385
+vn 0.989785 -0.067698 -0.125466
+vn 0.000000 0.000000 -1.000000
+vn -0.995696 0.065952 -0.065118
+vn 0.985466 0.120879 -0.119350
+vn -0.004353 0.074999 0.997174
+vn 0.000000 1.000000 -0.000000
+vt 0.000 0.000 0.000
+f 1 1 1 2 1 1 3 1 1
+f 1 1 1 3 1 1 4 1 1
+f 5 1 2 8 1 2 7 1 2
+f 5 1 2 7 1 2 6 1 2
+f 1 1 3 5 1 3 6 1 3
+f 1 1 3 6 1 3 2 1 3
+f 2 1 4 6 1 4 7 1 4
+f 2 1 4 7 1 4 3 1 4
+f 3 1 5 7 1 5 8 1 5
+f 3 1 5 8 1 5 4 1 5
+f 4 1 6 8 1 6 9 1 6
+f 4 1 6 9 1 6 11 1 6
+f 5 1 7 1 1 7 12 1 7
+f 5 1 7 12 1 7 10 1 7
+f 1 1 1 4 1 1 11 1 1
+f 1 1 1 11 1 1 12 1 1
+f 10 1 8 12 1 8 11 1 8
+f 10 1 8 11 1 8 9 1 8
+f 9 1 9 8 1 9 15 1 9
+f 9 1 9 15 1 9 14 1 9
+f 10 1 8 9 1 8 14 1 8
+f 10 1 8 14 1 8 13 1 8
+f 5 1 10 10 1 10 13 1 10
+f 5 1 10 13 1 10 16 1 10
+f 8 1 11 5 1 11 16 1 11
+f 8 1 11 16 1 11 15 1 11
+f 15 1 12 16 1 12 13 1 12
+f 15 1 12 13 1 12 14 1 12

+ 60 - 0
arena/3DModels/bazooka.obj

@@ -0,0 +1,60 @@
+v 1.000000 -2.000000 -6.000000
+v 1.000000 -2.000000 6.000000
+v -1.000000 -2.000000 5.999999
+v -1.000000 -2.000000 -6.000002
+v 1.000000 2.000000 -5.999997
+v 0.999999 2.000000 6.000004
+v -1.000000 2.000000 5.999998
+v -1.000000 2.000000 -6.000000
+v -1.000002 2.000000 6.740876
+v 0.999998 2.000000 6.740881
+v -1.000001 -2.000000 6.740876
+v 0.999999 -2.000000 6.740878
+v 0.199999 2.634928 6.740882
+v -0.200001 2.634928 6.740876
+v -0.200001 2.634928 5.999999
+v 0.199999 2.634928 6.000004
+vn 0.000000 -1.000000 0.000000
+vn 0.000000 1.000000 0.000000
+vn 1.000000 0.000000 0.000000
+vn -1.000000 -0.000000 -0.000000
+vn 0.000001 0.000001 -1.000000
+vn -1.000000 -0.000000 -0.000002
+vn 1.000000 0.000000 0.000002
+vn -0.000002 -0.000000 1.000000
+vn 0.621662 0.783285 0.000001
+vn -0.000005 -0.000001 1.000000
+vn -0.621662 0.783285 -0.000000
+vn 0.000005 0.000001 -1.000000
+vn -0.000000 1.000000 0.000001
+vt 0.0 1.0
+vt 1.0 0.0
+vt 0.0 0.0
+f 1 1 1 2 2 1 3 3 1
+f 1 1 1 3 2 1 4 3 1
+f 5 1 2 8 2 2 7 3 2
+f 5 1 2 7 2 2 6 3 2
+f 1 1 3 5 2 3 6 3 3
+f 1 1 3 6 2 3 2 3 3
+f 3 1 4 7 2 4 8 3 4
+f 3 1 4 8 2 4 4 3 4
+f 5 1 5 1 2 5 4 3 5
+f 5 1 5 4 2 5 8 3 5
+f 7 1 6 3 2 6 11 3 6
+f 7 1 6 11 2 6 9 3 6
+f 2 1 7 6 2 7 10 3 7
+f 2 1 7 10 2 7 12 3 7
+f 3 1 1 2 2 1 12 3 1
+f 3 1 1 12 2 1 11 3 1
+f 12 1 8 10 2 8 9 3 8
+f 12 1 8 9 2 8 11 3 8
+f 10 1 9 6 2 9 16 3 9
+f 10 1 9 16 2 9 13 3 9
+f 9 1 10 10 2 10 13 3 10
+f 9 1 10 13 2 10 14 3 10
+f 7 1 11 9 2 11 14 3 11
+f 7 1 11 14 2 11 15 3 11
+f 6 1 12 7 2 12 15 3 12
+f 6 1 12 15 2 12 16 3 12
+f 16 1 13 15 2 13 14 3 13
+f 16 1 13 14 2 13 13 3 13

+ 30 - 0
arena/3DModels/kube.obj

@@ -0,0 +1,30 @@
+v 1.000000 -1.000000 -1.000000
+v 1.000000 -1.000000 1.000000
+v -1.000000 -1.000000 1.000000
+v -1.000000 -1.000000 -1.000000
+v 1.000000 1.000000 -1.000000
+v 1.000000 1.000000 1.000000
+v -1.000000 1.000000 1.000000
+v -1.000000 1.000000 -1.000000
+vt 0.0 0.0
+vt 0.0 1.0
+vt 1.0 0.0
+vt 1.0 1.0
+vn 0.000000 -1.000000 0.000000
+vn 0.000000 1.000000 0.000000
+vn 1.000000 0.000000 0.000000
+vn -0.000000 -0.000000 1.000000
+vn -1.000000 -0.000000 -0.000000
+vn 0.000000 0.000000 -1.000000
+f 1 2 1  2 4 1  3 3 1
+f 1 2 1  3 3 1  4 1 1
+f 5 2 2  8 1 2  7 3 2
+f 5 2 2  7 3 2  6 4 2
+f 1 2 3  5 1 3  6 3 3
+f 1 2 3  6 3 3  2 4 3
+f 2 2 4  6 1 4  7 3 4
+f 2 2 4  7 3 4  3 4 4
+f 3 2 5  7 1 5  8 3 5
+f 3 2 5  8 3 5  4 4 5
+f 5 3 6  1 4 6  4 2 6
+f 5 3 6  4 2 6  8 1 6

+ 11 - 0
arena/3DModels/plan.obj

@@ -0,0 +1,11 @@
+v 1.000000 0.0 -1.000000
+v -1.000000 0.0 -1.000000
+v -1.000000 0.0 1.000000
+v 1.000000 0.0 1.000000
+vt 0.0 0.0
+vt 0.0 1.0
+vt 1.0 0.0
+vt 1.0 1.0
+vn 0.000000 1.000000 0.000000
+f 1 2 1 2 4 1 3 3 1
+f 1 2 1 3 3 1 4 1 1

+ 158 - 0
arena/Caisse.cpp

@@ -0,0 +1,158 @@
+#include "Caisse.h"
+
+// Permet d'éviter la ré-écriture du namespace glm::
+using namespace glm;
+
+// Constructeur et Destructeur
+Caisse::Caisse(float taille, std::string const texture) : Cube(taille),
+m_texture(texture),
+m_tailleCoordTextureBytes(72 * sizeof(float))
+{
+    // Coordonnées de texture temporaires
+
+    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
+
+
+    // Copie des valeurs dans le tableau final
+
+    for(int i (0); i < 72; i++)
+        m_coordTexture[i] = coordTextureTmp[i];
+
+    // Chargement automatique
+    charger();
+}
+
+
+Caisse::~Caisse()
+{
+
+}
+
+
+// Méthodes
+
+void Caisse::charger()
+{
+    // Destruction d'un éventuel ancien VBO
+
+    if(glIsBuffer(m_vboID) == GL_TRUE)
+        glDeleteBuffers(1, &m_vboID);
+
+
+    // Génération de l'ID
+
+    glGenBuffers(1, &m_vboID);
+
+
+    // Verrouillage du VBO
+
+    glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+
+        // Allocation de la mémoire vidéo
+
+        glBufferData(GL_ARRAY_BUFFER, m_tailleVerticesBytes + m_tailleCoordTextureBytes, 0, GL_STATIC_DRAW);
+
+
+        // Transfert des données
+
+        glBufferSubData(GL_ARRAY_BUFFER, 0, m_tailleVerticesBytes, m_vertices);
+        glBufferSubData(GL_ARRAY_BUFFER, m_tailleVerticesBytes, m_tailleCoordTextureBytes, m_coordTexture);
+
+
+    // Déverrouillage de l'objet
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+    // Destruction d'un éventuel ancien VAO
+
+    if(glIsVertexArray(m_vaoID) == GL_TRUE)
+        glDeleteVertexArrays(1, &m_vaoID);
+
+
+    // Génération de l'ID du VAO
+
+    glGenVertexArrays(1, &m_vaoID);
+
+
+    // Verrouillage du VAO
+
+    glBindVertexArray(m_vaoID);
+
+
+        // Verrouillage du VBO
+
+        glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+
+            // Accès aux vertices dans la mémoire vidéo
+
+            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
+            glEnableVertexAttribArray(0);
+
+
+            // Accès aux coordonnées de texture dans la mémoire vidéo
+
+            glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_tailleVerticesBytes));
+            glEnableVertexAttribArray(2);
+
+
+        // Déverrouillage du VBO
+
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+    // Déverrouillage du VAO
+
+    glBindVertexArray(0);
+}
+
+
+void Caisse::afficher(glm::mat4 pmv, Shader const &shad)
+{
+    // Verrouillage du VAO
+
+    glBindVertexArray(m_vaoID);
+
+
+        // Envoi des matrices
+
+        glUniformMatrix4fv(glGetUniformLocation(shad.getProgramID(), "pmv"), 1, GL_FALSE, glm::value_ptr(pmv));
+
+
+        // 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éverrouillage du VAO
+
+    glBindVertexArray(0);
+}

+ 32 - 0
arena/Caisse.h

@@ -0,0 +1,32 @@
+#ifndef DEF_CAISSE
+#define DEF_CAISSE
+
+
+// Includes
+
+#include "Cube.h"
+#include "Texture.h"
+#include <string>
+
+
+// Classe Caisse
+
+class Caisse : public Cube
+{
+    public:
+
+    Caisse(float taille, std::string const texture);
+    ~Caisse();
+
+    void charger();
+    void afficher(glm::mat4 pmv, Shader const &shad);
+
+
+    private:
+
+    Texture m_texture;
+    float m_coordTexture[72];
+    int m_tailleCoordTextureBytes;
+};
+
+#endif

+ 197 - 0
arena/Camera.cpp

@@ -0,0 +1,197 @@
+#include "Camera.h"
+
+
+// Permet d'éviter la ré-écriture du namespace glm::
+using namespace glm;
+
+
+// Constructeurs
+Camera::Camera()
+: m_phi(0.0), m_theta(0.0), m_orientation(), m_axeVertical(0, 0, 1), m_deplacementLateral(), m_deplacementLineaire(),
+m_position(), m_pointCible(), m_sensibilite(0.0), m_vitesse(0.0), m_vol(false)
+{
+
+}
+
+
+Camera::Camera(glm::vec3 position, glm::vec3 pointCible, glm::vec3 axeVertical, float sensibilite, float vitesse)
+: m_phi(0.0), m_theta(0.0), m_orientation(),
+m_axeVertical(axeVertical), m_deplacementLateral(), m_deplacementLineaire(),
+m_position(position), m_pointCible(pointCible),
+m_sensibilite(sensibilite), m_vitesse(vitesse), m_vol(false)
+{
+    // Actualisation du point ciblé
+    setPointcible(pointCible);
+}
+
+// Destructeur
+Camera::~Camera()
+{}
+
+
+// Méthodes
+void Camera::orienter(float xRel, float yRel)
+{
+    // Récupération des angles
+    m_phi -= yRel * m_sensibilite;
+    m_theta -= xRel * m_sensibilite;
+
+    // Limitation de l'angle phi
+    if(m_phi > 89.0)
+        m_phi = 89.0;
+    else if(m_phi < -89.0)
+        m_phi = -89.0;
+
+    // Conversion des angles en radian
+    float phiRadian = m_phi * M_PI / 180;
+    float thetaRadian = m_theta * M_PI / 180;
+
+    // Calcul des coordonnées sphériques
+    m_orientation.x = cos(phiRadian) * sin(thetaRadian);
+    m_orientation.y = sin(phiRadian);
+    m_orientation.z = cos(phiRadian) * cos(thetaRadian);
+
+    // Calcul de la normale
+    m_deplacementLateral = normalize(cross(m_axeVertical, m_orientation));
+
+    // Calcul vecteur pour avancer
+    m_deplacementLineaire = normalize(cross(m_deplacementLateral, m_axeVertical));
+
+    // Calcul du point ciblé pour OpenGL
+    m_pointCible = m_position + m_orientation;
+}
+
+
+void Camera::deplacer(Input const &input)
+{
+    // Gestion de l'orientation
+    if (input.getMainXRel()!=0 || input.getMainYRel()!=0)
+        orienter(input.getMainXRel(), input.getMainYRel());
+
+    // Avancée de la caméra
+    if (m_vol)
+        m_position = m_position - m_orientation * (m_vitesse * input.getMainXMove());
+    else
+        m_position = m_position - m_deplacementLineaire * (m_vitesse * input.getMainXMove());
+
+    // Déplacement lateral
+    m_position = m_position - m_deplacementLateral * (m_vitesse * input.getMainYMove());
+
+    // Calcul du point ciblé pour OpenGL
+    m_pointCible = m_position + m_orientation;
+}
+
+
+void Camera::lookAt(glm::mat4 &modelview)
+{
+    // Actualisation de la vue dans la matrice
+    modelview = glm::lookAt(m_position, m_pointCible, m_axeVertical);
+}
+
+
+// Getters et Setters
+
+void Camera::setPointcible(glm::vec3 pointCible)
+{
+    // Calcul du vecteur orientation
+    m_orientation = m_pointCible - m_position;
+    m_orientation = normalize(m_orientation);
+
+    // Si l'axe vertical est l'axe X
+    if(m_axeVertical.x == 1.0)
+    {
+        // Calcul des angles
+        m_phi = asin(m_orientation.x);
+        m_theta = acos(m_orientation.y / cos(m_phi));
+        if(m_orientation.y < 0)
+            m_theta *= -1;
+    }
+
+    // Si c'est l'axe Y
+    else if(m_axeVertical.y == 1.0)
+    {
+        // Calcul des angles
+        m_phi = asin(m_orientation.y);
+        m_theta = acos(m_orientation.z / cos(m_phi));
+        if(m_orientation.z < 0)
+            m_theta *= -1;
+    }
+
+    // Sinon c'est l'axe Z
+    else
+    {
+        // Calcul des angles
+        m_phi = asin(m_orientation.x);
+        m_theta = acos(m_orientation.z / cos(m_phi));
+
+        if(m_orientation.z < 0)
+            m_theta *= -1;
+    }
+
+    // Conversion en degrés
+    m_phi = m_phi * 180 / M_PI;
+    m_theta = m_theta * 180 / M_PI;
+}
+
+
+void Camera::setPosition(glm::vec3 position)
+{
+    // Mise à jour de la position
+    m_position = position;
+
+    // Actualisation du point ciblé
+    m_pointCible = m_position + m_orientation;
+}
+
+
+void Camera::setSensibilite(float sensibilite)
+{
+    m_sensibilite = sensibilite;
+}
+
+
+void Camera::setVitesse(float vitesse)
+{
+    m_vitesse = vitesse;
+}
+
+void Camera::setVol(bool activation)
+{
+    m_vol = activation;
+}
+
+float Camera::getSensibilite() const
+{
+    return m_sensibilite;
+}
+
+
+float Camera::getVitesse() const
+{
+    return m_vitesse;
+}
+
+glm::vec3 Camera::getPos() const
+{
+    return m_position;
+}
+
+glm::vec3 Camera::getDirect() const
+{
+    return m_pointCible - m_position;
+}
+
+float Camera::getTheta() const
+{
+    return m_theta;
+}
+
+float Camera::getPhi() const
+{
+    return m_phi;
+}
+
+glm::vec3 Camera::getNormale() const
+{
+    return m_deplacementLateral;
+}

+ 69 - 0
arena/Camera.h

@@ -0,0 +1,69 @@
+#ifndef DEF_CAMERA
+#define DEF_CAMERA
+
+
+///Jovian
+///Adaptation pour InputAndJoy
+///Dernière modif : plaqué au sol (m_linear)
+
+// Includes GLM
+#include <glm/glm.hpp>
+#include <glm/gtx/transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+
+// Autres includes
+#include "Input.h"
+
+
+// Classe
+class Camera
+{
+    public:
+
+    Camera();
+    Camera(glm::vec3 position, glm::vec3 pointCible, glm::vec3 axeVertical, float sensibilite, float vitesse);
+    ~Camera();
+
+    void orienter(float xRel, float yRel);
+    void deplacer(Input const &input);
+    void lookAt(glm::mat4 &modelview);
+
+    void setPointcible(glm::vec3 pointCible);
+    void setPosition(glm::vec3 position);
+
+    void setSensibilite(float sensibilite);
+    void setVitesse(float vitesse);
+
+    void setVol(bool activation);
+
+    float getSensibilite() const;
+    float getVitesse() const;
+
+    glm::vec3 getPos() const;
+    glm::vec3 getDirect() const;
+    float getTheta() const;
+    float getPhi() const;
+
+    glm::vec3 getNormale() const;
+
+
+    private:
+
+    float m_phi;
+    float m_theta;
+    glm::vec3 m_orientation;
+
+    glm::vec3 m_axeVertical;
+    glm::vec3 m_deplacementLateral;
+    glm::vec3 m_deplacementLineaire;
+
+    glm::vec3 m_position;
+    glm::vec3 m_pointCible;
+
+    float m_sensibilite;
+    float m_vitesse;
+    bool m_vol;
+};
+
+#endif

+ 224 - 0
arena/Cube.cpp

@@ -0,0 +1,224 @@
+#include "Cube.h"
+
+
+// Permet d'éviter la ré-écriture du namespace glm::
+
+using namespace glm;
+
+
+// Constructeur et Destructeur
+
+Cube::Cube(float taille) :m_vboID(0),
+                                                                                             m_tailleVerticesBytes(108 * sizeof(float)),
+                                                                                             m_tailleCouleursBytes(108 * sizeof(float)), m_vaoID(0)
+{
+    // 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()
+{
+    // Destruction du VBO
+
+    glDeleteBuffers(1, &m_vboID);
+
+
+    // Destruction du VAO
+
+    glDeleteVertexArrays(1, &m_vaoID);
+}
+
+
+// Méthodes
+
+void Cube::charger()
+{
+    // Destruction d'un éventuel ancien VBO
+
+    if(glIsBuffer(m_vboID) == GL_TRUE)
+        glDeleteBuffers(1, &m_vboID);
+
+
+    // Génération de l'ID
+
+    glGenBuffers(1, &m_vboID);
+
+
+    // Verrouillage du VBO
+
+    glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+
+        // Allocation de la mémoire vidéo
+
+        glBufferData(GL_ARRAY_BUFFER, m_tailleVerticesBytes + m_tailleCouleursBytes, 0, GL_STATIC_DRAW);
+
+
+        // Transfert des données
+
+        glBufferSubData(GL_ARRAY_BUFFER, 0, m_tailleVerticesBytes, m_vertices);
+        glBufferSubData(GL_ARRAY_BUFFER, m_tailleVerticesBytes, m_tailleCouleursBytes, m_couleurs);
+
+
+    // Déverrouillage de l'objet
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+    // Destruction d'un éventuel ancien VAO
+
+    if(glIsVertexArray(m_vaoID) == GL_TRUE)
+        glDeleteVertexArrays(1, &m_vaoID);
+
+
+    // Génération de l'identifiant du VAO
+
+    glGenVertexArrays(1, &m_vaoID);
+
+
+    // Verrouillage du VAO
+
+    glBindVertexArray(m_vaoID);
+
+
+        // Verrouillage du VBO
+
+        glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+
+            // Accès aux vertices dans la mémoire vidéo
+
+            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
+            glEnableVertexAttribArray(0);
+
+
+            // Accès aux couleurs dans la mémoire vidéo
+
+            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_tailleVerticesBytes));
+            glEnableVertexAttribArray(1);
+
+
+        // Déverrouillage du VBO
+
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+    // Déverrouillage du VAO
+
+    glBindVertexArray(0);
+}
+
+
+void Cube::afficher(glm::mat4 &projection, glm::mat4 &modelview)
+{
+    // Verrouillage du VAO
+
+    glBindVertexArray(m_vaoID);
+
+
+        // Envoi des matrices
+
+
+
+        // Rendu
+
+        glDrawArrays(GL_TRIANGLES, 0, 36);
+
+
+    // Déverrouillage du VAO
+
+    glBindVertexArray(0);
+}
+
+
+void Cube::updateVBO(void *donnees, int tailleBytes, int decalage)
+{
+    // Verrouillage du VBO
+
+    glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+
+        // Récupération de l'adresse du VBO
+
+        void *adresseVBO = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+
+        // Si l'adresse retournée est nulle alors on arrête le transfert
+
+        if(adresseVBO == NULL)
+        {
+            std::cout << "Erreur au niveau de la récupération du VBO" << std::endl;
+            glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+            return;
+        }
+
+
+        // Mise à jour des données
+
+        memcpy((char*)adresseVBO + decalage, donnees, tailleBytes);
+
+
+        // Annulation du pointeur
+
+        glUnmapBuffer(GL_ARRAY_BUFFER);
+        adresseVBO = 0;
+
+
+    // Déverrouillage du VBO
+
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+}

+ 65 - 0
arena/Cube.h

@@ -0,0 +1,65 @@
+#ifndef DEF_CUBE
+#define DEF_CUBE
+
+
+// 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 GLM
+
+#include <glm/glm.hpp>
+#include <glm/gtx/transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+
+// Includes
+#include "macro.h"
+#include "Shader.h"
+
+
+
+// Classe Cube
+
+class Cube
+{
+    public:
+
+    Cube(float taille);
+    ~Cube();
+
+    void charger();
+    void afficher(glm::mat4 &projection, glm::mat4 &modelview);
+    void updateVBO(void *donnees, int tailleBytes, int decalage);
+
+
+    protected:
+
+    float m_vertices[108];
+    float m_couleurs[108];
+
+    GLuint m_vboID;
+    int m_tailleVerticesBytes;
+    int m_tailleCouleursBytes;
+    GLuint m_vaoID;
+};
+
+#endif

+ 125 - 0
arena/FrameBuffer.cpp

@@ -0,0 +1,125 @@
+#include "FrameBuffer.h"
+
+// Constructeurs et Destructeur
+FrameBuffer::FrameBuffer() : m_id(0), m_largeur(0), m_hauteur(0), m_colorBuffers(0), m_depthBufferID(0), m_stencil(false)
+{}
+
+FrameBuffer::FrameBuffer(int largeur, int hauteur, bool stencil)
+: m_id(0), m_largeur(largeur), m_hauteur(hauteur), m_colorBuffers(0), m_depthBufferID(0), m_stencil(stencil)
+{}
+
+
+FrameBuffer::FrameBuffer(const FrameBuffer &frameBufferACopier)
+{
+    // Copie de la largeur, de la hauteur et du booléen
+    m_largeur = frameBufferACopier.m_largeur;
+    m_hauteur = frameBufferACopier.m_hauteur;
+    m_stencil = frameBufferACopier.m_stencil;
+
+    // Chargement de la copie du Frame Buffer
+    charger();
+}
+
+FrameBuffer::~FrameBuffer()
+{
+    // Destruction des buffers
+    glDeleteFramebuffers(1, &m_id);
+    glDeleteRenderbuffers(1, &m_depthBufferID);
+}
+
+// Méthodes
+bool FrameBuffer::charger()
+{
+    // Vérification d'un éventuel ancien FBO
+    if(glIsFramebuffer(m_id) == GL_TRUE)
+    {
+        // Destruction du Frame Buffer
+        glDeleteFramebuffers(1, &m_id);
+    }
+
+    // Génération d'un id
+    glGenFramebuffers(1, &m_id);
+
+    // Verrouillage du Frame Buffer
+    glBindFramebuffer(GL_FRAMEBUFFER, m_id);
+
+        // Création du Color Buffer
+        Texture* colorBuffer(new Texture(m_largeur, m_hauteur));
+        colorBuffer->create();
+
+        // Ajout au tableau
+        m_colorBuffers.push_back(colorBuffer);
+
+        // Création du Depth Buffer et du Stencil Buffer (si besoin)
+        if(m_stencil == true)
+            creerRenderBuffer(m_depthBufferID, GL_DEPTH24_STENCIL8);
+        else
+            creerRenderBuffer(m_depthBufferID, GL_DEPTH_COMPONENT24);
+
+        // Association du Color Buffer
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffers[0]->getID(), 0);
+
+        // Création du Depth Buffer et du Stencil Buffer (si besoin)
+        if(m_stencil == true)
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthBufferID);
+        else
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBufferID);
+
+        // Vérification de l'intégrité du FBO
+        if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+        {
+            // Libération des buffers
+            glDeleteFramebuffers(1, &m_id);
+            glDeleteRenderbuffers(1, &m_depthBufferID);
+
+            // Affichage d'un message d'erreur et retour de la valeur false
+            std::cout << "Erreur : le FBO est mal construit" << std::endl;
+            return false;
+        }
+
+    // Déverrouillage du Frame Buffer
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    // Si tout s'est bien passé, on renvoie la valeur true
+    return true;
+}
+
+void FrameBuffer::creerRenderBuffer(GLuint &id, GLenum formatInterne)
+{
+    // Destruction d'un éventuel ancien Render Buffer
+    if(glIsRenderbuffer(id) == GL_TRUE)
+        glDeleteRenderbuffers(1, &id);
+
+    // Génération de l'identifiant
+    glGenRenderbuffers(1, &id);
+
+    // Verrouillage
+    glBindRenderbuffer(GL_RENDERBUFFER, id);
+
+        // Configuration du Render Buffer
+        glRenderbufferStorage(GL_RENDERBUFFER, formatInterne, m_largeur, m_hauteur);
+
+    // Déverrouillage
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+}
+
+// Getters
+GLuint FrameBuffer::getID() const
+{
+    return m_id;
+}
+
+Texture* FrameBuffer::getColorBuffer(unsigned int index)
+{
+    return m_colorBuffers[index];
+}
+
+int FrameBuffer::getLargeur() const
+{
+    return m_largeur;
+}
+
+int FrameBuffer::getHauteur() const
+{
+    return m_hauteur;
+}

+ 55 - 0
arena/FrameBuffer.h

@@ -0,0 +1,55 @@
+#ifndef DEF_FRAMEBUFFER
+#define DEF_FRAMEBUFFER
+
+// 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 <vector>
+#include "Texture.h"
+
+// Classe
+class FrameBuffer
+{
+    public:
+
+    FrameBuffer();
+    FrameBuffer(int largeur, int hauteur, bool stencil = false);
+    FrameBuffer(const FrameBuffer &frameBufferACopier);
+    ~FrameBuffer();
+
+    bool charger();
+    void creerRenderBuffer(GLuint &id, GLenum formatInterne);
+
+    GLuint getID() const;
+    Texture* getColorBuffer(unsigned int index);
+
+    int getLargeur() const;
+    int getHauteur() const;
+
+
+    private:
+
+    GLuint m_id;
+
+    int m_largeur;
+    int m_hauteur;
+
+    std::vector<Texture*> m_colorBuffers;
+    GLuint m_depthBufferID;
+    bool m_stencil;
+};
+
+#endif

+ 224 - 0
arena/Input.cpp

@@ -0,0 +1,224 @@
+#include "Input.h"
+
+
+// Constructeur et Destructeur
+Input::Input()
+: m_x(0), m_y(0), m_xRel(0), m_yRel(0),
+m_avancer(SDL_SCANCODE_UP), m_reculer(SDL_SCANCODE_DOWN), m_droite(SDL_SCANCODE_RIGHT), m_gauche(SDL_SCANCODE_LEFT),
+m_terminer(false), m_relativeMouse(false), m_window(0), m_windowHalfHeight(0), m_windowHalfWidth(0)
+{
+    // 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:
+                if (m_relativeMouse)
+                {
+                    m_xRel = m_evenements.motion.x-m_windowHalfWidth;
+                    m_yRel = m_evenements.motion.y-m_windowHalfHeight;
+                }
+                else
+                {
+                    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;
+        }
+    }
+
+    // Pour éviter que la souris se barre en mode relative, on la "warp"
+    if (m_relativeMouse)
+         SDL_WarpMouseInWindow(m_window,m_windowHalfWidth,m_windowHalfHeight);
+}
+
+
+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)
+{
+    m_relativeMouse = reponse;
+}
+
+
+
+// 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;
+}
+
+void Input::setWindow(SDL_Window* activWindow)
+{
+    // Attributio directe
+    m_window = activWindow;
+
+    // Détermination de l'endroit de capture du pointeur
+    SDL_GetWindowSize(activWindow, &m_windowHalfWidth, &m_windowHalfHeight);
+    m_windowHalfWidth /= 2;
+    m_windowHalfHeight /=2;
+}
+
+void Input::setMoveKeys(SDL_Scancode avancer, SDL_Scancode reculer, SDL_Scancode droite, SDL_Scancode gauche)
+{
+    m_avancer = avancer;
+    m_reculer = reculer;
+    m_droite = droite;
+    m_gauche = gauche;
+}
+
+float Input::getMainXRel() const
+{
+    return (float) m_xRel;
+}
+
+float Input::getMainYRel() const
+{
+    return (float) m_yRel;
+}
+
+float Input::getMainXMove() const
+{
+    // Avancée de la caméra
+    if(getTouche(m_avancer))
+    {
+        return -1.0;
+    }
+
+    // Recul de la caméra
+    if(getTouche(m_reculer))
+    {
+        return 1.0;
+    }
+
+    // Caméra immobile
+    return 0.0;
+}
+
+float Input::getMainYMove() const
+{
+    // Déplacement vers la gauche
+    if(getTouche(m_gauche))
+    {
+        return -1.0;
+    }
+
+    // Déplacement vers la droite
+    if(getTouche(m_droite))
+    {
+        return 1.0;
+    }
+
+    // Caméra immobile
+    return 0.0;
+}

+ 68 - 0
arena/Input.h

@@ -0,0 +1,68 @@
+#ifndef DEF_INPUT
+#define DEF_INPUT
+
+///Jovian
+///Adaptation pour InputAndJoy
+
+// Include
+#include <SDL2/SDL.h>
+
+
+// Classe
+class Input
+{
+    public:
+
+    Input();
+    ~Input();
+
+    virtual void updateEvenements();
+    bool terminer() const;
+    void afficherPointeur(bool reponse) const;
+    void capturerPointeur(bool reponse);
+
+    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;
+
+    void setWindow(SDL_Window* activWindow);
+    void setMoveKeys(SDL_Scancode avancer, SDL_Scancode reculer, SDL_Scancode droite, SDL_Scancode gauche);
+
+    virtual float getMainXRel() const;
+    virtual float getMainYRel() const;
+    virtual float getMainXMove() const;
+    virtual float getMainYMove() const;
+
+
+    protected:
+
+    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;
+
+    SDL_Scancode m_avancer;
+    SDL_Scancode m_reculer;
+    SDL_Scancode m_droite;
+    SDL_Scancode m_gauche;
+
+    bool m_terminer;
+    bool m_relativeMouse;
+
+    SDL_Window* m_window;
+    int m_windowHalfHeight;
+    int m_windowHalfWidth;
+};
+
+#endif
+

+ 194 - 0
arena/InputAndJoy.cpp

@@ -0,0 +1,194 @@
+#include "InputAndJoy.h"
+
+InputAndJoy::InputAndJoy()
+: m_manette(0), m_nbAxes(0), m_nbBoutons(0), m_controleurType(0), m_seuil(3600), m_plage(32767 - m_seuil)
+{
+    // Démarrage du joystick
+    if (SDL_InitSubSystem(SDL_INIT_JOYSTICK)<0)
+    {
+        std::cout << "Problème lors de l'initialisation du matériel pour les manettes : "<<SDL_GetError()<< std::endl;
+    }
+    else
+    {
+        // Ouverture du joystick
+        SDL_JoystickEventState(SDL_ENABLE);
+        m_manette = SDL_JoystickOpen(0);
+        if (m_manette == NULL)
+        {
+            std::cout << "Manette non démarrée : " << SDL_GetError() << std::endl;
+            setMainControleur(CLAVIER_SOURIS);
+        }
+        else
+        {
+            setMainControleur(MANETTE);
+            // Détermination de la valeur des attributs
+            m_nbAxes = SDL_JoystickNumAxes(m_manette);
+            m_nbBoutons = SDL_JoystickNumButtons(m_manette);
+            for (int i(0); i<m_nbAxes; i++)
+                m_axeValue.push_back(0);
+            for (int i(0); i<m_nbBoutons; i++)
+                m_boutonValue.push_back(false);
+        }
+    }
+}
+
+InputAndJoy::~InputAndJoy()
+{
+    //SDL_JoystickClose(m_manette);
+}
+
+void InputAndJoy::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)
+        {
+        /// Evenements clavier et souris
+            // 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:
+                if (m_relativeMouse)
+                {
+                    m_xRel = m_evenements.motion.x-m_windowHalfWidth;
+                    m_yRel = m_evenements.motion.y-m_windowHalfHeight;
+                }
+                else
+                {
+                    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;
+
+        /// Evenements joystick
+            case SDL_JOYAXISMOTION:
+                if (m_evenements.jaxis.value > m_seuil)
+                    m_axeValue[m_evenements.jaxis.axis] = (int)(m_evenements.jaxis.value - m_seuil)*32767/m_plage;
+                else if (m_evenements.jaxis.value < -m_seuil)
+                    m_axeValue[m_evenements.jaxis.axis] = (int)(m_evenements.jaxis.value + m_seuil)*32767/m_plage;
+                else
+                    m_axeValue[m_evenements.jaxis.axis] = 0;
+                break;
+            case SDL_JOYBUTTONDOWN:
+                m_boutonValue[m_evenements.jbutton.button] = true;
+                break;
+            case SDL_JOYBUTTONUP:
+                m_boutonValue[m_evenements.jbutton.button] = false;
+                break;
+
+            default:
+            break;
+        }
+    }
+
+    // Pour éviter que la souris se barre en mode relative, on la "warp"
+    if (m_relativeMouse)
+         SDL_WarpMouseInWindow(m_window,m_windowHalfWidth,m_windowHalfHeight);
+}
+
+int InputAndJoy::getAxeValue(const Uint8 axeID) const
+{
+    if ( m_manette == NULL ) return 0;
+
+    if (axeID<m_nbAxes)
+        return m_axeValue[axeID];
+    else
+        std::cout << "Axe numéro "<<axeID<<" non-éxistant." << std::endl;
+    return -1;
+}
+
+bool InputAndJoy::getBoutonPad(const Uint8 bouton) const
+{
+    if ( m_manette == NULL ) return false;
+
+    if (bouton<m_nbBoutons)
+        return m_boutonValue[bouton];
+    else
+        std::cout << "Bouton numéro "<<bouton<<" non-éxistant." << std::endl;
+    return false;
+}
+
+void InputAndJoy::setMainControleur(int type)
+{
+    if (type == CLAVIER_SOURIS || type == MANETTE)
+        if (m_manette!=0 || type!=MANETTE)
+            m_controleurType = type;
+}
+
+float InputAndJoy::getMainXRel() const
+{
+    // Clavier
+    if (m_controleurType == CLAVIER_SOURIS)
+        return Input::getMainXRel();
+    // Manette
+        return (float)m_axeValue[3]/3000.0f;
+
+}
+
+float InputAndJoy::getMainYRel() const
+{
+
+    // Clavier
+    if (m_controleurType == CLAVIER_SOURIS)
+        return Input::getMainYRel();
+    // Manette
+        return (float)m_axeValue[4]/3000.0f;
+
+}
+
+float InputAndJoy::getMainXMove() const
+{
+
+    // Clavier
+    if (m_controleurType == CLAVIER_SOURIS)
+        return Input::getMainXMove();
+    // Manette
+        return (float)m_axeValue[1]/30000.0f;
+
+}
+
+float InputAndJoy::getMainYMove() const
+{
+
+    // Clavier
+    if (m_controleurType == CLAVIER_SOURIS)
+        return Input::getMainYMove();
+    // Manette
+        return (float)m_axeValue[0]/30000.0f;
+
+}
+
+

+ 52 - 0
arena/InputAndJoy.h

@@ -0,0 +1,52 @@
+#ifndef INPUTANDJOY_H_INCLUDED
+#define INPUTANDJOY_H_INCLUDED
+
+
+///Jovian
+///Mise à jour pour utiliser les boutons du joypad
+
+// Include
+#include <SDL2/SDL.h>
+#include <iostream>
+#include <vector>
+#include "Input.h"
+
+//Enum
+#define CLAVIER_SOURIS 1
+#define MANETTE 2
+
+// Classe
+class InputAndJoy : public Input
+{
+    public:
+
+    InputAndJoy();
+    ~InputAndJoy();
+
+    virtual void updateEvenements();
+
+    int getAxeValue(const Uint8 axeID) const;
+    bool getBoutonPad(const Uint8 bouton) const;
+
+    void setMainControleur(int type);
+
+    virtual float getMainXRel() const;
+    virtual float getMainYRel() const;
+    virtual float getMainXMove() const;
+    virtual float getMainYMove() const;
+
+
+    private:
+
+    SDL_Joystick* m_manette;
+    int m_nbAxes;
+    int m_nbBoutons;
+    int m_controleurType;
+    int const m_seuil;
+    int const m_plage; // Plage de données de l'axe réduite à cause du seuil ( imprécision )
+
+    std::vector<int> m_axeValue;
+    std::vector<bool> m_boutonValue;
+};
+
+#endif // INPUTANDJOY_H_INCLUDED

+ 399 - 0
arena/SceneOpenGL.cpp

@@ -0,0 +1,399 @@
+#include "SceneOpenGL.h"
+
+// Permet d'éviter la ré-écriture du namespace glm::
+using namespace glm;
+
+// Constructeur de Destucteur
+SceneOpenGL::SceneOpenGL(std::string titreFenetre, int largeurFenetre, int hauteurFenetre)
+: m_titreFenetre(titreFenetre), m_largeurFenetre(largeurFenetre),
+m_hauteurFenetre(hauteurFenetre), m_fenetre(0), m_contexteOpenGL(0),
+m_input(), m_texturLoader( "Textures/" ),
+m_shader( "Shaders/texture.vert", "Shaders/texture.frag" ),
+m_shLight( "Shaders/light.vert", "Shaders/light.frag" ),
+m_shGris( "Shaders/texture.vert", "Shaders/gris.frag" )
+{
+
+}
+
+SceneOpenGL::~SceneOpenGL()
+{
+    SDL_GL_DeleteContext(m_contexteOpenGL);
+    SDL_DestroyWindow(m_fenetre);
+    SDL_Quit();
+}
+
+// Méthodes
+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;
+    }
+
+    #ifdef __APPLE__
+        // Version d'OpenGL
+        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+
+        // Récupération du Bundle
+        CFURLRef URLBundle = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
+        char *cheminResources = new char[PATH_MAX];
+
+        // Changement du 'Working Directory'
+        if(CFURLGetFileSystemRepresentation(URLBundle, 1, (UInt8*)cheminResources, PATH_MAX))
+            chdir(cheminResources);
+
+        // Libération de la mémoire
+        delete[] cheminResources;
+        CFRelease(URLBundle);
+
+    #else
+        // Version d'OpenGL
+        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
+        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+
+    #endif
+
+    // Création de la fenêtre
+    uint32_t flag( SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL );
+    m_fenetre = SDL_CreateWindow(m_titreFenetre.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_largeurFenetre, m_hauteurFenetre, flag);
+    if(m_fenetre == 0)
+    {
+        std::cout << "Erreur lors de la creation de la fenetre : " << SDL_GetError() << std::endl;
+        SDL_Quit();
+
+        return false;
+    }
+
+    // Paramètres des évènements
+    m_input.setWindow( m_fenetre );
+    m_input.capturerPointeur( true );
+    m_input.setMoveKeys( SDL_SCANCODE_W, SDL_SCANCODE_S, SDL_SCANCODE_D, SDL_SCANCODE_A );
+
+    // 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()
+{
+    #ifdef WIN32
+        // On initialise GLEW
+        GLenum initialisationGLEW( glewInit() );
+
+        // Si l'initialisation a échoué :
+        if(initialisationGLEW != GLEW_OK)
+        {
+            // On affiche l'erreur grâce à la fonction : glewGetErrorString(GLenum code)
+            std::cout << "Erreur d'initialisation de GLEW : " << glewGetErrorString(initialisationGLEW) << std::endl;
+
+            // On quitte la SDL
+            SDL_GL_DeleteContext(m_contexteOpenGL);
+            SDL_DestroyWindow(m_fenetre);
+            SDL_Quit();
+
+            return false;
+        }
+    #endif
+
+    // Paramètres OpenGL avancés
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_CULL_FACE);
+
+    // Tout s'est bien passé, on retourne true
+    return true;
+}
+
+
+void SceneOpenGL::bouclePrincipale()
+{
+    // Variables temps
+    unsigned int frameRate (1000 / 50);
+    Uint32 debutBoucle(0), finBoucle(0), tempsEcoule(0);
+
+    // Frame Buffer
+    FrameBuffer frameBuffer(512, 512);
+    frameBuffer.charger();
+    m_texturLoader.addTextur("FBO_Tele", frameBuffer.getColorBuffer(0));
+
+    // Shaders
+    m_shader.charger();
+    m_shLight.charger();
+    m_shGris.charger();
+    Shader* shTarget(0x0);
+
+    // Matrices (première passe)
+    mat4 projectionFBO;
+
+    projectionFBO = perspective(70.0, (double)frameBuffer.getLargeur() / frameBuffer.getHauteur(), 1.0, 100.0);
+
+    // Matrices (seconde passe)
+    mat4 projection, projection30, projection70, plat;
+    mat4 view, unicite(1.0);
+
+    const float format( (float) m_largeurFenetre / m_hauteurFenetre );
+    projection70 = perspective(70.0, (double)format, 0.1, 100.0);
+    projection30 = perspective(30.0, (double)format, 0.1, 100.0);
+    const float plat_extY( 30.0 );
+    const float plat_extX( plat_extY * format );
+    plat = ortho(-plat_extX, plat_extX, -plat_extY, plat_extY, 0.1f, 100.0f);
+
+    // Vecteurs
+    uint16_t nbLight(3);
+    vec3 posLight[nbLight];
+    posLight[0] = vec3( 10.0, 3.0, 0.0 );
+    posLight[2] = vec3( 30.0, 3.5, 0.0 );
+    float posLightV[nbLight*3];
+
+    // Caméra mobile
+    Camera camera(vec3(0, 1.78, 0), vec3(0, 1.78, -1), vec3(0, 1, 0), 0.5, 0.5);
+    vec3 eyePos;
+    m_input.afficherPointeur(false);
+    m_input.capturerPointeur(true);
+
+    // Objet Caisse
+    OBJ metal;
+    metal.charger("3DModels/kube.obj", m_texturLoader.take("caisse_basic"));
+    mat4 model_metal(1.0);
+
+    OBJ plan;
+    plan.charger( "3DModels/plan.obj", m_texturLoader.take("pierres"), 50.0, 20.0);
+    mat4 model_plan(1.0);
+    model_plan = translate(model_plan, vec3(2.5,0.0,0.0));
+
+    OBJ tele;
+    tele.charger( "3DModels/plan.obj", m_texturLoader.take("FBO_Tele"), 2.5 );
+    mat4 model_tele(1.0);
+    model_tele = translate( model_tele, vec3(16.56,3.2,-0.5) );
+    model_tele = rotate(model_tele, 90.0f, vec3(0, 0, 1));
+
+    OBJ caisse;
+    caisse.charger("3DModels/kube.obj", m_texturLoader.take("chantier"));
+    mat4 model_caisseA(1.0),model_caisseB(1.0),model_caisseC(1.0);
+    model_caisseA = translate( model_caisseA, vec3(-6.56,1.0,-0.5) );
+    model_caisseB = translate( model_caisseB, vec3(6.56,1.0,4.5) );
+    model_caisseC = translate( model_caisseC, vec3(3.5,1.0,3.5) );
+
+    OBJ weapon;
+    weapon.charger( "3DModels/MPX.obj", m_texturLoader.take("chantier"), 0.2 );
+    mat4 model_weapon(1.0);
+
+    Mosaic sword;
+    sword.charger( "2DModels/sword_iron.bmp" );
+    mat4 model_sword(1.0);
+
+    float angle = 0.0;
+    float theta, theta_old = 0.0;
+    float phi, phi_old = 0.0;
+
+    bool rangee(true), rangement(false), veutRanger(false);
+    bool veutViser(false);
+    bool veutTemporiser(false);
+    bool veutLight(false), lightDone(false), lightState(false);
+    bool veutOverLight(false), overLightDone(false); GLint overLightState(false);
+
+    // Boucle principale
+    while(!m_input.terminer())
+    {
+        // On définit le temps de début de boucle
+        debutBoucle = SDL_GetTicks();
+
+        // Gestion des évènements
+        m_input.updateEvenements();
+
+        camera.setVol( m_input.getTouche( SDL_SCANCODE_LSHIFT ) );
+
+        if (m_input.getTouche(SDL_SCANCODE_ESCAPE))
+            break;
+
+        if (m_input.getTouche(SDL_SCANCODE_KP_3)) nbLight = 3;
+        if (m_input.getTouche(SDL_SCANCODE_KP_2)) nbLight = 2;
+        if (m_input.getTouche(SDL_SCANCODE_KP_1)) nbLight = 1;
+        if (m_input.getTouche(SDL_SCANCODE_KP_0)) nbLight = 0;
+
+        camera.deplacer(m_input);
+
+        veutRanger = m_input.getTouche(SDL_SCANCODE_E) || m_input.getBoutonPad(1);
+        if ( !rangement && veutRanger ) {
+            rangement = true;
+            rangee = !rangee;
+            if ( rangee ) camera.setVitesse(0.5f);
+            else camera.setVitesse(0.2f);
+        }
+        else if ( !veutRanger ) rangement = false;
+
+        veutTemporiser = m_input.getTouche( SDL_SCANCODE_SPACE ) || m_input.getBoutonPad(2);
+
+        veutViser = m_input.getBoutonSouris(3) || m_input.getBoutonPad(4);
+
+        veutLight = m_input.getTouche( SDL_SCANCODE_LCTRL ) || m_input.getBoutonPad(3);
+        if ( !lightDone && veutLight ) {
+            lightDone = true;
+            lightState = !lightState;
+        }
+        else if ( !veutLight ) lightDone = false;
+
+        veutOverLight = m_input.getTouche( SDL_SCANCODE_Q ) || m_input.getBoutonPad(0);
+        if ( !overLightDone && veutOverLight ) {
+            overLightDone = true;
+            overLightState = !overLightState;
+        }
+        else if ( !veutOverLight ) overLightDone = false;
+
+
+        /* ***** Première Passe ***** */
+
+        // Verrouillage du Frame Buffer
+        glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.getID());
+
+            // Nettoyage de l'écran
+            glClearColor(0.2, 0.2, 0.25, 1.0);
+            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+            // Redimensionnement de la zone d'affichage
+            glViewport(0, 0, frameBuffer.getLargeur(), frameBuffer.getHauteur());
+
+            // Placement de la caméra
+            view = lookAt(vec3(0, 0, 3), vec3(0, 0, 0), vec3(0, 1, 0));
+
+            // Gestion de la rotation de la caisse
+            if ( veutTemporiser )
+                angle = 0.05f;
+            else
+                angle = 2.0f;
+
+            // Activation du shader
+            glUseProgram( m_shGris.getProgramID() );
+
+                // Affichage de la caisse
+                model_metal = rotate(model_metal, angle, vec3(0, 1, 0));
+                metal.afficher(projectionFBO*view*model_metal, model_metal, &m_shGris);
+
+            // Désactivation du shader
+            glUseProgram( 0 );
+
+        // Déverrouillage du Frame Buffer
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+
+        /* ***** Seconde Passe ***** */
+
+        // Nettoyage de l'écran
+        glClearColor(0.0, 0.0, 0.0, 1.0);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+        // Redimensionnement de la zone d'affichage
+        glViewport(0, 0, m_largeurFenetre, m_hauteurFenetre);
+
+        // Gestion de la caméra
+        camera.lookAt(view);
+        if ( veutViser ) projection = projection30;
+        else if ( m_input.getTouche( SDL_SCANCODE_X ) ) projection = plat;
+        else projection = projection70;
+
+        // Gestion de la lumière
+        posLight[1] = camera.getPos() + vec3(0.0, 1.2, 0.0);
+        posLight[2] = rotateY( posLight[2], angle );
+
+        uint16_t j;
+        for ( uint16_t i(0); i<nbLight; i++ )
+        {
+            j = i * 3;
+            posLightV[j] = posLight[i].x;
+            posLightV[j+1] = posLight[i].y;
+            posLightV[j+2] = posLight[i].z;
+        }
+
+
+        // Activation du shader
+        if ( lightState )
+        {
+            eyePos = camera.getPos();
+            shTarget = &m_shLight;
+        }
+        else
+            shTarget = &m_shader;
+
+        glUseProgram( shTarget->getProgramID() );
+
+        if ( lightState )
+        {
+            glUniform3f(glGetUniformLocation(m_shLight.getProgramID(), "eyePos"), eyePos.x, eyePos.y, eyePos.z);
+            glUniform3fv(glGetUniformLocation(m_shLight.getProgramID(), "posLight"), nbLight, posLightV);
+            glUniform1i(glGetUniformLocation(m_shLight.getProgramID(), "overLight"), overLightState);
+            glUniform1i(glGetUniformLocation(m_shLight.getProgramID(), "nbLight"), (int)nbLight);
+        }
+
+            // Afficher le plan
+            plan.afficher(projection * view * model_plan, model_plan, shTarget);
+
+            // Afficher la télé
+            tele.afficher(projection * view * model_tele, model_tele, shTarget);
+
+            // Affichage de la caisse
+            model_caisseA = rotate(model_caisseA, angle, vec3(0, 1, 0));
+            weapon.afficher(projection * view * model_caisseA, model_caisseA, shTarget);
+            caisse.afficher(projection * view * model_caisseB, model_caisseB, shTarget);
+            caisse.afficher(projection * view * model_caisseC, model_caisseC, shTarget);
+
+            // Affichage de l'arme
+            if ( rangee ) {
+                theta = camera.getTheta() + 180;
+                phi = 90;
+            }
+            else {
+                theta = camera.getTheta();
+                phi = camera.getPhi();
+            }
+
+            theta_old = theta_old*3 + theta;
+            theta_old /= 4;
+            phi_old = phi_old*3 - phi;
+            phi_old /= 4;
+
+            model_weapon = translate( unicite, camera.getPos() );
+            model_weapon = rotate(model_weapon, theta_old, vec3(0, 1, 0));
+            model_weapon = rotate(model_weapon, phi_old, vec3(1, 0, 0) );
+
+            if ( veutViser ) model_weapon = translate( model_weapon, vec3(0,-0.5,1.0) );
+            else model_weapon = translate( model_weapon, vec3(-0.5,-0.7,1.0) );
+
+            glClear(GL_DEPTH_BUFFER_BIT); // L'arme s'affiche au premier plan quoi qu'il arrive
+
+            weapon.afficher(projection * view * model_weapon, model_weapon, shTarget);
+
+            // Affichage de l'épée
+            sword.afficher(projection * view * model_sword, model_sword, shTarget);
+
+        // Désactivation du shader
+        shTarget = 0x0;
+        glUseProgram( 0 );
+
+        // Actualisation de la fenêtre
+        SDL_GL_SwapWindow(m_fenetre);
+
+        // 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);
+    }
+}

+ 69 - 0
arena/SceneOpenGL.h

@@ -0,0 +1,69 @@
+#ifndef DEF_SCENEOPENGL
+#define DEF_SCENEOPENGL
+
+// Include Windows
+#ifdef WIN32
+    #include <GL/glew.h>
+
+// Include Mac
+#elif __APPLE__
+    #define GL3_PROTOTYPES 1
+    #include <OpenGL/gl3.h>
+    #include <CoreFoundation/CoreFoundation.h>
+
+// Include UNIX/Linux
+#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>
+#include <glm/gtx/rotate_vector.hpp>
+
+// Autres includes
+#include <SDL2/SDL.h>
+#include <iostream>
+#include <string>
+#include "Shader.h"
+#include "InputAndJoy.h"
+#include "TexturLoader.h"
+#include "Camera.h"
+#include "FrameBuffer.h"
+#include "3D/OBJ.h"
+#include "3D/Mosaic.h"
+
+// Classe
+class SceneOpenGL
+{
+    public:
+
+    SceneOpenGL(std::string titreFenetre, int largeurFenetre, int hauteurFenetre);
+    ~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;
+    InputAndJoy m_input;
+    TexturLoader m_texturLoader;
+
+    Shader m_shader;
+    Shader m_shLight;
+    Shader m_shGris;
+};
+
+#endif
+

+ 192 - 0
arena/Shader.cpp

@@ -0,0 +1,192 @@
+#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;
+}

+ 51 - 0
arena/Shader.h

@@ -0,0 +1,51 @@
+#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

+ 26 - 0
arena/Shaders/gris.frag

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

+ 67 - 0
arena/Shaders/light.frag

@@ -0,0 +1,67 @@
+// Version du GLSL
+#version 150 core
+
+// Entrées
+in vec3 vertex;
+in vec3 normale;
+in vec2 coordTexture;
+
+// Uniform
+uniform sampler2D texture;
+uniform vec3 eyePos;
+uniform vec3 posLight[10];
+uniform int overLight; // Dépassement de la couleur originale du pixel
+uniform int nbLight; // Nombre de lumičres (maxi 10)
+
+// Sortie
+out vec4 out_Color;
+
+// Fonction main
+void main()
+{
+    out_Color = vec4(0.0, 0.0, 0.0, 1.0);
+    vec4 pxColor = texture2D(texture, coordTexture);
+    float ambientColor = 0.2;
+    float loin;
+    float cosTheta;
+
+    vec4 colorLight;
+    if ( overLight ) colorLight = vec4(1.0, 0.5, 0.0, 1.0);
+    else colorLight = vec4(1.0, 1.0, 1.0, 1.0);
+    colorLight *= pxColor;
+
+    int i;
+    for ( i=0; i<nbLight; i++)
+    {
+        /// Cosinus
+        cosTheta = clamp( dot( normale, posLight[i]-vertex ), 0.0, 1.0 );
+        //float cosAlpha = clamp( dot( reflect( normalize(vertex-posLight[i]), normale), normalize(eyePos-vertex) ), 0.0, 1.0 );
+        //float viewDistance = 5.0f;
+
+        /// Distance
+        loin = distance( vertex, posLight[i] );
+        //loin = (0.5-(0.5/(viewDistance*viewDistance*viewDistance))*loin*loin*loin);
+
+        /// Couleurs
+
+        /// Calcule si nécessaire
+        if ( loin < 30 )
+        {
+            /// Calcul lumičre diffuse
+            float power = cosTheta * 100 / (loin*loin);
+            if ( overLight == 0 ) power = clamp( power, 0.0, 1.0 );
+            out_Color += colorLight * power * 0.4;
+
+            /// Calcul lumičre spéculaire
+            /*power = pow(cosAlpha,5) * 1000 / (loin*loin);
+            if ( overLight == 0 ) power = clamp( power, 0.0, 1.0 );
+            out_Color +=  colorLight * power * 0.4;*/ // Lumičre spéculaire
+        }
+    }
+
+    /// Lumičre ambiente
+    out_Color += pxColor * ambientColor;
+
+    /// Correction ransparence
+    out_Color.w = pxColor.w;
+}

+ 33 - 0
arena/Shaders/light.vert

@@ -0,0 +1,33 @@
+// Version du GLSL
+#version 150 core
+
+// Entrées
+in vec3 in_Vertex;
+in vec3 in_Normale;
+in vec2 in_TexCoord0;
+
+// Uniform
+uniform mat4 pmv; // Projection * view * model
+uniform mat4 m; // Matrice modèle
+
+// Sortie
+out vec3 vertex;
+out vec3 normale;
+out vec2 coordTexture;
+
+// Fonction main
+void main()
+{
+    // vertexition finale du vertex projeté en 3D
+    gl_Position = pmv * vec4(in_Vertex, 1.0);
+
+    // Envoi des coordonnées de texture au Fragment Shader
+    coordTexture = in_TexCoord0;
+
+    // Calcul vertexition pour la lumière
+	normale = mat3(m) * in_Normale;
+	normale = normalize( normale );
+
+    vec4 realPosition = m * vec4(in_Vertex, 1.0);
+    vertex = realPosition.xyz;
+}

+ 18 - 0
arena/Shaders/texture.frag

@@ -0,0 +1,18 @@
+// 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);
+}

+ 23 - 0
arena/Shaders/texture.vert

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

+ 148 - 0
arena/Surface3D.cpp

@@ -0,0 +1,148 @@
+#include "Surface3D.h"
+
+Surface3D::Surface3D(float tailleX, float tailleY, std::string const fichierImage, float multi)
+:m_texture( new Texture(fichierImage) ), m_textID( m_texture->getID() ),
+ m_vboID(0), m_tailleVerticesBytes(18*sizeof(float)), m_tailleCoordTextureBytes(12*sizeof(float)), m_vaoID(0)
+{
+    // 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];
+
+    // Chargement automatique
+    charger();
+}
+
+Surface3D::Surface3D(float tailleX, float tailleY, GLuint samplerID, float multi)
+:m_texture( 0x0 ), m_textID( samplerID ),
+ m_vboID(0), m_tailleVerticesBytes(18*sizeof(float)), m_tailleCoordTextureBytes(12*sizeof(float)), m_vaoID(0)
+{
+    // 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];
+
+    // Chargement automatique
+    charger();
+}
+
+Surface3D::~Surface3D()
+{
+    // Destruction du VBO
+    glDeleteBuffers(1, &m_vboID);
+
+    // Destruction du VAO
+    glDeleteVertexArrays(1, &m_vaoID);
+
+    // Destruction de la texture
+    if ( m_texture ) delete m_texture;
+}
+
+void Surface3D::charger()
+{
+    /// Chargement Vertex Buffer Object
+    // Destruction d'un éventuel ancien VBO
+    if(glIsBuffer(m_vboID) == GL_TRUE)
+        glDeleteBuffers(1, &m_vboID);
+
+    // Génération de l'ID
+    glGenBuffers(1, &m_vboID);
+
+    // Verrouillage du VBO
+    glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+        // Allocation de la mémoire vidéo
+        glBufferData(GL_ARRAY_BUFFER, m_tailleVerticesBytes + m_tailleCoordTextureBytes, 0, GL_STATIC_DRAW);
+
+        // Transfert des données
+        glBufferSubData(GL_ARRAY_BUFFER, 0, m_tailleVerticesBytes, m_vertices);
+        glBufferSubData(GL_ARRAY_BUFFER, m_tailleVerticesBytes, m_tailleCoordTextureBytes, m_coordTexture);
+
+    // Déverrouillage de l'objet
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+    /// Chargement Vertex Array Object
+    // Destruction d'un éventuel ancien VAO
+    if(glIsVertexArray(m_vaoID) == GL_TRUE)
+        glDeleteVertexArrays(1, &m_vaoID);
+
+    // Génération de l'ID du VAO
+    glGenVertexArrays(1, &m_vaoID);
+
+    // Verrouillage du VAO
+    glBindVertexArray(m_vaoID);
+
+        // Verrouillage du VBO
+        glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
+
+            // Accès aux vertices dans la mémoire vidéo
+            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
+            glEnableVertexAttribArray(0);
+
+            // Accès aux coordonnées de texture dans la mémoire vidéo
+            glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_tailleVerticesBytes));
+            glEnableVertexAttribArray(2);
+
+        // Déverrouillage du VBO
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+
+    // Déverrouillage du VAO
+    glBindVertexArray(0);
+}
+
+void Surface3D::afficher( glm::mat4 pmv, Shader const &shad )
+{
+    // Verouillage VAO
+    glBindVertexArray(m_vaoID);
+
+        // Envoi des matrices
+        glUniformMatrix4fv(glGetUniformLocation(shad.getProgramID(), "pmv"), 1, GL_FALSE, glm::value_ptr(pmv));
+
+        // Verrouillage de la texture
+        glBindTexture(GL_TEXTURE_2D, m_textID);
+
+        // Rendu
+        glDrawArrays(GL_TRIANGLES, 0, 6);
+
+        // Déverrouillage de la texture
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+    // Déverrouillage du VAO
+    glBindVertexArray(0);
+}

+ 48 - 0
arena/Surface3D.h

@@ -0,0 +1,48 @@
+#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"
+#include "macro.h"
+
+class Surface3D
+{
+    public:
+
+        Surface3D(float tailleX, float tailleY, std::string const fichierImage, float multi=1); // Détruira la texture
+        Surface3D(float tailleX, float tailleY, GLuint samplerID, float multi=1); // Ne détruira pas la texture
+        ~Surface3D();
+        void afficher(glm::mat4 pmv, Shader const &shad);
+        void charger();
+
+    private:
+
+        Texture* m_texture;
+        GLuint m_textID;
+        float m_vertices[18];
+        float m_coordTexture[12];
+
+        GLuint m_vboID;
+        int m_tailleVerticesBytes;
+        int m_tailleCoordTextureBytes;
+        GLuint m_vaoID;
+};
+
+#endif // SURFACE3D_H_INCLUDED

+ 59 - 0
arena/TexturLoader.cpp

@@ -0,0 +1,59 @@
+#include "TexturLoader.h"
+
+TexturLoader::TexturLoader() : m_folder("")
+{
+    // Constructeur par défaut
+}
+
+TexturLoader::TexturLoader(std::string folder) : m_folder(folder)
+{
+    // Constructeur avec implémentation du dossier cible
+}
+
+TexturLoader::~TexturLoader()
+{
+    for( m_it = m_paquet.begin(); m_it != m_paquet.end(); m_it++ )
+    {
+        delete m_it->second;
+        m_it->second = 0x0;
+    }
+}
+
+GLuint TexturLoader::take(std::string nom)
+{
+    // Cherche la texture dans le tableau
+    m_it = m_paquet.find(nom);
+
+    // Si la texture est déjà chargée, on la donne
+    if (m_it != m_paquet.end())
+        return m_it->second->getID();
+
+    // Sinon on la charge
+    else
+    {
+        m_paquet[nom] = new Texture(m_folder + nom + ".bmp");
+
+        return m_paquet[nom]->getID();
+    }
+}
+
+void TexturLoader::addTextur(std::string nom, Texture* sampler)
+{
+    m_it = m_paquet.find(nom);
+    if (m_it == m_paquet.end())
+    {
+        m_paquet[nom] = sampler;
+        return;
+    }
+    else
+    {
+        std::cout << "Attention ! La texture " <<nom<< " a déjà une surface associée. Destruction de la nouvelle surface." << std::endl;
+        delete sampler;
+    }
+}
+
+void TexturLoader::assignFolder(std::string folder)
+{
+    m_folder = folder;
+}
+

+ 27 - 0
arena/TexturLoader.h

@@ -0,0 +1,27 @@
+#ifndef TEXTURLOADER_H_INCLUDED
+#define TEXTURLOADER_H_INCLUDED
+
+#include "Texture.h"
+#include <map>
+
+class TexturLoader
+{
+public:
+
+    TexturLoader();
+    TexturLoader(std::string folder);
+    ~TexturLoader();
+
+    GLuint take(std::string nom);
+    void addTextur(std::string nom, Texture* sampler); // [!!!] La texture sera détruite dans le destructeur
+    void assignFolder(std::string folder);
+
+private:
+
+    std::string m_folder;
+    std::map<std::string, Texture*>::iterator m_it;
+    std::map<std::string, Texture*> m_paquet;
+
+};
+
+#endif // TEXTURLOADER_H_INCLUDED

+ 184 - 0
arena/Texture.cpp

@@ -0,0 +1,184 @@
+#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_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
+        if(imageInversee->format->Rmask == 0xff)
+            m_format = GL_RGBA;
+        else
+            m_format = 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(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;
+}
+

+ 58 - 0
arena/Texture.h

@@ -0,0 +1,58 @@
+#ifndef DEF_TEXTURE
+#define DEF_TEXTURE
+
+// Include Windows
+#ifdef WIN32
+    #include <GL/glew.h>
+    #include <SDL2/SDL_image.h>
+
+// Include Mac
+#elif __APPLE__
+    #define GL3_PROTOTYPES 1
+    #include <OpenGL/gl3.h>
+    #include <SDL2_image/SDL_image.h>
+
+// Include UNIX/Linux
+#else
+    #define GL3_PROTOTYPES 1
+    #include <GL3/gl3.h>
+#endif
+
+// Autres includes
+#include <SDL2/SDL.h>
+#include <iostream>
+#include <string>
+
+// Classe Textures
+class Texture
+{
+    public:
+
+    Texture();
+    Texture(std::string fichierImage);
+    Texture(int largeur, int hauteur, GLenum format = GL_RGBA, GLenum formatInterne = GL_RGBA, bool textureVide = true);
+    Texture(Texture const &autre);
+    ~Texture();
+
+    Texture& operator=(Texture const &autre);
+    bool createTexture();
+    void create( void* sampler = 0 );
+    SDL_Surface* inverserPixels(SDL_Surface *imageSource) const;
+
+    GLuint getID() const;
+    void setFichierImage(const std::string &fichierImage);
+
+
+    private:
+
+    GLuint m_id;
+    std::string m_fichierImage;
+
+    int m_largeur;
+    int m_hauteur;
+    GLenum m_format;
+    GLenum m_formatInterne;
+    bool m_textureVide;
+};
+
+#endif

BIN
arena/Textures/bleu_mur.bmp


BIN
arena/Textures/caisse_basic.bmp


BIN
arena/Textures/caisse_metal.bmp


BIN
arena/Textures/chantier.bmp


BIN
arena/Textures/pierres.bmp


BIN
arena/Textures/spectre.bmp


BIN
arena/Textures/test.bmp


BIN
arena/Textures/tireur.bmp


+ 12 - 0
arena/macro.h

@@ -0,0 +1,12 @@
+#ifndef MACRO_H_INCLUDED
+#define MACRO_H_INCLUDED
+
+// Macro utile au VBO
+#ifndef BUFFER_OFFSET
+
+    #define BUFFER_OFFSET(offset) ((char*)NULL + (offset))
+
+#endif
+
+
+#endif // MACRO_H_INCLUDED

+ 33 - 0
arena/main.cpp

@@ -0,0 +1,33 @@
+#include "SceneOpenGL.h"
+
+
+int main(int argc, char **argv)
+{
+    // Création de la sène
+
+    SceneOpenGL scene("The Frame Buffer", 1600, 900);
+
+
+    // Initialisation de la scène
+
+    if(scene.initialiserFenetre() == false)
+	return -1;
+
+    if(scene.initGL() == false)
+	return -1;
+
+
+    // Boucle Principale
+
+    scene.bouclePrincipale();
+
+    // Affichage de l'erreur
+    GLenum erreur = glGetError();
+    if ( erreur != GL_NO_ERROR ) {
+        std::cout << "Erreur de type " << erreur << "." << std::endl;
+    }
+
+    // Fin du programme
+
+    return 0;
+}