| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- /////////////////////////////////////////////////////////////////////////////
- // Name: penguin.cpp
- // Purpose: wxGLCanvas demo program
- // Author: Robert Roebling
- // Modified by: Sandro Sigala
- // Created: 04/01/98
- // Copyright: (c) Robert Roebling
- // 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 "penguin.h"
- #ifdef __DARWIN__
- #include <OpenGL/glu.h>
- #else
- #include <GL/glu.h>
- #endif
- #include "../../sample.xpm"
- // ---------------------------------------------------------------------------
- // MyApp
- // ---------------------------------------------------------------------------
- // `Main program' equivalent, creating windows and returning main app frame
- bool MyApp::OnInit()
- {
- if ( !wxApp::OnInit() )
- return false;
- // Create the main frame window
- MyFrame *frame = new MyFrame(NULL, wxT("wxWidgets Penguin Sample"),
- wxDefaultPosition, wxDefaultSize);
- #if wxUSE_ZLIB
- if (wxFileExists(wxT("penguin.dxf.gz")))
- frame->GetCanvas()->LoadDXF(wxT("penguin.dxf.gz"));
- #else
- if (wxFileExists(wxT("penguin.dxf")))
- frame->GetCanvas()->LoadDXF(wxT("penguin.dxf"));
- #endif
- /* Show the frame */
- frame->Show(true);
- return true;
- }
- IMPLEMENT_APP(MyApp)
- // ---------------------------------------------------------------------------
- // MyFrame
- // ---------------------------------------------------------------------------
- wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
- EVT_MENU(wxID_OPEN, MyFrame::OnMenuFileOpen)
- EVT_MENU(wxID_EXIT, MyFrame::OnMenuFileExit)
- EVT_MENU(wxID_HELP, MyFrame::OnMenuHelpAbout)
- wxEND_EVENT_TABLE()
- // MyFrame constructor
- MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
- const wxSize& size, long style)
- : wxFrame(frame, wxID_ANY, title, pos, size, style)
- {
- SetIcon(wxICON(sample));
- // Make the "File" menu
- wxMenu *fileMenu = new wxMenu;
- fileMenu->Append(wxID_OPEN, wxT("&Open..."));
- fileMenu->AppendSeparator();
- fileMenu->Append(wxID_EXIT, wxT("E&xit\tALT-X"));
- // Make the "Help" menu
- wxMenu *helpMenu = new wxMenu;
- helpMenu->Append(wxID_HELP, wxT("&About"));
- wxMenuBar *menuBar = new wxMenuBar;
- menuBar->Append(fileMenu, wxT("&File"));
- menuBar->Append(helpMenu, wxT("&Help"));
- SetMenuBar(menuBar);
- Show(true);
- m_canvas = new TestGLCanvas(this, wxID_ANY, wxDefaultPosition,
- GetClientSize(), wxSUNKEN_BORDER);
- }
- // File|Open... command
- void MyFrame::OnMenuFileOpen( wxCommandEvent& WXUNUSED(event) )
- {
- wxString filename = wxFileSelector(wxT("Choose DXF Model"), wxT(""), wxT(""), wxT(""),
- #if wxUSE_ZLIB
- wxT("DXF Drawing (*.dxf;*.dxf.gz)|*.dxf;*.dxf.gz|All files (*.*)|*.*"),
- #else
- wxT("DXF Drawing (*.dxf)|*.dxf)|All files (*.*)|*.*"),
- #endif
- wxFD_OPEN);
- if (!filename.IsEmpty())
- {
- m_canvas->LoadDXF(filename);
- m_canvas->Refresh(false);
- }
- }
- // File|Exit command
- void MyFrame::OnMenuFileExit( wxCommandEvent& WXUNUSED(event) )
- {
- // true is to force the frame to close
- Close(true);
- }
- // Help|About command
- void MyFrame::OnMenuHelpAbout( wxCommandEvent& WXUNUSED(event) )
- {
- wxMessageBox(wxT("OpenGL Penguin Sample (c) Robert Roebling, Sandro Sigala et al"));
- }
- // ---------------------------------------------------------------------------
- // TestGLCanvas
- // ---------------------------------------------------------------------------
- wxBEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
- EVT_SIZE(TestGLCanvas::OnSize)
- EVT_PAINT(TestGLCanvas::OnPaint)
- EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground)
- EVT_MOUSE_EVENTS(TestGLCanvas::OnMouse)
- wxEND_EVENT_TABLE()
- TestGLCanvas::TestGLCanvas(wxWindow *parent,
- wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxString& name)
- : wxGLCanvas(parent, id, NULL, pos, size,
- style | wxFULL_REPAINT_ON_RESIZE, name)
- {
- // Explicitly create a new rendering context instance for this canvas.
- m_glRC = new wxGLContext(this);
- m_gldata.initialized = false;
- // initialize view matrix
- m_gldata.beginx = 0.0f;
- m_gldata.beginy = 0.0f;
- m_gldata.zoom = 45.0f;
- trackball(m_gldata.quat, 0.0f, 0.0f, 0.0f, 0.0f);
- }
- TestGLCanvas::~TestGLCanvas()
- {
- delete m_glRC;
- }
- void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
- {
- // must always be here
- wxPaintDC dc(this);
- SetCurrent(*m_glRC);
- // Initialize OpenGL
- if (!m_gldata.initialized)
- {
- InitGL();
- ResetProjectionMode();
- m_gldata.initialized = true;
- }
- // Clear
- glClearColor( 0.3f, 0.4f, 0.6f, 1.0f );
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- // Transformations
- glLoadIdentity();
- glTranslatef( 0.0f, 0.0f, -20.0f );
- GLfloat m[4][4];
- build_rotmatrix( m, m_gldata.quat );
- glMultMatrixf( &m[0][0] );
- m_renderer.Render();
- // Flush
- glFlush();
- // Swap
- SwapBuffers();
- }
- void TestGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
- {
- // Reset the OpenGL view aspect.
- // This is OK only because there is only one canvas that uses the context.
- // See the cube sample for that case that multiple canvases are made current with one context.
- ResetProjectionMode();
- }
- void TestGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
- {
- // Do nothing, to avoid flashing on MSW
- }
- // Load the DXF file. If the zlib support is compiled in wxWidgets,
- // supports also the ".dxf.gz" gzip compressed files.
- void TestGLCanvas::LoadDXF(const wxString& filename)
- {
- wxFileInputStream stream(filename);
- if (stream.IsOk())
- #if wxUSE_ZLIB
- {
- if (filename.Right(3).Lower() == wxT(".gz"))
- {
- wxZlibInputStream zstream(stream);
- m_renderer.Load(zstream);
- } else
- {
- m_renderer.Load(stream);
- }
- }
- #else
- {
- m_renderer.Load(stream);
- }
- #endif
- }
- void TestGLCanvas::OnMouse(wxMouseEvent& event)
- {
- if (event.Dragging())
- {
- wxSize sz(GetClientSize());
- /* drag in progress, simulate trackball */
- float spin_quat[4];
- trackball(spin_quat,
- (2.0*m_gldata.beginx - sz.x) / sz.x,
- (sz.y - 2.0*m_gldata.beginy) / sz.y,
- (2.0*event.GetX() - sz.x) / sz.x,
- (sz.y - 2.0*event.GetY()) / sz.y);
- add_quats(spin_quat, m_gldata.quat, m_gldata.quat);
- /* orientation has changed, redraw mesh */
- Refresh(false);
- }
- m_gldata.beginx = event.GetX();
- m_gldata.beginy = event.GetY();
- }
- void TestGLCanvas::InitGL()
- {
- static const GLfloat light0_pos[4] = { -50.0f, 50.0f, 0.0f, 0.0f };
- // white light
- static const GLfloat light0_color[4] = { 0.6f, 0.6f, 0.6f, 1.0f };
- static const GLfloat light1_pos[4] = { 50.0f, 50.0f, 0.0f, 0.0f };
- // cold blue light
- static const GLfloat light1_color[4] = { 0.4f, 0.4f, 1.0f, 1.0f };
- /* remove back faces */
- glEnable(GL_CULL_FACE);
- glEnable(GL_DEPTH_TEST);
- /* speedups */
- glEnable(GL_DITHER);
- glShadeModel(GL_SMOOTH);
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
- glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
- /* light */
- glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
- glLightfv(GL_LIGHT1, GL_POSITION, light1_pos);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_color);
- glEnable(GL_LIGHT0);
- glEnable(GL_LIGHT1);
- glEnable(GL_LIGHTING);
- glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
- }
- void TestGLCanvas::ResetProjectionMode()
- {
- if ( !IsShownOnScreen() )
- return;
- // This is normally only necessary if there is more than one wxGLCanvas
- // or more than one wxGLContext in the application.
- SetCurrent(*m_glRC);
- int w, h;
- GetClientSize(&w, &h);
- // It's up to the application code to update the OpenGL viewport settings.
- // In order to avoid extensive context switching, consider doing this in
- // OnPaint() rather than here, though.
- glViewport(0, 0, (GLint) w, (GLint) h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(45.0f, (GLfloat)w/h, 1.0, 100.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
|