Un triangle et un Quad.

Un triangle et un Quad.

glVertex3f,gluPerspective,gluLookAt,glTranslatef...

Voir version :

Pas de dépendances

Télécharger :

#include <windows.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>

#pragma comment(lib,"sdl.lib")
#pragma comment(lib,"sdlmain.lib")
#pragma comment(lib, "opengl32.lib" )
#pragma comment(lib, "glu32.lib" )

#define XRESOL 400
#define YRESOL 300

int initGL()
{
    // init
    glShadeModel(GL_FLAT);
    glClearColor(0.0f,0.0f,0.0f,0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );  // active l'antialiasing
    // cadrage
    glViewport(0,0,XRESOL,YRESOL);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f,4.0/3.0,1.0f,100.0f);
    return 1;
}

int KeyHit()
{
    SDL_Event e;
    if (SDL_PollEvent(&e))
        if (e.type == SDL_KEYDOWN)
            return 1;
    return 0;
}

int main(int argc, char **argv)
{
    SDL_Surface *surface;
    float e = 0.0f;
    SDL_Init(SDL_INIT_VIDEO);
    surface = SDL_SetVideoMode(XRESOL,YRESOL,32,SDL_HWSURFACE|SDL_OPENGL);
    initGL();
    while(!KeyHit())
    {
        e+=(float)0.005;
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
        gluLookAt(0,0,0,0,0,-1,0,1,0);
        glTranslatef(-1.5f,0.0f,-6.0f);
        glBegin( GL_TRIANGLES );
            glVertex3f(  0.0f,  1.0f, e );
            glVertex3f( -1.0f, -1.0f, e );
            glVertex3f(  1.0f, -1.0f, e );
        glEnd( );                          

        glTranslatef( 3.0f, 0.0f, 0.0f );
        glBegin( GL_QUADS );               
            glVertex3f( -1.0f,  1.0f, e );
            glVertex3f(  1.0f,  1.0f, e );
            glVertex3f(  1.0f, -1.0f, e );
            glVertex3f( -1.0f, -1.0f, e );
        glEnd( );                          

        SDL_GL_SwapBuffers( );
    }
    SDL_Quit();
    return 0;
}



Commentaires

	Voici un exemple d'OpenGL a partir de SDL

  necessite d'installer SDL. OpenGL, quant a lui, est déja installé sur tous les compilateurs courants.
  Les librairies a linker :

  sdlmain.lib
  sdl.lib

  mais ajoutez maintenant également :

  opengl32.lib
  glu32.lib

* pour les termes techniques inévitables pour la 3d, réferez vous a la partie de ce site : 

	http://http://fvirtman.free.fr/deim/index.html


APRES LES EXPLICATIONS, PLEIN DE PETITS TESTS A FAIRE EN MODIFIANT LE PROGRAMME POUR COMPRENDRE LA PUISSANCE DU TRUC

  Voila vous etes pret a lancer ce programme. Il s'agit d'un rectangle et d'un carré, blanc, qui viennent vers vous

	Voici les explications :
	Nous partons du main :

  SDL_Init(SDL_INIT_VIDEO);  > initialise SDL (voir tuto SDL)

  surface=SDL_SetVideoMode(XRESOL,YRESOL,32,SDL_HWSURFACE|SDL_OPENGL);
  --> intialise le mode graphique en XRESOL*YRESOL en 32 bpp. Met la surface principale en VRAM (SDL_HWSURFACE)
  et prepare a l'utilisation de OpenGL, comme vu sur le deuxieme parametre du Flag
  Vous pouvez changer cela en ce que vous voulez. Vouc pouvez également préciser SDL_FULLSCREEN
  XRESOL et YRESOL sont définis en haut du programme.

  Passons a l'initialisation de OpenGL : si vous ne comprenez pas tout ce qui suit, recopiez toujours ça a la base...

	glShadeModel( GL_SMOOTH ); // dit a OpenGL qu'il faudra adoucir les bords des polygones. (sinon GL_FLAT)
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );  // la couleur de fond sera du noir code : 0,0,0,0 (RGBA) (note : on défini les couleurs entre 0 et 1 dans OpenGL)
    glClearDepth( 1.0f );  // laissez ce parametre tel quel, c'est pour le Z_buffer.
    glEnable( GL_DEPTH_TEST );  // active le Z_buffer
    glDepthFunc( GL_LEQUAL );  // défini qu'un polygone est devant un autre si son Z de profondeur est plus petit ou égal <-- toujours laisser ça comme ça
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );  // active l'antialiasing
    // cadrage

	glViewport( 0, 0,XRESOL,YRESOL);  // la 3d sera rasterisée sur le rectangle fenetre 0,0,1024,768 : donc sur toute la fenetre, si vous mettez plus petit, alors la projection ne prendra pas toute la fenetre.
    glMatrixMode( GL_PROJECTION );  // Selectionne la matrice de projection
    glLoadIdentity( );		// mise a l'identité de la matrice de projection (nécessaire avant le gluPerpective)
    gluPerspective( 45.0f, 4.0/3.0, 1.0f, 100.0f );  //définition du frustrum : 45° d'ouverture, raport 4/3, plan near = 1, plan far = 100


	OpenGL est maintenant initialisé.

  Concentrons nous sur le while du main : 

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
--> n'oubliez pas que l'on travaille en double buffer. On a donc 2 ecrans. L'un est affiché pendant que l'on travaille sur l'autre
La premiere chose a faire est d'effacer l'écran sur lequel on va dessiner : on efface tout.
glClear(GL_COLOR_BUFFER_BIT) permert cela : ça colorie l'écran en la couleur de fond définie. Voir l'initialisation : on a défini du noir
GL_DEPTH_BUFFER_BIT permet d'effacer aussi le Z-buffer.

    glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
