前回も同じテーマで「やみくも編」と称してアイドルイベントを利用して画像を動かしたが、今回はタイマーを使って、一定の間隔で再描画を行ってみる。GLPanelクラス内の変更がメインになる。
- glpanel.hpp
#include <wx/wx.h> #include <wx/glcanvas.h> #include "opengl.hpp" class GLPanel : public wxGLCanvas { private: bool isInitialized_; int frameRate_; wxTimer* timer_; OpenGL gl_; public: GLPanel(wxWindow* parent, wxGLContext* sharedContext, wxWindowID id, int frameRate); ~GLPanel(); void OnPaint(wxPaintEvent &event); void OnSize(wxSizeEvent &event); void OnEraseBackground(wxEraseEvent& event); void OnTimer(wxTimerEvent& event); }; #endif //__GLPANEL_HPP__
- glpanel.cpp
#include "glpanel.hpp" GLPanel::GLPanel(wxWindow* parent, wxGLContext* sharedContext, wxWindowID id, int frameRate) : wxGLCanvas(parent, sharedContext, id), isInitialized_(false), frameRate_(frameRate) { this->Connect(wxEVT_SIZE, wxSizeEventHandler(GLPanel::OnSize)); this->Connect(wxEVT_PAINT, wxPaintEventHandler(GLPanel::OnPaint)); this->Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(GLPanel::OnEraseBackground)); this->timer_ = new wxTimer(this); this->Connect(wxEVT_TIMER, wxTimerEventHandler(GLPanel::OnTimer)); this->timer_->Start(frameRate); } GLPanel::~GLPanel() { this->timer_->Stop(); } void GLPanel::OnPaint(wxPaintEvent &event) { wxPaintDC dc(this); if(!GetContext()){ return; } if(!isInitialized_){ SetCurrent(); gl_.init(); int w; int h; GetClientSize(&w, &h); gl_.setViewport(w, h); isInitialized_=true; } gl_.draw(); glFlush(); SwapBuffers(); } void GLPanel::OnSize(wxSizeEvent &event) { wxGLCanvas::OnSize(event); if(GetContext()) { SetCurrent(); gl_.setViewport(event.GetSize().GetWidth(), event.GetSize().GetHeight()); Refresh(); } } void GLPanel::OnEraseBackground(wxEraseEvent& event) { // Do nothing, to avoid flashing. } void GLPanel::OnTimer(wxTimerEvent& WXUNUSED(event)){ this->SetCurrent(); this->Refresh(); }
wxTimerを作成し、wxEVT_TIMERとOnTimerを関連づけている。this->timer_->Start(this->frameRate_)ではOnTimerを実行する間隔をミリ秒単位で渡している。それに伴って、GLPanelのメンバ変数にframeRate_(frame/msec)を用意し、インスタンス生成時に引数として与えるようになっている。wxTimerをストップしない状態で終了しようとすると例外が投げられるようなので、デストラクタを用意し、this->timer_Stop()でタイマーを停止している。
- MainWindow::MainWindow
MainWindow::MainWindow(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) { /* 以前から変更なし */ this->glpanel_=new GLPanel(this, NULL, wxID_ANY, 10); }
MainWindowクラスのコンストラクタ内でGLPanelを生成するときに、フレームレートも引数として渡すように変更している。
これをビルドし実行すると、
となってアニメーションの速度を調整できるようになる。