///////////////////////////////////////////////////////////////////////////// // Name: isosurf.cpp // Purpose: wxGLCanvas demo program // Author: Brian Paul (original gltk version), Wolfram Gloger // Modified by: Julian Smart // Created: 04/01/98 // RCS-ID: $Id: isosurf.cpp 54693 2008-07-18 13:56:25Z VZ $ // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #if !wxUSE_GLCANVAS #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library" #endif #include "wx/timer.h" #include "wx/glcanvas.h" #include "wx/math.h" #if defined(__WXMAC__) || defined(__WXCOCOA__) # ifdef __DARWIN__ # include # include # else # include # include # endif #else # include # include #endif #include "isosurf.h" #define MAX_CONTEXTS 32 #define SWAP_INTERVAL_MS 15 static void Init(void) { /* glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef( 0.0, 0.0, -6.0 ); */ } // The following part was written for wxWidgets 1.66 MyFrame *frame = NULL; IMPLEMENT_APP(MyApp) // `Main program' equivalent, creating windows and returning main app frame bool MyApp::OnInit() { // Create the main frame window frame = new MyFrame(NULL, wxT("wxWidgets OpenGL Isosurf Sample"), wxDefaultPosition, wxDefaultSize); // Make a menubar wxMenu *fileMenu = new wxMenu; fileMenu->Append(wxID_EXIT, _T("E&xit")); wxMenuBar *menuBar = new wxMenuBar; menuBar->Append(fileMenu, _T("&File")); frame->SetMenuBar(menuBar); // Make a TestGLCanvas // JACS #ifdef __WXMSW__ int *gl_attrib = NULL; #else int gl_attrib[20] = { WX_GL_RGBA, WX_GL_MIN_RED, 1, WX_GL_MIN_GREEN, 1, WX_GL_MIN_BLUE, 1, WX_GL_DEPTH_SIZE, 1, WX_GL_DOUBLEBUFFER, # if defined(__WXMAC__) || defined(__WXCOCOA__) GL_NONE }; # else None }; # endif #endif int cols = (int)sqrt((float)MAX_CONTEXTS); int rows = (int)ceil(MAX_CONTEXTS / (float)cols); wxGridSizer *sizer = new wxGridSizer(cols, rows, 1, 1); frame->SetSizer(sizer); for (int i = 0; i < MAX_CONTEXTS; i++) { wxWindow *window = new TestGLCanvas(frame, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, _T("TestGLCanvas"), gl_attrib); sizer->Add(window, 0, wxEXPAND); } // Show the frame sizer->Layout(); frame->Show(true); wxTimer *timer = new wxTimer(frame); timer->Start(SWAP_INTERVAL_MS); Init(); return true; } BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(wxID_EXIT, MyFrame::OnExit) EVT_TIMER(wxID_ANY, MyFrame::OnTimer) END_EVENT_TABLE() // My frame constructor MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(frame, wxID_ANY, title, pos, size, style) { } MyFrame::~MyFrame() { } // Intercept menu commands void MyFrame::OnExit( wxCommandEvent& WXUNUSED(event) ) { // true is to force the frame to close Close(true); } void MyFrame::OnTimer( wxTimerEvent& WXUNUSED(event) ) { Refresh(); } /* * TestGLCanvas implementation */ BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) EVT_SIZE(TestGLCanvas::OnSize) EVT_PAINT(TestGLCanvas::OnPaint) EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground) END_EVENT_TABLE() TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name, int* gl_attrib) : wxGLCanvas(parent, id, gl_attrib, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name) { parent->Show(true); SetCurrent(); } wxGLContext *TestGLCanvas::GetContext() { static wxGLContext *sharedContext = new wxGLContext(this); return sharedContext; } void TestGLCanvas::SetCurrent() { GetContext()->SetCurrent(*this); } bool painted = false; void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) ) { // This is a dummy, to avoid an endless succession of paint messages. // OnPaint handlers must always create a wxPaintDC. wxPaintDC dc(this); // Keep track of the fact that we've now painted at least once painted = true; #ifndef __WXMOTIF__ if (!GetContext()) return; #endif SetCurrent(); // No need to do any actual paintain... SwapBuffers(); } void TestGLCanvas::OnSize(wxSizeEvent& event) { // this is also necessary to update the context on some platforms wxGLCanvas::OnSize(event); // Ensure that the first paint event goes through otherwise we may crash on SetCurrent if (!painted) return; // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...) int w, h; GetClientSize(&w, &h); #ifndef __WXMOTIF__ if (GetContext()) #endif { SetCurrent(); glViewport(0, 0, (GLint) w, (GLint) h); } } void TestGLCanvas::OnEraseBackground( wxEraseEvent& WXUNUSED(event) ) { // Do nothing, to avoid flashing. }