Utiliser wxwidgets et la sdl en même temps

Soyez le premier à donner votre avis sur cette source.

Snippet vu 9 123 fois - Téléchargée 21 fois

Contenu du snippet

Ce code montre comment utiliser la SDL dans une fênetre WxWidgets

Source / Exemple :


#include <iostream>  
 
#include <wx/wxprec.h>  
 
#ifdef __BORLANDC__  
    #pragma hdrstop  
#endif  
 
#ifndef WX_PRECOMP  
    #include <wx/wx.h>  
#endif  
 
 
#include <wx/dcbuffer.h>  
#include <wx/image.h>  
 
#include <SDL/SDL.h>  
 
enum {  
    ID_FRAME = 10000,  
    ID_PANEL,  
    IDM_FILE_EXIT,  
    IDM_HELP_ABOUT  
};  
 
//le panel qui contiendra le contexte SDL  
class SDLPanel : public wxPanel {  
    DECLARE_CLASS(SDLPanel)  
    DECLARE_EVENT_TABLE()  
 
private:  
    SDL_Surface *screen;  
 
    void onPaint(wxPaintEvent &event);  
    void onEraseBackground(wxEraseEvent &event){}  
    void onIdle(wxIdleEvent &event);  
    void createScreen();  
 
public:  
    SDLPanel(wxWindow *parent);  
    ~SDLPanel();  
};  
 
//la frame  
class SDLFrame : public wxFrame {  
    DECLARE_CLASS(SDLFrame)  
    DECLARE_EVENT_TABLE()  
 
private:  
    SDLPanel *panel;  
 
    void onFileExit(wxCommandEvent &event){ Close(); }  
    void onHelpAbout(wxCommandEvent &event);  
 
public:  
    SDLFrame();  
    SDLPanel &getPanel(){ return *panel; }  
};  
 
//L'application  
class SDLApp : public wxApp {  
    DECLARE_CLASS(SDLApp)  
 
private:  
    SDLFrame *frame;  
 
public:  
    bool OnInit();  
    int OnRun();  
    int OnExit();  
};  
 
IMPLEMENT_APP(SDLApp)  
 
IMPLEMENT_CLASS(SDLApp, wxApp)  
//===========================================  
IMPLEMENT_CLASS(SDLFrame, wxFrame)  
 
BEGIN_EVENT_TABLE(SDLFrame, wxFrame)  
    EVT_MENU(IDM_FILE_EXIT, SDLFrame::onFileExit)  
    EVT_MENU(IDM_HELP_ABOUT, SDLFrame::onHelpAbout)  
END_EVENT_TABLE()  
//===========================================  
IMPLEMENT_CLASS(SDLPanel, wxPanel)  
 
BEGIN_EVENT_TABLE(SDLPanel, wxPanel)  
    EVT_PAINT(SDLPanel::onPaint)  
    EVT_ERASE_BACKGROUND(SDLPanel::onEraseBackground)  
    EVT_IDLE(SDLPanel::onIdle)  
END_EVENT_TABLE()  
//===========================================  
bool SDLApp::OnInit() {  
    // crée la SDLFrame  
    frame = new SDLFrame;  
    frame->SetClientSize(640, 480);  
    frame->Centre();  
    frame->Show();  
 
    // Notre frame au premier plan  
    SetTopWindow(frame);  
 
    //l'initialisation devrais toujours marché.  
    return true;  
}  
 
int SDLApp::OnRun() {  
    //initialise SDL  
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {  
        std::cerr << "Impossible d'initialiser SDL: " << SDL_GetError() << '\n';  
 
        return -1;  
    }  
 
    // Met ne place le mode vidéo sans crée de fenetre  
    SDL_SetVideoMode(0, 0, 0, SDL_SWSURFACE);  
 
    // démare la boucle principale  
    return wxApp::OnRun();  
}  
 
int SDLApp::OnExit() {  
    // quitte la SDL  
    SDL_Quit();  
 
    //retourne le code de sortie standard  
    return wxApp::OnExit();  
}  
 
SDLFrame::SDLFrame() {  
    // Crée la frame SDL  
    Create(NULL, ID_FRAME, wxT("Frame Title"), wxDefaultPosition,  
           wxDefaultSize, wxCAPTION | wxSYSTEM_MENU |  
           wxMINIMIZE_BOX | wxCLOSE_BOX);  
 
    // crée la bare de mnu  
    wxMenuBar *mb = new wxMenuBar;  
 
    // crée le menu file  
    wxMenu *fileMenu = new wxMenu;  
    fileMenu->Append(IDM_FILE_EXIT, wxT("E&xit"));  
 
    // add the file menu to the menu bar  
    mb->Append(fileMenu, wxT("&File"));  
 
    // crée le menu aide  
    wxMenu *helpMenu = new wxMenu;  
    helpMenu->Append(IDM_HELP_ABOUT, wxT("About"));  
 
    // ajoute le menu help a la bare de menus   
    mb->Append(helpMenu, wxT("&Help"));  
 
    //ajoute la bare de menu la frame  
    SetMenuBar(mb);  
 
    //crée le panel SDL.  
    panel = new SDLPanel(this);  
}  
 
void SDLFrame::onHelpAbout(wxCommandEvent &) {  
    wxMessageBox(wxT("wx-sdl snippet"),  
                 wxT("A propos du snippet WxSDL"), wxOK | wxICON_INFORMATION);  
}  
 
