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
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.