Programmation 3D avec codeblocks et OpenGL


La programmation 3D permet de manipuler des objets 3D créés à l'aide d'un logiciel de modélisation 3D ou créés à l'aide d'un fichier texte (voir la page creer-un-cube-3d-au-format-obj-avec-le-bloc-notes.php) ou d'un programme.

CodeBlocks est un environnement de développement (IDE) complet en langage C et C ++. Il est gratuit et il existe (à la date d'écriture de ces lignes) une version qui inclut le compilateur GCC (MingW /GNU GCC / G++). Le fichier correspondant (codeblocks-16.01mingw-setup.exe) est téléchargeable depuis le site officiel de codeoblockshttp://www.codeblocks.org/). Cette version inclut également les fichiers d'entête et librairies permettant de programmer avec OpenGL.

OpenGL (Open Graphics Library) est une une bibliothèque de fonctions gratuites qui facilite la programmation d'applications 3D écrites en C ou en C++. Cette bibliothèque, créée par Silicon Graphics, est en concurence avec la bibliothèque Direct3D de Microsoft..

GLUT (OpenGL Utility Toolkit) est une une bibliothèque de fonctions gratuites qui facilite la programmation d'applications en 2D et 3D avec OpenGL. Elle n'est pas dans le domaine public (Mark J. Kilgard détient les droits d'auteur) mais le texte de licence indique qu'elle peut être distribuée librement sans frais de licence. Cette bibliothèque permet de simplifier et de réduire les lignes de code associées à la définition de l'interface graphique utilisateur (GUI) des applications 3D.

La combinaison de ces outils permet de créer facilement, avec le langage C++, des programmes manipulant des objets 3D (on utilise ci-après Codeblocks16.01 et GLUT 3.7.6 avec Windows XP SP3)

Pour faire cela il faut :
1) Télécharger et installer codeblocks;
2) Télécharger et installer GLUT;
3) Créer un programme 3D avec codeblocks.

Remarques :
Il possible d'écrire un programme 3D en C++ simplement avec le bloc-notes (sans utiliser l'IDE codeblocks) puis de le compiler directement (sans passer par codeblocks), en utilisant l'outil invite de commande DOS de Windows et directement le compilateur GCC livré avec codeblocks (cf 4 ci-après).
Il est également possible d'utiliser Codeblocks et Open GL sans utiliser la bibliothèque GLUT mais en utilisant directement l'API de Windows; Dans ce cas la programmation de l'interface graphique utilisateur du programme créé nécessite beaucoup plus de lignes de code (cf 5 ci après)

1) Télécharger et installer codeblocks

Aller sur le site http://www.codeblocks.org/ et cliquer l'option de menu "Downloads".

01

Cliquer le lien "Download the binary release"

02

Sélectionner le fichier "codeblocks-16.01mingw-setup.exe" afin d'obtenir codeblocks avec le compilateur MingW et l'ensemble des fichiers associés (dont les fichiers librairies .a et d'entête .h permettant de programmer avec OpenGL). Cliquer le lien "Sourceforge.net".

03

Une fois le téléchargement terminé le fichier "codeblocks-16.01mingw-setup.exe" qui présente une taille d'environ 80Mo et se trouve dans le répertoire "C:\Documents and Settings\Nom de l'ordinateur\Mes documents\Downloads".

04

05

Pour installer codeblocks, cliquer ce fichier et suivre la procédure d'installation.

06

A la fin de la procédure d'installation, codeblocks se trouve dans le répertoire "C:\Program Files\CodeBlocks".

07

Le compilateur MingW se trouve dans le répertoire "C:\Program Files\CodeBlocks\MinGW". Ce répertoire comprend le répertoire "C:\Program Files\CodeBlocks\MinGW\include" qui contient l'ensemble des fichiers d'entête .h et le répertoire "C:\Program Files\CodeBlocks\MinGW\lib" qui contient l'ensemble des fichiers librairies .a utilisés par codeblocks.

08

Le répertoire "C:\Program Files\CodeBlocks\MinGW\include\GL" contient les fichiers d'entête "gl.h", "glext.h" et "glu.h" relatifs à OpenGL.

09

10

2) Télécharger et installer GLUT

Saisir "download glut" dans Google pour trouver des sites proposant une version précompilée de glut en téléchargement. Les liens proposés ne permettent malheureusement pas toujours d'obtenir le fichier recherché. Le fichier zip suivant glut-3.7.6-bin.zip contient la version 3.7.6 de GLUT précompilée.

11

Dézipper ce fichier. On obtient un répertoire contenant les fichiers "glut.h", "glut32.dll" et "glut32.lib"

12

1) Placer le fichier "glut.h" dans le répertoire "C:\Program Files\CodeBlocks\MinGW\include\GL"

13

2) Placer le fichier "glut32.dll" dans le répertoire "C:\WINDOWS\System"

14

3) Placer le fichier "glut32.lib" dans le répertoire "C:\Program Files\CodeBlocks\MinGW\lib"

15

GLUT est alors prêt à être utilisé avec codeblocks.

3) Créer un programme 3D avec codeblocks

3.1 Créer un nouveau projet

Lancer codeblocks. Cliquer "File/New/Project"

16

Dans la boîte de dialogue "New from template" qui s'ouvre, choisir "GLUT Project" puis cliquer le bouton Go.

17

La boîte de dialogue "GLUT Project" s'ouvre. Cliquer le bouton "Next".

18