--> Vous remettez en place le repere du monde sur l'origine (nous verrons bientot qu'on peut déplacer ce repere.
Il est important, au début de chaque frame, de remettre ce repere a l'origine
La matrice s'appelle GL_MODELVIEW, on la selectionne, et on la met a l'identité (valeur d'origine)

   	gluLookAt(0,0,0,0,0,-1,0,1,0);
--> positionne la caméra : encore une chose importante :
    on peut prendre les parametre par 3 :
	0,0,0  -> centre de la caméra
	0,0,-1 -> "at" : point ou la caméra regarde
	0,1,0  -> vecteur "up"

ensuite :

	glTranslatef( -1.5f, 0.0f, -6.0f );
    glBegin( GL_TRIANGLES );
      glVertex3f(  0.0f,  1.0f, e );
      glVertex3f( -1.0f, -1.0f, e );
      glVertex3f(  1.0f, -1.0f, e );
    glEnd( );                          

C'est ici qu'on dessine !!
remarquez que la premiere chose que l'on fait est un gl_Translatef, ça sert a faire une translation du repere global
si vous enelevez cette ligne, le triangle sera dessiné dans le repere global.
vu les coordonnées, ce sera un triangle dessiné au milieu.
Puis on dessine le triangle :
Tout comme un bloc, le dessin se fera entre un glBegin et un glEnd, toujours !
On spécifie dans le glBegin qu'on dessinera des triangles, ainsi, il assembleras les points par 3
Note : on peut donc définir entre un glBegin, et un glEnd, autant de points que l'on veut.
dans le cas d'un GL_TRIANGLES, il faudra que ce soit un multiple de 3 !

  avec glVertex3f, on défini les 3 coordonnées d'un point !
  ce qui fait l'animation, c'est le e, qui varie, ainsi, on dessine le triangle a chaque fois pas tout a fait au meme endroit
  et n'oublions que dessiner un objet un peu plus loin a chaque frame, c'est ça une animation...



    glTranslatef( 3.0f, 0.0f, 0.0f );
    glBegin( GL_QUADS );               
      glVertex3f( -1.0f,  1.0f, e );
      glVertex3f(  1.0f,  1.0f, e );
      glVertex3f(  1.0f, -1.0f, e );
      glVertex3f( -1.0f, -1.0f, e );
    glEnd( );                          


pour le quad, on specifie GL_QUADS, cette fois ci, les points sont au multiple de 4
le glTranslate est a partir du derniere repere, donc a partir de celui utilisé pour le triangle !
N'oubliez pas, si vous voulez repartir du repere initiale :
    glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();


Quelques astuces :

1) passez en FULLSCREEN : SDL_FULLSCREEN dans le SDL_SetVideoMode
2) faites un fond rouge : 1,0,0,0 dans glClearColor


