IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

SDL_Init et SDL_InitSubSystem


Sujet :

SDL

  1. #1
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 524
    Points : 5 184
    Points
    5 184
    Par défaut SDL_Init et SDL_InitSubSystem
    Bonjour à tous,

    initialiser la SDL se fait normalement avec SDL_Init et des flags qui indiquent quelles parties activer

    [mode bourrin ON]
    j'ai essayé un SDL_Init(0) avec succès
    suivi d'un SDL_InitSubSystem(SDL_INIT_VIDEO) avec succès également

    j'ai supprimé le SDL_Init(0) sans que cela pose problème
    [mode bourrin OFF]

    je me demandais si ce principe était convenable et ne risquait pas de poser des problèmes sur d'autres systèmes (je suis sous windows)

    en fait, je cherche à mettre la gestion de l'affichage (création de la fenêtre, changement de résolution, passe en fullscreen...) dans un singleton
    le constructeur du singleton fait appel à SDL_InitSubSystem(SDL_INIT_VIDEO) et son destructeur fait appel à SDL_QuitSubSystem(SDL_INIT_VIDEO)

    visiblement ça ne pose pas de problème à la SDL
    dites moi ce que vous en pensez

    ps: je précise qu'un appel à SDL_Quit est effectué lorsque le programme se termine, à voir également s'il est nécessaire ou inutile, pour l'instant j'ai préféré le laisser

    ci joint, une partie du code du singleton CDisplay :
    Code : 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
    #include "Display.h"
    #include "sdl/sdl.h"
     
     
    // static declaration of display manager's unique instance
    CDisplay* CDisplay::m_pInstance = NULL;
     
     
    // constructor & virtual destructor
    CDisplay::CDisplay(void)
    {
        // initialisation SDL video
        if ( SDL_InitSubSystem( SDL_INIT_VIDEO ) < 0 )
        {
            printf( "Echec SDL_Init : %s\n", SDL_GetError() );
            return; // throw exception
        }
     
    	// display parameters
    	m_sTemp.nScreenX = DISPLAY_SCREENX_DEFAULT;
    	m_sTemp.nScreenY = DISPLAY_SCREENY_DEFAULT;
    	m_sTemp.nScreenBpp = DISPLAY_SCREENBPP_DEFAULT;
    	// fullscreen flag
    	m_sTemp.bFullscreen = DISPLAY_FULLSCREEN_DEFAULT;
    	// OpenGL parameters
    	m_sTemp.nZBits = DISPLAY_ZBUFFER_DEFAULT;
    	m_sTemp.nStencilBits = DISPLAY_STENCIL_DEFAULT;
    	// mise à jour de l'affichage
    	Update(m_sTemp);
    }
     
    CDisplay::~CDisplay(void)
    {
    	SDL_QuitSubSystem( SDL_INIT_VIDEO );
    }
     
     
    // static method to retrieve unique instance of manager
    CDisplay* CDisplay::Initialize(void)
    {
    	if(!m_pInstance)
    		m_pInstance = new CDisplay;
     
    	return m_pInstance;
    }
     
    void CDisplay::ShutDown(void)
    {
    	delete m_pInstance;
    	m_pInstance = NULL;
    }
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Mettre le code dans un singleton ne me semble pas être une mauvaise idée. (Bien que le mettre dans le main ne m'a jamais posé de problème...)

    Par contre, il est bien spécifié qu'il faut d'abord faire un appel à SDL_Init.

    Il se peut que sans cet appel, tu vas avoir des problèmes sur différents systèmes. Pour le jouer safe, je dirais que tu dois assurer que cet appel a été fait et avant le code du constructeur de ton singleton.

    Jc

  3. #3
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Pour la peine, j'ai regardé le code de la SDL 1.2.11, voici le code de SDL_Init :

    Code : 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
     
    int SDL_Init(Uint32 flags)
    {
    #if !SDL_THREADS_DISABLED && SDL_THREAD_PTH
            if (!pth_init()) {
                    return -1;
            }
    #endif
     
            /* Clear the error message */
            SDL_ClearError();
     
            /* Initialize the desired subsystems */
            if ( SDL_InitSubSystem(flags) < 0 ) {
                    return(-1);
            }
     
            /* Everything is initialized */
            if ( !(flags & SDL_INIT_NOPARACHUTE) ) {
                    SDL_InstallParachute();
            }
            return(0);
    }
    Comme tu vois, il y a tout de même une initialisation de la gestion des threads qui sera fait (si c'est voulu au moment de la compilation) et une remise à zéro des messages d'erreur...

    Ensuite, on appelle effectivement SDL_InitSubSystem...

    Du coup, si tu voulais faire ton singleton, cela dépend si tu utilises des threads ou non et il faudrait installer le système de parachute SDL...

    Ceci confirme mes craintes -> pour avoir un code portable, tu vas devoir t'assurer qu'il y a un appel à SDL_Init avant de faire quoi que ce soit...

    Enfin, ceci confirme que SDL_Init(0) fonctionne, au final, aucun SubSystem est mis en place...

    Jc

  4. #4
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 524
    Points : 5 184
    Points
    5 184
    Par défaut
    Ok, donc je met un SDL_Init(0) au début de mon main et ensuite j'initialise le(s) sous-système(s) dont j'ai besoin

    Citation Envoyé par fearyourself
    Pour le jouer safe, je dirais que tu dois assurer que cet appel a été fait et avant le code du constructeur de ton singleton.
    c'est la raison pour laquelle j'ai modifié mon singleton
    plutot que de déclarer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CDisplay& CDisplay::Instance(void)
    {
       static CDisplay instance;
       return instance;
    }
    j'ai préféré faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CDisplay* CDisplay::Instance(void)
    {
       if(!m_pInstance)
          m_pInstance = new CDisplay;
       return m_pInstance;
    }
    vu qu'il faut que j'appelle le destructeur avant SDL_Quit
    le destructeur faisant appel à SDL_QuitSubSystem

    merci de m'avoir éclairé là dessus Jc
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  5. #5
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par shenron666
    Ok, donc je met un SDL_Init(0) au début de mon main et ensuite j'initialise le(s) sous-système(s) dont j'ai besoin

    c'est la raison pour laquelle j'ai modifié mon singleton
    plutot que de déclarer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CDisplay& CDisplay::Instance(void)
    {
       static CDisplay instance;
       return instance;
    }
    j'ai préféré faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CDisplay* CDisplay::Instance(void)
    {
       if(!m_pInstance)
          m_pInstance = new CDisplay;
       return m_pInstance;
    }
    vu qu'il faut que j'appelle le destructeur avant SDL_Quit
    le destructeur faisant appel à SDL_QuitSubSystem
    Ce n'est pas obligatoire :

    - SDL_Quit va tout arrêter comme un grand

    Par contre, si tu voulais vraiment faire proprement, il faut effectivement que SDL_Quit soit la dernière fonction SDL appelée.

    - Si jamais il te vient à l'esprit de vouloir utiliser SDL_WasInit, ne le fait pas ! Cette fonction suppose qu'au moins un subsystem a été mis en place. Appeler SDL_Init(0) lui ferait penser que rien n'a été fait...

    Jc

  6. #6
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 524
    Points : 5 184
    Points
    5 184
    Par défaut
    Citation Envoyé par fearyourself
    Ce n'est pas obligatoire :

    - SDL_Quit va tout arrêter comme un grand

    Par contre, si tu voulais vraiment faire proprement, il faut effectivement que SDL_Quit soit la dernière fonction SDL appelée.
    Je vais peut-etre revoir ma copie mais comme j'ai mis SDL_InitSubSystem(SDL_INIT_VIDEO) dans le constructeur de CDisplay, ma logique veut que je mette SDL_QuitSubSystem dans le destructeur

    Citation Envoyé par fearyourself
    - Si jamais il te vient à l'esprit de vouloir utiliser SDL_WasInit, ne le fait pas ! Cette fonction suppose qu'au moins un subsystem a été mis en place. Appeler SDL_Init(0) lui ferait penser que rien n'a été fait...
    OK, c'est noté
    je n'avais pas l'intention de l'utiliser et là du coup... encore moins

    encore merci pour tes conseils
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  7. #7
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    J'ai réfléchi au problème et je pense avoir trouvé une solution élégante à ton problème.

    On sait qu'à la construction, le subsystem est en place parce que sinon la fonction SDL_InitSubSystem aurait rendu un nombre négatif...

    A ce moment là, lors de la destruction, tu pourrais faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CDisplay::~CDisplay(void)
    {
    	SDL_QuitSubSystem( SDL_INIT_VIDEO );
            //S'il ne reste plus rien
            if(!SDL_WasInit(SDL_INIT_EVERYTHING)
                {
                 //On peut fermer SDL, on sait qu'aucun autre singleton le fera 
                 //(sauf cas multithreadé)
                 SDL_Quit();
                }
    }
    Histoire de pousser le bouchon plus loin, on peut aussi augmenter le constructeur pour qu'en interne il fasse l'initialisation :

    Code : 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
     
    // constructor & virtual destructor
    CDisplay::CDisplay(void)
    {
    //Cette appel retourne un nombre non nul si un subsystem est initialisé
     if(!SDL_WasInit(SDL_INIT_EVERYTHING))
                {
                 //On initialise SDL, on sait que ceci sera appele une fois vu qu'on verifie
                 //Si ce singleton s'est bien initialise
                 //(sauf cas multithreadé)
                 if(SDL_Init(0)!=0) 
                      {
                        printf( "Echec SDL_Init : %s\n", SDL_GetError() );
                        return; // throw exception
                      }
                }
     
        // initialisation SDL video
        if ( SDL_InitSubSystem( SDL_INIT_VIDEO ) < 0 )
        {
            printf( "Echec SDL_Init : %s\n", SDL_GetError() );
            return; // throw exception
        }
     
     	// display parameters
    	m_sTemp.nScreenX = DISPLAY_SCREENX_DEFAULT;
    	m_sTemp.nScreenY = DISPLAY_SCREENY_DEFAULT;
    	m_sTemp.nScreenBpp = DISPLAY_SCREENBPP_DEFAULT;
    	// fullscreen flag
    	m_sTemp.bFullscreen = DISPLAY_FULLSCREEN_DEFAULT;
    	// OpenGL parameters
    	m_sTemp.nZBits = DISPLAY_ZBUFFER_DEFAULT;
    	m_sTemp.nStencilBits = DISPLAY_STENCIL_DEFAULT;
    	// mise à jour de l'affichage
    	Update(m_sTemp);
    }
    Je l'ai pas testé mais cela devrait fonctionner...
    Jc

  8. #8
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 524
    Points : 5 184
    Points
    5 184
    Par défaut
    Merci pour ta réponse, elle est intéressante et a ses avantages tout comme ses inconvénients de la même façon que la solution précédente

    au final j'en suis resté au même point pour ne pas me casser la tête des jours et des jours uniquement sur ça

    j'avais repris une partie de ta proposition pour le destructeur mais ce qui reste peut-etre préférable c'est initialiser la SDL en dehors du constructeur

    finalement je vais tester la SDL avec SDL_WasInit(SDL_INIT_VIDEO) et générer une exception le cas échéant :
    Code : 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
    CDisplay::CDisplay(void)
    {
    	// initialisation SDL video
    	if (!SDL_WasInit( SDL_INIT_VIDEO ))
    		throw "SDL_VIDEO not initialized"; // throw exception
     
    	// display parameters
    	m_sTemp.nScreenX = DISPLAY_SCREENX_DEFAULT;
    	m_sTemp.nScreenY = DISPLAY_SCREENY_DEFAULT;
    	m_sTemp.nScreenBpp = DISPLAY_SCREENBPP_DEFAULT;
    	// fullscreen flag
    	m_sTemp.bFullscreen = DISPLAY_FULLSCREEN_DEFAULT;
    	// OpenGL parameters
    	m_sTemp.nZBits = DISPLAY_ZBUFFER_DEFAULT;
    	m_sTemp.nStencilBits = DISPLAY_STENCIL_DEFAULT;
    	// mise à jour de l'affichage
    	Update(m_sTemp);
    }
    et bien sûr dans ce cas, le destructeur ne fait rien
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  9. #9
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    D'accord et ceci t'oblige donc de créer ton singleton lors de l'exécution avec une allocation dynamique puisque tu dois attendre que la SDL soit initialisée, non ?

    Jc

  10. #10
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 524
    Points : 5 184
    Points
    5 184
    Par défaut
    c'est exact,

    d'un côté j'avais préféré un singleton avec allocation dynamique puisqu'on a plus de controle sur la création et la destruction de la fenêtre

    mais si en plus la SDL doit être initialisée AVANT le singleton, pas d'alternative

    je met un zip contenant le code source du singleton CDisplay et un main
    ceux que cela intéresse peuvent l'utiliser mais surtout si vous avez des commentaires intéressants sur la façon dont c'est programmé n'hésitez pas
    Fichiers attachés Fichiers attachés
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

Discussions similaires

  1. SDL_Init(SDL_INIT_VIDEO) == -1 ?
    Par humanite dans le forum SDL
    Réponses: 2
    Dernier message: 07/03/2013, 16h11
  2. undefined reference to `SDL_Init' projet C avec SDL
    Par marion5515 dans le forum Débuter
    Réponses: 2
    Dernier message: 21/05/2009, 13h19
  3. Toujours le problème avec SDL_Init
    Par Shiva87 dans le forum SDL
    Réponses: 11
    Dernier message: 10/06/2008, 13h31
  4. SDL_init renvoie NULL !?
    Par Shiva87 dans le forum SDL
    Réponses: 10
    Dernier message: 04/06/2008, 16h45
  5. Souci SDL_Init(SDL_INIT_VIDEO) sous Linux
    Par Disciple195 dans le forum SDL
    Réponses: 9
    Dernier message: 09/12/2007, 20h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo