wxWidgets + Rendern
-
Abend,
ich möchte mit wxWidgets ein Fenster erstellen und in einen Bereich davon mit DirectX rendern.
Durch googeln habe ich diese Seite gefunden: http://wiki.wxwidgets.org/Making_a_render_loop , auf der 2 Möglichkeiten fürs Rendern in wxWidgets gezeigt werden. Einmal mit einem Timer (gefällt mir nicht. Ich will die maximalen FPS haben) und einmal per Zeichnen im Idle Event.
Ich habe den Code 1:1 übernommen und zusätzlich ein Menü hinzugefügt:
#include "wx/sizer.h" #include "wx/wx.h" class BasicDrawPane : public wxPanel { public: BasicDrawPane(wxFrame* parent); void paintEvent(wxPaintEvent& evt); void paintNow(); void render( wxDC& dc ); DECLARE_EVENT_TABLE() }; class MyFrame; class MyApp: public wxApp { bool render_loop_on; bool OnInit(); void onIdle(wxIdleEvent& evt); MyFrame* frame; BasicDrawPane* drawPane; public: void activateRenderLoop(bool on); }; IMPLEMENT_APP(MyApp) class MyFrame : public wxFrame { public: MyFrame() : wxFrame((wxFrame *)NULL, -1, wxT("Hello wxDC"), wxPoint(50,50), wxSize(400,200)) { // Create a menu bar wxMenu *fileMenu = new wxMenu; // The “About” item should be in the help menu wxMenu *helpMenu = new wxMenu; helpMenu->Append(wxID_ABOUT, wxT("&About...\tF1"), wxT("Show about dialog")); fileMenu->Append(wxID_EXIT, wxT("E&xit\tAlt-X"), wxT("Quit this program")); // Now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar(); menuBar->Append(fileMenu, wxT("&File")); menuBar->Append(helpMenu, wxT("&Help")); // ... and attach this menu bar to the frame SetMenuBar(menuBar); // Create a status bar just for fun CreateStatusBar(2); SetStatusText(wxT("Welcome to wxWidgets!")); } void onClose(wxCloseEvent& evt) { wxGetApp().activateRenderLoop(false); evt.Skip(); // don't stop event, we still want window to close } DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_CLOSE(MyFrame::onClose) END_EVENT_TABLE() bool MyApp::OnInit() { render_loop_on = false; wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); frame = new MyFrame(); drawPane = new BasicDrawPane( frame ); sizer->Add(drawPane, 1, wxEXPAND); frame->SetSizer(sizer); frame->Show(); activateRenderLoop(true); return true; } void MyApp::activateRenderLoop(bool on) { if(on && !render_loop_on) { Connect( wxID_ANY, wxEVT_IDLE, wxIdleEventHandler(MyApp::onIdle) ); render_loop_on = true; } else if(!on && render_loop_on) { Disconnect( wxEVT_IDLE, wxIdleEventHandler(MyApp::onIdle) ); render_loop_on = false; } } void MyApp::onIdle(wxIdleEvent& evt) { if(render_loop_on){ drawPane->paintNow(); evt.RequestMore(); // render continuously, not only once on idle } } BEGIN_EVENT_TABLE(BasicDrawPane, wxPanel) EVT_PAINT(BasicDrawPane::paintEvent) END_EVENT_TABLE() BasicDrawPane::BasicDrawPane(wxFrame* parent) : wxPanel(parent) { } void BasicDrawPane::paintEvent(wxPaintEvent& evt) { wxPaintDC dc(this); render(dc); } void BasicDrawPane::paintNow() { wxClientDC dc(this); render(dc); } void BasicDrawPane::render( wxDC& dc ) { static int y = 0; static int y_speed = 2; y += y_speed; if(y<0) y_speed = 2; if(y>200) y_speed = -2; dc.SetBackground( *wxWHITE_BRUSH ); dc.Clear(); dc.DrawText(wxT("Testing"), 40, y); }
So, ich habe also einen leeren Frame mit einem Panel und im Idle Event setze ich den Hintergrund des Panels weiß und rendere einen Text.
Wenn ich das Programm laufen lasse, sehe ich auch den Text auf dem Panel rumflackern. Es gibt nur ein großes Problem: Wenn ich das Fenster bewege, oder resize oder (am schlimmsten) das Menü öffne (z.B. File aus der Menübar), dann pausiert das rendern komplett! Offenbar werden dann keine Idle Events mehr gefeuert?
Das ist für mich nicht akzeptabel, dass nur der Anwender ein Menü öffnet das Zeichnen pausiert. Wieso ist das so und was kann ich dagegen machen?Danke!
-
Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum Andere GUIs - Qt, GTK+, wxWidgets verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
DirectX und OpenGL lassen sich in wxWidgets einbinden.
Dafür musst du dann den HWND Handle des Fensters dir holen.
Such einfach mal nach DirectX im wxwidgetsforum.phlox
-
phlox81 schrieb:
DirectX und OpenGL lassen sich in wxWidgets einbinden.
Dafür musst du dann den HWND Handle des Fensters dir holen.
Such einfach mal nach DirectX im wxwidgetsforum.phlox
Hast du dir meinen Text überhaupt durchgelesen? -.-
Es geht mir doch garnicht ums einbinden, sondern um die Realisierung der RENDER LOOP.
-
Such nach wx-sdl und schau dir die dortige lösung mal an (den teil mit der event-loop), idle-event ist sicher besser als die timer-variante aber die "letzten" möglichen fps wirst du damit wahrscheinlich auch nicht rausholen können.