*****

Maintenant, passons a la couleur !!

Vous constatez que le triangle et le Quad dont blancs : c'est la couleur par défaut.
Vous voulez qu'ils soient bleus :

juste apres le GluLookAt, mettez :

  glColor3f(0,0,1);

Comme vous voyez, ça englobe le quad avec. Pourquoi ?
parce que vous définissez un "pinceau" bleu, et que tant que vous ne changez pas, ça reste bleu !
Maintenant, juste apres le premier glEnd(), définissez :

  glColor3f(1,1,0);

Joli non ?

Maintenant plus fort : au lieu de définir le quad entier en bleu, on va définir une couleur pour chaque point !

  modifiez le code pour avoir cela : (assurez vous avant que votre fond est bien noir)


	glTranslatef( -1.5f, 0.0f, -6.0f );
    glBegin( GL_TRIANGLES );
      glColor3f(1,0,0);
	  glVertex3f(  0.0f,  1.0f, e );
      glColor3f(0,1,0); 
      glVertex3f( -1.0f, -1.0f, e );
      glColor3f(0,0,1);
	  glVertex3f(  1.0f, -1.0f, e );
    glEnd( );                          


    glTranslatef( 3.0f, 0.0f, 0.0f );
    glBegin( GL_QUADS );               
		glColor3f(1,0,0);
		glVertex3f( -1.0f,  1.0f, e );
		glColor3f(0,1,0);
		glVertex3f(  1.0f,  1.0f, e );
		glColor3f(0,0,1);
		glVertex3f(  1.0f, -1.0f, e );
		glColor3f(1,1,0);
		glVertex3f( -1.0f, -1.0f, e );
    glEnd( );                          

* si vous ne voyez pas de dégradés, c'est que vous vous etes planté
Cependant, un dégradé fait penser a de la douceur, donc a du GL_SMOOTH
si vous remplacez le GL_SMOOTH dans glShadeModel par GL_FLAT, alors vous désactivez le dégradé

****

  Un autre test sympa :
  comme vous voyez, la coordonnée z des objets est toujours "e"
  donc vous avez toujours tout sur un meme plan !
  pour de la 3d, on appelle ça "ne pas profiter de la puissance du truc"
  donc on va faire en sorte de faire de l'anime dans l'espace :

  remplacez le e du premier glVertex3f par un -e
  cette fois ci, un point partira en arriere alors que les autres viendront toujours en avant
  ça va allonger le triangle, le coucher, voyez plutot en essayant....

*****

Un autre petite test : rétablissez le e au lieu du -e
comme vous voyez, le tout vient vers la caméra, puis disparait, normal ça passe derriere...
dans le :

     	gluLookAt(0,0,0,0,0,-1,0,1,0);
si vous remplacez par :
     	gluLookAt(0,0,0,0,0,1,0,1,0);

alors vous allez regarder derriere !
donc au début : écran noir !
mais au bout d'un moment, les formes vont donc passer de l'autre coté, et ce vous les verrez s'éloigner !

        O->      <<Formes
	  <-O        <<Formes

*****
Vecteur up ?
Si vous ne savez pas a quoi sert le vecteur up, mettez vous debout, ne bougez plus : votre centre O est donc fixe
fixez un point devant vous : votre centre "at" est fixe
mais hochez la tete : bien qu'étant fixe et visant le meme point, c'est pas la meme vue !
le vecteur up a bougé !
le vecteur up doit toujours etre normalisé (sa longueur vaut 1)
On va illustrer cela :

  essayez :
     	gluLookAt(0,0,0,0,0,-1,cos(e),sin(e),0);

au fur et a mesure du temps, e avance, et on s'appuie dessus pour faire tourner le vecteur e
(ça demande un peu de trigo) mais bon, disons que l'exemple montre que, pendant que les triangles arrivent,
on hoche la tete (et on tourne sans s'arreter :))
(n'oubliez pas, pour cette exemple : #include <math.h>)

******


Voici la base de OpenGL !! vous définissez des polygones dans l'esapces, vous les faites bouger, 
et/ou vous faites bouger votre caméra, et tout va bien !!
Cet exemple ne parle pas de lumieres, ni de textures, qui sont également dispo dans OpenGL, mais
ça permet de bien prendre en main OpenGL :)