web-dev-qa-db-fra.com

Rendu multithread sur OpenGL

J'ai une application multithread dans laquelle j'essaie de rendre avec différents threads. J'ai d'abord essayé d'utiliser le même contexte de rendu entre tous les threads, mais j'obtenais des contextes NULL actuels pour d'autres threads. J'ai lu sur Internet qu'un contexte ne peut être courant que sur un fil à la fois.

J'ai donc décidé de faire quelque chose de différent. Je crée une fenêtre, j'en extrait le HDC et crée le premier RC. Après cela, je partage ce HDC entre les threads et, à chaque nouveau thread que je crée, j’obtiens une nouvelle télécommande à partir du même HDC que je mets à jour pour ce thread. Chaque fois que je le fais, le RC renvoyé est toujours différent (généralement la valeur précédente + 1). Je fais une assertion pour vérifier si wglGetCurrentContext() retourne un RC, et il semblerait qu'il retourne celui qui vient d'être créé. Mais après avoir rendu le rendu, je n’obtiens aucun rendu et si j’appelle GetLastError(), j’obtiens l’erreur 6 (handle non valide ??).

Donc, cela signifie-t-il que, malgré chaque nouvel appel de wglCreateContext(), me donne une nouvelle valeur, cela signifie en quelque sorte que toutes ces valeurs différentes constituent le même "canal de connexion" pour les appels OpenGL?

Cela signifie-t-il que je devrai toujours invalider le précédent contexte de rendu sur un thread et l'activer sur le nouveau? Je dois vraiment faire cette synchronisation tout le temps ou y at-il une autre façon de travailler autour de ce problème?

15
filipehd

J'ai une application multithread dans laquelle j'essaie de rendre avec différents threads.

NE PAS !!!

Vous gagnerez rien d’essayer de multithread votre moteur de rendu. Fondamentalement, vous rencontrez une grande situation critique et le pilote sera simplement occupé à synchroniser les threads pour le comprendre.

Pour obtenir les meilleures performances de rendu, conservez toutes les opérations OpenGL sur un seul thread. Toute la parallélisation se fait gratuitement sur le GPU.

46
datenwolf

Je suggère de lire l'article suivant du consortium OpenGL.

http://www.opengl.org/wiki/OpenGL_and_multithreading

En termes simples, cela dépend beaucoup de ce que vous entendez par multi-threading en ce qui concerne OpenGl, si vous avez un thread qui effectue le rendu et un (ou plusieurs) qui effectue d'autres tâches (par exemple, intelligence artificielle, physique, logique de jeu, etc.), a parfaitement raison.

Si vous souhaitez que plusieurs threads se mêlent à OpenGL, vous ne pouvez pas, ou mieux, vous le pouvez, mais cela vous causera vraiment plus de problèmes que d'avantages.

Essayez de lire la FAQ suivante sur l'utilisation parallèle d'OpenGL pour avoir une meilleure idée de ce concept:

http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html

14
Maurizio Benedetti

Dans certains cas, il peut être judicieux d'utiliser plusieurs contextes de rendu dans différents threads. J'ai utilisé une telle conception pour charger des données d'image à partir d'un système de fichiers et pousser ces données dans une texture.

5
JoR

OpenGL sur Mac OS X est compatible avec un seul thread; pour l'activer:

#include <OpenGL/OpenGL.h>

CGLError err = 0;
CGLContextObj ctx = CGLGetCurrentContext();

// Enable the multi-threading
err =  CGLEnable( ctx, kCGLCEMPEngine);

if (err != kCGLNoError ) {
     // Multi-threaded execution is possibly not available
     // Insert your code to take appropriate action
}

Voir: Concurrence et OpenGL - Développeur Apple

Et: Questions-réponses techniques QA1612: Multithreading OpenGL ES et ...

0
geowar