Lo

Grade : Expert
Inscrit le: 26 Dec 2007, 17:33
|
| Ecrit le: 29 Dec 2008, 17:25 Message non corrigé | |
|
Voilà, j'ai fait une classe qui permet de déplacer une caméra fps, placée donc sur un personnage.
Elle modifie donc la position de la caméra, et la cible.
Après, j'essaierai de faire une caméra FreeFly pour éditer mes maps.
Je commence à me souvenir de la géométrie de l'espace en 3D.
Mais je dois encore améliorer la classe, notamment en utilisant vector3D pour la position des personnages.
Ainsi, bah mon main est déjà plus claire, pour ceux qui veulent voir la classe.
FPSCam.h :
#ifndef FPS_CAM
#define FPS_CAM
#include <SDL/SDL.h>
#include <math.h>
class FPSCamera {
private :
static float VIT_DEPL;
static float VIT_ROTATION;
static float DIST_VUE;
static float MAX_SAUT;
static float VIT_SAUT;
static enum MOUVEMENT {
AUCUN, AVANCE, RECULE, DROITE, GAUCHE
};
int mouvement, oldX, oldY;
float px , py, pz;
float tx, ty, tz;
float phi, teta;
bool sauter, monter, toucheTapee;
public :
FPSCamera (float x, float y, float z);
void gestionToucheEnfoncee (SDL_KeyboardEvent &event);
void gestionToucheRelevee (SDL_KeyboardEvent &event);
void gestionSouris (int relX, int relY);
void deplacer (float x, float y, float z, int nivSol);
void calculerCible (float x, float y, float z);
float getXPos () {return px;}
float getYPos () {return py;}
float getZPos () {return pz;}
float getTarX () {return tx;}
float getTarY () {return ty;}
float getTarZ () {return tz;}
float getTeta () {return teta;}
bool bouge ();
~FPSCamera () {}
};
#endif
FPSCam.cpp
#include "FPSCam.h"
FPSCamera::FPSCamera (float x, float y, float z) : mouvement(AUCUN), teta(0.0f), phi(0.0f), sauter(false), monter(false), toucheTapee(true), oldX(0), oldY(0) {
this->px = x;
this->py = y;
this->pz = z;
calculerCible (x, y, z);
}
void FPSCamera::gestionToucheEnfoncee(SDL_KeyboardEvent &event) {
if (event.keysym.sym == SDLK_SPACE) {
if (toucheTapee) {
sauter = true;
monter = true;
}
toucheTapee = false;
}
switch (event.keysym.sym) {
case SDLK_UP :
mouvement = AVANCE;
break;
case SDLK_DOWN :
mouvement = RECULE;
break;
case SDLK_RIGHT :
mouvement = DROITE;
break;
case SDLK_LEFT :
mouvement = GAUCHE;
break;
case SDLK_ESCAPE :
SDL_Quit ();
exit (EXIT_SUCCESS); break;
}
}
void FPSCamera::gestionToucheRelevee (SDL_KeyboardEvent &event) {
if (event.keysym.sym == SDLK_SPACE)
toucheTapee = true;
//Test avec la touche espace.
switch (event.keysym.sym) {
case SDLK_UP :
case SDLK_DOWN :
case SDLK_RIGHT :
case SDLK_LEFT :
mouvement = AUCUN;
break;
}
}
void FPSCamera::gestionSouris(int xrel, int yrel) {
if (xrel > oldX) { //Rotation à droite.
teta += xrel * VIT_ROTATION;
} else if (xrel < oldX) { //Rotation à gauche.
teta -= xrel * VIT_ROTATION;
}
if (yrel > oldY) { //Rotation vers le bas.
phi -= yrel * VIT_ROTATION;
if (phi < -45)
phi = -45;
} else if (yrel < oldY) { //Rotation vers le haut;
phi += yrel * 0.01f;
if (phi > 5)
phi = 5;
}
oldX = xrel;
oldY = yrel;
}
void FPSCamera::deplacer (float px, float py, float pz, int nivSol) {
//Mouvements en fonction du clavier.
if (sauter) {
if (monter && py <= MAX_SAUT + 5) {
py += sin (45.0f * 3.14f / 180.0f) * VIT_SAUT;
} else if (!monter && py > nivSol + 5){
py -= sin (45.0f * 3.14f / 180.0f) * VIT_SAUT;
}
if (py >= MAX_SAUT + 5)
monter = false;
if (py <= nivSol + 5)
sauter = false;
}
if (mouvement == AVANCE) {
pz += sin (teta * 3.14f / 180.0f) * VIT_DEPL;
px += cos (teta * 3.14f / 180.0f) * VIT_DEPL;
} else if (mouvement == RECULE) {
pz -= sin (teta * 3.14f / 180.0f) * VIT_DEPL;
px -= cos (teta * 3.14f / 180.0f) * VIT_DEPL;
} else if (mouvement == DROITE) {
pz += cos(teta * 3.14f / 180.0f) * VIT_DEPL;
px -= sin(teta * 3.14f / 180.0f) * VIT_DEPL;
} else if (mouvement == GAUCHE) {
pz -= cos(teta * 3.14f / 180.0f) * VIT_DEPL;
px += sin(teta * 3.14f / 180.0f) * VIT_DEPL;
}
this->px = px;
this->py = py;
this->pz = pz;
calculerCible (px, py, pz);
}
void FPSCamera::calculerCible (float x, float y, float z) {
tz = pz + (float) sin (teta * 3.14f / 180.0f) * DIST_VUE;
tx = px + (float) cos (teta * 3.14f / 180.0f) * DIST_VUE;
ty = py + (float) sin (phi * 3.14f / 180.0f) * DIST_VUE;
this->tx = tx;
this->tz = tz;
this->ty = ty;
}
bool FPSCamera::bouge () {
return mouvement != AUCUN;
}
Et mon main :
#include <GL/glut.h>
#include <stdlib.h>
#include <iostream>
#include "glOutils.h"
#include "CEntity.h"
#include "CMD2Model.h"
#include "FPSCam.h"
float FPSCamera::VIT_DEPL = 0.2f;
float FPSCamera::VIT_ROTATION = 0.01f;
float FPSCamera::DIST_VUE = 20.0f;
float FPSCamera::MAX_SAUT = 15.0f;
float FPSCamera::VIT_SAUT = 0.5f;
using namespace std;
const int largeur = 640;
const int hauteur = 490;
const int nivSol = 0;
void init ();
void afficher ();
GLuint textureId;
SDL_Cursor *viseur;
CMD2Model ogreMD2;
CEntity ogre;
float px = -10, py = 5, pz = -10;
float tx, ty, tz;
FPSCamera fpsCam (px, py, pz);
int frameDebut;
int frameFin;
string mode("Défaut");
bool boutonDroitEnfonce = false;
int main (int argc, char *argv[]) {
//Initialisation de glut.
SDL_Init (SDL_INIT_VIDEO);
SDL_WM_SetCaption("Mon premier programme OpenGL !",NULL);
SDL_Surface *ecran = SDL_SetVideoMode (largeur, hauteur, 32, SDL_OPENGL);
SDL_Event event;
SDL_EnableKeyRepeat (10, 10);
ogreMD2.LoadModel ("ogre.md2");
ogreMD2.LoadTexture ("_ogre.bmp");
ogre.SetModel (&ogreMD2);
ogre.SetScale(0.1f);
init ();
bool continuer = true;
while (continuer) {
SDL_PollEvent (&event);
switch (event.type) {
case SDL_QUIT :
continuer = false;
case SDL_KEYDOWN :
//Quel mouvement à faire en fonction de la touche qui a été enfoncée.
fpsCam.gestionToucheEnfoncee (event.key); break;
//Si une touche est relevée, annulation du mouvement.
case SDL_KEYUP :
fpsCam.gestionToucheRelevee (event.key); break;
}
if (event.type == SDL_MOUSEBUTTONDOWN) {
if (event.button.button == SDL_BUTTON_RIGHT)
boutonDroitEnfonce = true;
} else if (event.type == SDL_MOUSEBUTTONUP) {
boutonDroitEnfonce = false;
}
if (boutonDroitEnfonce)
fpsCam.gestionSouris (event.button.x, event.button.y);
fpsCam.deplacer (px, py, pz, nivSol);
afficher ();
}
// le programme n'arrivera jamais jusqu'ici.
SDL_Quit ();
return EXIT_SUCCESS;
}
void init () {
glEnable (GL_DEPTH_TEST);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_COLOR_MATERIAL);
glMatrixMode (GL_PROJECTION);
glEnable(GL_TEXTURE_2D);
glLoadIdentity ();
gluPerspective (90, (float) (largeur/hauteur), 3, 1000);
// Brouillard
// Brouillard
glFogi(GL_FOG_MODE, GL_LINEAR);
//GL_LINEAR, GL_EXP ou GL_EXP2
glFogf(GL_FOG_DENSITY, 0.35);
glFogf (GL_FOG_START, 150);
glFogf (GL_FOG_END, 200);
GLfloat fog_c[] = {0.7f, 0.7f, 0.7f, 1.0f}; // couleur du brouillard, ici gris clair
glFogfv(GL_FOG_COLOR, fog_c);
//glEnable(GL_FOG);
textureId = loadTexture ("sol_metal.bmp");
const char *curseur[] = {
"16 16 3 1", //Largeur et hauteur du curseur, nombre de couleurs différentes, caractères/pixels.
"X c #000000", //Couleurs.
". c #ffffff",
" c None",
//Pixels
" . ",
" . ",
" . ",
" . ",
" . ",
" . ",
" . ",
"................",
" . ",
" . ",
" . ",
" . ",
" . ",
" . ",
" . ",
" . ",
"0, 0"
};
viseur = cursorFromXPM(curseur);
SDL_SetCursor (viseur);
}
//Fonction appelée pour l'affichage.
void afficher () {
tx = fpsCam.getTarX();
tz = fpsCam.getTarZ ();
ty = fpsCam.getTarY ();
void gestionEvenements (SDL_Event &event);
if (!fpsCam.bouge()) {
frameDebut = 1;
frameFin = 40;
} else {
frameDebut = 40;
frameFin = 46;
}
//Effacement de l'écran et du tampon de profondeur.
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt(px , py, pz, tx, ty, tz, 0, 1, 0);
GLfloat ambientColor[] = {1.0f, 1.0f, 1.0f, 100};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 0.7f};
GLfloat lightPos[] = {-10, 10, -10, 0};
glLightfv (GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv (GL_LIGHT0, GL_POSITION, lightPos);
glEnable (GL_COLOR_MATERIAL);
glBindTexture (GL_TEXTURE_2D, textureId);
glBegin (GL_QUADS);
//Sol.
glColor3f (1.0f, 1.0f, 1.0f);
glNormal3f (0.0f, 1.0f, 0.0f);
glTexCoord2f (0.0f, 0.0f);
glVertex3d (1000, 0, -1000);
glTexCoord2f (0.0f, 100.0f);
glVertex3d (1000, 0, 1000);
glTexCoord2f (100.0f, 100.0f);
glVertex3d (-1000, 0, 1000);
glTexCoord2f (100.0f, 0.0f);
glVertex3d (-1000, 0, -1000);
//Face1.
glColor3ub(255, 0, 0);
glVertex3f (0, 0, 0);
glVertex3f (0, 5, 0);
glVertex3f (5, 5, 0);
glVertex3f (5, 0, 0);
//Face 2.
glColor3ub(0, 255, 0);
glVertex3f (5, 0, 0);
glVertex3f (5, 5, 0);
glVertex3f (5, 5, 5);
glVertex3f (5, 0, 5);
//Face 3.
glColor3ub (255, 255, 0);
glVertex3f (0, 0, 5);
glVertex3f (0, 5, 5);
glVertex3f (5, 5, 5);
glVertex3f (5, 0, 5);
//Face 4.
glColor3ub (255, 0, 255);
glVertex3f (0, 0, 5);
glVertex3f (0, 5, 5);
glVertex3f (0, 5, 0);
glVertex3f (0, 0, 0);
//Face5.
glColor3ub (255, 255, 0);
glVertex3f (0, 0, 0);
glVertex3f (5, 0, 0);
glVertex3f (5, 0, 5);
glVertex3f (0, 0, 5);
//Face6.
glColor3ub (0, 255, 255);
glVertex3f (0, 5, 0);
glVertex3f (5, 5, 0);
glVertex3f (5, 5, 5);
glVertex3f (0, 5, 5);
glEnd ();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
float fps = 80;
// courir : 40 -> 46
px = fpsCam.getXPos ();
py = fpsCam.getYPos ();
pz = fpsCam.getZPos ();
// On place le premier mesh
glPushMatrix();
glTranslated(px,py,pz);
glRotated(fpsCam.getTeta(),0,1,0);
ogre.Animate(frameDebut, frameFin, 10 / fps );
ogre.DrawEntity( -1, false, false);
glPopMatrix();
//Echange les buffers "front" et ""back".
glFlush ();
SDL_GL_SwapBuffers ();
}
En tout cas chez moi la classe marche nickel.
________ Parce qu'on ne peut s'exprimer que par nos créations. ^^
|
|