1

Salut,

je n'arrive pas à utiliser des fonctions opengl dans un thread SDL.
Je sais que la doc de SDL déconseille fortement d'utiliser une même librairie dans plusieurs threads mais je ne vois vraiment pas comment faire autrement.
Voici en gros ce que je fais pour afficher le message "Loading", défilant de gauche à droite pendant un... chargement :


bool loading;
SDL_mutex * mut;

void affiche ( void * data ) {

_ float pos = 0;
_ while ( loading) {

_ _ SDL_MutexP ( mut );

_ _ glBindTexture ( GL_TEXTURE_2D, textureLoading );
_ _ glBegin ( GL_TRUCS );
_ _ glVertex ( pos, ... );
_ _ ...
_ _ glEnd ( );

_ _ SDL_MutexV ( mut );

_ _ pos+=1;
_ _ if (pos>100) pos=0;

_ }
}

main () {

_ mut = SDL_CreateMutex ( );

_ loading = true;

_ SDL_thread * thr = SDL_CreateThread( affiche, NULL );


_ // et la, dans le main, je charge les datas
_ // en prenant soin d'encadrer aussi la partie qui charge les textures avec le mutex

_ GLuint texture;

_ SDL_mutexP ( mut );

_ glGenTextures(1, &texture);
_ glBindTexture(GL_TEXTURE_2D, texture);

_ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
_ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
_ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
_ glTexImage2D(GL_TEXTURE_2D, 0, PixelSize, Width, Height, 0, format, GL_UNSIGNED_BYTE, Data);

_ SDL_mutexV ( mut );

_ // enfin, pour mettre fin au thread :
_ loading = false;

}

malgré ça j'ai le message d'erreur suivant :
Error: Radeon timed out... exiting
pure virtual method called

Quand fais l'inverse ( le thread charge les datas et c'est dans le main qu'est affiché le message ) et que je vire les appels mutex, le chargement arrive au bout mais aucune texture n'a été chargée et au moins une des textures qui étaient déjà chargé avant disparait = devient blanche comme si elle avait été libérée ou que je passais 0 à glBindTexture (?!?).

Si je me contente de juste appeller la fonction d'affichage dans le thread sans rien faire d'autre qu'une boucle vide dans le main ça pose encore problème : encore des erreurs qui ressemblent à celle du haut ( qui pourrait être un message d'erreur du driver, non ? ).

Voila...
Ou est le problème ?
Je bosse sous linux / redhat, si ça à un rapport.
Ou peut-être n'est-ce pas du tout la bonne méthode pour afficher me message tout en chargeant des trucs en parallèle ?
Et enfin est-ce que ça va encore plus merder ( genre frire mon processeur ou la carte vidéo, reflasher le bios ) quand je vais essayer de compiler sous wind'oze ?


merci de votre aide

(désolé, c'est chiant à lire avec des '_' mais il n'y avait pas d'indentation car ni les espaces ni les tabulations n'ont l'air de passer en début de ligne)

2

-

3

OpenGL ne supporte pas le multithreading par défaut. Ca veut dire qu'un seul thread peut accéder à OpenGL à un instant donné.
Tu as trois possibilités :
1) tu t'arranges pour que tous les accès se fassent dans un seul thread
2) tu protèges l'accès à OpenGL par un mutex
3) tu utilises la version thread-safe de OpenGL (fortement déconseillé, car elle est beaucoup plus lente et pas forcément disponible sur tous les systèmes)

[edit: ah ok en fait je viens de voir que tu utilises le 2) dans ton code]

4

Par ailleurs, c'est ptet moi mais je vois pas dans ton code où tu initialises un rendering context opengl ?
Ni où tu swappes les buffers d'affichage d'ailleurs ?

5

merci orion_ j'y penserai
spectras :
Par ailleurs, c'est ptet moi mais je vois pas dans ton code où tu initialises un rendering context opengl ?
Ni où tu swappes les buffers d'affichage d'ailleurs ?


J'ai simplifié le code que j'ai vraiment écris... là j'ai pas remis les initilalisations, le swap des buffers d'opengl non plus, etc...
Mais tout ce passe bien dans cet ordre, toutes les initialisations ont bien été effectuées, je vérifie même ( mais je l'ai pas mis non pus, inutile à lire ) qu'il n'y a pas d'erreur lors des lock et unlock des mutex.
Bref c'est exactement mon code en allègé visuellement et au détail près que la partie qui crée la texture est en fait dans une fonction dans un autre cpp. Mais, dans cette fonction, j'ai bien encadré le code par le même mutex que celui qui encadre l'affichage dans le thread.

Histoire de rigoler un peu, voila un autre message que j'ai parfois :
Error: Radeon timed out... exiting
drmRadeonCmdBuffer: -22

Quelques chiffres... l'erreur se produit dans le thread affichage 'LOADING!' au bout de 4 ou 5 passages. Le main n'a même pas le temps d'arriver à une partie qui appelle la fonction qui charge les textures.
Ca plante - quasi - instantannement donc, alors que sans le thread qui affiche 'LOADING' le processus de chargement se termine correctement au bout de 2 secondes.

6

mouais on dirait que la lib opengl n'aime pas être utilisée depuis un thread différent de celui qui l'a initialisée.

7

Quel est l'intérêt d'utiliser OpenGL plutôt que SDL pour faire de la 2D ?

8

Utiliser l'accélération matérielle. Si tu veux un rendu accéléré, SDL passera aussi par OpenGL (même en 2D). Attention, si le matériel ou le driver ne gère pas les accélérations demandées, le OpenGL est émulé en logiciel, ce qui est nettement plus lent que de faire l'affichage directement en logiciel.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité