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

Développement 2D, 3D et Jeux Discussion :

Qt, OpenGL et les threads


Sujet :

Développement 2D, 3D et Jeux

  1. #1
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut Qt, OpenGL et les threads
    Bonjour,

    Je developpe une appli en QT avec une visualisation en OpenGL.

    Pour ameliorer les perfs de la fenetre de visualisation, j'utilise les Display Lists d'OpenGL...

    Jusque là, tout va bien.

    Maintenant, je souhaiterais preparer mes Display Lists dans un autre thread (un QThread), histoire de ne pas faire attendre l'utilisateur.

    Seulement voila :

    - si je cree une display list dans mon thread, la fonction "glGenLists()" me renvoit une erreur (GL_INVALID_OPERATION), normal, mon thread ne doit pas avoir de contexte openGL associé.

    - du coup, j'essaie de creer un contexte OpenGL dans mon thread, partagé avec le contexte OpenGL principal de mon appli (pour partager les display list) mais là, j'ai des erreurs QT du genre : "QWidgets must be created in the GUI thread"

    En fouillant un peu, j'ai l'impression que la methode de creation de contexte OpenGL de QT (QGLContext) crée en fait aussi un QGLWidget, ce qui explique l'erreur...

    Donc, ma question :

    Comment creer une display list sous QT dans un QThread ?

    Merci !

  2. #2
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    A mon avis, tu ne peux pas, et c'est plus à cause d'OpenGL que de Qt.

  3. #3
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Salut,

    Utilises-tu linux?

  4. #4
    Expert éminent
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Points : 6 812
    Points
    6 812
    Par défaut
    Comme te la dis Mathieu, je ne crois pas non plus que cela soit possible.. je ne pense pas que OpenGL supporte le multi-thread ( à confirmer ) .. Avec DirectX, tu peux le faire par l'intermédiaire des CommandQueue et d'un device par thread...

    EDIT : Après quelques recherches, il semblerait que ce soit possible en utilisant directement les méthodes de ton gestionnaire de fenêtre ( wglCreateContext, wglMakeCurrentContext, wglGetCurrentContext .. ) ..peut être une aide ici
    Mes Tutos DirectX, OpenGL, 3D : http://raptor.developpez.com/

  5. #5
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    En fait s'il utilise linux, c'est mort; il y a des appels X11 à la création d'un contexte (dixit la doc Qt), et par conséquent ça doit être fait dans le thread principal.

  6. #6
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Merci pour les reponses.

    Je compile à la fois pour Linux et pour Windows.

    Je pense que c'est possible, car la doc OpenGL dit qu'on ne peut avoir qu'un seul contexte OpenGL actif à la fois dans un thread donné.

    De plus, il me semble que les Display Lists peuvent etre partagée entre differents contexte.

    Donc, Si je cree 2 threads, avec chacun leur contexte, et que l'un crée des Display Lists en les partageant avec l'autre, l'autre doit pouvoir les afficher... non ?

    Sinon, j'ai bien noté qu'il me faudra surement faire une ou deux fonctions en 2 versions : une pour Linux et une pour Windows...

    PS : Je n'espere tout de meme pas afficher une display list dans un thread pendant que l'autre la compile. Le but est seulement de lancer 3 ou 4 threads chargés de créer toutes les displays list, puis de les afficher dans le thread principal.

  7. #7
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Est-ce réellement la création des display list qui va être coûteuse, ou bien seulement des fonctions de chargement de données à mettre dans les display list?

  8. #8
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    C'est bien la creation des display list.

    En fait, lorsque l'utilisateur ouvre un fichier contenant toute une "scene" 3d, une dizaine de display list sont crées.

    Cela peut prendre presque une minute, et du coup toute l'interface est bloquée pendant ce temps...

    Je souhaite juste mettre ce chargement dans un thread pour ne pas bloquer le reste de l'application.

  9. #9
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    J'en rajoute une couche comme quoi c'est possible :

    Dans le lien de raptor70 : ici

    "A thread can have only one current, active rendering context. When you use multiple threads and multiple rendering contexts, you must be careful to synchronize their use. For example, use one thread only to call SwapBuffers after all threads finish drawing."

    Donc a priori, rien ne s'y oppose, et utiliser des threads juste pour le chargement ne doit pas etre si compliqué...

    A mon avis, il s'agit surtout d'un probleme (avec Qt ?) de creation d'un contexte openGL dans un thread considéré par Qt comme "non-GUI"

  10. #10
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Soit un problème en effet dans Qt (si l'on se fie à la doc, il y a des appels X11 à la création du contexte ce qui rend ça impossible dans un thread), soit un bug dans ton code (pure supposition; je ne l'ai jamais fait, et le message que tu obtiens me laisse quelque peu perplexe).

    Tu devras donc soit instancier toi même tes contextes sans passer par QGLContext (cf Creating OpenGL Objects in a Second Thread - Mac, Linux, Windows), soit abordé le problème différemment en t'inspirant de ce que je te propose ci-dessous.

    Ce n'est pas la création des display list qui est longue mais plus probablement la lecture des données qui vont être stockées dans ta list.
    Tu pourrais avoir une approche différente qui consiste à instancier un thread qui va lire la scène, puis à chaque fois que le contenu total d'une liste est connu (ou plus globalement, un élément de la scène nécessitant un appel opengl), tu émets un signal depuis le worker thread vers le thread principal afin que ce dernier génère la display list à partir des données nouvellement lues.
    Ensuite, à la fin de l'exécution du thread, ton fichier est chargé avec tes display list instanciées sans problèmes de freeze de l'interface.

    PS: As-tu tenté de reproduire ça dans un code de test tout simple?

  11. #11
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    La creation de mes display list se fait en 2 temps :
    - lecture d'un fichier 3ds et stockage en memoire sous forme structurée (arborescence de sommets et de faces)
    - creation des display list en clisant l'arborescence en memoire

    La lecture se fait en 2-3 secondes, normal pour la lecture et le decodage d'un fichier, je pense.

    Par contre, la display list, c'est beaucoup plus long : 10-15 secondes pour une seule, correspondant à un fichier 3DS chargé en 2 secondes.

    Merci pour le lien, y'a surement de bonnes infos.

  12. #12
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Ca paraît énorme :s Tu as combien de sommets et de faces?

  13. #13
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Quelques milliers (pour chaque fichier)

  14. #14
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    C'est bien possible, il suffit de :
    - Désactiver le contexte OpenGL dans le thread principal
    - Le réactiver dans ton thread
    - Créer tes display lists
    - Désactiver le contexte dans ton thread
    - Réactiver le contexte dans le thread principal

    Maintenant, faut juste voir si QGLContext fournit des fonctions pour ça. Peut-être qu'il gère la désactivation automatiquement, sinon jette un oeil à la fonction doneCurrent pour ça.

  15. #15
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Si je comprends bien ce que tu proposes, ça correspondrait aux fonctions doneCurrent() ("Makes no GL context the current context.") et makeCurrent() ("Makes this context the current OpenGL rendering context"). Ca sonne juste?

  16. #16
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Ca sonne pas trop mal

  17. #17
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    C'est bien ce que j'essaie de faire, mais Qt refuse d'activer un contexte OpenGL dans mon thread de travail.

    J'ai l'impression que c'est parce que ce thread est considéré comme "non-GUI"...

    Je suis en train d'essayer en créant à la main un contexte OpenGL, avec du code différent pour windows et pour Linux

Discussions similaires

  1. SDL/Opengl : Probleme de texture avec les thread
    Par tektotodu96 dans le forum OpenGL
    Réponses: 3
    Dernier message: 25/04/2011, 01h42
  2. Gestion des message windows dans les threads
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2003, 17h25
  3. Question simple sur les threads :)
    Par momox dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/06/2003, 04h13
  4. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  5. OpenGL et les ATI ?
    Par Twofy dans le forum OpenGL
    Réponses: 4
    Dernier message: 11/09/2002, 16h13

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