Salut à tous !

Je m’initie à l’utilisation de GlExtmm. Pour cela, je me suis lancé dans la conversion du tutoriel de Nehe pour le faire utiliser GlExtmm. Cependant, dès le premier tutoriel, alors que j’essaye simplement de créer une fenêtre avec une zone de rendu OpenGL, j’obtiens une erreur de segmentation. Je suis certain d’avoir oublié une chose bête, mais je n’arrive pas à trouver de quoi il s’agit.

Je construit le code à l’aide de CMake. Comme il s’agit d’un tutoriel, je n’ai volontairement pas réalisé de procédure d’installation et je ne produit pas la documentation avec Doxygen, pour rendre la gestion plus légère. En revanche, comme j’ai l’habitude d’utiliser Boost.prg_exec_monitor dans tous mes projets qui ne sont pas en ligne de commande, je l’utilise là aussi. Tout mon code est situé dans un sous répertoire nommé « src » et je réalise la construction dans un sous répertoire appelé « build » (rien que de très classique).

Voici le contenu du fichier « CMakeLists.txt », situé à la racine du projet :

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
cmake_minimum_required(VERSION 2.6)
 
project(Tutoriel1 CXX)
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
set(EXECUTABLE_NAME tutoriel1)
 
find_package(
	Boost 
	1.31.1
)
 
find_package(PkgConfig)
 
pkg_check_modules(Glibmm glibmm-2.4>=2.4.0)
pkg_check_modules(GTKmm gtkmm-2.4>=2.4.0)
pkg_check_modules(GLExtmm gtkglextmm-1.2>=1.2.0)
link_directories(
        ${Boost_LIBRARY_DIRS}
        ${Glibmm_LIBRARY_DIRS}
        ${GTKmm_LIBRARY_DIRS}
        ${GLExtmm_LIBRARY_DIRS}
)
include_directories(
        ${Boost_INCLUDE_DIRS}
        ${Glibmm_INCLUDE_DIRS}
        ${GTKmm_INCLUDE_DIRS}
        ${GLExtmm_INCLUDE_DIRS}
)
 
file(
	GLOB_RECURSE
	source_files
	src/*
)
 
add_executable(
	${EXECUTABLE_NAME}
	${source_files}
)
 
target_link_libraries(
	${EXECUTABLE_NAME}
	${Boost_LIBRARIES}
	${Glibmm_LIBRARIES}
	${GTKmm_LIBRARIES}
	${GLExtmm_LIBRARIES}
)
Le contenu du fichier « src/fenetre.hpp » :

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
#ifndef FENETRE_HPP
#define FENETRE_HPP
 
#include <gtkmm/window.h>
#include <gtkmm/drawingarea.h>
#include <gtkglmm.h>
 
namespace Interface {
  /* Classe pour la zone de rendu OpenGL. */
  class GlDrawingArea: public Gtk::DrawingArea,
                       public Gtk::GL::Widget<GlDrawingArea> {
    public:
      GlDrawingArea ();
      virtual ~GlDrawingArea ();
 
    protected:
      /* -- Controlleurs: */
 
      /* À la demande d’affichage. */
      virtual bool on_expose_event (GdkEventExpose* event);
  };
 
  /* Classe pour la fenetre principale. */
  class Fenetre: public Gtk::Window {
    public:
      Fenetre ();
      virtual ~Fenetre();
 
    private:
      /* -- Composants membres : */
 
      /* Zone de rendu OpenGL. */
      GlDrawingArea zoneRendu;
  };
}
 
#endif  // #ifndef FENETRE_HPP
Contenu du fichier « src/fenetre.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
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
#include <glibmm/error.h>
#include <cstdlib>
 
#include "fenetre.hpp"
 
/* -- Constructeur par défaut de GlDrawingArea. --------------------------- */
Interface::GlDrawingArea::GlDrawingArea (): Gtk::DrawingArea () {
  /* Configuration d’OpenGL */
  Glib::RefPtr<Gdk::GL::Config> configuration;
 
  /* Tente d’ouvrir une espace à double tampon. */
  configuration = Gdk::GL::Config::create(Gdk::GL::MODE_RGB    |
                                          Gdk::GL::MODE_DEPTH  |
                                          Gdk::GL::MODE_DOUBLE);
  if (!configuration) {
    g_warning("Impossible de configurer OpenGL en mode double tampon, tente le mode simple tampon.\n");
    /* Tente de configurer un tampon simple. */
    configuration = Gdk::GL::Config::create(Gdk::GL::MODE_RGB   |
                                            Gdk::GL::MODE_DEPTH);
    if (!configuration) {
      g_critical("Impossible de configurer OpenGL.\n");
      std::exit(-2);
    }
 
    /* Donne accès à OpenGL au composant. */
    set_gl_capability(configuration);
  }
}
 
/* -- Destructeur de GlDrawingArea. --------------------------------------- */
Interface::GlDrawingArea::~GlDrawingArea () {
}
 
/* -- À la demande  d’affichage de GlDrawingArea. ------------------------- */
bool Interface::GlDrawingArea::on_expose_event (GdkEventExpose* event) {
  /* Fenêtre OpenGL. */
  Glib::RefPtr<Gdk::GL::Window> fenetreGl = get_gl_window();
 
  fenetreGl->gl_begin(get_gl_context());  
  glClear(GL_COLOR_BUFFER_BIT);
 
  /* Boucle principale. */
 
  fenetreGl->gl_end();
  fenetreGl->swap_buffers ();
 
    return true;
}
 
/* -- Constructeur par défaut de la fenêtre. ------------------------------ */
Interface::Fenetre::Fenetre (): Gtk::Window () {
  set_name("Tutoriel1");
  set_border_width(2);
 
  add(zoneRendu);
 
  show_all_children();
}
 
/* -- Destructeur de la fenêtre. ------------------------------------------ */
 
Interface::Fenetre::~Fenetre () {
}
Enfin, voici le contenu du fichier « src/main.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
 * Premier tutoriel : création d’une fenêtre avec une zone OpenGL.
 */
 
#include <iostream>
#include <boost/test/included/prg_exec_monitor.hpp>
#include <gtkmm/main.h>
#include <gtkglmm.h>
 
#include "fenetre.hpp"
 
/*
 * Principale fonctiondu programme.
 * Entrées :
 *   argc  Nombre d’arguments.
 *   argv  Valeures des arguments.
 * Retourne :
 *   0 si tout s’est bien passé.
 *   -1 en cas d’erreur venant de la GLib ou de ses dérivés.
 */
int cpp_main (int argc, char** argv) {
  try {
    /* Boucle d’évènements. */
    const Gtk::Main kit(argc, argv);
    Gtk::GL::init(argc, argv);
 
    /* Fenêtre principale. */
    Interface::Fenetre principale;
 
    kit.run(principale);
 
    return 0;
  }
  catch(const Glib::Error& ex) {
    /* Message d’erreur. */
    std::ostringstream message;
    message << "Erreur venant de GLib : " <<  ex.what() << '\n';
    g_warning(message.str().c_str());
    return -1;
  }
}
En réalisant un pas à pas, j’ai déterminé que l’erreur de segmentation a lieu au niveau de « kit.run(principale); », ce qui ne m’avance pas beaucoup. Comme je cherche à utiliser les meilleures pratiques, n’hésitez pas à faire des remarques sur l’approche si vous en avez. Cela dit, dans l’immédiat, je cherche surtout à identifier cette erreur de segmentation, mais je n’arrive pas à la localiser. Si vous avez une idée, je suis preneur.

À bientôt.

Le Farfadet Spatial