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

Qt Discussion :

[OpenGL 4.4] Erreur de segmentation avec des VBO


Sujet :

Qt

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut [OpenGL 4.4] Erreur de segmentation avec des VBO
    Bonjour tout le monde,

    Je sollicite votre aide pour un problème assez particulier. Je veux intégrer une interface Qt à mon moteur OpenGL. Qt propose des classes toutes faites, mais j'ai déjà mes propres classes pour gérer des concepts OpenGL. J'utilise donc QOpenGLFunctions_4_4_Core pour ne rien changer. Le truc c'est qu'à un moment du programme, une erreur de segmentation liée à la librarie Nvidia survient. J'ai cherché pendant plusieurs jour, avec debugger mais je ne comprend pas l'erreur. Je vous poste un code simplifié et épuré pour vous montrer le problème. Le problème survient lors de l'appel de la fonction glGenBuffers dans le fichier bufferObject.cpp
    Je précise que si je génère la VBO dans le fichier engine.cpp, cela ne plante pas. Avez vous une solution?

    Partie IHM:

    GLWidget.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
     
    #include "glwidget.hpp"
     
    GLWidget::GLWidget(int framesPerSecond, QWidget *parent):QOpenGLWidget(parent)
    {
        QSurfaceFormat format;
        format.setDepthBufferSize(24);
        format.setStencilBufferSize(8);
        format.setVersion(4, 4);
        format.setProfile(QSurfaceFormat::CoreProfile);
        setFormat(format);
        create();
     
        m_context = new QOpenGLContext();
        m_context->setFormat(format);
        m_context->create();
        m_context->makeCurrent(0);
    }
    GLWidget.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
     
    #ifndef GLWIDGET_HPP
    #define GLWIDGET_HPP
     
    #include "definitions.hpp"
    #include <QOpenGLWidget>
    //#include <QWidget>
    //#include <QWindow>
    #include <QObject>
    #include <QOpenGLContext>
     
    class GLWidget : public QOpenGLWidget
    {
    	Q_OBJECT
    public:
    	explicit GLWidget(int framesPerSecond = 0, QWidget *parent = 0);
    	~GLWidget();
     
    	virtual void initializeGL() = 0;
    	virtual void resizeGL(int w, int h) = 0;
    	virtual void paintGL() = 0;
     
        QOpenGLContext *m_context;
        openGLFunctions *m_functions;
    };
     
    #endif
    myGLWidget.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
     
    #include "graphics/engine.hpp"
    #include "myglwidget.hpp"
    #include <QObject>
     
    using namespace std;
    using glm::vec3;
    using seed_graphics::Engine;
     
    MyGLWidget::MyGLWidget(QStatusBar *qSB, QWidget *parent) 
        : GLWidget(60, parent)
    {
        m_engine = new Engine();
    }
     
    MyGLWidget::~MyGLWidget() 
    {
    }
     
    void MyGLWidget::initializeGL()
    {
        m_functions = m_context->versionFunctions<openGLFunctions>();
        m_functions->initializeOpenGLFunctions();
        m_engine->init();
    }
     
    void MyGLWidget::resizeGL(int width, int height)
    {
        if(height == 0)
            height = 1;
        m_functions->glViewport(0, 0, width, height);
    }
     
    void MyGLWidget::paintGL()
    {
    }
    myGLWidget.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
     
    #ifndef MYGLWIDGET_HPP
    #define MYGLWIDGET_HPP
     
    #define GLM_FORCE_RADIANS
    #include "glwidget.hpp"
    #include <iostream>
    #include <memory>
    #include <glm/glm.hpp>
     
        class Engine;
     
    class MyGLWidget : public GLWidget
    {
    	Q_OBJECT
    public:
        explicit MyGLWidget(QStatusBar *qSB, QWidget *parent = 0);
        ~MyGLWidget();
        void initializeGL();
        void resizeGL(int width, int height);
        void paintGL();
     
    private:
    	seed_graphics::Engine *m_engine;
    };
     
    #endif
    Partie Moteur graphique

    engine.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
     
    #include "engine.hpp"
    #include "buffers/bufferObject.hpp"
     
    #include <fstream>
    #include <iostream>
    #include <glm/glm.hpp>
     
    using glm::vec3;
    using std::cout;
    using std::endl;
     
    openGLFunctions* Engine::f = 0;
     
    Engine::Engine()
    {;
    }
     
    void Engine::init()
    {
    	context = QOpenGLContext::currentContext();
    	Engine::f = context->versionFunctions<openGLFunctions>();
    	f->initializeOpenGLFunctions();
    	m_buf = new BufferObject();
    	m_buf->create();
    }
     
    void Engine::render()
    {
    	f->glUseProgram(m_shaderProgram);
    	f->glBindVertexArray(m_vao);
    	f->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    	f->glBindVertexArray(0);
    }
    engine.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
     
    #ifndef ENGINE_HPP
    #define ENGINE_HPP
     
    #include "definitions.hpp"
     
    class BufferObject;
    class Engine
    {
    public:
    	explicit Engine();
    	~Engine();
     
    	void init();
    	void render();
     
    	static openGLFunctions *f;
     
    private:
    	BufferObject *m_buf;
     
    	QOpenGLContext *context;
    };
     
    }
     
    #endif // ENGINE_HPP
    objectBuffer.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
     
    #include "buffers/bufferObject.hpp"
    #include <iostream>
    BufferObject::BufferObject()
    {
    	m_id = 0;
    }
    bool BufferObject::create()
    {
    	openGLFunctions *f = Engine::f;
    	f->glEnable(GL_BLEND);
    	GLuint t = 0;
    	f->glGenBuffers(GL_ARRAY_BUFFER, &t);
    	f->glGenBuffers(GL_ARRAY_BUFFER, &m_id);
    	if(m_id)
    		return true;
    	return false;
    }
    definitions.hpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #ifndef DEFINITIONS_HPP
    #define DEFINITIONS_HPP
     
    #include <QOpenGLFunctions>
    #include <QOpenGLFunctions_4_4_Core>
     
    typedef QOpenGLFunctions_4_4_Core openGLFunctions;
     
    #endif // DEFINITIONS_HPP
    ObjectBuffer.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
     
    #ifndef BUFFER_OBJECT_HPP
    #define BUFFER_OBJECT_HPP
     
    #include "definitions.hpp"
    #include "buffer.hpp"
    #include "engine.hpp"
     
    class BufferObject
    {
    public:
    	explicit BufferObject();
    	~BufferObject();
    	bool create();
    private:
    	GLuint m_id;
    };
    #endif // BUFFER_OBJECT_HPP
    Je vous remercie d'avance.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 921
    Points : 220 492
    Points
    220 492
    Billets dans le blog
    127
    Par défaut
    Bonjour,

    Suivant la description du problème, il pourrait que ce soit un problème de thread. Notamment, tous les appels OpenGL doivent être fait dans le thread ayant créé le contexte OpenGL.

  3. #3
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Sauf confusion de ma part, les appels doivent être faits depuis le thread qui a invoqué makeCurrent pour la dernière fois.

    • Le pointeur de fonction est-il valide ?
    • L'appel est-il réalisé depuis le bon thread ?


    D'une manière générale lorsque tu développes avec OpenGL, teste et logge le résultat de tous les appels. Ce n'est pas superflu. Tu peux te faire des macros dédiées à cela.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2012
    Messages : 22
    Points : 18
    Points
    18
    Par défaut
    J'ai ajouté la fonction makeCurrent(0) dans la méthode create dans le fichier bufferObject.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
     
    #include "buffers/bufferObject.hpp"
    #include <QDebug>
    #include <iostream>
     
    namespace seed_graphics
    {
    BufferObject::BufferObject()
    {
    	m_id = 0;
    }
     
    BufferObject::~BufferObject()
    {
     
    }
     
    bool BufferObject::create()
    {
    	openGLFunctions *f = Engine::f;
            QOpenGLContext::currentContext()->makeCurrent(0);
     
    	if(m_id)
    		destroy();
    	f->glEnable(GL_BLEND);
    	GLuint t = 0;
    	std::cout << "test" << std::endl;
    	f->glGenBuffers(GL_ARRAY_BUFFER, &t);
    	f->glGenBuffers(GL_ARRAY_BUFFER, &m_id);
    	std::cout << "glbufferfin" << std::endl;
     
    	if(m_id)
    		return true;
    	return false;
    }
     
    void BufferObject::destroy()
    {
    	openGLFunctions *f = QOpenGLContext::currentContext()->versionFunctions<openGLFunctions>();
    	if(m_id)
    		f->glDeleteBuffers(1, &m_id);
    }
     
    }
    Mais du coup de cette façon, il faut que je mette à chaque fonction makeCurrent?
    Comment faut-il gérer efficacement les threads?

  5. #5
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    On intercepte les erreurs GL en analysant les valeurs de retour et/ou en utilisant les appels dédiés. Je te renvoie vers les cours de référence pour les détails.


    Citation Envoyé par chtimy Voir le message
    Mais du coup de cette façon, il faut que je mette à chaque fonction makeCurrent?
    Comment faut-il gérer efficacement les threads?
    Rien de sorcier vraiment, il suffit de réaliser les appels GL sur le même thread. Tu n'as qu'un seul makeCurrent à faire une fois le contexte initialisé.

Discussions similaires

  1. Réponses: 15
    Dernier message: 31/05/2013, 16h57
  2. erreur de segmentation avec des threads
    Par momoski89 dans le forum C
    Réponses: 2
    Dernier message: 07/05/2013, 17h17
  3. Réponses: 2
    Dernier message: 05/03/2007, 19h55
  4. Erreur à l'execution avec des dll
    Par Jim_Nastiq dans le forum Visual C++
    Réponses: 2
    Dernier message: 02/03/2007, 16h15
  5. Erreur sur IIS avec des cripts ASP
    Par Alin dans le forum ASP
    Réponses: 7
    Dernier message: 22/06/2004, 15h15

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