Bonjour,
J'ai un petit code à vous montrer, si ça vous dérange pas de regarder ça deux minutes ^^.
Voilà je crois que j'ai du le dire sur un autre topic (je crois), mais je reçoi bientôt (normalement) un livre sur l'OpenGL mais le truc c'est qu'il utilise pour le fenêtrage et les événements, ainsi que pour la souris (enfin tout ce qu'OpenGL gère pas), l'API Win32. Après l'avoir essayer dans la programmation de jeux c'est vraiment chiant comme API. Beaucoup de choses à écrire pour peu. C'est pour ça que j'ai commencé à regarder SDL en attendant de recevoir le livre, il parait que le couple OpenGL / SDL est un bon choix.
Bref, au niveau de l'implantation (d'un coup j'ai un doute, implantation ou implémentation ? ), je préfère tout séparer du main (je faisais comme ça en Win32), j'ai cru comprendre que ça portait le nom de Singleton ou un truc du genre. Et d'ailleurs, avant de copier le code, une question : pourquoi tous les codes que je vois commencent avec des C ? Du genre CAffichage, CMachin, CBidule,... Tu dois voir de quoi je parle ^^.
Bref, j'ai donc ça :
FenetrageSDL.h :
FenetrageSDL.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 // Classe FenetrageSDL // Cette classe est un singleton dont le seul but est d'afficher le fenêtrage, le reste de l'affichage // est relegué à OpenGL. #ifndef FENETRAGESDL_H #define FENETRAGESDL_H #include <iostream> #include <SDL/SDL.h> class FenetrageSDL { public: FenetrageSDL (int iLargeur = 640, int iHauteur = 480, int iBPP = 16); // Constructeur ~FenetrageSDL (); // Destructeur bool Init (); // Initialisation de l'affichage SDL_Surface * LireEcran () {return m_pEcran;} void ChangerDimensions (int, int); private: int m_iLargeur, m_iHauteur, m_iBPP; SDL_Surface * m_pEcran; // Pointeur vers la fenêtre }; #endif // FENETRAGESDL_H
Et main :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 #include "FenetrageSDL.h" FenetrageSDL::FenetrageSDL (int iLargeur, int iHauteur, int iBPP) : m_iLargeur (iLargeur), m_iHauteur (iHauteur), m_iBPP (iBPP) { // Rien à faire } FenetrageSDL::~FenetrageSDL() { SDL_Quit (); // Se charge de tout nettoyer } bool FenetrageSDL::Init () { // Initialise les sous-systèmes SDL if (SDL_Init (SDL_INIT_VIDEO) < 0) { std::cerr << "Impossible d'initialiser SDL : " << SDL_GetError (); return false; } m_pEcran = SDL_SetVideoMode (m_iLargeur, m_iHauteur, m_iBPP, SDL_HWSURFACE | SDL_DOUBLEBUF); // On vérifie la valeur de retour de la fonction if (m_pEcran == NULL) { std::cerr << "Impossible d'initialiser la video : " << SDL_GetError (); return false; } return true; // Tout s'est déroulé comme prévu, on renvoie true } void FenetrageSDL::ChangerDimensions (int iLargeur, int iHauteur) { m_iLargeur = iLargeur; m_iHauteur = iHauteur; m_pEcran = SDL_SetVideoMode (m_iLargeur, m_iHauteur, m_iBPP, SDL_HWSURFACE | SDL_DOUBLEBUF); }
1) J'ai toujours été étonné sur tous les codes SDL de ne jamais voir de SDL_FreeSurface (sParam.pEcran);. Pourquoi le pointeur vers l'écran n'est jamais deleté ? (d'ailleurs, SDL_FreeSurface == delete ??!!).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 // Inclusion des en-têtes #include <cstdlib> #include <iostream> #include <boost/shared_ptr.hpp> #include <SDL/SDL.h> #include "FenetrageSDL.h" // Structure contenant toutes les variables globales typedef struct VARGlobales { SDL_Surface * pEcran; // Pointeur vers la fenêtre d'affichage SDL_Surface * pBitmapCB; // Pointeur intelligent vers un bitmap SDL_Event event; } VARGlobales; VARGlobales sParam = {NULL, NULL, 0}; // Prototypes de fonction bool ChargerImages (); void Dessiner (); void Nettoyer (); int main (int argc, char** argv) { atexit (SDL_Quit); // Pointeur intelligent vers un objet FenetrageSDL boost::shared_ptr <FenetrageSDL> pFenetre (new FenetrageSDL (800, 600, 32)); if (pFenetre->Init () == false) return 1; // On initialise le pointeur de la structure, pour plus de facilité sParam.pEcran = pFenetre->LireEcran (); // On charge l'image if (!ChargerImages()) return 1; Dessiner (); SDL_Flip (sParam.pEcran); bool bFin = false; while (bFin == false) { // Boucle principale while (SDL_PollEvent (&sParam.event)) { switch (sParam.event.type) { case SDL_QUIT: bFin = true; break; case SDL_KEYDOWN: if (sParam.event.key.keysym.sym == SDLK_ESCAPE) bFin = true; else if (sParam.event.key.keysym.sym == SDLK_UP) { pFenetre->ChangerDimensions (1024, 768); sParam.pEcran = pFenetre->LireEcran (); Dessiner (); SDL_Flip (sParam.pEcran); } else if (sParam.event.key.keysym.sym == SDLK_DOWN) { pFenetre->ChangerDimensions (640, 480); sParam.pEcran = pFenetre->LireEcran (); Dessiner (); SDL_Flip (sParam.pEcran); } break; } } } void Nettoyer (); return 0; } bool ChargerImages () { // On charge l'image sParam.pBitmapCB = SDL_LoadBMP ("cb.bmp"); if (sParam.pBitmapCB == NULL) { std::cerr << "Impossible de charger le bitmap : " << SDL_GetError (); return false; } return true; // Tout s'est bien passé } void Dessiner () { // On dessine l'image SDL_Rect offset; offset.x = 0; offset.y = 0; SDL_BlitSurface (sParam.pBitmapCB, NULL, sParam.pEcran, &offset); } void Nettoyer () { SDL_FreeSurface (sParam.pBitmapCB); }
2) Est-ce que le atexit (SDL_Quit) au début du code est nécessaire étant donné que j'utilise un pointeur intelligent pour l'objet FenetrageSDL qui a dans son destructeur le SDL_Quit () ?
3) Est-ce une bonne technique d'implantation de séparer l'initialisation de l'affichage de la fenetre du main (je veux dire par là, n'est-ce pas pire que de le faire dans le main, car moi je trouve ça plus clair) ? Juste au niveau de ça, après toutes les fonctions de dessin seront gérées par OpenGL.
4) Y a t'il un petit exemple d'un code affichant une simple fenêtre en mélangeant SDL et OpenGL afin que je voille quelles modifications apporter à SDL pour utiliser OpenGL (le livre que j'ai commandé n'utilise hélas que Win32 pour le fenêtrage, pas d'exemple avec SDL malgré le fait qu'ils en parlent comme étant une solution portable...).
5) Y a t'il des fuites de mémoires dans mon code ? J'avoue que je me perds un peu avec la SDL_Surface * pEcran de la classe et celle de la structure de variables globales qui pointent vers celle-ci (je préfère faire comme ça, c'est plus simple d'y acceder, sinon il faudrait faire un truc du genre : pFenetre->LirePointeur()->Bidule.
6) EDIT : j'oubliais, j'ai toujours les deux warning unused variable argc et argv. Et ta technique du void (argc), void (argv) a la fin du code ne fonctionne pas :/
Mirci ^^
Partager