Présentation du système de fenêtrage FLTK

Auteur/Traducteur : FROMY ANTHONY

 

CB37 Présentation du système de fenêtrage FLTK (Présentation, exemple de code permettant d'intégrer une scène OpenGL)

Introduction:

Bonjour à tous et bienvenue dans un nouveau tutoriel. Aujourd'hui nous allons parler des fenêtres graphiques, plus précisément d'une bibliothèque logicielle libre écrite en C++, FLTK ! Sa principale fonction est d'aider à créer et gérer des interfaces graphiques, combinées à OpenGL. Asseyez-vous, prenez un café ou un thé, n'oubliez pas les marshmallows on commence.

Pour commencer, qu'est-ce que FLTK?

FLTK (prononcé "fulltick") est une boîte à outils d'interface graphique C ++ multi-plateforme pour UNIX / Linux (X11), Windows et MacOS X. FLTK offre une fonctionnalité graphique moderne sans bloat et prend en charge les graphiques 3D via OpenGL et son émulation GLUT intégrée.

FLTK est conçu pour être petit et assez modulaire pour être lié statiquement, mais fonctionne bien comme une bibliothèque partagée. FLTK comprend également un excellent générateur d'interface utilisateur appelé FLUID qui peut être utilisé pour créer des applications en quelques minutes.

Pour continuer qu'est-ce que OPENGL

Résultat de recherche d'images pour "opengl"

Si vous êtes le propriétaire d'un certain système d'exploitation nommé Windows, vous aurez probablement vu quelques écrans de veille pompeusement appelés "écrans de veille OpenGL", qui affichent de magnifiques animations 3D, comme une boîte changeant de forme, ou des canalisations parcourant l'écran dans tous les sens (mais pourquoi des canalisations, bordel ?). Hé bien OpenGL, c'est la librairie qui permet d'aboutir à ces screensavers (pardon, écrans de veille) hyper évolués. Mais sachez qu'OpenGL n'est pas un petit machin pourri servant juste à faire des animations pourries. Non, en fait OpenGL est une librairie graphique 3D très évoluée et totalement portable offrant de nombreuses ressources aux programmeurs cherchant à faire de la synthèse d'images (pour les jeux par exemples).

Utiliser OpenGL dans FLTK

La façon la plus simple de créer un affichage OpenGL est de sous-classer Fl_Gl_Window. Votre sous-classe doit implémenter une draw()méthode qui utilise les appels OpenGL pour dessiner l'affichage. Votre programme principal doit appeler redraw()lorsque l'affichage doit changer, et (un peu plus tard) FLTK va appeler draw().

Avec un peu de soin, vous pouvez également utiliser OpenGL pour dessiner dans des fenêtres FLTK normales. Cela vous permet d'utiliser l'ombrage Gouraud pour dessiner vos widgets. Pour ce faire, vous utilisez les fonctions gl_start () et gl_finish () autour de votre code OpenGL.

Vous devez inclure le fichier d'en-tête de FLTK . Il inclura le fichier, définira certaines fonctions de dessin supplémentaires fournies par FLTK et inclura le fichier d'en-tête nécessaire aux applications WIN32.<FL/gl.h><GL/gl.h><windows.h>

Certaines règles de codage simples (voir les affichages OpenGL et "Retina") permettent d'écrire du code multi-plateforme qui va dessiner des graphismes OpenGL haute résolution s'il est affiché sur "Retina" avec MacOS X.

Faire une sous-classe de Fl_Gl_Window

Pour créer une sous-classe de Fl_Gl_Window , vous devez fournir:

  • Une définition de classe.
  • Une draw()méthode
  • Une handle()méthode si vous devez recevoir une entrée de l'utilisateur.

Si votre sous-classe fournit des contrôles statiques dans la fenêtre, ils doivent être redessinés chaque fois que le FL_DAMAGE_ALLbit est défini dans la valeur retournée par damage(). Pour les fenêtres à double tampon, vous devrez entourer le code de dessin avec le code suivant pour vous assurer que les deux tampons sont redessinés:

#ifndef MESA
glDrawBuffer(GL_FRONT_AND_BACK);
#endif // !MESA
... draw stuff here ...
#ifndef MESA
glDrawBuffer(GL_BACK);
#endif // !MESA

Définir la sous-classe

Pour définir la sous-classe, vous venez de sous-classer la classe Fl_Gl_Window :

class MyWindow : public Fl_Gl_Window {
void draw();
int handle(int);
public:
MyWindow(int X, int Y, int W, int H, const char *L)
: Fl_Gl_Window(X, Y, W, H, L) {}
};

Les méthodes draw()et handle()sont décrites ci-dessous. Comme n'importe quel widget, vous pouvez inclure des données privées et publiques supplémentaires dans votre classe (telles que des informations de graphique de scène, etc.)

La méthode draw ()

La draw()méthode est l'endroit où vous réalisez votre dessin OpenGL:

void MyWindow::draw() {
if (!valid()) {
... set up projection, viewport, etc ...
... window size is in w() and h().
... valid() is turned on by FLTK after draw() returns
}
... draw ...
}

Le handle () Méthode

La handle()méthode gère les événements de la souris et du clavier pour la fenêtre:

int MyWindow::handle(int event) {
switch(event) {
case FL_PUSH:
... mouse down event ...
... position in Fl::event_x() and Fl::event_y()
return 1;
case FL_DRAG:
... mouse moved while down event ...
return 1;
case FL_RELEASE:
... mouse up event ...
return 1;
case FL_FOCUS :
case FL_UNFOCUS :
... Return 1 if you want keyboard events, 0 otherwise
return 1;
case FL_KEYBOARD:
... keypress, key is in Fl::event_key(), ascii in Fl::event_text()
... Return 1 if you understand/use the keyboard event, 0 otherwise...
return 1;
case FL_SHORTCUT:
... shortcut, key is in Fl::event_key(), ascii in Fl::event_text()
... Return 1 if you understand/use the shortcut event, 0 otherwise...
return 1;
default:
// pass other events to the base class...
return Fl_Gl_Window::handle(event);
}
}

Quand il handle()est appelé, le contexte OpenGL n'est pas configuré! Si votre affichage change, vous devriez appeler redraw()et laisser draw()faire le travail. N'appelez aucune fonction de dessin OpenGL de l'intérieurhandle()!

Vous pouvez appeler des fonctions OpenGL comme la détection des occurrences et les fonctions de chargement de texture en procédant comme suit:

case FL_PUSH:
make_current(); // make OpenGL context current
if (!valid()) {
... set up projection exactly the same as draw ...
valid(1); // stop it from doing this next time
}
... ok to call NON-DRAWING OpenGL code here, such as hit
detection, loading textures, etc...

Votre programme principal peut maintenant créer une de vos fenêtres en faisant new MyWindow(...).

Vous pouvez également utiliser votre nouvelle classe de fenêtre dans FLUID en:

  1. Mettre votre définition de classe dans un MyWindow.Hfichier.
  2. Création d'un widget Fl_Box dans FLUID.
  3. Dans le panneau widget, remplissez le champ "class" avec MyWindow. Cela permettra à FLUID de produire des constructeurs pour votre nouvelle classe.
  4. Dans le champ "Extra Code", mettez #include "MyWindow.H"le fichier de sortie FLUID à compiler.

Vous devez mettre glwindow->show()votre code principal après avoir appelé show()la fenêtre contenant la fenêtre OpenGL.

Utilisation d'OpenGL dans des fenêtres FLTK normales

Vous pouvez mettre du code OpenGL dans la draw()méthode, comme décrit dans Dessiner le widget dans le chapitre précédent, ou dans le code pour un boxtype ou d'autres endroits avec un certain soin.

Plus important encore, avant d'afficher des fenêtres, y compris celles qui n'ont pas de dessin OpenGL, vous devez initialiser FLTK pour qu'il sache qu'il utilisera OpenGL. Vous pouvez utiliser l'un des symboles décrits pour Fl_Gl_Window::mode()décrire comment vous avez l'intention d'utiliser OpenGL:

Fl :: gl_visual (FL_RGB);

Vous pouvez ensuite placer le code de dessin OpenGL partout où vous pouvez dessiner normalement en l'entourant avec gl_start () et gl_finish () pour configurer, puis relâcher, un contexte OpenGL avec une projection orthographique de sorte que 0,0 soit le coin inférieur gauche de la fenêtre et chaque pixel est une unité. L'écrêtage en cours est reproduit avec les glScissor()commandes OpenGL. Ces fonctions synchronisent également le flux graphique OpenGL avec le dessin effectué par d'autres fonctions X, WIN32 ou FLTK.

gl_start ();
... mettez votre code OpenGL ici ...
gl_finish ();

Le même contexte est réutilisé à chaque fois. Si votre code modifie la transformation de projection ou toute autre chose que vous devriez utiliser glPushMatrix()et glPopMatrix()fonctionne pour remettre l'état avant d'appeler gl_finish().

Vous pouvez utiliser Fl_Window::current()->h()pour obtenir la hauteur drawable afin que vous puissiez inverser les coordonnées Y.

Malheureusement, il y a un tas de limitations que vous devez respecter pour une portabilité maximale:

  • Vous devez choisir un visuel par défaut avec Fl :: gl_visual () .
  • Vous ne pouvez pas passer FL_DOUBLEà Fl :: gl_visual () .
  • Vous ne pouvez pas utiliser Fl_Double_Window ou Fl_Overlay_Window .

Ne pas appeler gl_start()ou gl_finish()lors de l' établissement dans un Fl_Gl_Window !

Fonctions de dessin OpenGL

FLTK fournit des fonctions de dessin OpenGL utiles. Ils peuvent être librement mélangés avec tous les appels OpenGL, et sont définis en incluant ce que vous devez inclure à la place de l'en-tête OpenGL .<FL/gl.h><GL/gl.h>

void gl_color (Fl_Color)

Définit la couleur OpenGL actuelle sur une couleur FLTK. Pour les modes d'index de couleurs, il sera utilisé fl_xpixel(c), ce qui est juste si cette fenêtre utilise la palette de couleurs par défaut!

void gl_rect (int x, int y, int w, int h)
void gl_rectf (int x, int y, int w, int h)

Esquisse ou remplit un rectangle avec la couleur actuelle. Si Fl_Gl_Window :: ortho () a été appelée, alors le rectangle remplira exactement le rectangle de pixels passé.

void gl_font (Fl_Font fontid, taille int)

Définit la police OpenGL actuelle sur la même police que vous obtenez en appelant fl_font () .

int gl_height ()
int gl_descent ()
float largeur_gl (const char * s)
float largeur_gl (const char * s, int n)
float largeur_w (uchar c)

Renvoie des informations sur la police OpenGL actuelle.

void gl_draw (const char * s)
void gl_draw (const char * s, int n)

Dessine une chaîne terminée par un nombre nul ou un tableau de ncaractères dans la police OpenGL actuelle à la position raster actuelle.

void gl_draw (const char * s, int x, int y)
vide gl_draw (const char * s, int n, int x, int y)
vide gl_draw (const char * s, float x, float y)
void gl_draw (const char * s, int n, float x, float y)

Dessine une chaîne terminée par un caractère nul ou un tableau de ncaractères dans la police OpenGL actuelle à la position donnée.

vide gl_draw (const char * s, int x, int y, int w, int h, Fl_Align)

Dessine une chaîne formatée dans une boîte, avec les nouvelles lignes et les onglets étendus, les autres caractères de contrôle modifiés en ^ X et alignés avec les bords ou le centre. Exactement la même sortie que fl_draw () .

Utiliser OpenGL 3.0 (ou versions supérieures)

Le sous-répertoire examples contient OpenGL3test.cxx, un programme jouet montrant comment utiliser OpenGL 3.0 (ou des versions supérieures) avec FLTK de manière multi-plateforme. Il contient également OpenGL3-glut-test.cxx qui montre comment utiliser la compatibilité GLUT de FLTK et OpenGL 3.

Sur les plates-formes MSWindows et Unix / Linux , FLTK crée des contextes implémentant la version OpenGL la plus élevée prise en charge par le matériel, qui est également compatible avec les versions OpenGL inférieures. Ainsi, FLTK permet le code source ciblant toute version d'OpenGL. L'accès aux fonctions à partir des versions OpenGL au-dessus de 1.1 nécessite de charger des pointeurs de fonction au moment de l'exécution sur ces plateformes. FLTK recommande d'utiliser la bibliothèque GLEW pour effectuer cela. Il est donc nécessaire d'installer la bibliothèque GLEW (voir ci-dessous). Sur la plate - forme Mac OS X , FLTK crée par défaut des contextes implémentant les versions 1 ou 2 d'OpenGL. Pour accéder à OpenGL 3.0 (ou aux versions supérieures), utilisez l' FL_OPENGL3indicateur (voir ci-dessous). Mac OS 10.7 ou supérieur est requis; GLEW est possible mais pas nécessaire.

Installation de GLEW (plates-formes Unix / Linux et MSWindows)
GLEW est disponible en tant que paquet pour la plupart des distributions Linux et sous forme de source à l' adresse http://glew.sourceforge.net/ . Pour la plate-forme MSWindows, une bibliothèque statique Visual Studio (glew32.lib) peut être téléchargée à partir du même site Web; une bibliothèque statique de style MinGW (libglew32.a) peut être créée à partir de la source avec la commande make.
Modifications au niveau de la source pour OpenGL 3:
  • Placez ceci dans tous les fichiers source utilisant OpenGL (au lieu de #include < FL / gl.h >, et avant #include <FL / glut.h> si vous utilisez GLUT):

    #if defined(__APPLE__)
    # include <OpenGL/gl3.h> // defines OpenGL 3.0+ functions
    #else
    # if defined(WIN32)
    # define GLEW_STATIC 1
    # endif
    # include <GL/glew.h>
    #endif
  • Ajoutez l' FL_OPENGL3indicateur lorsque vous appelez Fl_Gl_Window :: mode (int a) ou glutInitDisplayMode ().
  • Mettez ceci dans la handle(int event)fonction membre de la première à créer parmi vos classes dérivées de Fl_Gl_Window:

    #ifndef __APPLE__
    static int first = 1;
    if (first && event == FL_SHOW && shown()) {
    first = 0;
    make_current();
    glewInit();
    }
    #endif
  • Alternativement, si vous utilisez GLUT, mettez

    #ifndef __APPLE__
    glewInit();
    #endif

    après le premier appel de glutCreateWindow ().

Si GLEW est installé sur la plate-forme de développement Mac OS, il est possible d'utiliser le même code pour toutes les plateformes, à une exception près:

#ifdef __APPLE__
glewExperimental = GL_TRUE;
#endif

avant l'appel de glewInit ().

Fin du tutoriel, ne soyez pas triste il me reste encore deux autres tutoriels avant la fin de l'année.

Je tiens à remercier FLTK pour son tutoriel dont je me suis inspiré pour vous permettre de connaître les bases de l'intégration FLTK dans OpenGL. Je vous conseille, si vous cherchez à approfondir vos connaissances sur le sujet, à suivre les différents tutoriels proposés par leur documentation.

Je tiens aussi à remercier Wikipédia qui m’a permis de vous définir précisément ce qu'est une OpenGL.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *