]> git.saurik.com Git - wxWidgets.git/blob - samples/opengl/cube/cube.cpp
1. switched to new wxGLCanvas API (not using the implicit context)
[wxWidgets.git] / samples / opengl / cube / cube.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: cube.cpp
3 // Purpose: wxGLCanvas demo program
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin to use new wxGLCanvas API (2007-04-09)
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #include "wx/wx.h"
29 #endif
30
31 #if !wxUSE_GLCANVAS
32 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
33 #endif
34
35 #include "cube.h"
36
37 #if !defined(__WXMSW__) && !defined(__WXPM__)
38 #include "../../sample.xpm"
39 #endif
40
41 // ============================================================================
42 // implementation
43 // ============================================================================
44
45 // ----------------------------------------------------------------------------
46 // MyApp: the application object
47 // ----------------------------------------------------------------------------
48
49 IMPLEMENT_APP(MyApp)
50
51 bool MyApp::OnInit()
52 {
53 if ( !wxApp::OnInit() )
54 return false;
55
56 // Create the main window
57 new MyFrame();
58
59 return true;
60 }
61
62 int MyApp::OnExit()
63 {
64 delete m_glContext;
65
66 return wxApp::OnExit();
67 }
68
69 void MyApp::SetCurrent(wxGLCanvas *canvas)
70 {
71 wxCHECK_RET( canvas, _T("canvas can't be NULL") );
72
73 if ( !m_glContext )
74 m_glContext = new wxGLContext(canvas);
75
76 m_glContext->SetCurrent(*canvas);
77 }
78
79 // ----------------------------------------------------------------------------
80 // TestGLCanvas
81 // ----------------------------------------------------------------------------
82
83 BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
84 EVT_SIZE(TestGLCanvas::OnSize)
85 EVT_PAINT(TestGLCanvas::OnPaint)
86
87 EVT_KEY_DOWN(TestGLCanvas::OnKeyDown)
88 END_EVENT_TABLE()
89
90 static /* const */ int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
91
92 TestGLCanvas::TestGLCanvas(wxWindow *parent)
93 : wxGLCanvas(parent, wxID_ANY, attribs)
94 {
95 InitGL();
96 }
97
98 // this function is called on each repaint so it should be fast
99 void TestGLCanvas::Render()
100 {
101 wxGetApp().SetCurrent(this);
102
103 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
104 glCallList(m_gllist);
105
106 glFlush();
107 SwapBuffers();
108 }
109
110 void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
111 {
112 wxPaintDC dc(this);
113
114 Render();
115 }
116
117 void TestGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
118 {
119 // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
120 int w, h;
121 GetClientSize(&w, &h);
122
123 wxGetApp().SetCurrent(this);
124 glViewport(0, 0, w, h);
125 }
126
127 void TestGLCanvas::InitGL()
128 {
129 wxGetApp().SetCurrent(this);
130
131 /* set viewing projection */
132 glMatrixMode(GL_PROJECTION);
133 glLoadIdentity();
134 glFrustum(-0.5f, 0.5f, -0.5f, 0.5f, 1.0f, 3.0f);
135
136 /* position viewer */
137 glMatrixMode(GL_MODELVIEW);
138 glLoadIdentity();
139 glTranslatef(0.0f, 0.0f, -2.0f);
140
141 /* position object */
142 glRotatef(30.0f, 1.0f, 0.0f, 0.0f);
143 glRotatef(30.0f, 0.0f, 1.0f, 0.0f);
144
145 glEnable(GL_DEPTH_TEST);
146 glEnable(GL_LIGHTING);
147 glEnable(GL_LIGHT0);
148
149 // create the list of commands to draw the cube: then we can just (quickly)
150 // execute it in Render() later
151 m_gllist = glGenLists(1);
152 glNewList(m_gllist, GL_COMPILE);
153
154 /* draw six faces of a cube */
155 glBegin(GL_QUADS);
156 glNormal3f( 0.0f, 0.0f, 1.0f);
157 glVertex3f( 0.5f, 0.5f, 0.5f); glVertex3f(-0.5f, 0.5f, 0.5f);
158 glVertex3f(-0.5f,-0.5f, 0.5f); glVertex3f( 0.5f,-0.5f, 0.5f);
159
160 glNormal3f( 0.0f, 0.0f,-1.0f);
161 glVertex3f(-0.5f,-0.5f,-0.5f); glVertex3f(-0.5f, 0.5f,-0.5f);
162 glVertex3f( 0.5f, 0.5f,-0.5f); glVertex3f( 0.5f,-0.5f,-0.5f);
163
164 glNormal3f( 0.0f, 1.0f, 0.0f);
165 glVertex3f( 0.5f, 0.5f, 0.5f); glVertex3f( 0.5f, 0.5f,-0.5f);
166 glVertex3f(-0.5f, 0.5f,-0.5f); glVertex3f(-0.5f, 0.5f, 0.5f);
167
168 glNormal3f( 0.0f,-1.0f, 0.0f);
169 glVertex3f(-0.5f,-0.5f,-0.5f); glVertex3f( 0.5f,-0.5f,-0.5f);
170 glVertex3f( 0.5f,-0.5f, 0.5f); glVertex3f(-0.5f,-0.5f, 0.5f);
171
172 glNormal3f( 1.0f, 0.0f, 0.0f);
173 glVertex3f( 0.5f, 0.5f, 0.5f); glVertex3f( 0.5f,-0.5f, 0.5f);
174 glVertex3f( 0.5f,-0.5f,-0.5f); glVertex3f( 0.5f, 0.5f,-0.5f);
175
176 glNormal3f(-1.0f, 0.0f, 0.0f);
177 glVertex3f(-0.5f,-0.5f,-0.5f); glVertex3f(-0.5f,-0.5f, 0.5f);
178 glVertex3f(-0.5f, 0.5f, 0.5f); glVertex3f(-0.5f, 0.5f,-0.5f);
179 glEnd();
180
181 glEndList();
182 }
183
184 void TestGLCanvas::OnKeyDown( wxKeyEvent& event )
185 {
186 GLfloat x = 0,
187 y = 0,
188 z = 0;
189
190 bool inverse = false;
191
192 switch ( event.GetKeyCode() )
193 {
194 case WXK_RIGHT:
195 inverse = true;
196 // fall through
197
198 case WXK_LEFT:
199 // rotate around Z axis
200 z = 1;
201 break;
202
203 case WXK_DOWN:
204 inverse = true;
205 // fall through
206
207 case WXK_UP:
208 // rotate around Y axis
209 y = 1;
210 break;
211
212 default:
213 event.Skip();
214 return;
215 }
216
217 float angle = 5;
218 if ( inverse )
219 angle = -angle;
220
221 wxGetApp().SetCurrent(this);
222
223 glMatrixMode(GL_MODELVIEW);
224 glRotatef(angle, x, y, z);
225
226 // refresh all cubes
227 for ( wxWindowList::const_iterator i = wxTopLevelWindows.begin();
228 i != wxTopLevelWindows.end();
229 ++i )
230 {
231 (*i)->Refresh(false);
232 }
233 }
234
235 // ----------------------------------------------------------------------------
236 // MyFrame: main application window
237 // ----------------------------------------------------------------------------
238
239 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
240 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
241 EVT_MENU(wxID_NEW, MyFrame::OnNewWindow)
242 END_EVENT_TABLE()
243
244 MyFrame::MyFrame()
245 : wxFrame(NULL, wxID_ANY, _T("wxWidgets OpenGL Cube Sample"),
246 wxDefaultPosition, wxSize(400, 300))
247 {
248 m_canvas = new TestGLCanvas(this);
249
250 SetIcon(wxICON(sample));
251
252 // Make a menubar
253 wxMenu *winMenu = new wxMenu;
254 winMenu->Append(wxID_EXIT, _T("&Close"));
255 winMenu->Append(wxID_NEW, _T("&New") );
256 wxMenuBar *menuBar = new wxMenuBar;
257 menuBar->Append(winMenu, _T("&Window"));
258
259 SetMenuBar(menuBar);
260
261 Show();
262 }
263
264 void MyFrame::OnExit( wxCommandEvent& WXUNUSED(event) )
265 {
266 // true is to force the frame to close
267 Close(true);
268 }
269
270 void MyFrame::OnNewWindow( wxCommandEvent& WXUNUSED(event) )
271 {
272 (void) new MyFrame();
273 }
274