Freeglut 2.8.0 : vas-y pépé !

Posté par  . Édité par claudex et Lucas Bonnet. Modéré par Lucas Bonnet.
Étiquettes :
35
22
jan.
2012
Serveurs d’affichage

Voici un petit état des lieux de Freeglut, la réécriture libre de GLUT (une bibliothèque permettant de créer facilement un contexte OpenGL).

NdM : merci à jseb pour son journal.

Logo freeglut

Sommaire

Freeglut : origine et objectifs

Freeglut vient de GLUT

  • Freeglut est une réécriture de la bibliothèque GLUT.

  • GLUT (OpenGL Utility Toolkit) est une bibliothèque permettant au programmeur de créer facilement une fenêtre contenant un contexte OpenGL. Sont assurés grâce à un système de callbacks :

    • L'affichage.
    • Les entrées-sorties minimales (clavier, souris, joystick).
  • GLUT permet donc de s'affranchir des spécificités de l'OS pour se concentrer sur l'essentiel : OpenGL. L'API est très simple et va à l'essentiel.

    • On l'utilise généralement pour écrire de courts programmes de tests, ou dans un but d'apprentissage.
    • L'écriture de programmes plus conséquents est bien entendu possible. Cependant, le côté spartiate de GLUT fait qu'on lui préfère généralement des bibliothèques plus fournies et plus généralistes, telles que la SDL ou l'excellente ClanLib.

Limitations de GLUT

  • Mark Kilgard, l'auteur de GLUT, a distribué les sources jusqu'à la dernière version (3.7 , août 1998).
    • Malheureusement, la distribution des sources s'accompagnait de l'interdiction de diffuser les modifications apportées.

La réponse Freeglut

  • Freeglut est né en 1999 de la volonté de s'affranchir des limitations de redistribution, afin de continuer à faire vivre cette bibliothèque.

  • Quelques améliorations furent apportées au passage, mais le but premier est une compatibilité maximale avec GLUT et l'ajout de nouveautés n'est pas une priorité.

    • Aujourd'hui, toutes les distributions utilisent Freeglut en lieu et place de la GLUT, y compris pour les programmes binaires liés à la GLUT originale.
    • Un programme compilé avec GLUT peut s'exécuter avec la lib Freeglut, sur laquelle il se linke sans problèmes.
  • Les sorties des versions stables de Freeglut sont régulières, même si elles s'espacent parfois de quelques années.

    • La précédente version date de fin 2009. Il ne faut donc pas se décourager, les commits réguliers en font une bibliothèque bien vivante.
  • À ma connaissance, il s'agit de la dernière bibliothèque en vie qui réimplémente GLUT (OpenGLUT, née d'une scission avec Freeglut, est morte depuis 2005).

Différences fondamentales avec GLUT

  • Mode step : nous ne sommes plus prisonniers de la « MainLoop » de GLUT.

    • Dans GLUT, une fois les initialisations terminées et sa boucle principale lancée, le seul moyen de reprendre le contrôle était d'utiliser les callbacks mis à disposition par GLUT.
    • Très « machine à état » dans l'esprit OpenGL d'origine, mais pas forcément pratique.
    • Freeglut offre un mode step, qui permet d'avancer d'une itération dans la boucle d'événements (« glutMainLoopEvent »). Ceci permet d'écrire des programmes plus lisibles, avec une vraie « boucle principale », vos routines n'étant plus reléguées dans les callbacks de GLUT qui les exécutera selon son bon vouloir.
  • Game mode : c'est sorte de mode exclusif, très prisé par les jeux qui se moquent de cohabiter avec votre horloge ou le curseur souris de votre bureau.

    • Sur ma machine, ce mode fonctionne très bien en plein écran. J'ai déjà eu des blocages en mode fenêtré, mais ce genre de mode est plutôt destiné au plein écran.
  • Le multisampling est supporté très simplement.

    • Il suffit de le demander à l'initialisation, puis d'activer l'état lorsque vous désirez rendre avec de l'antialiasing.
  • Support de la roulette souris. Et oui, cela semble évident maintenant, mais en 1998, GLUT n'avait pas ce support.

  • Les contextes OpenGL/ : glutInitContextVersion, glutInitContextFlags, et glutInitContextProfile.

    • Ces fonctions (non référencées dans la doc officielle) permettent de spécifier la version d'OpenGL à supporter.
    • On peut également spécifier un niveau de compatibilité.
  • Quelques disparitions, comme le support de certains périphériques peu usités (votre avis pourra varier).

    • Cf. « spaceballs » et « tablets » dans la doc.
    • Freeglut intègre la définition de ces fonctions pour la compatibilité avec GLUT, mais ne fera rien si ces fonctions sont appelées.

