main.h
Code: Select all
#ifndef _MAIN_
#define _MAIN_
#include <wx/wx.h>
class MainApp : public wxApp
{
public:
virtual bool OnInit();
};
#endif
Code: Select all
#include "main.h"
#include "MainFrame.h"
IMPLEMENT_APP(MainApp)
bool MainApp::OnInit()
{
MainFrame *MyFrame = new MainFrame(_("Main Frame"));
MyFrame->Show(true);
return true;
}
Code: Select all
#ifndef _MAINFRAME_
#define _MAINFRAME_
#include <wx.h>
#include <wx/tglbtn.h>
#include <wx/aui/aui.h>
#include "GLCanvas.h"
#include "wx/thread.h"
#include "ThreadRendering.h"
class MainFrame : public wxFrame
{
public:
MainFrame(const wxString& title);
~MainFrame(){m_mgr.UnInit();};
void SendRenderThread(wxCommandEvent& event)
{
//wxThread *test = new ThreadRendering(m_canvas);
//test->Create();
//test->Run();
m_canvas->Refresh(true);
m_canvas->Render();
};
private:
wxAuiManager m_mgr;
GLCanvas *m_canvas;
wxPanel *Panel;
wxButton *Button;
DECLARE_EVENT_TABLE()
};
#endif
Code: Select all
#include "MainFrame.h"
BEGIN_EVENT_TABLE(MainFrame, wxFrame)
EVT_BUTTON(101, MainFrame::SendRenderThread)
END_EVENT_TABLE()
MainFrame::MainFrame(const wxString &title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize)
{
m_mgr.SetManagedWindow(this);
m_canvas = new GLCanvas(this, wxID_ANY, wxDefaultPosition, wxSize(100, 100), 0, _("GLCanvas"));
m_mgr.AddPane(m_canvas, wxAuiPaneInfo().Float());
Panel = new wxPanel(this);
Button = new wxButton(Panel, 101, _("Button!"), wxDefaultPosition, wxDefaultSize);
m_mgr.Update();
}
Code: Select all
#ifndef _GLCANVAS_
#define _GLCANVAS_
#include "wx/wxprec.h"
#include "wx/glcanvas.h"
class GLCanvas : public wxGLCanvas
{
public:
//GLCanvas(wxWindow *parent, const wxString &title);
GLCanvas(wxWindow *parent, wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0, const wxString& name = _T("RenderGLCanvas"));
void OnEraseBackground(wxEraseEvent& event);
void OnPaint(wxPaintEvent& event);
void Render();
void InitGL();
private:
bool gl_init;
DECLARE_EVENT_TABLE()
};
#endif
Code: Select all
#include "GLCanvas.h"
GLCanvas::GLCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name)
{
gl_init = false;
}
BEGIN_EVENT_TABLE(GLCanvas, wxGLCanvas)
EVT_PAINT(GLCanvas::OnPaint)
EVT_ERASE_BACKGROUND(GLCanvas::OnEraseBackground)
END_EVENT_TABLE()
void GLCanvas::Render()
{
wxPaintDC dc(this);
SetCurrent();
// Init OpenGL once, but after SetCurrent
if(!gl_init)
{
InitGL();
gl_init = true;
}
glBegin(GL_LINES);
glColor3ub(255, 0, 0);
glVertex3f(-1.5f, 0, 0);
glVertex3f(1.5f, 0, 0);
glColor3ub(0, 255, 0);
glVertex3f(0, -1.5f, 0);
glVertex3f(0, 1.5f, 0);
glColor3ub(0, 0, 255);
glVertex3f(0, 0, -1.5f);
glVertex3f(0, 0, 1.5f);
glEnd();
glFlush();
SwapBuffers();
}
void GLCanvas::OnPaint(wxPaintEvent& event)
{
Render();
}
void GLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
{
// empty function, to avoid flashing.
}
void GLCanvas::InitGL()
{
SetCurrent();
// set viewing projection
glMatrixMode(GL_PROJECTION);
glFrustum(-0.5f, 0.5f, -0.5f, 0.5f, 1.0f, 3.0f);
// position viewer
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0f, 0.0f, -2.0f);
}
Code: Select all
#ifndef _THREADRENDERING_
#define _THREADRENDERING_
#include "wx/thread.h"
#include "wx.h"
#include "GLCanvas.h"
class ThreadRendering : public wxThread
{
public:
ThreadRendering(GLCanvas *canvas){p_canvas = canvas;};
~ThreadRendering(){};
void Render(){};
private:
GLCanvas *p_canvas;
void *Entry();
};
#endif
Code: Select all
#include "ThreadRendering.h"
void *ThreadRendering::Entry()
{
wxMutexGuiEnter();
p_canvas->Refresh(true);
wxMutexGuiLeave();
return NULL;
};
I hear all the time that threads shouldn't tough the GUI and that they should perhaps push calls through to the parent thread to initiate drawing, but I don't know how to handle thread events or even how to go about doing this in the first place! I understand that my code may be a bit sloppy right now, much patch and test, but please help me out with what is the best proposed way to call a second thread, and have it draw to the GLCanvas
- Many many thanks