Ok, I am including the full code below. I had it broken into files by class. I started with your example and have been modifying it to make a simple test bed for things I need to understand better. It is probably clear I am a wxWidgets novice and struggling with things that are obvious to others. Note that in void Canvas::Resized(wxSizeEvent& evt) I have commented out a call to the parent OnSize() method. I am using wxWidgets 2.9 and seeing "deprecated" warnings about this call, and as written, it has no effect anyway.
One of the issues I am still wrestling with is which methods need to be developed differently when different "canvas" types are used. My next step on this code will be to make the window scrollable. I am still pondering the changes this will require.
Code: Select all
/*
* app.h
*
* Created on: Jan 14, 2013
* Author: John
*/
#ifndef APP_H_
#define APP_H_
#include "wx/wx.h"
class App: public wxApp
{
public:
virtual bool OnInit();
virtual int OnExit();
};
DECLARE_APP(App)
#endif /* APP_H_ */
/*
* canvas.h
*
* Created on: Jan 14, 2013
* Author: John
*/
#ifndef CANVAS_H_
#define CANVAS_H_
#include "wx/wx.h"
#include "wx/glcanvas.h"
class Canvas : public wxGLCanvas
{
wxGLContext* m_context;
public:
Canvas(wxFrame* parent, int* args);
virtual ~Canvas();
void Resized(wxSizeEvent& evt);
int GetWidth();
int GetHeight();
void Render(wxPaintEvent& evt);
void Prepare2DViewport(int topleft_x, int topleft_y,
int bottomright_x, int bottomright_y);
// events
void MouseMoved(wxMouseEvent& event);
void MouseDown(wxMouseEvent& event);
void MouseWheelMoved(wxMouseEvent& event);
void MouseReleased(wxMouseEvent& event);
void RightClick(wxMouseEvent& event);
void MouseLeftWindow(wxMouseEvent& event);
void KeyPressed(wxKeyEvent& event);
void KeyReleased(wxKeyEvent& event);
DECLARE_EVENT_TABLE()
};
#endif /* CANVAS_H_ */
/*
* frame.h
*
* Created on: Jan 14, 2013
* Author: John
*/
#ifndef MAINFRAME_H_
#define MAINFRAME_H_
class Canvas;
class MainFrame : public wxFrame
{
public:
MainFrame();
virtual ~MainFrame();
private:
void OnClose(wxCloseEvent& event);
void OnQuit(wxCommandEvent& event);
Canvas * m_canvas;
DECLARE_EVENT_TABLE()
};
#endif /* MAINFRAME_H_ */
/*------------------------------------------------------------------------------
* app.cpp
*
* Created on: Jan 14, 2013
* Author: John
*/
#include "wx/wx.h"
//#include "app.h"
//#include "mainframe.h"
IMPLEMENT_APP(App)
//------------------------------------------------------------------------------
bool App::OnInit()
{
if ( !wxApp::OnInit() )
return false;
MainFrame *frame = new MainFrame;
frame->Show(true);
return true;
}
//------------------------------------------------------------------------------
int App::OnExit()
{
return wxApp::OnExit();
}
//------------------------------------------------------------------------------
/*
* canvas.cpp
*
* Created on: Jan 14, 2013
* Author: John
*/
//#include "canvas.h"
#include "wx/wx.h"
#include "wx/sizer.h"
#include "wx/glcanvas.h"
//#include "main.h"
// include OpenGL
#include <GL/glu.h>
#include <GL/gl.h>
//#include "canvas.h"
#include "wxGLString.h"
BEGIN_EVENT_TABLE(Canvas, wxGLCanvas)
EVT_MOTION(Canvas::MouseMoved)
EVT_LEFT_DOWN(Canvas::MouseDown)
EVT_LEFT_UP(Canvas::MouseReleased)
EVT_RIGHT_DOWN(Canvas::RightClick)
EVT_LEAVE_WINDOW(Canvas::MouseLeftWindow)
EVT_SIZE(Canvas::Resized)
EVT_KEY_DOWN(Canvas::KeyPressed)
EVT_KEY_UP(Canvas::KeyReleased)
EVT_MOUSEWHEEL(Canvas::MouseWheelMoved)
EVT_PAINT(Canvas::Render)
END_EVENT_TABLE()
// some useful events to use
void Canvas::MouseMoved(wxMouseEvent& event) {}
void Canvas::MouseDown(wxMouseEvent& event) {}
void Canvas::MouseWheelMoved(wxMouseEvent& event) {}
void Canvas::MouseReleased(wxMouseEvent& event) {}
void Canvas::RightClick(wxMouseEvent& event) {}
void Canvas::MouseLeftWindow(wxMouseEvent& event) {}
void Canvas::KeyPressed(wxKeyEvent& event) {}
void Canvas::KeyReleased(wxKeyEvent& event) {}
Canvas::Canvas(wxFrame* parent, int* args) :
wxGLCanvas(parent, wxID_ANY, args, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE)
{
m_context = new wxGLContext(this);
// To avoid flashing on MSW
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
}
Canvas::~Canvas()
{
delete m_context;
}
void Canvas::Resized(wxSizeEvent& evt)
{
//wxGLCanvas::OnSize(evt);
Refresh();
}
/** Inits the OpenGL viewport for drawing in 2D. */
void Canvas::Prepare2DViewport(int x1, int y1,
int x2, int y2)
{
/*
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(x1, y1, abs(x2-x1), abs(y2-y1));
glOrtho(x1, x2, y2, y1, 0, 1);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
*/
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // white Background
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D); // textures
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glViewport(x1, y1, x2 - x1, y2 - y1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(x1, x2, y2, y1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int Canvas::GetWidth()
{
return GetSize().x;
}
int Canvas::GetHeight()
{
return GetSize().y;
}
void Canvas::Render( wxPaintEvent& evt )
{
if(!IsShown()) return;
wxGLCanvas::SetCurrent(*m_context);
wxPaintDC dc(this);
Prepare2DViewport(0, 0, GetWidth(), GetHeight());
glColor3f(0.,0.,0.);
// draw a box
glLineWidth(2.);
glBegin(GL_LINE_LOOP);
glVertex2i(50, 50);
glVertex2i(50, 100);
glVertex2i(100, 100);
glVertex2i(100, 50);
glEnd();
// draw a circle
const float PI = 3.14159;
GLint points = 200;
GLfloat angle;
GLfloat xc, yc, r;
r = 25.; // radius
xc = 75.; // x coordinate of center
yc = 200.; // y coordinate of center
glBegin(GL_LINE_LOOP);
for(int i = 0; i < points; i++)
{
angle = 2*PI*i/points;
glVertex2f(xc+r*cos(angle), yc+r*sin(angle));
}
glEnd();
// draw some text
static wxGLString my_message;
static wxGLStringArray my_messages;
static wxGLNumberRenderer number;
// init them the first time only
if(my_message.IsEmpty())
{
my_message = wxString( wxT("Hello world !!!") );
my_message.setFont( wxFont( 50, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD) );
my_message.consolidate(&dc);
my_messages.addString( wxT("wxGLString can") );
my_messages.addString( wxT("render strings in") );
my_messages.addString( wxT("OpenGL easily!! ") );
my_messages.addString( wxT("And with Unicode : \x1414 \x1562 \x1593") );
my_messages.consolidate(&dc);
number.consolidate(&dc);
}
// render string everytime
my_message.bind();
my_message.rotate(30);
glColor3f(1,0,0);
my_message.render(80,80);
my_messages.bind();
glColor3f(0,0.6,0); my_messages.get(0).render(5,200);
glColor3f(0,0,0.6); my_messages.get(1).render(55,225);
glColor3f(0,0.6,0.6); my_messages.get(2).render(105,250);
glColor3f(0.6,0.6,0); my_messages.get(3).render(155,275);
number.bind();
glColor3f(0,0,0);
number.renderNumber( -3.141591f, 250, 50 );
glFlush();
SwapBuffers();
}
/*------------------------------------------------------------------------------
* frame.cpp
*
* Created on: Jan 14, 2013
* Author: John
*/
#include "wx/wx.h"
//#include "canvas.h"
//#include "mainframe.h"
BEGIN_EVENT_TABLE(MainFrame, wxFrame)
EVT_CLOSE(MainFrame::OnClose)
EVT_MENU(wxID_EXIT, MainFrame::OnQuit)
END_EVENT_TABLE()
// -----------------------------------------------------------------------------
MainFrame::MainFrame()
: wxFrame(NULL, wxID_ANY, "wxWidgets MDI Sample",
wxDefaultPosition, wxSize(647, 400))
{
// Layout the frame:
// -- create a box sizer to control the canvas
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
// -- create the canvas
int args[] = {WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0};
m_canvas = new Canvas( (wxFrame*) this, args);
// -- add the canvas to the sizer
sizer->Add(m_canvas, 1, wxEXPAND);
// -- add the sizer to the frame
this->SetSizer(sizer);
this->SetAutoLayout(true);
// -- create a status bar
CreateStatusBar();
// -- and make it all visible
this->Show();
}
// -----------------------------------------------------------------------------
MainFrame::~MainFrame()
{
}
// -----------------------------------------------------------------------------
void MainFrame::OnClose(wxCloseEvent& event)
{
event.Skip();
return;
}
// -----------------------------------------------------------------------------
void MainFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close();
}
// -----------------------------------------------------------------------------