Freeglut et les versions d'OpenGL

OpenGL 1.2 / 2

  • Pas de surprises particulières, je ne m'étends pas sur le sujet.

OpenGL 3 (et les suivants)

  • Comme vous le savez, OpenGL a beaucoup changé ces dernières années.

    • Son modèle de machine à états a volé en éclat, laissant la place à une vision très macro du développement, afin de coller au plus près à l'architecture des cartes récentes (pleins de shaders à faire turbiner en parallèle).
    • On peut regretter la disparition de ce qui faisait la force d'OpenGL, toujours est-il que vous ne pourrez que difficilement (ou pas du tout) accéder aux fonctionnalités récentes d'OpenGL avec l'ancienne API (parfois référencée ironiquement sous le terme d'« Ancien Testament » dans certaines docs).
  • Pour utiliser la nouvelle API de OpenGL, il vous faudra utiliser GLEW conjointement à Freeglut.

    • GLEW est une bibliothèque dédiée à la gestion des extensions d'OpenGL et permet notamment d'accéder aux shaders.

La doc est naze

  • Le plus gros problème de Freeglut est sa documentation très parcellaire.
    • Le répertoire « doc » n'a pas bougé depuis la version 2.0.0 de Freeglut (2003).
    • Quelques essais de réécriture méritoires, mais rien qui ne puisse servir de référence pour l'instant.

Quelques ressources pour l'édification des masses

  • Les ressources suivantes sont à la fois un cours d'OpenGL dans toute sa glorieuse modernité, mais également le moyen d'utiliser correctement Freeglut. Ces auteurs ont défriché pour vous le terrain, profitez-en.
  • Pour une introduction aux shaders et au monde moderne, voir lighthouse.
  • Pour une vision plus complète et progressive, voici un livre disponible gratuitement et très intéressant : Learning Modern 3D Graphics Programming (Jason L. McKesson)

Pendant que j'y suis…

  • Bien que cela ne soit pas une obligation pour utiliser Freeglut avec OpenGL 3 et suivants, vous aurez également besoin d'une bibliothèque pour vous simplifier les maths.
    • La lib GLM est tout à fait ce que vous cherchez

Nouveautés dans Freeglut 2.8.0

Essentiellement de la correction de bugs

  • Le mode plein-écran ainsi que le game mode fonctionnent mieux. Promis juré.

    • Ce fut une grosse partie du volume des mails échangés sur la mailing liste.
  • Amis sous Solaris, MacOSX et BSD, vous n'êtes pas oubliés : de nombreuses modifications pour s'assurer que tous les programmes tests fournis dans l'archive fonctionnent sur vos plateformes.

  • Ajout de makefiles pour VisualStudio 2010.

    • Avec toujours le support pour les versions antérieures.
  • Amélioration du support Open Watcom avec un vrai Makefile à la place de l'ancien support qui ne fonctionnait pas.

  • Ainsi que la phrase traditionnelle : de nombreux bugs sont corrigés. Pour voir si le bug agaçant qui vous pourrissait la vie est corrigé, je vous renvoie à la mailing liste.

Il y a cependant quelques nouveautés

  • Des callbacks pour le multitouch.

  • Support des buffers RGB (apparus dans OpenGL 3) via les extensions GLX et WGL. Permet d'appliquer une correction gamma aux images.

  • Un exemple complet pour utiliser OpenGL 3 (avec un peu de code piqué dans GLEW, pour éviter une dépendance).

Où trouver Freeglut ?

Les sources

Disponibilité des binaires 2.8.0

  • Arch : vient de passer en « testing ».
  • Fedora : un rpm est disponible.
  • Ubuntu : probablement dans stable depuis la première rc.
  • Gentoo : disponible en « unstable ».
  • Slackware : il faudra compiler.
  • Windows : dispo pour MSVC et Mingw entre autres ici
  • MacOSX : disponible contre une empreinte digitale et un scan rétinien.

