123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- #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);
- }
- }
|