IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

Erreur de segmentation avec GlExtmm


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut Erreur de segmentation avec GlExtmm
    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

  2. #2
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut Sortie Valgrind.
    Salut à tous !

    À toutes fins utiles, voici la sortie que Valgrind me donne :

    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
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    $ valgrind ./build/bin/Debug/tutoriel1 --leak-check=full --track-origins=yes
    ==7850== Memcheck, a memory error detector
    ==7850== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==7850== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==7850== Command: ./build/bin/Debug/tutoriel1 --leak-check=full --track-origins=yes
    ==7850== 
    ==7850== Syscall param ioctl(generic) points to uninitialised byte(s)
    ==7850==    at 0xB0E4AC7: ioctl (syscall-template.S:82)
    ==7850==    by 0x4060B44: ukiCreateContext (in /usr/lib/x86_64-linux-gnu/libatiuki.so.1.0)
    ==7850==    by 0x127957D5: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==    by 0x131FAD5F: ???
    ==7850==    by 0x131F9E17: ???
    ==7850==    by 0x131F9F1F: ???
    ==7850==    by 0x127CE17F: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==  Address 0x7feff5598 is on thread 1's stack
    ==7850== 
    ==7850== Conditional jump or move depends on uninitialised value(s)
    ==7850==    at 0x127DC0F4: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==    by 0x127DB853: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==    by 0x127DBACC: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==    by 0x127CC967: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850== 
    ==7850== Invalid write of size 8
    ==7850==    at 0x4C2A7ED: memcpy (mc_replace_strmem.c:838)
    ==7850==    by 0x11E5CB62: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==  Address 0x7fd84bf27ff8 is not stack'd, malloc'd or (recently) free'd
    ==7850== 
    ==7850== Invalid write of size 8
    ==7850==    at 0x4C2A7ED: memcpy (mc_replace_strmem.c:838)
    ==7850==    by 0x11E5CB77: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==  Address 0x7fd84bf27ff8 is not stack'd, malloc'd or (recently) free'd
    ==7850== 
    ==7850== Conditional jump or move depends on uninitialised value(s)
    ==7850==    at 0x127D121F: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==    by 0x6804130000000F: ???
    ==7850==    by 0x2DEACFFFF: ???
    ==7850==    by 0x3A0000000F: ???
    ==7850==    by 0xCF: ???
    ==7850==    by 0x1101: ???
    ==7850==    by 0x3802167F: ??? (mc_malloc_wrappers.c:364)
    ==7850==    by 0x131FC7CF: ???
    ==7850== 
    ==7850== Conditional jump or move depends on uninitialised value(s)
    ==7850==    at 0x127D1224: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==    by 0x6804130000000F: ???
    ==7850==    by 0x2DEACFFFF: ???
    ==7850==    by 0x3A0000000F: ???
    ==7850==    by 0xCF: ???
    ==7850==    by 0x1101: ???
    ==7850==    by 0x3802167F: ??? (mc_malloc_wrappers.c:364)
    ==7850==    by 0x131FC7CF: ???
    ==7850== 
    ==7850== Conditional jump or move depends on uninitialised value(s)
    ==7850==    at 0x127D1228: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==    by 0x6804130000000F: ???
    ==7850==    by 0x2DEACFFFF: ???
    ==7850==    by 0x3A0000000F: ???
    ==7850==    by 0xCF: ???
    ==7850==    by 0x1101: ???
    ==7850==    by 0x3802167F: ??? (mc_malloc_wrappers.c:364)
    ==7850==    by 0x131FC7CF: ???
    ==7850== 
    ==7850== Invalid write of size 1
    ==7850==    at 0x4C2A7C8: memcpy (mc_replace_strmem.c:838)
    ==7850==    by 0x127D23F5: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==  Address 0x7fd84ba68583 is not stack'd, malloc'd or (recently) free'd
    ==7850== 
    ==7850== Invalid write of size 8
    ==7850==    at 0x4C2A7ED: memcpy (mc_replace_strmem.c:838)
    ==7850==    by 0x127D23F5: ??? (in /usr/lib/x86_64-linux-gnu/dri/fglrx_dri.so)
    ==7850==  Address 0x7fd84ba68578 is not stack'd, malloc'd or (recently) free'd
    ==7850== 
    ==7850== Invalid read of size 8
    ==7850==    at 0x8B973BA: Gdk::GL::Drawable::gl_begin(Glib::RefPtr<Gdk::GL::Context> const&) (in /usr/lib/libgdkglextmm-x11-1.2.so.0.0.0)
    ==7850==    by 0x41B97F: Interface::GlDrawingArea::on_expose_event(_GdkEventExpose*) (fenetre.cpp:53)
    ==7850==    by 0x5B37BB2: Gtk::Widget_Class::expose_event_callback(_GtkWidget*, _GdkEventExpose*) (in /usr/lib/libgtkmm-2.4.so.1.1.0)
    ==7850==    by 0x69BF098: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)
    ==7850==    by 0x50AF6DF: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3200.4)
    ==7850==    by 0x50C04CF: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3200.4)
    ==7850==    by 0x50C82DA: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3200.4)
    ==7850==    by 0x50C8851: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3200.4)
    ==7850==    by 0x6AD693D: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)
    ==7850==    by 0x69BDA7F: gtk_main_do_event (in /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.10)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    ==7850==    by 0x712A46B: ??? (in /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0.2400.10)
    ==7850==    by 0x712A412: ??? (in /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0.2400.10)
    ==7850==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
    ==7850== 
    ==7850== Warning: client switching stacks?  SP change: 0xead7860 --> 0x7fefff4d0
    ==7850==          to suppress, use: --max-stackframe=34096708720 or greater
     
    **** exception(225): memory access violation at address: 0x00000008: no mapping at fault address
    ******** errors detected; see standard output for details ********
    ==7850== 
    ==7850== HEAP SUMMARY:
    ==7850==     in use at exit: 4,593,599 bytes in 7,270 blocks
    ==7850==   total heap usage: 42,126 allocs, 34,856 frees, 8,619,425 bytes allocated
    ==7850== 
    ==7850== LEAK SUMMARY:
    ==7850==    definitely lost: 17,507 bytes in 14 blocks
    ==7850==    indirectly lost: 3,792,311 bytes in 615 blocks
    ==7850==      possibly lost: 137,180 bytes in 771 blocks
    ==7850==    still reachable: 646,601 bytes in 5,870 blocks
    ==7850==         suppressed: 0 bytes in 0 blocks
    ==7850== Rerun with --leak-check=full to see details of leaked memory
    ==7850== 
    ==7850== For counts of detected and suppressed errors, rerun with: -v
    ==7850== Use --track-origins=yes to see where uninitialised values come from
    ==7850== ERROR SUMMARY: 2621629 errors from 10 contexts (suppressed: 8 from 8)
    Il semble bien que l’erreur survient au niveau de « fenetreGl->gl_begin(get_gl_context()); », mais je n’ai toujours pas localisé l’erreur que je fais.

    À bientôt.

    Le Farfadet Spatial

  3. #3
    Membre actif Avatar de poincare
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mai 2007
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 48
    Par défaut
    Test du tutoriel sur OpenGL : il manque une fonction d'intialisation du contexte et les instructions de configuration ne me semblent pas correctes.
    Le même en Ada (plus lisible pour moi que Cpp) et qui ne genere pas d'erreur.

    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
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    with Gtk.Window; use Gtk.Window;
    with Gtk.GLArea; use Gtk.GLArea;
     
    package Fenetre_Pkg is
     
       type Fenetre_Record is new Gtk_Window_Record with record
          zoneRendu : Gtk_GLArea;
       end record;
       type Fenetre_Access is access all Fenetre_Record'Class;
     
       procedure Nouvelle (Fenetre : out Fenetre_Access);
     
       Configuration_Impossible : exception;
     
    end Fenetre_Pkg;
     
    -----------------------------------------------------------------
    with Gtk;          use Gtk;
    with Gtk.Widget;   use Gtk.Widget;
    with Gtk.Enums;    use Gtk.Enums;
    with Gtk.Handlers;
    with Gtk.Main;
    -- Interface avec OpenGL
    with Gdk.GL; use Gdk.GL;
    with gl_h;
     
    with Ada.Text_IO; use Ada.Text_IO;
     
    package body Fenetre_Pkg is
     
       -- Configurations possibles pour la zone de dessin
       Config_Double : constant Gtk.GLArea.Attributes_Array :=
         (Gdk_GL_Use_Gl,
          Gdk_GL_Rgba,
          Gdk_GL_Depth_Size,
          Gdk_GL_Doublebuffer);
       --  Note: as opposed to what exists in C, you don't need to have
       --  the last element in the array be GDK_GL_NONE. This is done
       --  transparently by GtkAda itself.
       Config_Simple : constant Gtk.GLArea.Attributes_Array :=
         (Gdk_GL_Use_Gl,
          Gdk_GL_Rgba,
          Gdk_GL_Depth_Size);
     
       package Windows_Cb is new Gtk.Handlers.Callback (Gtk_Widget_Record);
       package Return_Windows_Cb is new Gtk.Handlers.Return_Callback (
          Gtk_Widget_Record,
          Boolean);
     
       -- procedures Standard GTK pour la terminaison
       procedure Destroy (Widget : access Gtk_Widget_Record'Class) is
          pragma Unreferenced (Widget);
       begin
          Gtk.Main.Main_Quit;
       end Destroy;
     
       -- procedures pour la gestion de l'evenement expose event
       function Glarea_Expose_Event
         (Widget : access Gtk_Widget_Record'Class)
          return   Boolean
       is
          Area : constant Gtk_GLArea := Gtk_GLArea (Widget);
       begin
     
          --  OpenGL calls can be done only if make_current returns true
          if Make_Current (Area) then
             gl_h.glBegin (mode => 0);
             gl_h.glClear (gl_h.GL_COLOR_BUFFER_BIT);
             gl_h.glEnd;
             --  Swap backbuffer to front
             Swap_Buffers (Area);
          end if;
          return True;
       end Glarea_Expose_Event;
     
       procedure Initialize (Fenetre : access Fenetre_Record'Class);
       -- declaration pour la visibilite
     
       procedure Nouvelle (Fenetre : out Fenetre_Access) is
       begin
          Fenetre := new Fenetre_Record;
          Initialize (Fenetre);
       end Nouvelle;
     
       procedure Initialize (Fenetre : access Fenetre_Record'Class) is
          Double_Tampon_OK : Boolean;
       begin
     
          Gtk.Window.Initialize (Fenetre, Window_Toplevel);
          Set_Title (Fenetre, "Tutoriel N°1 avec Ada");
          Set_Position (Fenetre, Win_Pos_Center);
          Set_Modal (Fenetre, False);
          Set_Resizable (Fenetre, True);
          Set_Default_Size (Fenetre, 600, 400);
          Set_Border_Width (Fenetre, 2);
          -- Tentative de creer un espace à double tampon
          Double_Tampon_OK := True;
          begin
             Gtk.GLArea.Gtk_New (Fenetre.zoneRendu, Config_Double);
          exception
             when Constraint_Error =>
                Double_Tampon_OK := False;
          end;
          if not Double_Tampon_OK then
             Put_Line
               ("Impossible de configurer OpenGL en mode double tampon," &
                " tente le mode simple tampon.");
             begin
             -- Tentative de creer un espace de dessin simple
                Gtk.GLArea.Gtk_New (Fenetre.zoneRendu, Config_Simple);
             exception
                when Constraint_Error =>
                   raise Configuration_Impossible;
             end;
          end if;
          -- Dimensions de la zone de dessin
          Set_Size_Request (Fenetre.zoneRendu, 500, 380);
          Add (Fenetre, Fenetre.zoneRendu);
          --
          -- manque le signal de configuration pour initialiser
          -- le contexte opengl (configure-event)
     
          --  Connexion du signal d'exposition de la fenetre.
          Return_Windows_Cb.Connect
            (Fenetre.zoneRendu,
             "expose_event",
             Return_Windows_Cb.To_Marshaller (Glarea_Expose_Event'Access));
          --  Connexion du signal de fermeture de la fenetre.
          Windows_Cb.Connect
            (Fenetre,
             "destroy",
             Windows_Cb.To_Marshaller (Destroy'Access));
     
       end Initialize;
     
    end Fenetre_Pkg;
    -----------------------------------------------------------------
    -- units from standard Gtk
    with Gtk;        use Gtk;
    with Gtk.Main;
    with Gtk.Widget; use Gtk.Widget;
    -- units from Gtk binding to OpenGL
    with Gdk.GL; use Gdk.GL;
     
    -- Ada predefined units
    with Ada.Text_IO;      use Ada.Text_IO;
    with Ada.Exceptions;   use Ada.Exceptions;
    with Ada.Command_Line; use Ada.Command_Line; use Ada;
     
    -- Application specific unit
    with Fenetre_Pkg; use Fenetre_Pkg;
     
    procedure Tuto_GL is
     
       Fenetre_principale : Fenetre_Pkg.Fenetre_Access;
     
    begin
       Gtk.Main.Init;
       -- verification qu'OpenGL est supporte
       if not Gdk.GL.Query then
          Text_IO.Put_Line ("Erreur : OpenGL n'est pas supporte !");
          Set_Exit_Status (-2);
          return; -- fin du programme
       end if;
       Text_IO.Put_Line ("OpenGL est bien supporte ;-)");
     
       Fenetre_Pkg.Nouvelle (Fenetre_principale);
       Show_All (Fenetre_principale);
       Gtk.Main.Main;
     
    exception
       when Configuration_Impossible =>
          Text_IO.Put_Line ("Impossible d'utiliser OpenGL");
          Set_Exit_Status (-1);
       when Erreur : others =>
          Text_IO.Put_Line ("Erreur " & Exception_Information (Erreur));
          Set_Exit_Status (-1);
    end Tuto_GL;

  4. #4
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut
    Salut à tous !

    Tout d’abord, merci de ta réponse, Poincare.

    Malheureusement, je n’ai jamais utilisé Ada. Du coup, j’ai un peu de mal à faire le lien. Je reste un peu dubitatif.

    Fondamentalement, j’ai repris la structure du tutoriel, concernant la partie sur les fenêtre de rendu. Simplement, j’ai changé le composant DrawingArea par un composant personnalisé possédant des capacités OpenGL.

    J’ai essayé de prendre en compte tes remarques et j’ai ajouté quelques protections. Concrètement, seul le fichier « fenetre.cpp » change :

    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
    #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_RGBA   |
                                              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_RGBA  |
                                                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);
     
        /* Connecte le contrôleur de signal s’il ne s’agit pas déjà d’une
           méthode virtuelle surchargée. */
        #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
        signal_expose_event().connect(sigc::mem_fun(*this,
                                                &GlDrawingArea::on_expose_event),
                                                    false);
        #endif  // #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
      }
    }
     
    /* -- 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();
     
      if (fenetreGl) {
        create_gl_context();
        fenetreGl->gl_begin(get_gl_context());
        glClear(GL_COLOR_BUFFER_BIT);
     
        /* Boucle principale OpenGL. */
     
        fenetreGl->gl_end();
        if (double_buffered()) fenetreGl->swap_buffers();
      }
      else {
        g_warning("Impossible d’obtenir le contexte OpenGL.\n");
      }
     
      return true;
    }
     
    /* -- Constructeur par défaut de la fenêtre. ------------------------------ */
    Interface::Fenetre::Fenetre (): Gtk::Window (), zoneRendu () {
      set_title("Tutoriel 1");
      set_default_size(200, 200);
      set_border_width(2);
     
      add(zoneRendu);
     
      show_all_children();
    }
     
    /* -- Destructeur de la fenêtre. ------------------------------------------ */
     
    Interface::Fenetre::~Fenetre () {
    }
    Plus d’erreur de segmentation (je m’en suis protégé), mais il ne parvient toujours pas à obtenir le contexte OpenGL. Voici une sortie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ ./build/bin/Debug/tutoriel1 
     
    ** (tutoriel1:9592): WARNING **: Impossible d’obtenir le contexte OpenGL.
     
     
    ** (tutoriel1:9592): WARNING **: Impossible d’obtenir le contexte OpenGL.
     
    no errors detected
    N’aurais-je pas placé « create_gl_context(); » au bon endroit ?

    À bientôt.

    Le Farfadet Spatial

  5. #5
    Membre éclairé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 190
    Par défaut
    Salut à tous !

    J’ai fini par trouver, c’était en effet une erreur stupide : une accolade fermante mal placée dans le constructeur, qui fait qu’en mode double tampon (celui sur lequel fonctionne ma carte) il ne donnait pas les capacités OpenGL au composant… Voici une version de « src/fenetre.cpp » qui donne satisfaction :

    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
    #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_RGBA   |
                                              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_RGBA  |
                                                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);
     
      /* Connecte le contrôleur de signal s’il ne s’agit pas déjà d’une
         méthode virtuelle surchargée. */
      #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
      signal_expose_event().connect(sigc::mem_fun(*this,
                                                &GlDrawingArea::on_expose_event),
                                                    false);
      #endif  // #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
    }
     
    /* -- 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();
     
      if (fenetreGl) {
        if (!create_gl_context()) {
          g_critical("Impossible de créer un contexte OpenGL.\n");
          std::exit(-3);
        }
        fenetreGl->gl_begin(get_gl_context());
     
        glClear(GL_COLOR_BUFFER_BIT);
     
        /* Boucle principale OpenGL. */
     
        fenetreGl->gl_end();
        fenetreGl->swap_buffers();
      }
      else {
        g_critical("Impossible d’obtenir le contexte OpenGL.\n");
      }
     
      return true;
    }
     
    /* -- Constructeur par défaut de la fenêtre. ------------------------------ */
    Interface::Fenetre::Fenetre (): Gtk::Window (), zoneRendu () {
      set_title("Tutoriel 1");
      set_default_size(200, 200);
      set_border_width(2);
     
      add(zoneRendu);
     
      show_all_children();
    }
     
    /* -- Destructeur de la fenêtre. ------------------------------------------ */
     
    Interface::Fenetre::~Fenetre () {
    }
    Sacré nom d’une pipe en bois !

    À bientôt.

    Le Farfadet Spatial

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur de segmentation avec delete
    Par ValyGator dans le forum C++
    Réponses: 13
    Dernier message: 11/02/2009, 20h44
  2. Erreur de segmentation avec fclose
    Par sylvanus35 dans le forum Débuter
    Réponses: 7
    Dernier message: 09/08/2008, 05h33
  3. Erreur de segmentation avec libxml2
    Par DevMg dans le forum XML
    Réponses: 0
    Dernier message: 18/02/2008, 14h44
  4. Erreur de segmentation avec RSA_verify
    Par LorDjidane dans le forum C
    Réponses: 7
    Dernier message: 14/06/2007, 11h29
  5. Erreur de segmentation avec un main vide
    Par matique dans le forum Réseau
    Réponses: 10
    Dernier message: 22/04/2007, 07h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo