Bonjour,

Mon jeu possede plusieurs ecrans differents deja en place, et j'aimerais faire un bel effet de transition avec Fade in & fade out.

L'appel de la transition se fait en dehors du thread de rendu graphique.

Voici la classe:

Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#ifndef FADE_H_INCLUDED
#define FADE_H_INCLUDED
 
/// Used for screen fading.
#include <SFML/Graphics.hpp>
 
class Fade
{
public:
    Fade() : m_fadein(false), m_fadeout(false), m_started(false), m_rect(sf::RectangleShape()), m_alpha(0), m_goal(0) {  };
    ~Fade() {  }
 
    /// Called by the secondary thread
    void FadeOut() {
        /// Setting the flag to true, so the rendering thread knows that he has to fade out the screen
        /// Regular screen to full black screen.
        m_fadeout = true; m_alpha = 0; m_goal = 255;
        m_rect.setFillColor(sf::Color(0,0,0,0));
    }
    /// Called by the secondary thread
    void FadeIn() {
        /// Setting the flag to true, so the rendering thread knows that he has to fade in the screen
        m_fadein = true; m_alpha = 255; m_goal = 0;
        //m_rect.setFillColor(sf::Color(0,0,0,255));
    }
 
    /// Simply returns the shape for displaying
    inline sf::RectangleShape& getShape() { return m_rect; }
 
    /// Used by the main loop, if this returns true, the thread will draw it
    inline bool doFade() {
        if(m_fadein && (m_alpha > m_goal)) // black > screen
        {
            m_alpha--;
            m_rect.setFillColor(sf::Color(0,0,0,m_alpha));
            return true;
        }
        else if(m_fadeout && (m_alpha < m_goal)) // screen > black
        {
            m_alpha++;
            m_rect.setFillColor(sf::Color(0,0,0,m_alpha));
            return true;
        }
        else { return false; }
    }
 
    /// Used by the secondary thread, if this is true, it means the main thread is fading. Some sort of mutex :P
    inline bool Fading() const { return (m_started); }
 
    /// Used by the main thread to know if he has to perform a fade
    inline bool requestFade() const { return (m_fadein | m_fadeout); }
 
    /// Both used by the main thread to change the flags, so the secondary thread will know that he is fading. (cf: Fading())
    void startFading() { m_started = true; }
    void doneFading() { m_started = false; m_fadein = false; m_fadeout = false; }
    inline static const unsigned int fadingTime() { return fading_time; }
 
private:
 
    /// Flag: Fade in action
    bool m_fadein;
    /// Flag: Fade out action
    bool m_fadeout;
    /// Flag: if theres a fade processing
    bool m_started;
 
    /// SFML's shape
    sf::RectangleShape m_rect;
 
    /// Current alpha.
    unsigned int m_alpha;
    /// Alpha to reach
    unsigned int m_goal;
 
    static const unsigned int fading_time = 10; // in ms
 
};
 
 
 
#endif // FADE_H_INCLUDED


Quand je veux faire un fade, de mon thread secondaire, je fais ceci:
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
    m_gameui.getRenderer().getFader().FadeOut(); // Appel a fade out : ecran > ecran noir
    nextScreen(); // Simple routine qui permet a l'ecran de se mettre a jour sous l'ecran noir
    while(m_gameui.getRenderer().getFader().Fading()) {} // On attend pendant que le fade se termine (donc ecran noir
    m_gameui.getRenderer().getFader().FadeIn(); // Et hop on retourne au nouvel ecran


Et mon thread principal:

Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
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
58
59
60
61
62
63
short LoginScreen::Run()
{
    m_desktop.GetEngine().LoadThemeFromFile("Data/css/login.css");
 
    /// Add the UI to the window
    m_desktop.Add(getScreen());
    /// Rendering loop
    while(m_game.getRenderer().getApp().isOpen() && m_game.isRunning())
    {
        /// Clearing the window
        m_game.getRenderer().getApp().clear();
 
 
        sf::Event event;
        while(m_game.getRenderer().getApp().pollEvent(event))
        {
            /// Event handling
                /// SFGUI
            m_desktop.HandleEvent(event);
                /// SFML
            if(event.type == sf::Event::Closed)
            {
                /// This will automatically terminate the networker thread & nicely exit the game
                m_game.crash();
            }
        }
        m_game.getRenderer().getApp().resetGLStates();
        /// Drawings (SFGUI)
            /// UI
        if(changeScreen())
        {
            oldScreen()->Show(false);
            m_desktop.Remove(oldScreen());
            getScreen()->Show(true);
            m_desktop.Add(getScreen());
        }
 
        /// Fading out (screen to black)
        if(m_game.getRenderer().getFader().requestFade())
        {
            m_game.getRenderer().getFader().startFading();
        }
        if(m_game.getRenderer().getFader().Fading())
        {
            if(m_game.getRenderer().getFader().doFade())
            {
                m_game.getRenderer().getApp().draw(m_game.getRenderer().getFader().getShape());
            }
            else
            {
                m_game.getRenderer().getFader().doneFading();
            }
        }
 
        /// Displayings
        m_desktop.Update(0.f);
        m_game.getRenderer().display(m_game.getRenderer().getApp());
        m_game.getRenderer().getApp().display();
 
    }
 
    return -1;
}

Le probleme ?
L'ecran devient tout noir d'un coup, et j'ai acces a l'ecran caché derriere ce noir.
Comment faire pour avoir une belle transition ?

Merci d'avance,

nico