SDL et la 3D





Vous trouvez que SDL c'est bien, vous adorez les jeux en 2D comme Gauntlet ou SuperMarioLand mais vous désirez tater de la 3D. SDL ne contient aucune primitive à cet effet, car réaliser un jeu de fonction performants pour de la 3D est une entreprise de longue haleine. Aussi SDL a préféré fournir à ces utilisateurs un accès vers une librairie qui est devenue un standard aujourd'hui dans le monde de la 3D, j'ai nommé OpengGL. Cette librairie correspond en effet complètement à la philosophie multiplateforme voulue dans la Simple DirectMedia Layer. Voyons comment opérer...





SDL et OpenGL





Comme je le dit plus haut SDL ne fournit aucun jeu de primitives permettant d'attaquer directement de la 3D dans son code. En revanche, elle alloue le droit d'accéder à OpenGL, et ce d'une façon très simple.

Les seules primitives que SDL livre en ce qui concerne OpenGL sont les suivantes :

  • int SDL_GL_LoadLibrary(const char* path);
  • void *SDL_GL_GetProcAddress(const char* proc);
  • int SDL_GL_GetAttribute(SDL_GLattr attr, int *value);
  • int SDL_GL_SetAttribute(SDL_GLattr attr, int value);
  • void SDL_GL_SwapBuffers(void );

Et l'énumération que je détaillerai plus bas :

  • SDL_GLattr

Comme vous pouvez le constater ça ne casse pas briques ! En fait il est fort probable que vous n'utilisiez que SDL_GL_SwapBuffers(), du moins ce sera la fonction que vous utiliserez le plus souvent à ce niveau.

OH LA ! Attends un peu ! Me diront certains. Pourquoi se servir de SDL dans ce cas, quels sont ses apports comparé à GLUT par exemple? Ceux qui ne voient pas de quoi je parle devraient d'abord se référer aux cours d'OpenGL du site. C'est vrai lorsqu'on voit les fonctions que SDL fournit on se demande bien l'intérêt que peu prendre son utilisation au sein d'une application OpenGL travaillant déjà avec GLUT. La réponse comporte pluseiurs éléments, à vous de les juger valables ou pas.

Tout d'abord imaginez que vous travaillez sur une application qui ne nécessite pas OpenGL en premier lieu, puis qu'au fur et à mesure vous désirez en ajouter pour quelques raisons obscures que ce soit, vous serez alors heureux d'apprendre que votre application SDL pourra se permettre une telle extension.

Ensuite, et c'est surtout là la véritable raison, SDL est une librairie beaucoup plus puissante, souple et diversifiées que ne l'est GLUT en ce qui concerne la gestion des évènements et même de la plateforme. Dès lors le choix ne se discute plus. Cette simplicité vous permet de ne pas complètement changer de librairie pour ajouter de la 3D dans vos applications.

Attention cependant car cela ne signifie pas que vous ne pourrez plus utilisez GLUT dans vos programmes, au contraire. En fait là où SDL remplace GLUT se trouve lors de la création et de l'initialisation de la fenêtre, la gestion des évènements, et tout ce qui concerne les relations avec la plateforme sur laquelle tourne l'applications. En revanche, tout ce qui concerne le déroulement de l'application peut encore utiliser GLUT.

