Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques > SDL
SDL Forum d'entraide sur l'API SDL. Avant de poster -> FAQ SDL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 26/06/2012, 11h28   #1
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
Par défaut SDL - Gestion d'un événement dans une boucle

Bonjour à tous,

je me permet de requérir à votre aide.
Je viens de dessiner dans un axe Oxy mon signal provenant d'une classe extérieure. Je voudrai maintenant y ajouter des boutons afin de changer les échelles,..
Mais avant de créer un bouton je voudrai juste gérer les évènements. Je commence par le plus simple: appuyer sur 'echap' et cela ferme le programme.
Pour le moment lorsque j'appuie sur 'echap' mon programme arrête de dessiner et lorsque je relâche il continue de dessiner.
J'ai mis ci-dessous, les grandes lignes de mon programme.
J'ai beau le retourner dans tous les sens, je n'arrive pas à gérer cet évènement, et du coup je n'arrive pas à gérer les autres.

Merci par avance.

Code :
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
 
SDL_SURFACE *screen,*graph;
 
//screen est ma fenetre principale
//graph est ma fenetre pour le dessin
 
SDL_INIT_VIDEO
screen = SDL_SetVideoMode
graph = SDL_CreateRGBSurface
 
int continuer =1;
while (continuer)
	{
		SDL_FillRect(screen,..);
 
		for (j=0;j<10;j++)
		{
			SDL_Rect position_graph; position_graph.x =10; position_graph.y=30;
			SDL_FillRect(graph,..);
			SDL_BlitSurface(graph);
 
			int i;
			for(i=0;i<9;i++)
                         {ligne();//fonction qui trace une ligne}
			/* encore plein de petites boucles afin de dessiner mes axes et graduations */
 
			for (i=j*640;i<640+j*640;i++) //ma fenetre de dessin fait 640 pixels de large
			{
				SDL_PollEvent(&event);
				switch(event.type)
				{
					case SDL_QUIT:
						continuer =0;
					case SDL_KEYDOWN:
						switch(event.key.keysym.sym)
						{
							case SDLK_ESCAPE:
							continuer =0;
							break;
 
							default:
							break;
						}
 
					break;
					default:
					putpixel(i%640+40,(signal.param[i]*80+370)); //affichage des points de mon signal. Signal contenu dans un tableau d'un classe annexe.
				}
 
				SDL_Flip(screen);
			} 
		} 
 
	} 
 
	SDL_FreeSurface(graph);
	SDL_Quit();
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/06/2012, 14h50   #2
wax78
Modérateur
 
Avatar de wax78
 
Homme Renaud Warnotte
Développeur informatique
Inscription : août 2006
Messages : 2 170
Détails du profil
Informations personnelles :
Nom : Homme Renaud Warnotte
Âge : 32
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2006
Messages : 2 170
Points : 4 136
Points : 4 136
Envoyer un message via MSN à wax78
As mon avis tu px jetter ton code a la poubelle (ou du moins le recommencer en grosse partie).

Tu as bien lu http://loka.developpez.com/tutoriel/sdl/ ?

La gestion des events, ne doit certainement pas se faire dans tes boucles for (remplace certainement par surement).

Decouple bien l'affichage et la gestion des evenement pour les mettre "au meme niveau" et ne pas imbriquer la gestion des event dans la boucle qui te sert a "dessiner".
wax78 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 26/06/2012, 17h36   #3
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
ok, merci du conseil.
je vais relire le tuto, et refaire mon code.
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/06/2012, 00h32   #4
edgarjacobs
Membre éclairé
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 206
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 53
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 206
Points : 326
Points : 326
En général, les tâches se decomposent comme suit:

Code :
1
2
3
4
5
6
7
- initialisation sdl (et ttf si nécessaire)
- affichage
- tant que l'utilisateur ne demande pas l'arrêt
      - attendre la commande utilisateur (SDL_WaitEvent)
      - traiter la commande (ce qui peut bien sur impliquer recalculs, affichage...)
- libération mémoire
- fermeture sdl (et ttf éventuellement)
Une variante que l'on trouve régulièrement dans la boucle d'attente de la commande est
Code :
1
2
3
4
- tant que l'utilisateur ne demande pas l'arrêt
     - vérifier si une commande est donnée (SDL_PollEvent)
     - si commande, la traiter *
     - effectuer une/des tache(s) *
* inversables bien entendu
edgarjacobs est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 03/07/2012, 10h54   #5
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
merci pour cette vue globale d'un projet !!

Et pour ma part je me tournerai plus facilement vers SDL_PollEvent, puisque je vais dessiner des données en temps réel et que le programme dessine et n'attend pas un/des évènement(s) de la part de l'utilisateur.

Encore merci pour cette info !
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/07/2012, 11h28   #6
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
bonjour, j'ai utilisé le plan fourni par edgarjacobs. en effet cela fonctionne(lorsque j'appuie sur echap le programme se ferme). Mais je n'arrive plus a voir mon signal défiler.
Mon signal est contenu dans un tableau.
une fois que la première partie du signal a atteint l'extrémité droite de la fenêtre de dessin, je redessine cette fenêtre et je fais apparaître le deuxième partie du signal,. etc.. jusqu'à la fin de mon signal.

