Programmer en C++ avec OpenGL sous Ubuntu


OpenGL (Open Graphics Library) est une interface de programmation 3D écrite en langage C, disponible sous Linux, Microsoft Windows et Mac OS. Cette interface peut être utilisée par les programmeurs C++ pour développer de puissantes applications 3D (jeu vidéo, modélisation...).

Pour pouvoir programmer en C++ avec avec OpenGL sous Ubuntu, il faut commencer par:
1) Installer OpenGL
2) Vérifier l'installation d'OpenGL
3) Écrire, compiler et exécuter des programmes C++ avec OpenG

Dans ce qui suit, on utilise OpenGL version 3.0 sous Ubuntu 18.04.

1) Installer OpenGL

Pour installer OpenGL sous Ubuntu, il faut installer les paquets GLU (OpenGL Utility Library), FreeGLUT (Free openGL Utility Toolkit) et Mesa, dans les versions propices au développement d'applications (paquets -dev) et, optionnelement, le paquet GLEW (openGL Extension Wrangler - extension spécialisée).

01

Pour cela on exécute les commandes suivantes:
0) sudo apt-get update
puis
1) sudo apt-get install libglu1-mesa-dev
2) sudo apt-get install freeglut3-dev
3) sudo apt-get install mesa-common-dev
et optionnellement,
4) sudo apt-get install libglew-dev

Ces 4 paquets sont complémentaires et jouent les rôles suivants :

1.1) GLU (Paquet : libglu1-mesa-dev)

GLU (OpenGL Utility Library) est la bibliothèque principale d'OpenGL. Elle fournit des fonctions OpenGL de haut niveau s'appuyant sur des commandes de bas niveau. Ce paquet fournit les en-têtes et les bibliothèques statiques pour compiler des programmes avec GLU.

1.2) FreeGLUT (Paquet : freeglut3-dev)

FreeGLUT est une alternative (open-source, récente et maintenue) à la librairie GLUT (OpenGL Utility Toolkit) qui n'est plus maintenue. Cette librairie permet de créer et mettre en oeuvre facilement et rapidement des fenêtres graphiques simples dans le cadre d'un programme C++ utilisant OpenGL. Pour mettre en oeuvre des fenêtres graphiques plus élaborées on peut utiliser des interfaces graphiques plus évoluées, comme GTK+ par exemple, à la place de FreeGLUT.
Ce paquet fournit les bibliothèques et les en-têtes appropriés pour le développement de fenêtres graphiques de type GLUT.

1.3) Mesa (Paquet : mesa-common-dev)

Mesa (également appelé Mesa 3D) est une bibliothèque fournissant une implémentation open source d'OpenGL. Ce paquet fournit : les spécifications des extensions OpenGL spécifiques à Mesa; les notes de version complètes et les fichiers d'en-têtes de développement communs à tous les paquets Mesa.

1.4) Glew (Paquet : libglew-dev)

Glew (OpenGL Extension Wrangler) est une bibliothèque C/C++, open source, multiplateforme qui permet de gérer automatiquement les extensions OpenGL prises en charge sur un ordinateur donné. Cette bibliothèque est facultative. Elle n'est pas nécessaire pour réaliser des programmes simples mais elle devient très commode lorsque les programmes sont plus complexes.

Remarque

Les programmeurs peuvent écrire les deux instructions suivantes, en début de programme, juste après l'instruction glutInit();, afin de fiabiliser le contexte de programmation entre la version d'OpenGL installée d'une part et le matériel vidéo présent sur l'ordinateur d'autre part (carte graphique, chipset....).
glutInitContextVersion(3,0);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
La première instruction prend en paramètre le numéro de la version d'OpenGL implémentée sur l'ordinateur utilisé (ici c'est la version 3.0 qui donne le paramètre 3,0).
La seconde instruction demande à OpenGL d'initialiser le contexte qui répond exactement à la présente configuration matérielle et logicielle. En effet, l'initialisation d'un contexte qui soit exactement adapté à la version d'OpenGL installée et prenant en compte la configuration matérielle existante est utile voir nécessaire car les versions d'OpenGL se succèdent sans cesse (version 1.0 en 1994 puis versions 1.1, 1.2, 1.3, 1.4, 1.5, 2.0, 2.1, 3.0, 3.1, 3.2, 3.3, 4.0... et version 4.6 en 2020) avec des modifications plus ou moins importantes d'une version à l'autre. Dans ces conditions, chaque nouvelle version d'OpenGL introduit de nouvelles fonctions et marque d'autres fonctions comme étant obsolètes donc susceptibles d'être supprimées dans une future version d'OpenGL. C'est pourquoi l'initalisation du contexte OpenGL qui soit adapté de façon précise à la situation rencontrée, facilite ensuite le travail d'OpenGL et par voie de conséquence la vie du programmeur.

2) Vérifier l'installation d'OpenGL

Pour vérifier l'installation d'OpenGL, on vérifie la présence des paquets installés puis on affiche la version de OpenGL implémentée.

2.1) Vérifier la présence des paquets installés

On tape, dans le terminal de commande, la commande suivante qui affiche la liste des paquets installés sur l'ordinateur:
sudo dpkg-query -l

En examinant la liste affichée dans le terminal, on doit trouver les lignes suivantes (liste non exhaustive):