Aller plus loin

  • # Merci

    Posté par  . Évalué à 3.

    Juste un petit commentaire pour vous remercier de la news, c'était très instructif.

  • # Commentaire supprimé

    Posté par  . Évalué à 9.

    Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Re: SIGPUCE

      Posté par  . Évalué à 5.

      C'est parce que l'hiver n'est pas assez froid pour tuer les puces.

      La prochaine fois, c'est promis, je passe un coup d'insecticide.

      Discussions en français sur la création de jeux videos : IRC freenode / #gamedev-fr

  • # Resizing

    Posté par  . Évalué à 1.

    Est-il possible dans cette version de créer une fenêtre qui ne soit pas redimensionnable ?

    Dans la 2.6, ça ne semble pas possible, c'est pourtant une fonctionnalité assez pratique (notamment avec des tiling window managers).

    • [^] # Re: Resizing

      Posté par  . Évalué à 3. Dernière modification le 23 janvier 2012 à 00:48.

      Pour une fenêtre non redimensionnable, je laisserais faire le WM. Après tout, c'est à lui de gérer les fenêtres, pas au programme de poser ce genre de limitations. Le programme devrait se cantonner à gérer les redimensionements (le callback défini par glutReshapeFunc). Cela permet de bien se comporter dans tous les cas (WM qui autorise le redimensionnement ou pas).

      Si vraiment tu tiens à le faire toi-même, je vois deux solutions:

      — Utiliser le «gamemode». Donc plutôt du plein écran, avec les éventuels problèmes de retour en résolution d'origine. En fenêtrage, c'est du quitte ou double, et il ne faut pas compter sur un rafraichissement propre du reste de l'écran.

      — Ou bien, au moment du callback sur la fonction de reshape, utiliser glutReshapeWindow pour forcer le redimensionnement immédiat de la fenêtre aux valeurs de ton choix.
      Je pense que c'est une meilleure solution, même si à mon avis ce n'est pas très propre.
      J'ai fait un test pour vérifier, et ça a l'air de marcher (testé avec Freeglut 2.6 , et ça doit même aller avec les versions antérieures).

      #include <stdio.h>
      #include <GL/glut.h>
      
      int time_period = 25;
      unsigned int width=0, height=0;
      
      void timer(int id_timer)
      {
        glutPostRedisplay();
        glutTimerFunc(time_period, timer, id_timer);
      }
      
      
      void reshape (int w, int h)
      {
        glutReshapeWindow(width,height); //empêche le redimensionnement
      
        glViewport (0, 0, w, h);
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
      
        glFrustum(-1,1,0,1, -1,1); /* left, right, bottom, top, near, far */
      }
      
      void display()
      {
          glClearColor (.5, .5, .5, 1);
          glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
          glMatrixMode (GL_MODELVIEW);
          glLoadIdentity ();
          glutWireTeapot (0.5);
          glTranslatef (-1,0,0);
          glutSwapBuffers ();
      }
      
      void keyboard (unsigned char c, int mousex, int mousey)
      {
        mousex=mousex; mousey=mousey; //pour les warnings de gcc -W
        if (c==27) exit(0);
      }
      
      int main (int argc, char **argv)
      {
        width = argc>1?atoi(argv[1]):640;
        height = argc>2?atoi(argv[2]):480;
        width = width < 1024  && width > 0? width:640;
        height = height < 768 && height > 0? height:480;
      
        glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
      
        //pas de glutInitWindowPosition pour un WM qui fait le tiling lui même
        glutInitWindowSize (width, height);
        glutInit (&argc, argv);
        glutCreateWindow ("test anti-redimensionnement");
        glutTimerFunc(time_period, timer, 1 /* id timer */);
        glutDisplayFunc (display);
        glutReshapeFunc (reshape);
        glutKeyboardFunc (keyboard);
      
        glutMainLoop ();
        return 0;
      }
      
      

      Discussions en français sur la création de jeux videos : IRC freenode / #gamedev-fr

      • [^] # Re: Resizing

        Posté par  . Évalué à 2.

        Mauvaise idée d'essayer de forcer la taille avec un glutReshapeWindow dans le callback de reshape avec un tiling WM: le WM redimensionne à la taille A, le programme à la taille B, le WM à la taille A, le programme à la taille B, etc.

        Dans le principe, X permet d'indiquer des « hints » de taille minimum et maximum pour une fenêtre (avec les fonctions XSetWMHints et XSetNormalHints). Ce sont des indications que le WM peut très bien ignorer, mais leur présence est un indicateur pour lui. Par exemple, awesome utilise cette information pour distinguer une fenêtre « classique » (redimensionnable) d'une « popup », pour laquelle des indicateurs de tailles ont été mis. Ça lui permet d'afficher ces dernières correctement, et pas en prenant toutes la place, comme les pionniers du genre aux débuts de ce type de WM.

        D'autres bibliothèques concurrentes (au hasard glfw, sfml, sdl, par exemple) permettent de mettre ces indicateurs à taille minimum = taille maximum, dommage que ça manque à freeglut.

    • [^] # Re: Resizing

      Posté par  . Évalué à 3.

      C'est peut-être une question bête, mais j'aimerais savoir en quoi cette fonctionnalité est pratique.

      En tant qu'utilisateur, je n'aime pas les fenêtres dont la taille est bloquée, et préfère largement celles qui gèrent correctement le redimensionnement. Ce sera encore plus vrai pour quelqu'un qui utilise un gestionnaire de fenêtres « en tuiles » (il y a des termes informatiques que je ne devrais peut-être pas traduire…), puisque ces gestionnaires de fenêtre sont faits pour laisser l'utilisateur se préoccuper d'autre chose que la taille et position des fenêtre. Fixer la taille de la fenêtre, c'est lui rappeler que les fenêtres existent (alors qu'il voulait l'oublier), c'est ne pas respecter son choix d'avoir des fenêtres placées et dimensionnées d'une certaine manière, c'est prendre le risque de le frustrer et de perdre un utilisateur.

      En tant que développeur (bon, je ne développe pas assez non-plus pour faire figure d'autorité), j'essaye de faire en sorte que mes interfaces gèrent correctement le redimensionnement, et ce même dans des configurations très bizarres (ratio inattendus, résolutions très basses…). C'est plus compliqué, certes, mais on n'est pas obligé de le faire à l'extrême comme moi, et au final, l'application ne semble pas « cassée » quand on redimensionne la fenêtre.

      • [^] # Re: Resizing

        Posté par  (site web personnel) . Évalué à 4.

        Un exemple (très spécifique, mais cas réel).

        Pour un système de réalité virtuelle immergée, avec 2 surfaces de projection + stéréoscopie (bref, 4 vidéo-projecteurs), j'ai un soft qui peut gérer 4 fenêtres de rendu en mode xinerama via un seul process... et on doit pouvoir gérer exactement le positionnement des fenêtres sans être em**** par le window-manager (qui veut afficher des barres de menus et autres trucs dont on ne veut pas).

        Python 3 - Apprendre à programmer dans l'écosystème Python → https://www.dunod.com/EAN/9782100809141

      • [^] # Re: Resizing

        Posté par  . Évalué à 1.

        Les jeux sont des cas très specifique de fenêtrage, mais la distinction avec une application "normale" ne se fait pas au niveau du WM.

        Même dans le cas du « tuilage », ce n'est pas gênant d'avoir une fenêtre hors-scope quand on lance un jeu, puisque l'attention va y être portée à l'exclusion des autres fenêtres (si c'est un bon jeu :)). Et il y'a des dimensions qui ne conviennent pas à certains jeux (mais on peut donner des indices au WM, voir ci-dessus).

  • # GLEW

    Posté par  (site web personnel) . Évalué à 3.

    Pour utiliser la nouvelle API de OpenGL, il vous faudra utiliser GLEW conjointement à Freeglut.

    Personnellement, je n'utilise pas exclusivement GLEW.

    J'ai en haut d'un fichier commun à mon projet un truc à peut près comme cela :

    #if defined(USE_GLEW)
    #include <GL/glew.h>
    #elif defined(USE_GL3_GL3)
    #define GL3_PROTOTYPES
    #include <GL3/gl3.h>
    #define __gl_h_
    #endif
    
    

    le gl3.h étant récupéré de chez Khronos.

    J'inclue freeglut après tout cela et ça roule (pour l'instant).

  • # Réécriture ?

    Posté par  . Évalué à 1.

    Une question que je me suis toujours posé par rapport à une réécriture:

    Comment récrire un programme ou un extrait de programme non libre que l'on a lu (et qui nous a plu) en respectant le copyright ?

    Il y aura forcément des bouts de code "identique" ?

    Si certains peuvent m'éclairer sur l'aspect juridique (qu'est ce qui est légal et illégale) et pratique (à part la lobotomie) de la chose ?

    • [^] # Re: Réécriture ?

      Posté par  . Évalué à 3.

      Est-ce que la réponse d'un mec qui n'y connais rien (moi, en l'occurrence) compte ?

      C'est un sujet qui a déjà été abordé sur LinuxFr. La solution proposée est qu'une personne – celle qui a eu le malheur de lire des bouts de code – crée une documentation, qui spécifie comment doit se comporter le programme, et une autre personne qui n'a jamais été en contact avec le code développe une solution libre à partir de la spécification.

      Le commentaire où j'ai lu ça

      Le lien Wikipédia fournit dans le commentaire si tu ne veux pas cliquer deux fois de suite (mais sinon, tu peux découvrir le journal ayant provoqué le commentaire) :
      en:Clean_room_design

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.