2016-10-18 1 views
2

Je suis actuellement en train de parcourir les tutoriels Lazy Foo pour SDL2 (je le fais sur une machine Linux) et je rencontre une sorte de bug où l'inclusion de SDL_PollEvent dans mon La boucle principale semble empêcher SDL_UpdateWindowSurface de mettre à jour réellement. Si je laisse la boucle SDL_PollEvent, le bmp chargé s'affiche correctement. Toutefois, si j'inclue la boucle SDL_PollEvent ou même un appel à SDL_PollEvent, la fenêtre ne sera jamais mise à jour avec une image. Tout le reste semble fonctionner correctement, SDL_PollEvent met en file d'attente les événements correctement et la boucle gère les événements correctement, mais pour une raison quelconque, il existe une divergence visuelle entre l'inclusion de SDL_PollEvent et l'omission.SDL_PollEvent semble empêcher la surface de fenêtre de se mettre à jour

En utilisant le code fourni par Lesson 03: Event driven programming:

Cette boucle ne parvient pas à mettre à jour la fenêtre:

while(!quit) 
{ 
    //Handle events on queue 
    while(SDL_PollEvent(&e) != 0) 
    { 
    //User requests quit 
    if(e.type == SDL_QUIT) 
    { 
     quit = true; 
    } 
    } 

    //Apply the image 
    SDL_BlitSurface(gXOut, NULL, gScreenSurface, NULL); 

    //Update the surface 
    SDL_UpdateWindowSurface(gWindow); 
} 

Cette boucle met à jour avec succès la fenêtre avec l'image chargée:

while(!quit) 
{ 

    //Apply the image 
    SDL_BlitSurface(gXOut, NULL, gScreenSurface, NULL); 

    //Update the surface 
    SDL_UpdateWindowSurface(gWindow); 
} 

Mais cesse de travailler avec l'inclusion d'un seul appel à SDL_PollEvent:

while(!quit) 
{ 
    SDL_PollEvent(&e); 

    //Apply the image 
    SDL_BlitSurface(gXOut, NULL, gScreenSurface, NULL); 

    //Update the surface 
    SDL_UpdateWindowSurface(gWindow); 
} 
+0

Etes-vous en train de déclarer «e»? Y a-t-il un 'SDL_Event e;' quelque part? – DiegoSalazar

+0

Aussi appelez-vous SDL_PollEvent dans le fil approprié? De la docs: "Comme cette fonction appelle implicitement SDL_PumpEvents(), vous ne pouvez appeler cette fonction que dans le thread qui définit le mode vidéo." https://wiki.libsdl.org/SDL_PollEvent – DiegoSalazar

+0

Oui, mis à part le code affiché ci-dessus, le reste du code reste le même que le code utilisé dans le didacticiel, qui peut être téléchargé depuis la page. – carpemb

Répondre

1

SDL_GetWindowSurface documentation indique This surface will be invalidated if the window is resized. Lors de la création initiale de la fenêtre, plusieurs événements sont générés, tels que SDL_WINDOWEVENT_SHOWN et SDL_WINDOWEVENT_EXPOSED. Bien que la fenêtre ne soit pas marquée comme redimensionnable par l'utilisateur, je suppose que le gestionnaire de fenêtres a toujours la possibilité d'effectuer un redimensionnement; vous pouvez vouloir vérifier quels événements sont placés dans votre file d'attente d'événements (car je ne peux pas reproduire votre problème - peut être, par exemple, spécifique au gestionnaire de fenêtres).

Pour le mettre dans d'autres mondes, la surface de la fenêtre n'est pas garantie de persister après certains événements, de sorte que la file d'attente d'événements de rinçage peut théoriquement invalider la surface. Vous devez obtenir la surface de la fenêtre après avoir purgé la file d'attente des événements juste avant de dessiner, sur chaque image:

while(!quit) 
{ 
    // event loop here 

    // get surface to draw on 
    gScreenSurface = SDL_GetWindowSurface(gWindow); 

    //Apply the image 
    SDL_BlitSurface(gXOut, NULL, gScreenSurface, NULL); 

    //Update the surface 
    SDL_UpdateWindowSurface(gWindow); 
}