///////////////////////////////////////////////////////////////////////////// // 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$ // 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 // disabled because this has apparently changed in OpenGL 1.2, so doesn't link // correctly if this is on... #ifdef GL_EXT_vertex_array #undef GL_EXT_vertex_array #endif #include "isosurf.h" #include "../../sample.xpm" // The following part is taken largely unchanged from the original C Version GLboolean speed_test = GL_FALSE; GLboolean use_vertex_arrays = GL_FALSE; GLboolean doubleBuffer = GL_TRUE; GLboolean smooth = GL_TRUE; GLboolean lighting = GL_TRUE; #define MAXVERTS 10000 static GLfloat verts[MAXVERTS][3]; static GLfloat norms[MAXVERTS][3]; static GLint numverts; static GLfloat xrot; static GLfloat yrot; static void read_surface( const wxChar *filename ) { FILE *f = wxFopen(filename,_T("r")); if (!f) { wxString msg = _T("Couldn't read "); msg += filename; wxMessageBox(msg); return; } numverts = 0; while (!feof(f) && numvertsAppend(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 if(!doubleBuffer) { printf("don't have double buffer, disabling\n"); #ifdef __WXGTK__ gl_attrib[9] = None; #endif doubleBuffer = GL_FALSE; } frame->m_canvas = new TestGLCanvas(frame, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, _T("TestGLCanvas"), gl_attrib ); // Show the frame frame->Show(true); frame->m_canvas->SetCurrent(); read_surface( _T("isosurf.dat") ); Init(); return true; } BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(wxID_EXIT, MyFrame::OnExit) 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) { m_canvas = NULL; SetIcon(wxICON(sample)); } MyFrame::~MyFrame() { delete m_canvas; } // Intercept menu commands void MyFrame::OnExit( wxCommandEvent& WXUNUSED(event) ) { // true is to force the frame to close Close(true); } /* * TestGLCanvas implementation */ BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) EVT_SIZE(TestGLCanvas::OnSize) EVT_PAINT(TestGLCanvas::OnPaint) EVT_CHAR(TestGLCanvas::OnChar) EVT_MOUSE_EVENTS(TestGLCanvas::OnMouseEvent) 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, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name, gl_attrib) { parent->Show(true); SetCurrent(); /* Make sure server supports the vertex array extension */ char* extensions = (char *) glGetString( GL_EXTENSIONS ); if (!extensions || !strstr( extensions, "GL_EXT_vertex_array" )) { use_vertex_arrays = GL_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); #ifndef __WXMOTIF__ if (!GetContext()) return; #endif SetCurrent(); draw1(); SwapBuffers(); } void TestGLCanvas::OnSize(wxSizeEvent& event) { // this is also necessary to update the context on some platforms wxGLCanvas::OnSize(event); // 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::OnChar(wxKeyEvent& event) { switch( event.GetKeyCode() ) { case WXK_ESCAPE: wxTheApp->ExitMainLoop(); return; case WXK_LEFT: yrot -= 15.0; break; case WXK_RIGHT: yrot += 15.0; break; case WXK_UP: xrot += 15.0; break; case WXK_DOWN: xrot -= 15.0; break; case 's': case 'S': smooth = !smooth; if (smooth) { glShadeModel(GL_SMOOTH); } else { glShadeModel(GL_FLAT); } break; case 'l': case 'L': lighting = !lighting; if (lighting) { glEnable(GL_LIGHTING); } else { glDisable(GL_LIGHTING); } break; default: event.Skip(); return; } Refresh(false); } void TestGLCanvas::OnMouseEvent(wxMouseEvent& event) { static int dragging = 0; static float last_x, last_y; //printf("%f %f %d\n", event.GetX(), event.GetY(), (int)event.LeftIsDown()); if(event.LeftIsDown()) { if(!dragging) { dragging = 1; } else { yrot += (event.GetX() - last_x)*1.0; xrot += (event.GetY() - last_y)*1.0; Refresh(false); } last_x = event.GetX(); last_y = event.GetY(); } else dragging = 0; } void TestGLCanvas::OnEraseBackground( wxEraseEvent& WXUNUSED(event) ) { // Do nothing, to avoid flashing. }