
|
|
|
|
OpenGL / Newton Game Dynamicsvous devez connaitre le C++ pour pouvoir bien comprendre ce tuto.
Sommaire du chapitre :
Partie OpenGLAllez , on fonce direct . Je ne vais pas vous faire les lessons de moral , parce que je sais que vous n'aimez pas . Commencez par telecharger Newton Game dynamique , ici : www.newtongamedynamics.com Si vous vous demander a quoi sert ce moteur mettez simplement dans la tete qu'il nous permet d'avoir des effets réalistes. Et si vous dites que vous allez faire des jeux sans la physique , vous etes en train de vous mettre un clou dans la tete , c'es COMME VIVRE SANS MANGER . Maintenant , suivez les instructions suivante : 1- Créez un nouveau dossier dans "Dev-Cpp\Mingw32\" que vous nommerez "Newton" 2- Copiez le header du dossier "NewtonSDK\sdk\" et collez le dans le nouveau dossier que vous venez de créer y a un instant. 3- Copiez le fichier "...\NewtonSDK\sdk\dll\Newton.lib" et collez le dans "...\Dev-Cpp\mingw32\lib\" 4- Copiez la dll "...\NewtonSDK\sdk\dll\Newton.dll" et collez le dans "C:\WINDOWS\system32\" . Normalement vous etes grand , vous pouvez configurer votre projet ( le " linker " exactement ). Il faut que vous ajoutiez le fichier Newton.lib a la liste , sans oublier ceux de la SDL . Sachez que je code avec Dev C++ . Qu'ont au code le voici : ( C'est un code C++ bien sur ) Code : #include <cstdlib> #include <iostream> #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> using namespace std ; int main(int argc, char *argv[]) { SDL_Event event ; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); SDL_WM_SetCaption("OpenGL / Newton Application", NULL); SDL_Surface *ecran = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(70,(double)640/480,1,1000); glEnable(GL_DEPTH_TEST); while (1) { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN : switch (event.key.keysym.sym) { case SDLK_ESCAPE: exit(0); break; } } SDL_Delay(8); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); // Code pour les lumiére |||||||||||||||||||||||||||||||||||| glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glEnable (GL_LIGHTING); // Code pour les lumiéres glEnable (GL_LIGHT0); GLfloat LampeDiffuse [] = {1.0f, 1.0f, 1.0f}; GLfloat LampeAmbient [] = {0.75f, 0.75f, 0.75f}; GLfloat LampePosition [] = {-5.0f, -5.0f, 10.0f, 5.0f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, LampeDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LampeDiffuse); glLightfv (GL_LIGHT0, GL_AMBIENT, LampeAmbient); glLightfv (GL_LIGHT0, GL_POSITION, LampePosition); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); glColor3f (1.0f, 1.0f, 1.0f); glColorMaterial (GL_FRONT_AND_BACK, GL_EMISSION); glColor3f (0.0f, 0.0f, 0.0f); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| gluLookAt(5,5,2,0,0,0,0,0,1); glFlush(); SDL_GL_SwapBuffers(); } return 0 ; } Voila le code minimal pour commencer notre application . Si vous ne le comprenez pas désoler de vous dire ça mais vous devez rentrez chez vous . Il y a une petite exeption , si vous comprenez tous le code sauf seului des lumiéres , vous pouvez continuer . Le code colorer en vert sert a faire de la lumiére ... . On continue ? Alors , on va créer une fonction qui fera afficher un cube . Et pour cela , créez 2 nouveaux fichiers : 1- Test.h 2- Test.cpp Rendez vous dans le fichier "Test.h" , tapez le code suivant : Code : #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> #ifndef TEST_H #define TEST_H void DessinerCube(GLfloat taille); #endif Et puis Tapez le code suivant dans le fichier "Test.cpp" : Code : #include "Test.h" void DessinerCube(GLfloat taille) { glBegin(GL_QUADS); glColor3ub(255,0,0); //face rouge glVertex3d(taille,taille,taille); glVertex3d(taille,taille,-taille); glVertex3d(-taille,taille,-taille); glVertex3d(-taille,taille,taille); glColor3ub(0,255,0); //face verte glVertex3d(taille,-taille,taille); glVertex3d(taille,-taille,-taille); glVertex3d(taille,taille,-taille); glVertex3d(taille,taille,taille); glColor3ub(0,0,255); //face bleue glVertex3d(-taille,-taille,taille); glVertex3d(-taille,-taille,-taille); glVertex3d(taille,-taille,-taille); glVertex3d(taille,-taille,taille); glColor3ub(255,255,0); //face jaune glVertex3d(-taille,taille,taille); glVertex3d(-taille,taille,-taille); glVertex3d(-taille,-taille,-taille); glVertex3d(-taille,-taille,taille); glColor3ub(0,255,255); //face cyan glVertex3d(taille,taille,-taille); glVertex3d(taille,-taille,-taille); glVertex3d(-taille,-taille,-taille); glVertex3d(-taille,taille,-taille); glColor3ub(255,0,255); //face magenta glVertex3d(taille,-taille,taille); glVertex3d(taille,taille,taille); glVertex3d(-taille,taille,taille); glVertex3d(-taille,-taille,taille); glEnd(); } Pour l'instant rien de nouveau , rien de magique ! mais je n'est pas dis mon dernier mot ! Maintenat revenez au fichier main.cpp et essayer d'utiliser la fonction pour afficher un cube ou deux . Normalement c'est simple , et le code que vous devez avoir a la fin cera celui ci : Code : #include <cstdlib> #include <iostream> #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> #include "Test.h" using namespace std ; int main(int argc, char *argv[]) { SDL_Event event ; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); SDL_WM_SetCaption("OpenGL / Newton Application", NULL); SDL_Surface *ecran = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(70,([b]double[/b])640/480,1,1000); glEnable(GL_DEPTH_TEST); while (1) { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN : switch (event.key.keysym.sym) { case SDLK_ESCAPE: exit(0); break; } } SDL_Delay(8); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); GLfloat LampeDiffuse [] = {1.0f, 1.0f, 1.0f}; GLfloat LampeAmbient [] = {0.75f, 0.75f, 0.75f}; GLfloat LampePosition [] = {-5.0f, -5.0f, 10.0f, 5.0f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, LampeDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LampeDiffuse); glLightfv (GL_LIGHT0, GL_AMBIENT, LampeAmbient); glLightfv (GL_LIGHT0, GL_POSITION, LampePosition); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); glColor3f (1.0f, 1.0f, 1.0f); glColorMaterial (GL_FRONT_AND_BACK, GL_EMISSION); glColor3f (0.0f, 0.0f, 0.0f); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); gluLookAt(5,5,2,0,0,0,0,0,1); glTranslated(0,0,0); DessinerCube(1.0); glFlush(); SDL_GL_SwapBuffers(); } return 0 ; } IMPORTANT : n'oubliez pas d'inclure le fichier Test.h dans votre fichier main.cpp Maintenant , executer pour avoir cette image : On aura fort besoin d'une matrice 4x4 , qu'on fera avec une structure , donc retournez au fichier "Test.h" et mettez y le code qui faut , je veut dire celui ci . Code : #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> #ifndef TEST_H #define TEST_H struct Mat { GLfloat Matrice[4][4] ; }; void DessinerCube(GLfloat taille); #endif Mais une matrice doit etre initialiser a chaque fois pour qu'elle marche correctement , ce qui veut dire qu'on va créer une fonction qui initialisera nos matrice . D'abord , il faut mettre le prototype dans le fichier "Test.h" , voici le prototype : Code : void Init_Mat(Mat &matrice); Comme vous pouvez le constater sur le prototype , j'ais utiliser une référence, c'est trés pratique . Et puis on doit mettre le code dans le fichier "Test.cpp" , on va l'ajouter : Code : #include "Test.h" void DessinerCube(GLfloat taille) { glBegin(GL_QUADS); glColor3ub(255,0,0); //face rouge glVertex3d(taille,taille,taille); glVertex3d(taille,taille,-taille); glVertex3d(-taille,taille,-taille); glVertex3d(-taille,taille,taille); glColor3ub(0,255,0); //face verte glVertex3d(taille,-taille,taille); glVertex3d(taille,-taille,-taille); glVertex3d(taille,taille,-taille); glVertex3d(taille,taille,taille); glColor3ub(0,0,255); //face bleue glVertex3d(-taille,-taille,taille); glVertex3d(-taille,-taille,-taille); glVertex3d(taille,-taille,-taille); glVertex3d(taille,-taille,taille); glColor3ub(255,255,0); //face jaune glVertex3d(-taille,taille,taille); glVertex3d(-taille,taille,-taille); glVertex3d(-taille,-taille,-taille); glVertex3d(-taille,-taille,taille); glColor3ub(0,255,255); //face cyan glVertex3d(taille,taille,-taille); glVertex3d(taille,-taille,-taille); glVertex3d(-taille,-taille,-taille); glVertex3d(-taille,taille,-taille); glColor3ub(255,0,255); //face magenta glVertex3d(taille,-taille,taille); glVertex3d(taille,taille,taille); glVertex3d(-taille,taille,taille); glVertex3d(-taille,-taille,taille); glEnd(); } void Init_Mat(Mat &matrice) { for (int x = 0 ; x < 4 ; ++x) for (int y = 0 ; y < 4 ; y++) { if (x == y) matrice.matrice [x][y] = 1.0f; else matrice.matrice [x][y] = 0.0f; } } Bravo !!! On vien de finir la partie OpenGL , et on va tous de suite passer a la partie Newton , je pense que vous ne connaissez pas vous en sérvir de ce moteur physique , alors je vais y aller doucement . ![]() Partie NewtonSi vous voulez commencer avec Newton , il faut que vous sachiez quoi faire pour créer un objet simple : 1- Tout d'abord , il faut céer le monde , quoi vous n'avait pas compris ! un MONDE , un WORLD grace a cette ligne :Code : NewtonWorld *world = NewtonCreate(0,0); 2- Créer un Body , un objet si vous voulez , grace a cette ligne : Code : NewtonBody *body = NewtonCreateBody(world,NewtonCreateBox(world,tailleX,tailleY,tailleZ,0)); Ici , on a créer un cube , mais rien ne nous empéche de créer une sphere. 3- On doit lui donner une matrice . 4- On doit lui donner : a) La masse b) Les inerties : b-a) Inertie X . b-a) Inertie Y . b-a) Inertie Z . Tous ça garce a cette petite ligne : Code : NewtonBodySetMassMatrix(body,masse,inertieX,inertieY,inertieZ); 5- On doit créer une fonction pour lui appliquer des forces . 6- On doit mettre ajour le monde : Code : NewtonUpdate(world, 1.0f/80.0f); 80.0f designe le nombre de MAJ (Mise A Jour) par seconde. Et voila c'est simple , vous ne trouvez pas ? ![]() Et si on essayez de faire un petit quelque chose ?!! Regardez bien , je écrire le code , et je vais vous montrer le nouveau en bleu : Code : #include <cstdlib> #include <iostream> #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> #include "Test.h" using namespace std ; int main(int argc, char *argv[]) { SDL_Event event ; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); SDL_WM_SetCaption("OpenGL / Newton Application", NULL); SDL_Surface *ecran = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(70,(double)640/480,1,1000); glEnable(GL_DEPTH_TEST); Mat mat ; Init_Mat(mat); NewtonWorld *world = NewtonCreate(0,0); NewtonBody *body = NewtonCreateBody(world,NewtonCreateBox(world,2,2,2,0)); NewtonBodySetMatrix(body,&mat.matrice[0][0]); NewtonBodySetMassMatrix(body,10,2,2,2); Code : while (1) { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN : switch (event.key.keysym.sym) { case SDLK_ESCAPE: exit(0); break; } } SDL_Delay(8); NewtonUpdate(world, 1.0f/80.0f); Code : glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); GLfloat LampeDiffuse [] = {1.0f, 1.0f, 1.0f}; GLfloat LampeAmbient [] = {0.75f, 0.75f, 0.75f}; GLfloat LampePosition [] = {-5.0f, -5.0f, 10.0f, 5.0f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, LampeDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LampeDiffuse); glLightfv (GL_LIGHT0, GL_AMBIENT, LampeAmbient); glLightfv (GL_LIGHT0, GL_POSITION, LampePosition); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); glColor3f (1.0f, 1.0f, 1.0f); glColorMaterial (GL_FRONT_AND_BACK, GL_EMISSION); glColor3f (0.0f, 0.0f, 0.0f); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); gluLookAt(5,5,2,0,0,0,0,0,1); glTranslated(0,0,0); DessinerCube(1.0); glFlush(); SDL_GL_SwapBuffers(); } return 0 ; } On a tous fait sauf une , c'est la fonction pour appliquer les forces . On va la créer mais dans le fichier "Test.cpp" , donc on doit d'abord mettre le prototype dans le fichier "Test.h" , voici le prototype pour que vous l'ajoutiez : Code : void ApplquerForce(const NewtonBody *nbody); Puis rendez vous dans le fichier "Test.cpp" pour y mettre ce code : Code : void AppliquerForce(const NewtonBody *nbody) { float mass, ix, iy, iz; //On recupere la masse et l'inertie du corp NewtonBodyGetMassMatrix(nbody, &mass, &ix, &iy, &iz); //on cree une force 3D pour attirer l'objet vers le bas float force[3] = {0, 0, mass * -9.81}; // l'effet de la terre //On les envoi au corps NewtonBodyAddForce(nbody, force); } Revenez au fichier "main.cpp" et ajoutez la ligne de la fonctoin , attendez ça se fait d'une magnére un peut particuliére : Mat mat ; Init_Mat(mat); NewtonWorld *world = NewtonCreate(0,0); NewtonBody *body = NewtonCreateBody(world,NewtonCreateBox(world,2,2,2,0)); NewtonBodySetMatrix(body,&mat.matrice[0][0]); NewtonBodySetMassMatrix(body,10,2,2,2); NewtonBodySetForceAndTorqueCallback(body, AppliquerForce); Et voila , vous pouvez executer !!! [u][color=purple]Oh Zuut rien ne se passe !! Et , on plus j'ais fait tous ça pour rien !! Non vous n'avez pas fait tous ça pour rien , en réalité l'objet bouge mais le cube ne bouge pas , c'est parce que le cube n'est pas l'objet , ou tous simplement : OpenGL fait cavalier seul et Newton aussi . Ou OpenGL travaille tous seul et Newton aussi , mais pas pour longtemps , on va tous de suite faire la paix entre eux. ![]() Partie UnionOn est a 2 pas de achever notre application , on va maintenant lier OpenGL a Newton , pour qu'il nous affiche ce qui se passe dans le monde de Newton . Si vous m'avait bien suivi , vous constaterez que la matrice "mat" qu'on a créer contient toutes les informations consérnant l'objet "body" , et si vous révisez bien vous lesson OpenGL , vous trouverait que ce dernier utilise aussi les matrice de 4x4 . Donc , si on envoi a notre cube la matrice du body , il fera tous ce que le "body" fait . Ce qu'on va faire : 1- Récuperer la matrice du body , grace a la fonction : Code : NewtonBodyGetMatrix(body,&mat.matrice[0][0]); 2- On l'envoi a OpenGL tous en la multipluant , grace a cette petite ligne : Code : glMultMatrixf(&mat.matrice [0][0]); 3- On dessine le Cube . Note : pour que tous ça marche trés bien : Vous vous souvenez de cette ligne ? : Code : NewtonBody *body = NewtonCreateBody(world,NewtonCreateBox(world,2,2,2,0)); On a mis 2 pour la taille. Mais dans la fonction DessinerCube() , on ne doit envoyer que la moitier , donc 1. Parce que dans notre fonction fait le double de la valeur qu'on lui a envoyer : par exemple : taille = 1. Dans la fonction on a mis (-taille jusqu'a taille) Et si vous calculer trés bien , vous découvrirez que : entre -1 et 1 , y a deux steps , -1 et 0 et 1. Et si on passez a la pratique ?!! Je vais simplement vous donner le code du main complet , vous découvrirez le nouveau tous seul comme des grands. J'ais également utiliser glPushMatrix(); et glPopMatrix(); ne pas encombrer les matrices quand il y'aura baucoup . Et voici le code : Code : #include <cstdlib> #include <iostream> #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> #include "Test.h" using namespace std ; void AppliquerForce(const NewtonBody *nbody) { float mass, ixx, iyy, izz; //On recupere la masse et l'inertie du corp NewtonBodyGetMassMatrix(nbody, &mass, &ixx, &iyy, &izz); //on cree une force tridimentionelle float force[3] = {0, 0, mass * -9.81}; //On les envoi au corps NewtonBodyAddForce(nbody, force); } int main(int argc, char *argv[]) { SDL_Event event ; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); SDL_WM_SetCaption("OpenGL / Newton Application", NULL); SDL_Surface *ecran = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(70,(double)640/480,1,1000); glEnable(GL_DEPTH_TEST); Mat mat ; Init_Mat(mat); NewtonWorld *world = NewtonCreate(0,0); NewtonBody *body = NewtonCreateBody(world,NewtonCreateBox(world,2,2,2,0)); NewtonBodySetMatrix(body,&mat.matrice[0][0]); NewtonBodySetMassMatrix(body,10,2,2,2); NewtonBodySetForceAndTorqueCallback(body, AppliquerForce); while (1) { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN : switch (event.key.keysym.sym) { case SDLK_ESCAPE: exit(0); break; } } SDL_Delay(8); NewtonUpdate(world, 1.0f/80.0f); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); GLfloat LampeDiffuse [] = {1.0f, 1.0f, 1.0f}; GLfloat LampeAmbient [] = {0.75f, 0.75f, 0.75f}; GLfloat LampePosition [] = {-5.0f, -5.0f, 10.0f, 5.0f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, LampeDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LampeDiffuse); glLightfv (GL_LIGHT0, GL_AMBIENT, LampeAmbient); glLightfv (GL_LIGHT0, GL_POSITION, LampePosition); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); glColor3f (1.0f, 1.0f, 1.0f); glColorMaterial (GL_FRONT_AND_BACK, GL_EMISSION); glColor3f (0.0f, 0.0f, 0.0f); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); gluLookAt(5,5,2,0,0,0,0,0,1); glPushMatrix(); NewtonBodyGetMatrix(body,&mat.matrice[0][0]); glMultMatrixf(&mat.matrice[0][0]); DessinerCube(1); glPopMatrix(); glFlush(); SDL_GL_SwapBuffers(); } return 0 ; } Si vous executez maintenant , vous devrez voir un cube qui tombe et qui passe !!! C'est du nouveau ça ???!!!!!! On va faire quelque chose de bon tout de suite ! Pour voir les effet de la physique il faut au moin qu'il y'ait 2 cubes. Maintenant que vous etes grands , vous allez créer un tous nouveau cube , mettez le un peut plus haut que ce premier. Et ce premier cube mettez , ça masse et ces inertie a 0 . puis lancez. Si vous etes bloquer , alors regardez ce code : Code : #include <cstdlib> #include <iostream> #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> #include "FunctionZS.h" using namespace std ; void AppliquerForce(const NewtonBody *nbody) { float mass, ixx, iyy, izz; //On recupere la masse et l'inertie du corp NewtonBodyGetMassMatrix(nbody, &mass, &ixx, &iyy, &izz); //on cree une force tridimentionelle float force[3] = {0, 0, mass * -9.81}; //On les envoi au corps NewtonBodyAddForce(nbody, force); } int main(int argc, char *argv[]) { SDL_Event event ; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); SDL_WM_SetCaption("OpenGL / Newton Application", NULL); SDL_Surface *ecran = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(70,(double)640/480,1,1000); glEnable(GL_DEPTH_TEST); Mat mat , mat2 ; Init_Mat(mat); Init_Mat(mat2); mat2.matrice[3][2] = 4.0f ; mat2.matrice[3][1] = 1.0f ; NewtonWorld *world = NewtonCreate(0,0); NewtonBody *body = NewtonCreateBody(world,NewtonCreateBox(world,2,2,2,0)); NewtonBodySetMatrix(body,&mat.matrice[0][0]); NewtonBodySetMassMatrix(body,0,0,0,0); NewtonBodySetForceAndTorqueCallback(body, AppliquerForce); NewtonBody *body2 = NewtonCreateBody(world,NewtonCreateBox(world,2,2,2,0)); NewtonBodySetMatrix(body2,&mat2.matrice[0][0]); NewtonBodySetMassMatrix(body2,10,2,2,2); NewtonBodySetForceAndTorqueCallback(body2, AppliquerForce); while (1) { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN : switch (event.key.keysym.sym) { case SDLK_ESCAPE: exit(0); break; } } SDL_Delay(8); NewtonUpdate(world, 1.0f/80.0f); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); GLfloat LampeDiffuse [] = {1.0f, 1.0f, 1.0f}; GLfloat LampeAmbient [] = {0.75f, 0.75f, 0.75f}; GLfloat LampePosition [] = {-5.0f, -5.0f, 10.0f, 5.0f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, LampeDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LampeDiffuse); glLightfv (GL_LIGHT0, GL_AMBIENT, LampeAmbient); glLightfv (GL_LIGHT0, GL_POSITION, LampePosition); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); glColor3f (1.0f, 1.0f, 1.0f); glColorMaterial (GL_FRONT_AND_BACK, GL_EMISSION); glColor3f (0.0f, 0.0f, 0.0f); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); gluLookAt(5,5,2,0,0,0,0,0,1); glPushMatrix(); NewtonBodyGetMatrix(body,&mat.matrice[0][0]); glMultMatrixf(&mat.matrice[0][0]); DessinerCube(1); glPopMatrix(); glPushMatrix(); NewtonBodyGetMatrix(body2,&mat2.matrice[0][0]); glMultMatrixf(&mat2.matrice[0][0]); DessinerCube(1); glPopMatrix(); glFlush(); SDL_GL_SwapBuffers(); } return 0 ; } TP : Créer une sphereCe TP est simple , mais c'est complétement du nouveau . Au lieu de créer deux cubes , pourquoi ne pas faire un seul , et pour remplacer la place de l'autre , on va créer une sphére. Donc le but de ce TP est de créer une sphére . On va pas faire tous le tour du monde pour changer 4 ou 5 lignes , on va allez directement au but. La premiére ligne qui doit changer est celle ci : Code : NewtonBody *body = NewtonCreateBody(world,NewtonCreateBox(world,2,2,2,0)); Et voici la fonction qui nous permet de créer une sphere : Code : NewtonCreateBody(world, NewtonCreateSphere(world,rayonX,rayonY,rayonZ,NULL)); Pour que la shére soit vraiment une sphére , il faut mettre la meme valeur a tous les rayons. La deuxiéme chose qui faut changer c'est le cube , on en a plus besoin d'afficher un cube , il nous faut une sphere , et une sphere avec OpenGL ça se fait avec les Quadrique . Je vous propose de créer une fonction , comme celle ci : Code : void DessinerSphere(GLfloat rayon , int R , int G , int B) { glColor3ub(R,G,B); GLUquadric* params = gluNewQuadric(); gluQuadricDrawStyle(params,GLU_FILL); gluQuadricTexture(params,GL_FALSE); gluSphere(params,rayon,30,30); gluDeleteQuadric(params); } Mais qu'est ce que je fait , si je continue comme ça , c'est moi qui va vous faire le TP . Allez a vous de jouer , vous savez tous ce qui vous faut , essayez de faire une sphere. ![]() POO : Classe CubeVous ne trouvez pas quelque chose bizzard . Je vais vous dire ce qui ne va pas , Alors pour créer un objet est l'afficher on doit écrire au moins 4 ligne , mais un programmeurest toujours un mort vivant , c'est le p^lus grand féniant . Donc il essaye d'ecrire le plus moins code. Comment peut-on rendre le travaille plus simple et plus rapide ? On va faire appele a la POO ( Programmation Orientée Objet ).Maintenant que vous connaissez toutes les procedure , normalement vous pouvez faire cette étape tous seul , oui comme des grands . Donc je ne vais pas trop trainer , je vais passer rapidement . La classe CubeIl faut tous d'abord créer 2 fichiers : 1- Cube.h -------- 2- Cube.cpp Le fichier Cube.hLe fichier Cube.h doit contenir ce code . Code : #include <iostream> #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> #include "FunctionZS.h" #ifndef CCUBE_H #define CCUBE_H class Cube { public : Cube(); ~Cube(); void Init(NewtonWorld *world, GLfloat taille[3], GLfloat position[3],GLfloat couleur[3], GLfloat masse = 10 , GLfloat inertie = 2, bool Mobile = true ); void setPosition(GLfloat position[3]); void dessiner(); private : NewtonBody *m_body ; GLfloat m_taille[3],m_position[3], m_couleur[3] ; GLfloat m_masse ; }; #endif Le fichier Cube.cppEt le Cube.cpp doit contenir ce code la : Code : #include "Cube.h" Cube::Cube() { m_position[0] = 0 ; m_position[1] = 0 ; m_position[2] = 0 ; m_taille[0] = 2 ; m_taille[1] = 2 ; m_taille[2] = 2 ; m_masse = 10.0f ; m_couleur[0] = 120 ; m_couleur[1] = 120 ; m_couleur[2] = 120 ; } Cube::~Cube() { NewtonDestroyBody(NewtonBodyGetWorld (m_body), m_body); } void Cube::Init(NewtonWorld *world, GLfloat taille[3], GLfloat position[3],GLfloat couleur[3], GLfloat masse , GLfloat inertie , bool Mobile ) { m_position[0] = position[0] ; m_position[1] = position[1] ; m_position[2] = position[2] ; m_taille[0] = taille[0] ; m_taille[1] = taille[1] ; m_taille[2] = taille[2] ; m_masse = masse ; m_couleur[0] = couleur[0] ; m_couleur[1] = couleur[1] ; m_couleur[2] = couleur[2] ; m_body = NewtonCreateBody(world, NewtonCreateBox(world,m_taille[0],m_taille[1],m_taille[2],NULL)); Mat matrice ; for (int x = 0 ; x < 4 ; ++x) for (int y = 0 ; y < 4 ; y++) { if (x == y) matrice.matrice [x][y] = 1.0f; else matrice.matrice [x][y] = 0.0f; } // On définit la matrice de manière à ce que l'objet soit placé aux positions // spécifiées en utilisant la dernière colonne de la matrice matrice.matrice [3][0] = m_position[0] ; matrice.matrice [3][1] = m_position[1] ; matrice.matrice [3][2] = m_position[2] ; NewtonBodySetMatrix(m_body,&matrice.matrice[0][0]); NewtonBodySetMassMatrix(m_body,m_masse,inertie,inertie,inertie); if (Mobile) { NewtonBodySetForceAndTorqueCallback(m_body, AppliquerForce); } m_taille[0] *= 0.5f ; m_taille[1] *= 0.5f ; m_taille[2] *= 0.5f ; } void Cube::setPosition(GLfloat position[3]) { Mat matrice ; for (int x = 0 ; x < 4 ; ++x) for (int y = 0 ; y < 4 ; y++) { if (x == y) matrice.matrice [x][y] = 1.0f; else matrice.matrice [x][y] = 0.0f; } // On définit la matrice de manière à ce que l'objet soit placé aux positions // spécifiées en utilisant la dernière colonne de la matrice matrice.matrice [3][0] = m_position[0] ; matrice.matrice [3][1] = m_position[1] ; matrice.matrice [3][2] = m_position[2] ; NewtonBodySetMatrix(m_body,&matrice.matrice[0][0]); } void Cube::dessiner() { Mat matrice ; NewtonBodyGetMatrix(m_body,&matrice.matrice[0][0]); glPushMatrix (); { glMultMatrixf(&matrice.matrice [0][0]); glColor3ub (m_couleur[0], m_couleur[1], m_couleur[2]); glBegin(GL_QUADS); glNormal3f (0.0f, 0.0f, 1.0f); glVertex3f(-m_taille[0], -m_taille[1], m_taille[2]); glVertex3f(m_taille[0], -m_taille[1], m_taille[2]); glVertex3f(m_taille[0], m_taille[1], m_taille[2]); glVertex3f(-m_taille[0], m_taille[1], m_taille[2]); glNormal3f (0.0f, 0.0f, -1.0f); glVertex3f(-m_taille[0], -m_taille[1], -m_taille[2]); glVertex3f(-m_taille[0], m_taille[1], -m_taille[2]); glVertex3f(m_taille[0], m_taille[1], -m_taille[2]); glVertex3f(m_taille[0], -m_taille[1], -m_taille[2]); glNormal3f (0.0f, 1.0f, 0.0f); glVertex3f(-m_taille[0], m_taille[1], -m_taille[2]); glVertex3f(-m_taille[0], m_taille[1], m_taille[2]); glVertex3f(m_taille[0], m_taille[1], m_taille[2]); glVertex3f(m_taille[0], m_taille[1], -m_taille[2]); glNormal3f (0.0f, -1.0f, 0.0f); glVertex3f(-m_taille[0], -m_taille[1], -m_taille[2]); glVertex3f(m_taille[0], -m_taille[1], -m_taille[2]); glVertex3f(m_taille[0], -m_taille[1], m_taille[2]); glVertex3f(-m_taille[0], -m_taille[1], m_taille[2]); glNormal3f (1.0f, 0.0f, 0.0f); glVertex3f(m_taille[0], -m_taille[1], -m_taille[2]); glVertex3f(m_taille[0], m_taille[1], -m_taille[2]); glVertex3f(m_taille[0], m_taille[1], m_taille[2]); glVertex3f(m_taille[0], -m_taille[1], m_taille[2]); glNormal3f (-1.0f, 0.0f, 0.0f); glVertex3f(-m_taille[0], -m_taille[1], -m_taille[2]); glVertex3f(-m_taille[0], -m_taille[1], m_taille[2]); glVertex3f(-m_taille[0], m_taille[1], m_taille[2]); glVertex3f(-m_taille[0], m_taille[1], -m_taille[2]); glEnd (); } glPopMatrix(); } Le TestMaintenant vous n'avais qu'a utiliser la class dans le main.cpp, pour créer un cube sans trop écrire. Le main.cppCode : #include <cstdlib> #include <iostream> #include <SDL/SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <Newton/Newton.h> // On inclue le fichier Cube.h pour utiliser la class Cube #include "Cube.h" using namespace std ; int main(int argc, char *argv[]) { SDL_Event event ; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); SDL_WM_SetCaption("OpenGL / Newton Application", NULL); SDL_Surface *ecran = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(70,(double)640/480,1,1000); glEnable(GL_DEPTH_TEST); // Creation des cube //----------------------------------------- float taille[3] = { 10 , 10 , 0.25 } , position[3] = { 0 , 0 , 0 } , couleur[3] = { 100 , 100 , 100 } ; Cube sol ; sol.Init(world, taille, position, couleur, 0, 0, false); taille[0] = 1 ; taille[1] = 1 ; taille[2] = 1 ; position[0] = 0 ; position[1] = 0 ; position[2] = 5 ; Cube boite1 ; boite1.Init(world, taille, position, couleur, 10, 2, true); position[0] = 0 ; position[1] = 0.5 ; position[2] = 10 ; Cube boite2 ; boite2.Init(world, taille, position, couleur, 10, 2, true); //-------------------//----------------------------------------- while (1) { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN : switch (event.key.keysym.sym) { case SDLK_ESCAPE: exit(0); break; } } SDL_Delay(8); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); GLfloat LampeDiffuse [] = {1.0f, 1.0f, 1.0f}; GLfloat LampeAmbient [] = {0.75f, 0.75f, 0.75f}; GLfloat LampePosition [] = {-5.0f, -5.0f, 10.0f, 5.0f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, LampeDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LampeDiffuse); glLightfv (GL_LIGHT0, GL_AMBIENT, LampeAmbient); glLightfv (GL_LIGHT0, GL_POSITION, LampePosition); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); glColor3f (1.0f, 1.0f, 1.0f); glColorMaterial (GL_FRONT_AND_BACK, GL_EMISSION); glColor3f (0.0f, 0.0f, 0.0f); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); gluLookAt(5,5,2,0,0,0,0,0,1); // On dessine les cubes //---------------------------------- sol.dessiner ; boite1.dessiner ; boite2.dessiner ; //----------------------//---------------------------------- glFlush(); SDL_GL_SwapBuffers(); } return 0 ; } Création d'un Loader - C - 1Dans cette partie , je vais vous apprendre a créer un loader pour le fichier DirectX, avec la plus simple méthode. Et quand vous découvrirez le truc, vous allez pouvoir créer d'autre loader pour d'autres fichiers. C'est la chose d'ont vous révez tous les temps. On va découper ce chapitre en 2 , la 1ere on va faire le loader avec le C. Dans la 2eme ,on le fera avec le C++. Alors pour la 1ere partie , ou on va faire notre loader bassé sur le C , les fonctions principale sont : -> fopen . -> fscanf. -> fclose Mais ça ne sera pas tous , on aura également d'utiliser les boucles et quelques chose d'autre. Et si on commençait tout de suite , ça serait déja pas mal. Présentation du format DirectXMais avant de faire quoi que se soit , il faut avoir une petite idée sur ce qu'il y a dans un fichier DirectX. voyant la structure d'un simple cube : Code : xof 0303txt 0032 template VertexDuplicationIndices { <b8d65549-d7c9-4995-89cf-53a9a8b031e3> DWORD nIndices; DWORD nOriginalVertices; array DWORD indices[nIndices]; } template XSkinMeshHeader { <3cf169ce-ff7c-44ab-93c0-f78f62d172e2> WORD nMaxSkinWeightsPerVertex; WORD nMaxSkinWeightsPerFace; WORD nBones; } template SkinWeights { <6f0d123b-bad2-4167-a0d0-80224f25fabb> STRING transformNodeName; DWORD nWeights; array DWORD vertexIndices[nWeights]; array float weights[nWeights]; Matrix4x4 matrixOffset; } Frame RootFrame { FrameTransformMatrix { 1.000000,0.000000,0.000000,0.000000, 0.000000,1.000000,0.000000,0.000000, 0.000000,0.000000,-1.000000,0.000000, 0.000000,0.000000,0.000000,1.000000;; } Frame Cube { FrameTransformMatrix { 1.000000,0.000000,0.000000,0.000000, 0.000000,1.000000,0.000000,0.000000, 0.000000,0.000000,1.000000,0.000000, 0.000000,0.000000,0.000000,1.000000;; } Mesh { 24; 1.000000; 1.000000; -1.000000;, 1.000000; -1.000000; -1.000000;, -1.000000; -1.000000; -1.000000;, -1.000000; 1.000000; -1.000000;, 1.000000; 1.000000; 1.000000;, -1.000000; 1.000000; 1.000000;, -1.000000; -1.000000; 1.000000;, 1.000000; -1.000000; 1.000000;, 1.000000; 1.000000; -1.000000;, 1.000000; 1.000000; 1.000000;, 1.000000; -1.000000; 1.000000;, 1.000000; -1.000000; -1.000000;, 1.000000; -1.000000; -1.000000;, 1.000000; -1.000000; 1.000000;, -1.000000; -1.000000; 1.000000;, -1.000000; -1.000000; -1.000000;, -1.000000; -1.000000; -1.000000;, -1.000000; -1.000000; 1.000000;, -1.000000; 1.000000; 1.000000;, -1.000000; 1.000000; -1.000000;, 1.000000; 1.000000; 1.000000;, 1.000000; 1.000000; -1.000000;, -1.000000; 1.000000; -1.000000;, -1.000000; 1.000000; 1.000000;; 6; 4; 0, 3, 2, 1;, 4; 4, 7, 6, 5;, 4; 8, 11, 10, 9;, 4; 12, 15, 14, 13;, 4; 16, 19, 18, 17;, 4; 20, 23, 22, 21;; MeshMaterialList { 1; 6; 0, 0, 0, 0, 0, 0;; Material Material { 0.800000; 0.800000; 0.800000;1.0;; 0.500000; 1.000000; 1.000000; 1.000000;; 0.0; 0.0; 0.0;; } //End of Material } //End of MeshMaterialList MeshNormals { 24; 0.577349; 0.577349; -0.577349;, 0.577349; -0.577349; -0.577349;, -0.577349; -0.577349; -0.577349;, -0.577349; 0.577349; -0.577349;, 0.577349; 0.577349; 0.577349;, -0.577349; 0.577349; 0.577349;, -0.577349; -0.577349; 0.577349;, 0.577349; -0.577349; 0.577349;, 0.577349; 0.577349; -0.577349;, 0.577349; 0.577349; 0.577349;, 0.577349; -0.577349; 0.577349;, 0.577349; -0.577349; -0.577349;, 0.577349; -0.577349; -0.577349;, 0.577349; -0.577349; 0.577349;, -0.577349; -0.577349; 0.577349;, -0.577349; -0.577349; -0.577349;, -0.577349; -0.577349; -0.577349;, -0.577349; -0.577349; 0.577349;, -0.577349; 0.577349; 0.577349;, -0.577349; 0.577349; -0.577349;, 0.577349; 0.577349; 0.577349;, 0.577349; 0.577349; -0.577349;, -0.577349; 0.577349; -0.577349;, -0.577349; 0.577349; 0.577349;; 6; 4; 0, 3, 2, 1;, 4; 4, 7, 6, 5;, 4; 8, 11, 10, 9;, 4; 12, 15, 14, 13;, 4; 16, 19, 18, 17;, 4; 20, 23, 22, 21;; } //End of MeshNormals } } } Si il y'avait une texture pour ce cube , on l'aurez trouver juste au dessous mais pour cette fois, on se contontera seulement de charger un modele 3D , sans le texturer. Important : Le modele que vous devez charger doit étre de faces rectangulaires et non triangulaires, Maitenant , faisant simplifier le travail. Pour éviter de se déplacer dans le fichier aprés l'ouverture, on enlévera simplement ce que n'est pas important . Ce qui est important est la partie "Mesh {", donc ce que j'obtiens moi c'est ceci : vous pouvez copier le contenu et le placer dans un fichier texte , puis l'enregistrer sous "cube.x" Code : 24; 1.000000; 1.000000; -1.000000;, 1.000000; -1.000000; -1.000000;, -1.000000; -1.000000; -1.000000;, -1.000000; 1.000000; -1.000000;, 1.000000; 1.000000; 1.000000;, -1.000000; 1.000000; 1.000000;, -1.000000; -1.000000; 1.000000;, 1.000000; -1.000000; 1.000000;, 1.000000; 1.000000; -1.000000;, 1.000000; 1.000000; 1.000000;, 1.000000; -1.000000; 1.000000;, 1.000000; -1.000000; -1.000000;, 1.000000; -1.000000; -1.000000;, 1.000000; -1.000000; 1.000000;, -1.000000; -1.000000; 1.000000;, -1.000000; -1.000000; -1.000000;, -1.000000; -1.000000; -1.000000;, -1.000000; -1.000000; 1.000000;, -1.000000; 1.000000; 1.000000;, -1.000000; 1.000000; -1.000000;, 1.000000; 1.000000; 1.000000;, 1.000000; 1.000000; -1.000000;, -1.000000; 1.000000; -1.000000;, -1.000000; 1.000000; 1.000000;; 6; 4; 0, 3, 2, 1;, 4; 4, 7, 6, 5;, 4; 8, 11, 10, 9;, 4; 12, 15, 14, 13;, 4; 16, 19, 18, 17;, 4; 20, 23, 22, 21;; Prét pour l'analysation INFRAROUGE ?[b] -> Donc la premiére ligne contient la valeur [b]24, qui peut deviner ce que c'est ? . Acune idée ? Dacords , je vais vous le dire 24 c'est le nombre de vertices , notez que chaque vertice contient 3 flottantes ( x , y , z ). -> puis ça viens les coordonnnées des vertices qui sont séparer par des ";" ( point virgule ) -> puis voici un autre nombre : "6" , celui ci est le nombre de face . ( Et oui , c'est vous avez réflichis un peut vous aurez découvert qu'un cube a 6 faces . -> puis ... prenons cette ligne : 4; 0, 3, 2, 1;, ->->Regardez bien a ces nombres . Le premier "4" indique le nombre de vertices dans le face. Et oui , c'est 4, donc c'est des faces rectangulaires. Note: on peut y trouver "3", ce qui veut dire que la face est triangulaire. ->-> comme vous voyez , y a 4 nombres qui suivent ce sont les indices des vertices. Par exemple:0, 3, 2, 1;, Cela veut dire que cette face de 4 vertices , ce construit de ces 4 vertices : pour les indices , il nous procure la position de la vertice . Par exemple : 0 veut fait référence a la premiére vertice , 3 fait référence a la 4 vertice ... et ainsi de suite ... maintenat vous savez a quoi on a afaire , il nous reste plus qu'a coder le code. Vous voulez faire une classe pour charger les modele ? Moi je ne vais pas vous dire la façon de faire une classe , je vais vous apprendre a charger le modele , si vous voulez créer une classe , vous n'avais qu'a la faire a votre propre magniére. Ramassage des donnéesDonc vous devez avoir ce code la dans votre main ( code de fenetrage ) Code : #include <cstdlib> #include <iostream> #include <SDL/SDL.h> #include <gl/gl.h> #include <gl/glu.h> using namespace std ; int main(int argc, char** argv) { SDL_Event event ; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); SDL_Surface *ecran = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(80,(double)800/600,1,1000); while (1) { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN : switch (event.key.keysym.sym) { case SDLK_ESCAPE: exit(0); break; } } SDL_Delay(6); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); GLfloat LampeDiffuse [] = {1.5f, 1.5f, 1.5f}; GLfloat LampeAmbient [] = {1.0f, 1.0f, 1.0f}; GLfloat LampePosition [] = {-5.0f, -5.0f, 10.0f, 5.0f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, LampeDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LampeDiffuse); glLightfv (GL_LIGHT0, GL_AMBIENT, LampeAmbient); glLightfv (GL_LIGHT0, GL_POSITION, LampePosition); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); glColor3f (1.0f, 1.0f, 1.0f); glColorMaterial (GL_FRONT_AND_BACK, GL_EMISSION); glColor3f (0.0f, 0.0f, 0.0f); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); gluLookAt(10,10,5,0,0,0,0,0,1); glFlush(); SDL_GL_SwapBuffers(); } return 0 ; } Voila , maintanant on peut vraiment commencer . Donc la premiére des choses a faire est d'ouvrir le fichier "simpleCube.x" , mois je l'ais mis dans le disque locale "C". Donc la procedure a suivre est celle ci : Note: Mettez ce code juste avant la boucle principale "while". Code : FILE*file = fopen("C:/simpleCube.x","r"); Puis on doit scaner le fichier pour récupérer le nombre de Vertices , grace a cette petite ligne. Code : int nbrVertice ; fscanf(file,"%i;",&nbrVertice); Puis nous devons créer le tableau de flottantes pour y mettre les informations des vertices . Donc nous avons besoin d'un tableau comme cellui ci : Code : float vertice[nbrVertice][3]; Puis nous allons faire une boucle "for" , pour charger les coordonnées des vertices. Code : for(int i = 0 ; i < nbrVertice ; i++) { fscanf(file,"%f; %f; %f;,",&vertice[i][0],&vertice[i][1],&vertice[i][2]); } Et puis les face , on scane le fichier pour avoir le nombre de face : Code : int nbrFace ; fscanf(file,";%i;",&nbrFace); Puis , on crée un tableau d'entiers pour stocké les face . Code : int face[nbrFace][4]; int NVPF ; // NVPF : Nombre Vertices Par Face for(int i = 0 ; i < nbrFace ; i++) { fscanf(file,"%i; %i, %i, %i, %i;,",&NVPF,&face[i][0],&face[i][1],&face[i][2],&face[i][3]); } Création d'un Loader - C - 2Et enfin voici ce qu'on jusqu'ici : Code : #include <cstdlib> #include <iostream> #include <SDL/SDL.h> #include <gl/gl.h> #include <gl/glu.h> using namespace std ; int main(int argc, char** argv) { SDL_Event event ; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); SDL_Surface *ecran = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(80,(double)800/600,1,1000); FILE*file = fopen("C:/simpleCube.x","r"); int nbrVertice ; fscanf(file,"%i",&nbrVertice); float vertice[nbrVertice][3]; for(int i = 0 ; i < nbrVertice ; i++) { fscanf(file,"%f; %f; %f;,",&vertice[i][0],&vertice[i][1],&vertice[i][2]); } int nbrFace ; fscanf(file,"%i",&nbrFace); int face[nbrFace][4]; int NVPF ; // NVPF : Nombre Vertices Par Face for(int i = 0 ; i < nbrFace ; i++) { fscanf(file,"%i; %i, %i, %i, %i;,",&NVPF,&face[i][0],&face[i][1],&face[i][2],&face[i][3]); } while (1) { SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN : switch (event.key.keysym.sym) { case SDLK_ESCAPE: exit(0); break; } } SDL_Delay(6); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW ); glLoadIdentity( ); glEnable (GL_DEPTH_TEST); glEnable (GL_COLOR_MATERIAL); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); GLfloat LampeDiffuse [] = {1.5f, 1.5f, 1.5f}; GLfloat LampeAmbient [] = {1.0f, 1.0f, 1.0f}; GLfloat LampePosition [] = {-5.0f, -5.0f, 10.0f, 5.0f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, LampeDiffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, LampeDiffuse); glLightfv (GL_LIGHT0, GL_AMBIENT, LampeAmbient); glLightfv (GL_LIGHT0, GL_POSITION, LampePosition); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); glColor3f (1.0f, 1.0f, 1.0f); glColorMaterial (GL_FRONT_AND_BACK, GL_EMISSION); glColor3f (0.0f, 0.0f, 0.0f); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 128); gluLookAt(10,10,5,0,0,0,0,0,1); glFlush(); SDL_GL_SwapBuffers(); } return 0 ; } Maintenant qu'on a tous ce qu'on veut on passe au [b]RENDER ( RENDU )[/b] Dessiner le modeleOn a maintenant tous ce qui compte le plus , donc cette partie sera un gateau . De meme ça ne demande pas d'expliquation en voici le code : Code : glColor3ub(0,0,255); glBegin(GL_QUADS); for(int i = 0 ; i < nbrFace ; i++) { glVertex3f(vertice[face[i][0]][0],vertice[face[i][0]][1],vertice[face[i][0]][2]); glVertex3f(vertice[face[i][1]][0],vertice[face[i][1]][1],vertice[face[i][1]][2]); glVertex3f(vertice[face[i][2]][0],vertice[face[i][2]][1],vertice[face[i][2]][2]); glVertex3f(vertice[face[i][3]][0],vertice[face[i][3]][1],vertice[face[i][3]][2]); } glEnd(); Comme , je vous l'ais dit tout en haut , le tableau face contient la position des vertice pour les utiliser aprés d'une façon plus juste . Question : Qu'est ce qui prouve que tu ne trompe pas , enfin on sais tous créer un cube , non ? Vous n'avez qu'a essayer sur un autre modele , vous pouvez exoprter des modele depuis blender Mais attention il faut enlever tous ce qu'il y a avant le nombre de vertice , comme on la fait avec le cube . 2éme chose , le modele que vous voulez charger ne doit pas etre de face triangulaire. ExerciceOn a fait un loader qui charge les fichier DirectX de faces triangulaires , mais c'est trés simple de le modifier pour qu'il devient un loader de faces rectangulaires , Alors a vous de jouer . Et j'ais une petite récomponse , pour celui qui arrive a modifier le loader : Voici un modele 3D de face triangulaire , et croyez moi , CE N'EST PAS UN CUBE . ( un personnage humain ). Le modele Sydney.x[url][/url] le tuto n'est pas encore terminer (entrain de rédaction). Rédigé par OSasuke
|
||
|
Hébergeur du site : 1and1.fr Site de création de Jeux Vidéo Apprenez à créer vos propres Jeux Video A propos de la construction du site... |
373010 pages ont été consultées sur le site ! Dont 262 pages pendant les 24 dernières heures. Page générée en 0.696 secondes Nos partenaires - Otium Production : Aide aux débutants à créer leurs jeux - A.C.S.E.L. : Club de patinage artistique de Caen |