Programmer en D avec SDL et openGL
Bonjour cher lecteur,
Aujourd'hui je vous présente comment programmer en D pour faire des applications 2D et 3D grâce à SDL et openGL.
Prérequis
Ajouter le dépôt D comme expliqué ici: Depôt pour le
langage D
Installer ensuite les paquets Derelict-SDL et Derelict-GL, les bibliothèques
statiques et de développement soit
# yum install derelict-SDL* derelict-GL*
Exemple de code
Créons un fichier main.d qui contient
private import Display; private import derelict.sdl.sdl: SDL_Event, SDL_PollEvent, SDL_QUIT; void main(){ bool isRunning = true; Display display = new Display(); scope(exit) display.cleanup(); while(isRunning){ isRunning = display.event(); // clear the screen. by default it clears to black display.clear(); //display graphic display.drawGLFrame(); } }
- On crée un booléen pour la boucle principale du programme
- On crée une instance de classe Display que l'on verra son contenu plus loin
- Lorsque le programme se terminera, il executera obligatoirement la méthode display.cleanup()
- Tant qu'un évènement donne pas l'ordre de quitter (bouton fermer par
exemple) le booléen sera vrai
- On on rafraichit l'image
Maintenant créons notre fichier Display.d
private import derelict.sdl.sdl; private import derelict.opengl.gl; private import derelict.opengl.glu; private import tango.stdc.stringz; //private import tango.io.Stdout; class Display{ // horizontal and vertical screen resolution private uint height; private uint width; // number of bits per pixel used for display. 24 => true color private uint bitsPerPixel; // field of view => the angle our camera will see vertically private float fov; // distance of the near clipping plane private float nearPlane; // distance of the far clipping plane private float farPlane; /** * Setup some basic OpenGL parameters */ private void setupGL(){ // switch to the projection mode matrix glMatrixMode(GL_PROJECTION); // load the identity matrix for projection glLoadIdentity(); // setup a perspective projection matrix gluPerspective(fov, cast(float)height / width, nearPlane, farPlane); // switch back to the modelview transformation matrix glMatrixMode(GL_MODELVIEW); // load the identity matrix for modelview glLoadIdentity(); } /** * Library initializer */ private void init(){ // initialize SDL, GL and GLU Derelict modules DerelictSDL.load(); DerelictGL.load(); DerelictGLU.load(); // initialize SDL's VIDEO module SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); // enable double-buffering SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // create our OpenGL window SDL_SetVideoMode(height, width, bitsPerPixel, SDL_OPENGL); SDL_WM_SetCaption(toStringz("D is the best"), null); setupGL(); } /** * Constructor */ public this(){ height = 800; width = 600; bitsPerPixel= 24; fov = 90; nearPlane = 0.1f; farPlane = 100.f; init(); } public ~this(){ //cleanup(); } /** * be nice and release all resources */ public static void cleanup(){ // tell SDL to quit if(SDL_Quit !is null) SDL_Quit(); // release GL, GLU and SDL's shared libs DerelictGLU.unload(); DerelictGL.unload(); DerelictSDL.unload(); } public void clear(){ glClear(GL_COLOR_BUFFER_BIT); } public void drawGLFrame(){ glBegin(GL_TRIANGLES); glColor3f (1, 0, 0); glVertex3f(-1, -1, -2); glColor3f (0, 1, 0); glVertex3f(1, -1, -2); glColor3f (0, 0, 1); glVertex3f(0, 1, -2); glEnd(); // swap the buffers, making our backbuffer the visible one SDL_GL_SwapBuffers(); } public bool event(){ bool isRunning = true; SDL_Event event; // handle all SDL events that we might've received in this loop iteration while(SDL_PollEvent(&event)){ switch(event.type){ // user has clicked on the window's close button case SDL_QUIT: isRunning = false; break; // by default, we do nothing => break from the switch default: break; } //Stdout.formatln("event.type: {}",event.type); } return isRunning; } }
Ici on crée une classe pour gérer l'affichage que l'on appelle Display.
Elle contient des attributs pour:
- La résolution de la fenêtre (height, width)
- La qualité de l'image (bitsPerPixel)
- Angle de caméra (fov)
- Spécifie la distance minimum entre le spectateur par rapport au plan (nearPlane)
- Spécifie la distance maximum entre le spectateur par rapport au plan (farPlane)
Le constructeur par défaut initialise les attributs ainsi que les
bibliothèques openGL/SDL par l'appel de la fonction init()
La fonction event renvoie un booléen, faux si on souhaite quitter sinon
vrai
La fonction drawGLFrame dessine un triangle
La fonction statique cleanup est optionnelle elle permet de s'assurer de
quitter proprement
Je vous laisse potasser sur le code
Compilation
Pour compiler l'application on doit spécifier les bibliothèques avec lesquelles le programme est lié soit ici:
$ ldc -g -w -L -ldl -L -lDerelictGL -L -lDerelictGLU -L -lDerelictSDL -L -lDerelictUtil *.d -of example
Produira un éxécutable nommé example
Éxécution
Simplement, après compilation
$ ./example
Résultat
C'est beau hein!
Liens
A bientôt
Signé: bioinfornatics, Jonathan MERCIER