je fais donc:
-initialisation
-affichage de ma fenêtre de dessin et de mon signal(entier)
-tant que l'utilisateur ne demande pas l'arrêt
-libération mémoire
-fermeture sdl

je comprends bien qu'une fois que mon signal a été affiché en entier je ne pourrai plus agir sur lui.
pour afficher mon signal(qui contient 64 000 points) dans une fenêtre de dessin de 640pixels je fais:

Code :
1
2
3
4
5
for (j=0;j<10;j++)
{
  for (i=j*640;i<640+j*640;i++)
  putpixel(i%640+40,(signal.param[i]*80+370));
}
la question est donc : comment agir sur mon signal sachant qu'il se trouve dans une boucle sachant que wax78 m'a répondu :
Citation:
Decoupe bien l'affichage et la gestion des evenement pour les mettre "au meme niveau" et ne pas imbriquer la gestion des event dans la boucle qui te sert a "dessiner".
Je n'arrive pas a séparer les events et le dessin.

je ne sais pas si c'est assez clair, et je m'en excuse par avance.
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/07/2012, 13h01   #7
edgarjacobs
Membre éclairé
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 206
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 53
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 206
Points : 326
Points : 326
Je ne connais pas ton programme, mais je verrais bien une structure comme celle-ci
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
void afficheSignal(int *positionDebut,....)
{
...
    (*positionDebut)+=qqChose;
}
 
void traitement(...)
{
    positionDebut=0;
    afficheSignal(&positionDebut,...);
    done=0;
    while(!done) {
        if(SDL_PollEvent(&event)) {
            // Traiter l'event
            }
        if(....) dessineSignal(&positionDebut,....);
        }
}
mais je n'ai peut-être pas compris ton problème.
edgarjacobs est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/07/2012, 15h24   #8
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
Bonjour,


J'ai simplifié mon problème.
j'ai un tableau de 2000points que je remplis.
je voudrai afficher les 600premiers points en continu, c'est-à-dire que tant que l'on ne fait rien le programme affiche les 600premiers points.
Lorsque l'on appuie sur la touche 'a', il va par exemple afficher du point 500 au point 1100. Et si l'on ne touche a rien il va continuer a afficher les points de 500 à 1100, et va attendre une autre touche qui va afficher un autre intervalle etc...

Pour cela j'ai utilisé vos méthodes AfficheSignal() et Traitement()

Code :
1
2
3
4
5
6
7
8
9
10
11
 
void AfficheSignal(int *PositionDebut)
{
    int x =2; //commence a dessiner a partir du 2eme pixel a partir du bord de la fenetre
    for (int i = 0;i<NOMBREPRINT;i++) //boucle qui dessine sur 600 pixels
    {
        ligne (x,result[i+(*PositionDebut)]*30+240, x+1,result[i+(*PositionDebut)+1]*30+240,vert);
        x+=1;
 
    }
}
Code :
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
 
void traitement()
{
    int positionDebut = 0;
    AfficheSignal(&positionDebut); // va afficher les 600 premiers points de mon signal
    bool done = false;
    while (!done)
    {
        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                done = true;
                break;
 
                // check for keypresses
            case SDL_KEYDOWN:
                {
                    // exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                    if (event.key.keysym.sym == SDLK_a) //si j'appuie sur 'a'
                           AfficheSignal(&positionDebut+700) ; //va afficher mon signal a partir du 700ème point
                    break;
                }
            } // end switch
        } // end of message processing
 
 
        // DRAWING STARTS HERE
 
        // clear screen
        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
 
 
 
        // DRAWING ENDS HERE
 
        // finally, update the screen :)
        SDL_Flip(screen);
    }
 
}
le problème est ,je pense,que je ne sors pas de la boucle while(!done), mon programme compile mais crash à l'execution.
Je suis désolé mais j'ai vraiment du mal avec ces events.
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2012, 15h33   #9
wax78
Modérateur
 
Avatar de wax78
 
