I am making a series of applications on physics simulations and until now I've done some of them using purely the handy SFML library. Now I want to add some GUI elements to them. I am just a little bit familiar with wxWidgets framework and wxFrames but have no idea how wxDc works, which seems to be at the core of SFML-wxWidgets integration. I will list my queries one by one.
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
class wxSFMLCanvas : public wxControl, public sf::RenderWindow
{
public:
wxSFMLCanvas(wxWindow* Parent = NULL, wxWindowID Id = -1, const wxPoint& Position = wxDefaultPosition,
const wxSize& Size = wxDefaultSize, long Style = 0);
virtual ~wxSFMLCanvas();
private:
DECLARE_EVENT_TABLE()
virtual void OnUpdate();
void OnIdle(wxIdleEvent&);
void OnPaint(wxPaintEvent&);
void OnEraseBackground(wxEraseEvent&);
void OnSize(wxSizeEvent&);
};
void wxSFMLCanvas::OnUpdate()
{
}
void wxSFMLCanvas::OnIdle(wxIdleEvent&)
{
// Send a paint message when the control is idle, to ensure maximum framerate
Refresh();
}
void wxSFMLCanvas::OnPaint(wxPaintEvent&)
{
// Prepare the control to be repainted
wxPaintDC Dc(this);
// Let the derived class do its specific stuff
OnUpdate();
// Display on screen
display();
}
void wxSFMLCanvas::OnEraseBackground(wxEraseEvent&)
{
}
void wxSFMLCanvas::OnSize(wxSizeEvent&)
{
}
wxSFMLCanvas::wxSFMLCanvas(wxWindow* Parent, wxWindowID Id, const wxPoint& Position, const wxSize& Size, long Style) :
wxControl(Parent, Id, Position, Size, Style) {
sf::RenderWindow::create(GetHandle());
}
wxSFMLCanvas::~wxSFMLCanvas()
{
}
class MyCanvas : public wxSFMLCanvas
{
sf::CircleShape circ;
public:
MyCanvas(wxWindow* Parent, wxWindowID Id, wxPoint& Position, wxSize& Size, long Style = 0) : wxSFMLCanvas(Parent, Id, Position, Size, Style) {
// specify circle
circ.setRadius(50.0f);
circ.setOrigin(50.0f,50.0f);
circ.setFillColor(sf::Color::Blue);
circ.setPosition(100.0f, 100.0f);
}
private:
virtual void OnUpdate() {
// Clear the view
clear(sf::Color(0, 128, 128));
// Display the circle in the view
draw(circ);
}
};
class MyFrame : public wxFrame
{
public:
MyFrame() : wxFrame(NULL, wxID_ANY, "SFML wxWidgets", wxDefaultPosition, wxSize(800, 600)) {
wxPoint tmp1 = wxPoint(50, 50);
wxSize tmp2 = wxSize(700, 500);
new MyCanvas(this, wxID_ANY, tmp1, tmp2);
}
};
class MyApplication : public wxApp
{
private:
virtual bool OnInit()
{
// Create the main window
MyFrame* MainFrame = new MyFrame;
MainFrame->Show();
return true;
}
};
IMPLEMENT_APP(MyApplication);
This throws a bunch of unresolved externals:
Error LNK2001 unresolved external symbol "protected: virtual struct wxEventTable const * __cdecl wxSFMLCanvas::GetEventTable(void)const " (?GetEventTable@wxSFMLCanvas@@MEBAPEBUwxEventTable@@XZ) test1 C:\Users\rajat\source\repos\test1\test1.obj 1
Error LNK2001 unresolved external symbol "protected: virtual class wxEventHashTable & __cdecl wxSFMLCanvas::GetEventHashTable(void)const " (?GetEventHashTable@wxSFMLCanvas@@MEBAAEAVwxEventHashTable@@XZ) test1 C:\Users\rajat\source\repos\test1\test1.obj 1
Error LNK2019 unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) test1 C:\Users\rajat\source\repos\test1\MSVCRTD.lib(exe_main.obj) 1
Furthermore, I don't quite understand how in this example wxWidgets is supposed to draw the contents of a sf::RenderWindow
. It will be very helpful if someone can rectify this barebone code so that it works. And also hopefully explain how it works.
Is there an alternative to wxWidgets that would work with SFML, or has a handy tool for fast and simple graphical library? The only requirement is that I should be able to compile it on MSVS for x64 framework and statically link to my application. I considered Qt, but I can't get it to either compile on my own, or even if I do, it's only the 32-bit shared library configuration.
How is the code supposed to work? The sf::RenderWindow
is created using sf::RenderWindow::create(GetHandle())
. Is it supposed to draw everything on its own? Or do I have to copy the bitmap of the SFML window and draw on the wxControl
by myself? It will be really helpful if someone could shed some light on how it's supposed to work.
Your error is due to using DECLARE_EVENT_TABLE
but not using any wxBEGIN_EVENT_TABLE/wxEND_EVENT_TABLE
, i.e. you never define your event table nor connect any event handlers.
I don't know anything about SFML, so I can't really help you with the rest, but apparently drawing is supposed to be done from your wxEVT_PAINT
handler -- once you connect it -- by just calling sf::RenderWindow::Display()
.