Choisir un répertoire pour ranger le projet (répertoire "C:\essai" par exemple) et un nom pour le projet ("essai" par exemple) Codeblocks attribue alors automatiquement le nom "essai.cbp" au projet.

19

Préciser l'emplacement où se trouvent les répertoires contenant le fichier d'entête "glut.h" et la librairie "glut32.lib" de GLUT. C'est à dire l'emplacement "C:\Program Files\CodeBlocks\MinGW" puis cliquer "Next".

20

Choisir le compilateur GNU GCC Compiler, cocher l'option "Release" et décocher l'option "Debug" (pour l'exemple simple qui suit , le projet n'aura pas besoin d'être déboguer). Cliquer le bouton "Finish".

21

3.2 Examiner le code source généré par défaut

Un nouveau projet est généré automatiquement par codeblocks doté d'un code source de base généré automatiquement par codeblocks dans le fichier "main.cpp". Cliquer le lien "main.cpp" pour observer ce code source qui peut naturellement être modifié selon le besoin.

22

3.3 Compiler et exécuter le programme

Cliquer l'option de menu "Buid/Build and run" pour compiler le projet en l'état et lancer son exécution.

23

Un message d'erreur apparaît indiquant que certaines référence sont indéfinies.

24

En fait, il y a un oubli dans le code source généré par défaut par codeblocks. Il manque l'inclusion, en début de programme, du fichier d'entête" windows.h" qui est indispensable. Corriger le code source de "main.cpp" en ajoutant #include au début du listing.

25

Cliquer à nouveau l'option de menu "Buid/Build and run" pour compiler le projet et lancer son exécution. Cette fois ci tout se passe bien. Il n'y a aucune erreur lors de la compilation et le programme s'exécute correctement. On voit une sphère, un cone et un tore qui tournent sur eux même en étant affichés simultanément en mode lisse et en mode maillé.

26

3.4 Modifier le code source

Remplacer le code source généré automatiquement par codeblocks par le code source minimal suivant.

#include <windows.h>
#include <GL/glut.h>

void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(0.0, 0.0);
glVertex2f(1.0, 0.0);
glVertex2f(0.5, 0.9);
glEnd();
glFlush();
}
void init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1.0, 1.0, 0.0);//left, right, bottom, top of screen viewing region
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 400);
glutInitWindowPosition(0, 0);
glutCreateWindow("Essai");
glutDisplayFunc(display);
init();
glutMainLoop();
}

Projet source codeblocks compacté avec le logiciel open source 7-zip : essai.7z

Observer le résultat obtenu après compilation.

27

4) Créer un programme 3D sans utiliser l'IDE codeblocks

A l'aide du bloc-note, placer le code source ci-dessus dans un fichier texte nommé "test.cpp" placé dans un répertoire "C:\test" par exemple.

28

Cliquer "Tous les programme/ Accessoires/Invite de commande". Avec l'outil invite de commande DOS de Windows, se rendre dans le répertoire test (pour cela saisir les commandes DOS "cd..:" puis "cd test").

29

Taper g++ -o test -Wall test.cpp -mwindows glut32.lib -lopengl32 -lglu32

30

L'option -Wall signifie que l'on demande que tous les messages de warning (ou d'erreurs) qui se produisent lors de la compilation soient affichés.

L'exécutable "test.exe" est aussitôt généré dans le répertoire "C:\test". Il suffit de cliquer ce fichier pour exécuter le programme.

31

5) Utiliser Codeblocks et OpenGL sans utiliser GLUT

Lancer codeblocks et, cette fois-ci, dans la boîte de dialogue "New from template" qui s'ouvre, choisir "Open GL Project" puis cliquer le bouton Go.

32

Préciser le nom et le répertoire du projet ("test" et "C:\test" par exemple) et cliquer le bouton "Next".

33

Choisir les mêmes options que précédemment puis cliquer "Finish".

34

On examine le code source généré par défaut par codeblocks et on constate que la partie interface utilisateur s'appuie cette fois-ci non plus sur GLUT mais sur l'interface de programmation (API) de Windows. De ce fait, pour faire pratiquement la même chose, le programme nécessite un code source beaucoup plus volumineux.

35

#include <windows.h>
#include <gl/gl.h>
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
void EnableOpenGL(HWND hwnd, HDC*, HGLRC*);
void DisableOpenGL(HWND, HDC, HGLRC);

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcex;
HWND hwnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
float theta = 0.0f;

/* register window class */
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "GLSample";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;
if (!RegisterClassEx(&wcex))
return 0;
/* create main window */
hwnd = CreateWindowEx(0,
"GLSample",
"OpenGL Sample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
256,
256,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
/* enable OpenGL for the window */
EnableOpenGL(hwnd, &hDC, &hRC);

/* program main loop */
while (!bQuit)
{
/* check for messages */
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
/* handle or dispatch messages */
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
/* OpenGL animation code goes here */
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(theta, 0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(0.87f, -0.5f);
glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(-0.87f, -0.5f);
glEnd();
glPopMatrix();
SwapBuffers(hDC);
theta += 1.0f;
Sleep (1);
}
}
/* shutdown OpenGL */
DisableOpenGL(hwnd, hDC, hRC);
/* destroy the window explicitly */
DestroyWindow(hwnd);
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
}
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
/* get the device context (DC) */
*hDC = GetDC(hwnd);
/* set the pixel format for the DC */
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
/* create and enable the render context (RC) */
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
}
void DisableOpenGL (HWND hwnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hwnd, hDC);
}

Compiler et exécuter le programme en cliquant "Build/Build and run"

36