2016-03-25

SDL2 on wxWidgets

メモ

#include <wx/wx.h>

#include <wx/splitter.h>
#include <wx/spinctrl.h>
#include <SDL.h>
#include <cassert>
#include <cmath>
#include <iostream>
#include <cstdlib>

class MyApp : public wxApp
{
public:
    bool OnInit() override;
};

class SDL2Window : public wxWindow
{
    wxDECLARE_EVENT_TABLE();
private:
    wxTimer timer;
    SDL_Window* window = nullptr;
    SDL_Renderer* renderer = nullptr;
    double rotate = 0.0;
public:
    double speed = 0.05;
public:
    static constexpr int TIMER_ID = 1;
public:
    SDL2Window(wxWindow* parent, wxSize const& size)
        :wxWindow(parent, wxID_ANY, wxDefaultPosition, size)
        ,timer(this, TIMER_ID)
    {
        SDL_Init(SDL_INIT_VIDEO);
        window = SDL_CreateWindowFrom(reinterpret_cast<void*>(GetHandle()));    
        renderer = SDL_CreateRenderer(window, -1, 0);

        assert(window && renderer);

        timer.Start(15);
    }

public:
    void OnTimer(wxTimerEvent&) {
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
        }
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);

        auto constexpr center_x = 100;
        auto constexpr center_y = 100;
        auto constexpr radius = 40;
        SDL_RenderDrawLine(renderer, center_x + radius * std::cos(rotate),
            center_y + radius * std::sin(rotate),
            center_x - radius * std::cos(rotate),
            center_y - radius * std::sin(rotate));
        rotate += speed;

        SDL_RenderPresent(renderer);
    }
};
wxBEGIN_EVENT_TABLE(SDL2Window, wxWindow)
EVT_TIMER(SDL2Window::TIMER_ID, SDL2Window::OnTimer)
wxEND_EVENT_TABLE()

class TopFrame : public wxFrame
{
public:
    static constexpr int BUTTON_ID = 21;
public:
    TopFrame(const wxString& title, const wxPoint& pos)
        :wxFrame(nullptr, wxID_ANY, title, pos, wxSize(640, 600))
    {
        auto splitter = new wxSplitterWindow(this);

        auto sdlwindow = new SDL2Window(splitter, wxSize(640, 480));


        auto panel = new wxPanel(splitter);
        panel->Show();

        auto spin = new wxSpinCtrlDouble(panel);
        auto slider = new wxSlider(panel, wxID_ANY, 5, -314/2, 314/2, wxPoint(200, 0), wxSize(400, 40));
        spin->Show();
        spin->SetRange(-M_PI, M_PI);
        spin->SetIncrement(0.01);
        spin->SetValue(0.05);
        spin->Bind(wxEVT_SPINCTRLDOUBLE, [=](wxSpinDoubleEvent& event) {
            auto const val = event.GetValue();
            slider->SetValue(static_cast<int>(val * 100));
            sdlwindow->speed = val;
        });
        slider->Show();
        slider->Bind(wxEVT_SCROLL_CHANGED, [=](wxScrollEvent& ev) {
            auto const val = slider->GetValue() * 0.01;
            spin->SetValue(val);
            sdlwindow->speed = val;
        });

        splitter->SplitHorizontally(sdlwindow, panel, 480);

    }
};

wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit()
{
    wxFrame* frame = new TopFrame("SDL2 on wxWidgets Test", wxDefaultPosition);
    frame->Show(true);
    return true;
}

ひとつ上へ