Homme Renaud Warnotte
Développeur informatique
Inscription : août 2006
Messages : 2 170
Détails du profil
Informations personnelles :
Nom : Homme Renaud Warnotte
Âge : 32
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2006
Messages : 2 170
Points : 4 136
Points : 4 136
Envoyer un message via MSN à wax78
Et a quel endroit crash-t-il exactement ?
wax78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2012, 16h43   #10
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
j'ai résolu mon problème d'execution.
donc maintenant il m'ouvre ma fenetre vierge, mais je ne vois aucun dessin apparaitre. par hasard j'ai appuyé sur ma touche 'a', au cas où, mais toujours pas de dessin.
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/07/2012, 01h46   #11
edgarjacobs
Membre éclairé
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 206
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 53
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 206
Points : 326
Points : 326
C'est parce que, lorsque tu sors de ton while(SDL_PollEvent(&event)), tu redessines et affiches une fenêtre noire.

De plus, dans ta fonction AfficheSignal, je ne vois pas de SDL_UpdateRect() ou de SDL_Flip(). Donc, même si ton image est bien fabriquée en mémoire, elle n'est jamais envoyée à l'écran (sauf si la fonction ligne() le fait).
edgarjacobs est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 16/07/2012, 11h56   #12
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
Bonjour, alors j'ai corrigé avec ce que vous m'avez dit. En effet je n'avais pas de mise à jour d'écran dans ma fonction AfficheSignal (ni dans ma fonction ligne() ).

Du coup mon programme affiche bien mes premiers points, mais lorsque j'appuie sur la touche 'a', il ne se passe rien. (par contre lorsque j'appuie sur 'Echap', le programme se termine bien.)

Du coup je me permet de remettre mes deux fonctions corrigées.

Code :
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
 
void AfficheSignal(int *PositionDebut)
{
    Uint32 vert = SDL_MapRGB(screen->format,0,255,0); //definition de la couleur du signal
    int x =2;   //commence a dessiner a partir du 2eme pixel a partir du bord de la fenetre
    for (int i = 0;i<NOMBREPRINT;i++) //boucle qui dessine sur 600 pixels
    {
        ligne (x,result[i+(*PositionDebut)]*30+240, x+1,result[i+(*PositionDebut)+1]*30+240,vert);//le coeff *30+240 permet de visualiser le signal en le placant au centre de la fenetre et en augmentant son gain
        x++;
 
    }
    SDL_Flip(screen); //mise a jour de l'ecran
 
}
 
void traitement()
{
    int positionDebut = 0;
    AfficheSignal(&positionDebut); // va afficher les 600 premiers points de mon signal
 
 
    bool done = false;
    while (!done)
    {
        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                done = true;
                break;
 
 
            case SDL_KEYDOWN:
                {
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                    if (event.key.keysym.sym == SDLK_a) //si j'appuie sur 'a'
                        {
                            positionDebut=600;
                            AfficheSignal(&positionDebut); //va afficher mon signal a partir du 600ème point
                        }
                    break;
                }
            } // end switch
        } // end of message processing
    }
}
mon programme pour le moment affiche mes premiers points et c'est tout, je ne peux donc toujours pas intéragir avec lui sauf en le quittant.
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/07/2012, 12h12   #13
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
c'est en postant mon dernier message que j'ai trouvé la solution,
j'ai par hasard tapé sur la lettre 'q' a la place de 'a' et cela a marché, je ne sais pourquoi. (certainement que SDL est codé sur un clavier QWERTY, non ?)
et il y avait une erreur dans mon switch(event.type)

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
case SDL_KEYDOWN:
                {
 
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                        //break;
 
                   else if (event.key.keysym.sym == SDLK_a) //si j'appuie sur 'a'
                        {
                            SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); //remplit ma fenetre de blanc
                            positionDebut=600;
                            AfficheSignal(&positionDebut); //va afficher mon signal a partir du 600ème point
                        }
                    break;
}
l'erreur était au niveau du break et des if, mon problème est donc résolu.

Merci beaucoup !!
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/07/2012, 21h33   #14
edgarjacobs
Membre éclairé
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 206
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 53
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 206
Points : 326
Points : 326
J'ai exactement le même problème, et je ne sais pas pourquoi*.

Je l'ai contourné dans un de mes programmes, en ajoutant l'instruction
et en testant
Code :
if(event.key.keysym.unicode=='a')
Mais attention: a=97, A=65, ctrl+(shift+)a=1, b=98, B=66, ctrl+(shift+)b=2 etc..., et ce genre de test
Code :
if(event.key.keysym.unicode=='a' && event.key.keysym.mod&KMOD_CTRL)
ne fonctionne plus...

EDIT: *après avoir fait quelques tests, il s'agit simplement de la disposition du clavier QWERTY...
edgarjacobs est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 16/07/2012, 21h49   #15
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : juin 2012
Messages : 22
Détails du profil
Informations personnelles :
Nom : Homme quentin rausch
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : juin 2012
Messages : 22
Points : 10
Points : 10
j'ai contourné ce problème en choisissant des touches qui étaient communes a qwerty et azerty, puisque le choix des touches ne m'importe que très peu, mais merci du conseil !
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 08h23.


 
 
 
 
Partenaires

Hébergement Web