Maintenant que nous savons tout ça, je vais vous donner une raison de plus d'utiliser la Simple DirectMedia Layer dans vos applications OpenGL. C'est que si vous avez déjà suivie les cours qui précèdent, vous avez réaliser 90% du travail ! En effet puisque SDL ne gère pas directement la 3D et laisse le travail à OpenGL il va de soi que son utilisation reste la même et que mis à part les fonctions suscitées il n'y a pas de différence dans l'utilisation de SDL dans votre application. (Hum... je viens de m'accorder un petit break en jouant à Q3 et je suis passé en HurtMePlenty de dernier (sur 8 persos) à premier en 4 parties... moi qui ne suis pas un fraggueur... attention MadCow !) Revenons à nos moutons... :-)

Alors que réalise ces fonctions finalement ? Tout d'abord nous devons analyser la SDL_GLattr.

C'est une simple énumération dont voici les éléments :

SDL_GL_RED_SIZE           taille de la composante rouge du framebuffer en bits
SDL_GL_GREEN_SIZE         taille de la composante verte du framebuffer en bits
SDL_GL_BLUE_SIZE          taille de la composante bleue du framebuffer en bits
SDL_GL_ALPHA_SIZE         taille de la composante alpha du framebuffer en bits
SDL_GL_DOUBLEBUFFER       active ou désactive le double buffering 1 ou 0
SDL_GL_BUFFER_SIZE        taille du framebuffer en bits
SDL_GL_DEPTH_SIZE         taille du depth buffer en bits
SDL_GL_STENCIL_SIZE       taille du stencil buffer en bits
SDL_GL_ACCUM_RED_SIZE     taille de la composante rouge de l'accumulation buffer en bits
SDL_GL_ACCUM_GREEN_SIZE   taille de la composante verte de l'accumulation buffer en bits
SDL_GL_ACCUM_BLUE_SIZE    taille de la composante bleue de l'accumulation buffer en bits
SDL_GL_ACCUM_ALPHA_SIZE   taille de la composante alpha de l'accumulation buffer en bits

Pas besoin d'explication, si vous avez fait un peu d'OpenGL vous comprendrez très facilement la signification de chacun des éléments.

Lorsque vous travaillez dans un contexte OpenGL il se peut que vous désiriez utiliser un librarie spécifique pour votre application, la fonction SDL_GL_LoadLibrary() vous permet de spécifier le chemin d'accès de cette librairie, retournant 0 en cas de succès et -1 en cas d'échec. Mais agir de cette façon va vous apporter un surplus de boulot. En effet puisque vous chargez la librairie OpenGL en dymanique vous devez aussi récupérer toutes les fonctions que vous utilisez dans votre application sinon vous ne pourriez pas compiler.

Pour cela il vous faudra accomplir l'action suivante pour chacune des fonctions GL que vous utilisez (tiré de la doc) :

typedef void (*GL_ActiveTextureARB_Func)(unsigned int);
GL_ActiveTextureARB_Func glActiveTextureARB_ptr = 0;
int has_multitexture=1;


/* on récupère le pointeur sur la fonction opengl dans la librairie chargée en dynamique */
glActiveTextureARB_ptr=(GL_ActiveTextureARB_Func) SDL_GL_GetProcAddress("glActiveTextureARB");

/* on vérifie la validité du pointeur récupéré */
if(!glActiveTextureARB_ptr){
  fprintf(stderr, "Abscence de l'extension multitextures.\n");
  has_multitexture=0;
}

if(has_multitexture){
  glActiveTextureARB_ptr(GL_TEXTURE0_ARB);
...
}

Vous remarquez que vous devez employer la fonction void *SDL_GL_GetProcAddress(char const *proc); qui retourne un pointeur sur l'adresse de la fonction correspondante à la valeur de la chaîne proc passée en paramètre. Si cette fonction n'existe pas dans la librairie chargée alors le pointeur vaut NULL.

Bien donc maintenant vous savez comment charger une librairie opengl dynamiquement.

Passons à la fonction int SDL_GL_GetAttribute(SDL_GLattr attr, int *value); cette fonction est utilisée pour connaître les valeurs des paramètres OpenGL de votre application. Encore une fois ce n'est pas le but de ce petit cours sur la relation SDL/OpenGL aussi si vous êtes perdus essayer d'abord d'apprendre les bases de la programmation OpenGL puis tout ce que je dis ici vous semblera très clair. Donc, il vous faux passer un des éléments de l'énumération SDL_GLattr dont vous désirez connaître la valeur, celle-ci sera stockée dans le pointeur value. Symétriquement SDL propose la fonction intSDL_GL_SetAttribute(SDL_GLattr attr, int value); vous permettant de positionner les valeurs de l'énumération comme vous le désirez. Attention cependant, cette fonction doit toujours être appelée avant l'appel à SDL_SetVideoMode(). Car lorsque vous appellerez cette dernière fonction et que vous passerez le flag SDL_OPENGL, le contexte devra être préalablement fixé pour qu'il soit pris en compte lors de son initialisation.

Dernière fonction void SDL_GL_SwapBuffers(void ); que vous utiliserez le plus souvent. En effet ele remplace le glFlush() et le glutSwapBuffers();

Voilà pour la petite présentation des relations SDL et OpenGL.






Précédent  |  Index  |  Suivant  ]



by Sylvain Hellegouarch
Last update: 19/11/2000