SDLPanel::SDLPanel(wxWindow *parent) : wxPanel(parent, ID_PANEL), screen(NULL) {  
    //definit la taille du panel  
    wxSize size(640, 480);  
 
    SetMinSize(size);  
    SetMaxSize(size);  
    SetSize(size);  
 
    //génère une évenement IDLE pour "démarer" la fenêtre.  
    wxIdleEvent event;  
    event.SetEventObject(this);  
    this->AddPendingEvent(event);  
}  
 
SDLPanel::~SDLPanel() {  
    if (screen != NULL) {  
        SDL_FreeSurface(screen);  
    }  
}  
 
void SDLPanel::onPaint(wxPaintEvent &) {  
    // on ne peut dessiner si l'écran n'existe pas  
    if (screen == NULL) {  
        return;  
    }  
 
    //vérouille l'écran si besoin est.  
    if (SDL_MUSTLOCK(screen)) {  
        if (SDL_LockSurface(screen) < 0) {  
            return;  
        }  
    }  
 
    // ccrée un bitmap a partir de l'écran  
    wxBitmap bmp(wxImage(screen->w, screen->h,  
                    static_cast<unsigned char *>(screen->pixels), true));  
 
    //devérouille l'écran  
    if (SDL_MUSTLOCK(screen)) {  
        SDL_UnlockSurface(screen);  
    }  
 
    //paint l'écran  
    wxBufferedPaintDC dc(this, bmp);  
}  
 
void SDLPanel::onIdle(wxIdleEvent &) {  
    // crée screen  
    createScreen();  
 
    //vérouille si besoin est   
    if (SDL_MUSTLOCK(screen)) {  
        if (SDL_LockSurface(screen) < 0) {  
            return;  
        }  
    }  
 
    //ne cherchez pas a comprendre , contentez vous de regarder.  
    int tick = SDL_GetTicks();  
 
    for (int y = 0; y < 480; y++) {  
        for (int x = 0; x < 640; x++) {  
            wxUint32 color = (y * y) + (x * x) + tick;  
            wxUint8 *pixels = static_cast<wxUint8 *>(screen->pixels) +  
                              (y * screen->pitch) +  
                              (x * screen->format->BytesPerPixel);  
 
            #if SDL_BYTEORDER == SDL_BIG_ENDIAN  
                pixels[0] = color & 0xFF;  
                pixels[1] = (color >> 8) & 0xFF;  
                pixels[2] = (color >> 16) & 0xFF;  
            #else  
                pixels[0] = (color >> 16) & 0xFF;  
                pixels[1] = (color >> 8) & 0xFF;  
                pixels[2] = color & 0xFF;  
            #endif  
        }  
    }  
 
    //dévérouille si besoin est   
    if (SDL_MUSTLOCK(screen)) {  
        SDL_UnlockSurface(screen);  
    }  
 
    //rafraichie le panel  
    Refresh(false);  
 
    //endort l'application  
    wxMilliSleep(33);  
}  
 
void SDLPanel::createScreen() {  
    if (screen == NULL) {  
        int width, height;  
        GetSize(&width, &height);  
 
        screen = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,  
                                      24, 0, 0, 0, 0);  
    }  
}

Conclusion :


Ce code a été testé sous WinXP et sous Linux(distribution Fedora Core 5).
Compilé avec WxWidgets v 2.6.3 et SDL version 1.2.9

A voir également

Ajouter un commentaire

Commentaires

davidbrcz1
Messages postés
3
Date d'inscription
samedi 5 novembre 2005
Statut
Membre
Dernière intervention
23 juillet 2007
-
J qurqis bien citer lq pqge originale si je m em etais souvenue.
De plus , j ai quelque peu reorganise le code pour eliminer les warning/erreus du code originale.

Merci pour l erreur je ne l avais pas vue.
cs_bZb
Messages postés
1
Date d'inscription
mercredi 14 septembre 2005
Statut
Membre
Dernière intervention
13 février 2008
-
J'ai dû remplacer :
SDL_SetVideoMode(0, 0, 0, SDL_SWSURFACE);
par :
SDL_SetVideoMode(-1, -1, 0, SDL_SWSURFACE);
sinon il m'ouvrait une fenêtre Wx et une fenêtre SDL.
darwog
Messages postés
2
Date d'inscription
mardi 22 février 2005
Statut
Membre
Dernière intervention
5 mai 2008
-
Comment vous le faites marcher ? :
Chez moi ca compile, mais le résultat est une appli qui met le proc à 100% et n'affiche rien (l'intérieur de la frame ne se raffraichit pas, comme un bureau windoz planté).
http://img354.imageshack.us/my.php?image=temprb6.jpg
darwog
Messages postés
2
Date d'inscription
mardi 22 février 2005
Statut
Membre
Dernière intervention
5 mai 2008
-
[edit] : en fait, ca faisait comme dit ci-dessus avec la version originale(l'autre site), mais avec cette version ca passe. Merci :)
Sinon, idem que BZB pour le VideoMode.
CChargy
Messages postés
126
Date d'inscription
samedi 24 avril 2004
Statut
Membre
Dernière intervention
6 janvier 2008
-
Le problème du SDL_SetVideoMode, vient du fait que depuis une certaine version de la SDL, je sais plus laquelle, SDL_SetVideoMode(0, 0, 0, SDL_SWSURFACE); permet d'ouvrir une fenêtre sur tout l'écran alors qu'avant cette ligne n'ouvait pas de fenêtre SDL mais en créait le contexte ...

Voila
Bonne prog'
Colin CHARGY
Commenter la réponse de luhtor

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.