
Creer un projet OpenGL
3 messages
• Page 1 sur 1
Creer un projet OpenGL
Il y a quelques années, lorsque j'ai commencé à programmer, les jeux 3D m'ont fasciné. Quand j'ai eu les connaissances suffisantes pour créer des petits jeux, je me suis intéressé à la SDL (une librairie simple pour faire des jeux 2D). Mais je me suis rapidement rendu compte que derrière la simplicité de la librairie se cachait un gros problème : les performances...
Se basant sur DirectX5 (époque de windows 95
), dès que l'on utilise de la transparence ou qu'on affiche plein de trucs à l'écran, ça devient très vite saccadé... Je me suis alors penché sur OpenGL, et je fus vite conquis !
OpenGL se base sur un principe de caméra et d'objets 3D. Il est tout à fait possible de faire un jeux en 2D (comme le montre le projet d'un de mes étudiants) en plaçant une caméra pour qu'elle fasse une "vue du dessus".
Pour vous aider à commencer la programmation 3D, j'ai rédigé quelques posts à la suite...
Se basant sur DirectX5 (époque de windows 95

OpenGL se base sur un principe de caméra et d'objets 3D. Il est tout à fait possible de faire un jeux en 2D (comme le montre le projet d'un de mes étudiants) en plaçant une caméra pour qu'elle fasse une "vue du dessus".
Pour vous aider à commencer la programmation 3D, j'ai rédigé quelques posts à la suite...
- Tibo
- Administrateur du site
- Messages: 147
- Inscription: 26 Mar 2008, 13:58
Utiliser la bibliothèque OpenGL
Pour répondre aux problèmes courants lors de la création de fenêtres OpenGL, voici un certain nombre de conseils (valables pour toutes versions de Visual Studio).
Dans les propriétés du projet, il faut :
Ensuite, pour simplifier l'utilisation des textures, je vous recommande d'utiliser DevIL. Son incorporation dans Visual n'est pas beaucoup plus complexe. De même que pour OpenGL, il faut :
Si vous voulez utiliser à la fois DevIL et OpenGL, pensez à mettre toutes les dépendences (opengl32.lib glu32.lib DevIL.lib ILU.lib ILUT.lib)
Normalement, si vous avez tout respecté, ça devrait marcher... N'hésitez pas à poster vos erreurs si ça ne marche pas !
Dans les propriétés du projet, il faut :
- Dire au compilateur que l'on utilise des DLL multi-thread :
- Code: Tout sélectionner
Configuration Properties->C/C++->Code Generation->Runtime Library : Multi-threaded DLL
- Dire au linker que l'on utilise des DLL d'OpenGL :
- Code: Tout sélectionner
Configuration Properties->Linker->Input->Additionnal Dependencies : opengl32.lib glu32.lib
- Utiliser les entêtes des librairies d'openGL :
#include <gl/gl.h>
#include <gl/glu.h>
Attention : glut.h est à éviter car il n'est plus mis à jour !
Ensuite, pour simplifier l'utilisation des textures, je vous recommande d'utiliser DevIL. Son incorporation dans Visual n'est pas beaucoup plus complexe. De même que pour OpenGL, il faut :
- Dire au compilateur que l'on utilise des DLL multi-thread :
- Code: Tout sélectionner
Configuration Properties->C/C++->Code Generation->Runtime Library : Multi-threaded DLL
- Dire au linker que l'on utilise des DLL de DevIL:
- Code: Tout sélectionner
Configuration Properties->Linker->Input->Additionnal Dependencies : DevIL.lib ILU.lib ILUT.lib
- Utiliser les entêtes des librairies d'openGL :
#include <IL/il.h>
#include <IL/ilu.h>
#include <IL/ilut.h> - Ajouter les fichiers .h de Devil dans le répertoire d'installation de Visual :
- Code: Tout sélectionner
Pour moi : C:\Program Files\Microsoft Visual Studio 9.0\VC\include
- Ajouter aussi les fichier .lib de Devil :
- Code: Tout sélectionner
Pour moi : C:\Program Files\Microsoft Visual Studio 9.0\VC\lib
Si vous voulez utiliser à la fois DevIL et OpenGL, pensez à mettre toutes les dépendences (opengl32.lib glu32.lib DevIL.lib ILU.lib ILUT.lib)
Normalement, si vous avez tout respecté, ça devrait marcher... N'hésitez pas à poster vos erreurs si ça ne marche pas !
- Tibo
- Administrateur du site
- Messages: 147
- Inscription: 26 Mar 2008, 13:58
Créer une fenêtre OpenGL
Pour créer une fenêtre OpenGL, il y a deux possibilités :
Tout d'abord, relisez bien mes cours sur Windows pour que l'on parte sur les mêmes bases...
Je suppose donc que vous avez compris l'intérêt de la fonction MainProc...
Pour commencer, créons une fenêtre OpenGL... On ne va pas faire comme dans mon cours car on veux pouvoir la paramétrer plus en détails...
Voila le code pour créer une fenêtre OpenGL :
Une fois la fenetre faite, il faut traiter les messages qui lui arrivent... C'est ici que nous avons besoin de MainProc ! Un petit exemple de MainProc qui enregistre toutes les touches pressées dans un tableau ainsi que les mouvements de la souris :
Bon, avec ce début, vous ne pouvez pas encore faire grand chose (juste prendre un tube d'aspirine), inspirez vous pour la suite du TP de N4th (TP sur les pointeurs), ou du site suivant : http://neogamedev.chable.net/?PageID=2000
- utiliser GLUT qui permet de s'affranchir de détails techniques propres à Windows (ou linux...). Le but du post ici n'est pas de faire un tutorial sur GLUT, utilisez celui là qui est très bien fait !
- utiliser les fonctions de Windows.
Tout d'abord, relisez bien mes cours sur Windows pour que l'on parte sur les mêmes bases...
Je suppose donc que vous avez compris l'intérêt de la fonction MainProc...
Pour commencer, créons une fenêtre OpenGL... On ne va pas faire comme dans mon cours car on veux pouvoir la paramétrer plus en détails...
Voila le code pour créer une fenêtre OpenGL :
- Code: Tout sélectionner
BOOL fenetre::CreeGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat;
WNDCLASS wc;
DWORD dwExStyle;
DWORD dwStyle;
RECT WindowRect;
WindowRect.left=(long)0;
WindowRect.right=(long)width;
WindowRect.top=(long)0;
WindowRect.bottom=(long)height;
// Met a jour l'info de fullscreen
fullscreen=fullscreenflag;
// Recupere l'instance de la fenetre
hInstance = GetModuleHandle(NULL);
// Redessine si modification de la taille ou de la position et garde un seul DC pour la fenetre.
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
// fonction de traitement des messages (voir mon cours)
wc.lpfnWndProc = (WNDPROC) fenetre::MainProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
// Icone par default
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
// Curseur par default
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// Pas de fond pour Opengl (c'est justement lui qui dessinera le fond)
wc.hbrBackground = NULL;
// On ne veut pas de menu
wc.lpszMenuName = NULL;
// Nom de la fenetre
wc.lpszClassName = "OpenGL";
// Essaye de creer la class fenetre :
if (!RegisterClass(&wc))
{
MessageBox(fenetre::hWnd,"Impossible de cree la class fenetre....","ERREUR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if (fullscreen)// Est on en plein ecran?
{
//oui, alors on passe la fenêtre en fullscreen...
DEVMODE dmScreenSettings;
EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dmScreenSettings);
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width;
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
dmScreenSettings.dmDisplayFrequency=70;
// Essaye de faire les changements de rezo. NOTE: CDS_FULLSCREEN permet d'enlever la bar demarrer
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// Si ce n'est pas reussi, on donne le choix d'essayer en fenetre
if (MessageBox(fenetre::hWnd,"Le mode plein ecran n'est pas suporté...\n essayer en mode fenetré?","Initialisation",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE; // Fenetre choisi. Fullscreen = FALSE
}
else
{
// Erreur, le programme ferme :
MessageBox(fenetre::hWnd,"Erreur d'initialisation...","ERREUR",MB_OK|MB_ICONSTOP);
return FALSE;
}
}
}
if (fullscreen)// Si on est en plein ecran
{
//alors on a un style de fenêtre particulier
dwExStyle=WS_EX_APPWINDOW;
dwStyle=WS_POPUP;
ShowCursor(FALSE);
}
else
{
//sinon, on a un style de fenêtre normal :
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle=WS_OVERLAPPEDWINDOW;
}
//on récupère les dimensions de la fenetre :
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
// Cree la fenetre
if (!(hWnd=CreateWindowEx(dwExStyle,
"OpenGL",// Nom de la class
title,// Nom de la fenetre
dwStyle |// Style de la fenetre
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN,
0, 0,// Position de la fenetre
WindowRect.right-WindowRect.left,// Calcule la largeur
WindowRect.bottom-WindowRect.top,// Calcule la hauteur
NULL,
NULL,
hInstance,// Instance
NULL)))
{
//problème, donc on :
FinGL();// supprime le contexte
MessageBox(fenetre::hWnd,"Creation de la fenetre echoué.","ERREUR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR),// Taille du descripteur de fenetre
1,// Numero de version
PFD_DRAW_TO_WINDOW |// Le format sera pour une fenetre
PFD_SUPPORT_OPENGL |// Le format sera pour Opengl
PFD_DOUBLEBUFFER,// Le format sera en double buffering
PFD_TYPE_RGBA,// Le format sera en RGBA
bits,// Profondeur de couleur (32 ici)
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16, // Z-Buffer
0,// Pas de Stencil Buffer
0,// Pas de buffer auxilliere
PFD_MAIN_PLANE,
0,
0, 0, 0
};
if (!(hDC=GetDC(hWnd)))// A t on un DC
{
//erreur, donc on quitte :
FinGL();// supprime le contexte
MessageBox(fenetre::hWnd,"Ne peut pas creer de support OpenGL ...","ERREUR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))
{
//si on ne trouve pas de format de pixel utilisable
FinGL();// supprime le contexte
MessageBox(fenetre::hWnd,"Ne trouve pas de format de pixel utilisable ...","ERREUR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
{
FinGL();// supprime le contexte
MessageBox(fenetre::hWnd,"Ne peut pas utiliser le format de pixel ...","ERREUR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if (!(hRC=wglCreateContext(hDC)))
{
FinGL();// supprime le contexte
MessageBox(fenetre::hWnd,"Ne peut pas cree de context d'affichage ...","ERREUR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if(!wglMakeCurrent(hDC,hRC))
{
FinGL();// supprime le contexte
MessageBox(fenetre::hWnd,"Ne peut pas activer le context d'affichage ...","ERREUR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
ShowWindow(hWnd,SW_SHOW);// affiche la fenetre
SetForegroundWindow(hWnd);// Met en priorité superieure
SetFocus(hWnd); // Redirige le clavier vers la fenetre
return TRUE;// Success
}
Une fois la fenetre faite, il faut traiter les messages qui lui arrivent... C'est ici que nous avons besoin de MainProc ! Un petit exemple de MainProc qui enregistre toutes les touches pressées dans un tableau ainsi que les mouvements de la souris :
- Code: Tout sélectionner
LRESULT CALLBACK fenetre::WndProc( HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)// Dispatche les messages de windows
{
case WM_KEYDOWN:// Une touche est pressée?
{
keys[wParam] = true;// Si oui, on la marque à vrai
return 0;
}
case WM_KEYUP:// Une touche est relachée?
{
keys[wParam] = false;// Si oui, on la marque à faux
return 0;
}
case WM_ACTIVATE:// Une activation de la fenetre?
{
if (!HIWORD(wParam))// Regarde si c'est une activation
{
active=true;
}
else
{
active=false;// Ou une desactivation
}
return 0;
}
case WM_COMMAND:// Intercepte les messages que j'ai defini
{
};
case WM_SYSCOMMAND:// Intercepte les messages systemes
{
switch (wParam)
{
case SC_SCREENSAVE:// Economiseur d'ecran se declanche?
case SC_MONITORPOWER:// Economie d'energie se declanche?
return true;// Empeche d'arriver
}
break;
}
case WM_CLOSE:// Doit on fermet la fenetre?
{
PostQuitMessage(0);// Quitte l'appli
return 0;
}
case WM_SIZE:// Redimension de la fenetre?
{
Redimension(LOWORD(lParam),HIWORD(lParam));
return 0;
}
case WM_LBUTTONDOWN://souris droite enfoncé
{
keys[259] = true;// Si oui, on la marque à vrai
return 0;
}
break;
case WM_LBUTTONUP://souris droite relachée
{
keys[259] = false;// Si oui, on la marque à vrai
return 0;
}
case WM_MBUTTONDOWN://souris milieu enfoncé
{
keys[258] = true;// Si oui, on la marque à vrai
return 0;
}
break;
case WM_MBUTTONUP://souris milieu relachée
{
keys[258] = false;// Si oui, on la marque à vrai
return 0;
}
break;
case WM_RBUTTONDOWN://souris droite enfoncé
{
keys[257] = true;// Si oui, on la marque à vrai
return 0;
}
break;
case WM_RBUTTONUP://souris droite relachée
{
keys[257] = false;// Si oui, on la marque à faux
return 0;
}
break;
case WM_MOUSEMOVE:
{
sourisx = LOWORD (lParam);
sourisy = HIWORD (lParam);
sourisdx=ancSourisx-sourisx;
sourisdy=ancSourisy-sourisy;
ancSourisx = sourisx;
ancSourisy = sourisy;
return 0;
}
break;
}
// Passe les autres messages à DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
Bon, avec ce début, vous ne pouvez pas encore faire grand chose (juste prendre un tube d'aspirine), inspirez vous pour la suite du TP de N4th (TP sur les pointeurs), ou du site suivant : http://neogamedev.chable.net/?PageID=2000
- Tibo
- Administrateur du site
- Messages: 147
- Inscription: 26 Mar 2008, 13:58
3 messages
• Page 1 sur 1
Retourner vers Programmation Windows
Qui est en ligne
Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité