Code: Select all
#include "wx/wx.h"
#include <wx/glcanvas.h>
#include "glhelper.h"
class WaveformViewer:public wxPanel
{
public:
WaveformViewer(wxWindow* window);
~WaveformViewer();
private:
void OnCanvasPaint(wxPaintEvent&);
void OnCanvasSize(wxSizeEvent&);
void InitGL();
wxGLCanvas* m_canvas;
wxGLContext* m_context;
GLHelper m_helper;
};
WaveformViewer::WaveformViewer(wxWindow* window)
:wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxTAB_TRAVERSAL | wxNO_BORDER |
wxFULL_REPAINT_ON_RESIZE)
{
// Create the canvas and context.
#if wxCHECK_VERSION(3,1,0)
// These settings should work with any GPU from the last 10 years.
wxGLAttributes dispAttrs;
dispAttrs.PlatformDefaults().RGBA().DoubleBuffer().EndList();
wxGLContextAttrs cxtAttrs;
cxtAttrs.PlatformDefaults().CoreProfile().OGLVersion(3, 3).EndList();
m_canvas = new wxGLCanvas(this, dispAttrs);
m_context = new wxGLContext(m_canvas, NULL, &cxtAttrs);
if ( !m_context->IsOK() )
{
wxLogDebug("Failed to create context.");
return;
}
#else
int dispAttrs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_CORE_PROFILE,
WX_GL_MAJOR_VERSION ,3, WX_GL_MINOR_VERSION, 3, 0 };
m_canvas = new wxGLCanvas(this, wxID_ANY, dispAttrs);
m_context = new wxGLContext(m_canvas, NULL);
// Unfortunately, there doesn't seem to be any way to check if the
// context is ok prior to wxWidgets 3.1.0.
#endif // wxCHECK_VERSION
wxBoxSizer* szr = new wxBoxSizer(wxVERTICAL);
szr->Add(m_canvas, wxSizerFlags(1).Expand());
SetSizer(szr);
// On Linux, we must delay delay initialization until the canvas has
// been full created. On windows, we can finish now.
#ifdef __WXMSW__
InitGL();
#elif defined(__WXGTK__)
m_canvas->Bind(wxEVT_CREATE, [this](wxWindowCreateEvent&){InitGL();});
#endif // defined
}
WaveformViewer::~WaveformViewer()
{
delete m_context;
}
void WaveformViewer::OnCanvasSize(wxSizeEvent& event)
{
wxSize sz = event.GetSize();
m_helper.SetSize(sz.GetWidth(), sz.GetHeight());
event.Skip();
}
void WaveformViewer::OnCanvasPaint(wxPaintEvent&)
{
wxPaintDC dc(m_canvas);
m_helper.Render();
m_canvas->SwapBuffers();
}
void WaveformViewer::InitGL()
{
// First call SetCurrent or GL initialization will fail.
m_context->SetCurrent(*m_canvas);
// Initialize GLEW.
bool glewInialized = m_helper.InitGlew();
if ( !glewInialized )
{
wxLogDebug("Failed it initialize GLEW.");
return;
}
// Bind event handlers for the canvas. Binding was delayed until OpenGL was
// initialized because these handlers will need to call OpenGL functions.
m_canvas->Bind(wxEVT_SIZE, &WaveformViewer::OnCanvasSize, this);
m_canvas->Bind(wxEVT_PAINT, &WaveformViewer::OnCanvasPaint, this);
}
class wxGlewFrame: public wxFrame
{
public:
wxGlewFrame(wxWindow*);
};
wxGlewFrame::wxGlewFrame(wxWindow* parent)
:wxFrame(parent, wxID_ANY, wxString())
{
new WaveformViewer(this);
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
wxGlewFrame* frame = new wxGlewFrame(NULL);
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
Otherwise, I guess you could try debugging into the glewInit call to see where it fails or try the second answer from here to get a string description of why initialization is failing.
Edit: another thing to check is to see if the SetCurrent call is failing. Maybe add something like this to the InitGL method
Code: Select all
bool current = m_context->SetCurrent(*m_canvas);
if ( !current )
{
wxLogDebug("Unable to set context current.");
return;
}
}