GLU ii libglu1-mesa:a 9.0.0-2.1bui amd64    Mesa OpenGL utility library (GLU)
ii libglu1-mesa:i 9.0.0-2.1bui i386    Mesa OpenGL utility library (GLU)
ii libglu1-mesa-d 9.0.0-2.1bui amd64    Mesa OpenGL utility library

FreeGLUT
ii freeglut3:amd6 2.8.1-3 amd64    OpenGL Utility Toolkit
ii freeglut3-dev: 2.8.1-3 amd64    OpenGL Utility Toolkit developmen

Mesa
ii mesa-common-de 20.0.8-0ubun amd64    Developer documentation for Mesa
ii mesa-utils 8.4.0-1       amd64    Miscellaneous Mesa GL utilities
ii mesa-va-driver 20.0.8-0ubun amd64    Mesa VA-API video acceleration dr
ii mesa-vdpau-dri 20.0.8-0ubun amd64    Mesa VDPAU video acceleration dri

GLEW
ii libglew-dev:am 2.0.0-5 amd64    OpenGL Extension Wrangler - devel
ii libglew2.0:amd 2.0.0-5 amd64    OpenGL Extension Wrangler - runti

2.2) Afficher la version de OpenGL implémentée

Pour afficher la version de OpenGL implémentée, il suffit de taper la commande suivante dans le terminal de commandes:
glxinfo | grep "OpenGL version"

La commande glxinfo donne des informations sur la version d'OpenGL qui est implémentée sur un ordinateur donné. Pour pouvoir diposer de cette commande, il faut avoir préalablement installé le paquet mesa-utils. Si celui-ci n'est pas installé, on l'installe à l'aide des commandes suivantes:
sudo apt-get update
sudo apt-get install mesa-utils

Dans le cas présent, on trouve la version OpenGL 3.0

02

3) Ecrire, compiler et exécuter des programmes C++ avec OpenGL

3.1) Exemple 1

On commence par écrire le programme test1.cpp suivant qui se limite à afficher le numéro de la version de OpenGL implémentée sur l'ordinateur et permet donc de vérifier que OpenGL fonctionne.

/* essai.cpp indique la version de opengl
compilation: g++ test1.cpp -o test1 -lglut -lGLU -lGL
exécution: ./test1
*/
#include <GL/freeglut.h>
#include <cstdio>
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutCreateWindow("OpenGL-Test1");
printf("Version de OpenGL supportée (%s): \n", glGetString(GL_VERSION));
}

test1.cpp

On compile ce programme à l'aide de la commande suivante, le terminal de commande étant ouvert dans le répertoire où se trouve le fichier "test1.cpp":
g++ test1.cpp -o test1 -lglut -lGLU -lGL

puis on exécute le programme à l'aide de la commande
./test1

On retrouve l'information de version OpenGL 3.0 précédemment obtenue à l'aide de la commande glxinfo.

03

3.2) Exemple 2

Le programme test2.cpp suivant affiche un triangle rouge dans une fenêtre à fond noir.

/*
test2.cpp affichage d'un triangle rouge dans une fenêtre
compilation: g++ test2.cpp -o test2 -lglut -lGLU -lGL
exécution: ./test2
*/
//#include <GL/glut.h>
#include <GL/freeglut.h>
void affiche()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(300, 200);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL-Test2");
glutDisplayFunc(affiche);
glutMainLoop();
return 0;
}

test2.cpp

04

3.3) Exemple 3

Le programme suivant affiche un carré rouge dans une fenêtre à fond gris.

Ce programme assure la mise en oeuvre (facultative) de glutInitContextVersion à l'aide des deux instructions suivantes:
glutInitContextVersion(3, 0);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);


Il est à noter que dans le cas présent, le paramètre ?,x passé à glutInitContextVersion(?.x) doit être obligatoirement 3.0 (version de OpenGL implémentée ici). Si le paramètre passé à la fonction ne correspond pas à la version de OpenGL installée, le programme compile mais on obtient un message d'erreur au moment de l'exécution.

Il apparatient à chaque programmeur de passer à la fonction glutInitContextVersion() le paramètre ?,x qui correspond à sa configuration matérielle et logicielle spécifique.

Ce programme assure également la mise en oeuvre (facultative) de glew. L'instruction glewExperimental=GL_TRUE; est nécessaire et doit être placée juste avant l'instruction glewInit();

Cette fois-ci le programme doit être compilé avec la commande suivante ajoutant -lGLEW à la commande précédente, ce qui donne:
g++ test3.cpp -o test3 -lglut -lGLU -lGL -lGLEW

/*
test3.cpp affichage d'un carré rouge dans une fenêtre à fond gris
compilation: g++ test3.cpp -o test3 -lglut -lGLU -lGL -lGLEW
exécution: ./test3
*/
#include <GL/glew.h>
#include <GL/freeglut.h>

void affiche(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 10.0, 0.0);
glVertex3f(10.0, 10.0, 0.0);
glVertex3f(10.0, 0.0, 0.0);
glEnd();
glFlush();
}

int main(int argc, char **argv)
{
glutInit(&argc, argv);
// Mise en oeuvre (facultative) de glutInitContextVersion(?.x)
glutInitContextVersion(3, 0);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
//
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(300, 200);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGl-Test 3");
glutDisplayFunc(affiche);
//Mise en oeuvre (facultative) de glew
glewExperimental = GL_TRUE;
glewInit();
//
glClearColor(0.5, 0.5, 0.5, 0.0);
glutMainLoop();
}

test3.cpp

05