]>
git.saurik.com Git - wxWidgets.git/blob - samples/opengl/cube/cube.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGLCanvas demo program
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
31 #error Please set wxUSE_GLCANVAS to 1 in setup.h.
36 #ifndef __WXMSW__ // for wxStopWatch, see remark below
38 #include <sys/unistd.h>
40 #include <sys/timeb.h>
43 #define ID_NEW_WINDOW 10000
44 #define ID_DEF_ROTATE_LEFT_KEY 10001
45 #define ID_DEF_ROTATE_RIGHT_KEY 10002
47 /*----------------------------------------------------------
48 Control to get a keycode
49 ----------------------------------------------------------*/
50 class ScanCodeCtrl
: public wxTextCtrl
53 ScanCodeCtrl( wxWindow
* parent
, wxWindowID id
, int code
,
54 const wxPoint
& pos
, const wxSize
& size
);
55 void OnChar( wxKeyEvent
& event
) { } /* do nothing */
56 void OnKeyDown(wxKeyEvent
& event
);
58 // any class wishing to process wxWindows events must use this macro
61 BEGIN_EVENT_TABLE( ScanCodeCtrl
, wxTextCtrl
)
62 EVT_CHAR( ScanCodeCtrl::OnChar
)
63 EVT_KEY_DOWN( ScanCodeCtrl::OnKeyDown
)
66 ScanCodeCtrl::ScanCodeCtrl( wxWindow
* parent
, wxWindowID id
, int code
,
67 const wxPoint
& pos
, const wxSize
& size
)
68 : wxTextCtrl( parent
, id
, "", pos
, size
)
70 buf
.Printf( "0x%04x", code
);
74 void ScanCodeCtrl::OnKeyDown( wxKeyEvent
& event
)
76 buf
.Printf( "0x%04x", event
.KeyCode() );
80 /*------------------------------------------------------------------
81 Dialog for defining a keypress
82 -------------------------------------------------------------------*/
84 class ScanCodeDialog
: public wxDialog
87 ScanCodeDialog( wxWindow
* parent
, wxWindowID id
, const int code
,
88 const wxString
&descr
, const wxString
& title
);
91 ScanCodeCtrl
*m_ScanCode
;
92 wxTextCtrl
*m_Description
;
95 ScanCodeDialog::ScanCodeDialog( wxWindow
* parent
, wxWindowID id
,
96 const int code
, const wxString
&descr
, const wxString
& title
)
97 : wxDialog( parent
, id
, title
, wxPoint(-1, -1), wxSize(96*2,76*2) )
99 new wxStaticText( this, -1, "Scancode", wxPoint(4*2,3*2),
101 m_ScanCode
= new ScanCodeCtrl( this, -1, code
, wxPoint(37*2,6*2),
104 new wxStaticText( this, -1, "Description", wxPoint(4*2,24*2),
106 m_Description
= new wxTextCtrl( this, -1, descr
, wxPoint(37*2,27*2),
109 new wxButton( this, wxID_OK
, "Ok", wxPoint(20*2,50*2), wxSize(20*2,13*2) );
110 new wxButton( this, wxID_CANCEL
, "Cancel", wxPoint(44*2,50*2),
114 int ScanCodeDialog::GetValue()
117 wxString buf
= m_ScanCode
->GetValue();
118 sscanf( buf
.c_str(), "%i", &code
);
122 /*----------------------------------------------------------------------
123 Utility function to get the elapsed time (in msec) since a given point
124 in time (in sec) (because current version of wxGetElapsedTime doesn´t
125 works right with glibc-2.1 and linux, at least for me)
126 -----------------------------------------------------------------------*/
127 unsigned long wxStopWatch( unsigned long *sec_base
)
129 unsigned long secs
,msec
;
131 #ifndef __WXMSW__ // think every unice has gettimeofday
133 gettimeofday( &tv
, (struct timezone
*)NULL
);
135 msec
= tv
.tv_usec
/1000;
150 return( (secs
-*sec_base
)*1000 + msec
);
153 /*----------------------------------------------------------------
154 Implementation of Test-GLCanvas
155 -----------------------------------------------------------------*/
157 BEGIN_EVENT_TABLE(TestGLCanvas
, wxGLCanvas
)
158 EVT_SIZE(TestGLCanvas::OnSize
)
159 EVT_PAINT(TestGLCanvas::OnPaint
)
160 EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground
)
161 EVT_KEY_DOWN( TestGLCanvas::OnKeyDown
)
162 EVT_KEY_UP( TestGLCanvas::OnKeyUp
)
163 EVT_ENTER_WINDOW( TestGLCanvas::OnEnterWindow
)
166 unsigned long TestGLCanvas::m_secbase
= 0;
167 int TestGLCanvas::m_TimeInitialized
= 0;
168 unsigned long TestGLCanvas::m_xsynct
;
169 unsigned long TestGLCanvas::m_gsynct
;
171 TestGLCanvas::TestGLCanvas(wxWindow
*parent
, wxWindowID id
,
172 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
):
173 wxGLCanvas(parent
, (wxGLCanvas
*) NULL
, id
, pos
, size
, style
, name
)
178 m_rright
= WXK_RIGHT
;
181 TestGLCanvas::TestGLCanvas(wxWindow
*parent
, const TestGLCanvas
&other
,
182 wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, long style
,
183 const wxString
& name
) :
184 wxGLCanvas(parent
, other
.GetContext(), id
, pos
, size
, style
, name
)
187 m_gllist
= other
.m_gllist
; /* share display list */
189 m_rright
= WXK_RIGHT
;
192 TestGLCanvas::~TestGLCanvas()
196 void TestGLCanvas::Render()
201 if (!GetContext()) return;
205 /* init OpenGL once, but after SetCurrent */
212 /* clear color and depth buffers */
213 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
217 m_gllist
= glGenLists( 1 );
218 glNewList( m_gllist
, GL_COMPILE_AND_EXECUTE
);
219 /* draw six faces of a cube */
221 glNormal3f( 0.0F
, 0.0F
, 1.0F
);
222 glVertex3f( 0.5F
, 0.5F
, 0.5F
); glVertex3f(-0.5F
, 0.5F
, 0.5F
);
223 glVertex3f(-0.5F
,-0.5F
, 0.5F
); glVertex3f( 0.5F
,-0.5F
, 0.5F
);
225 glNormal3f( 0.0F
, 0.0F
,-1.0F
);
226 glVertex3f(-0.5F
,-0.5F
,-0.5F
); glVertex3f(-0.5F
, 0.5F
,-0.5F
);
227 glVertex3f( 0.5F
, 0.5F
,-0.5F
); glVertex3f( 0.5F
,-0.5F
,-0.5F
);
229 glNormal3f( 0.0F
, 1.0F
, 0.0F
);
230 glVertex3f( 0.5F
, 0.5F
, 0.5F
); glVertex3f( 0.5F
, 0.5F
,-0.5F
);
231 glVertex3f(-0.5F
, 0.5F
,-0.5F
); glVertex3f(-0.5F
, 0.5F
, 0.5F
);
233 glNormal3f( 0.0F
,-1.0F
, 0.0F
);
234 glVertex3f(-0.5F
,-0.5F
,-0.5F
); glVertex3f( 0.5F
,-0.5F
,-0.5F
);
235 glVertex3f( 0.5F
,-0.5F
, 0.5F
); glVertex3f(-0.5F
,-0.5F
, 0.5F
);
237 glNormal3f( 1.0F
, 0.0F
, 0.0F
);
238 glVertex3f( 0.5F
, 0.5F
, 0.5F
); glVertex3f( 0.5F
,-0.5F
, 0.5F
);
239 glVertex3f( 0.5F
,-0.5F
,-0.5F
); glVertex3f( 0.5F
, 0.5F
,-0.5F
);
241 glNormal3f(-1.0F
, 0.0F
, 0.0F
);
242 glVertex3f(-0.5F
,-0.5F
,-0.5F
); glVertex3f(-0.5F
,-0.5F
, 0.5F
);
243 glVertex3f(-0.5F
, 0.5F
, 0.5F
); glVertex3f(-0.5F
, 0.5F
,-0.5F
);
249 glCallList( m_gllist
);
255 void TestGLCanvas::OnEnterWindow( wxMouseEvent
& event
)
260 void TestGLCanvas::OnPaint( wxPaintEvent
& event
)
265 void TestGLCanvas::OnSize(wxSizeEvent
& event
)
268 GetClientSize(& width
, & height
);
275 glViewport(0, 0, width
, height
);
279 void TestGLCanvas::OnEraseBackground(wxEraseEvent
& event
)
281 // Do nothing, to avoid flashing.
284 void TestGLCanvas::InitGL()
288 /* set viewing projection */
289 glMatrixMode(GL_PROJECTION
);
290 glFrustum(-0.5F
, 0.5F
, -0.5F
, 0.5F
, 1.0F
, 3.0F
);
292 /* position viewer */
293 glMatrixMode(GL_MODELVIEW
);
294 glTranslatef(0.0F
, 0.0F
, -2.0F
);
296 /* position object */
297 glRotatef(30.0F
, 1.0F
, 0.0F
, 0.0F
);
298 glRotatef(30.0F
, 0.0F
, 1.0F
, 0.0F
);
300 glEnable(GL_DEPTH_TEST
);
301 glEnable(GL_LIGHTING
);
305 GLfloat
TestGLCanvas::CalcRotateSpeed( unsigned long acceltime
)
309 t
= ((GLfloat
)acceltime
) / 1000.0f
;
321 GLfloat
TestGLCanvas::CalcRotateAngle( unsigned long lasttime
,
322 unsigned long acceltime
)
326 t
= ((GLfloat
)(acceltime
- lasttime
)) / 1000.0f
;
327 s1
= CalcRotateSpeed( lasttime
);
328 s2
= CalcRotateSpeed( acceltime
);
330 return( t
* (s1
+ s2
) * 135.0f
);
333 void TestGLCanvas::Action( long code
, unsigned long lasttime
,
334 unsigned long acceltime
)
336 GLfloat angle
= CalcRotateAngle( lasttime
, acceltime
);
340 else if (code
== m_rright
)
344 void TestGLCanvas::OnKeyDown( wxKeyEvent
& event
)
346 long evkey
= event
.KeyCode();
347 if (evkey
== 0) return;
349 if (!m_TimeInitialized
)
351 m_TimeInitialized
= 1;
352 m_xsynct
= event
.m_timeStamp
;
353 m_gsynct
= wxStopWatch(&m_secbase
);
361 unsigned long currTime
= event
.m_timeStamp
- m_xsynct
;
363 // we have to test for m_Key != 0 because otherwise the test would be
364 // always true because it is set to 0 in OnKeyUp() below - I don't know
365 // why is it like this, just fixing blindly (VZ)
366 if (evkey
!= m_Key
&& m_Key
!= 0)
369 m_LastRedraw
= m_StartTime
= m_LastTime
= currTime
;
372 if (currTime
>= m_LastRedraw
) // Redraw:
374 Action( m_Key
, m_LastTime
-m_StartTime
, currTime
-m_StartTime
);
376 m_LastRedraw
= wxStopWatch(&m_secbase
) - m_gsynct
;
377 m_LastTime
= currTime
;
383 void TestGLCanvas::OnKeyUp( wxKeyEvent
& event
)
393 void TestGLCanvas::Rotate( GLfloat deg
)
397 glMatrixMode(GL_MODELVIEW
);
398 glRotatef((GLfloat
)deg
, 0.0F
, 0.0F
, 1.0F
);
403 /* -----------------------------------------------------------------------
405 -------------------------------------------------------------------------*/
407 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
408 EVT_MENU(wxID_EXIT
, MyFrame::OnExit
)
409 EVT_MENU( ID_NEW_WINDOW
, MyFrame::OnNewWindow
)
410 EVT_MENU( ID_DEF_ROTATE_LEFT_KEY
, MyFrame::OnDefRotateLeftKey
)
411 EVT_MENU( ID_DEF_ROTATE_RIGHT_KEY
, MyFrame::OnDefRotateRightKey
)
414 // My frame constructor
415 MyFrame::MyFrame(wxFrame
*frame
, const wxString
& title
, const wxPoint
& pos
,
416 const wxSize
& size
, long style
)
417 : wxFrame(frame
, -1, title
, pos
, size
, style
)
422 // Intercept menu commands
423 void MyFrame::OnExit(wxCommandEvent
& event
)
428 void MyFrame::OnNewWindow()
430 MyFrame
*frame
= new MyFrame(NULL
, "Cube OpenGL Demo Clone",
431 wxPoint(50, 50), wxSize(400, 300));
434 frame
->SetIcon(wxIcon("mondrian"));
438 wxMenu
*winMenu
= new wxMenu
;
440 winMenu
->Append(wxID_EXIT
, "&Close");
441 winMenu
->Append(ID_NEW_WINDOW
, "&New" );
442 wxMenuBar
*menuBar
= new wxMenuBar
;
443 menuBar
->Append(winMenu
, "&Window");
445 winMenu
= new wxMenu
;
446 winMenu
->Append(ID_DEF_ROTATE_LEFT_KEY
, "Rotate &left");
447 winMenu
->Append(ID_DEF_ROTATE_RIGHT_KEY
, "Rotate &right");
448 menuBar
->Append(winMenu
, "&Key");
450 frame
->SetMenuBar(menuBar
);
452 frame
->m_canvas
= new TestGLCanvas( frame
, *m_canvas
, -1,
453 wxPoint(0, 0), wxSize(200, 200) );
459 void MyFrame::OnDefRotateLeftKey()
461 ScanCodeDialog
dial( this, -1, m_canvas
->m_rleft
,
462 wxString("Left"), "Define key" );
463 int result
= dial
.ShowModal();
464 if( result
== wxID_OK
)
465 m_canvas
->m_rleft
= dial
.GetValue();
467 void MyFrame::OnDefRotateRightKey()
469 ScanCodeDialog
dial( this, -1, m_canvas
->m_rright
,
470 wxString("Right"), "Define key" );
471 int result
= dial
.ShowModal();
472 if( result
== wxID_OK
)
473 m_canvas
->m_rright
= dial
.GetValue();
476 /*------------------------------------------------------------------
477 Application object ( equivalent to main() )
478 ------------------------------------------------------------------ */
482 bool MyApp::OnInit(void)
484 wxLog::SetTraceMask(wxTraceMessages
);
486 // Create the main frame window
487 MyFrame
*frame
= new MyFrame(NULL
, "Cube OpenGL Demo", wxPoint(50, 50),
491 frame
->SetIcon(wxIcon("mondrian"));
495 wxMenu
*winMenu
= new wxMenu
;
497 winMenu
->Append(wxID_EXIT
, "&Close");
498 winMenu
->Append(ID_NEW_WINDOW
, "&New" );
499 wxMenuBar
*menuBar
= new wxMenuBar
;
500 menuBar
->Append(winMenu
, "&Window");
502 winMenu
= new wxMenu
;
503 winMenu
->Append(ID_DEF_ROTATE_LEFT_KEY
, "Rotate &left");
504 winMenu
->Append(ID_DEF_ROTATE_RIGHT_KEY
, "Rotate &right");
505 menuBar
->Append(winMenu
, "&Key");
507 frame
->SetMenuBar(menuBar
);
509 frame
->m_canvas
= new TestGLCanvas(frame
, -1, wxPoint(0, 0), wxSize(200, 200));