]> git.saurik.com Git - wxWidgets.git/blob - samples/opengl/penguin/penguin.cpp
wxCocoa compilation fixes (include OpenGL/glu.h there too)
[wxWidgets.git] / samples / opengl / penguin / penguin.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: penguin.cpp
3 // Purpose: wxGLCanvas demo program
4 // Author: Robert Roebling
5 // Modified by: Sandro Sigala
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22
23 #if !wxUSE_GLCANVAS
24 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
25 #endif
26
27 #include "penguin.h"
28 #ifdef __DARWIN__
29 #include <OpenGL/glu.h>
30 #else
31 #include <GL/glu.h>
32 #endif
33
34 #include "../../sample.xpm"
35
36 // ---------------------------------------------------------------------------
37 // MyApp
38 // ---------------------------------------------------------------------------
39
40 // `Main program' equivalent, creating windows and returning main app frame
41 bool MyApp::OnInit()
42 {
43 // Create the main frame window
44 MyFrame *frame = new MyFrame(NULL, wxT("wxWidgets Penguin Sample"),
45 wxDefaultPosition, wxDefaultSize);
46
47 #if wxUSE_ZLIB
48 if (wxFileExists(wxT("penguin.dxf.gz")))
49 frame->GetCanvas()->LoadDXF(wxT("penguin.dxf.gz"));
50 #else
51 if (wxFileExists(wxT("penguin.dxf")))
52 frame->GetCanvas()->LoadDXF(wxT("penguin.dxf"));
53 #endif
54
55 /* Show the frame */
56 frame->Show(true);
57
58 return true;
59 }
60
61 IMPLEMENT_APP(MyApp)
62
63 // ---------------------------------------------------------------------------
64 // MyFrame
65 // ---------------------------------------------------------------------------
66
67 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
68 EVT_MENU(wxID_OPEN, MyFrame::OnMenuFileOpen)
69 EVT_MENU(wxID_EXIT, MyFrame::OnMenuFileExit)
70 EVT_MENU(wxID_HELP, MyFrame::OnMenuHelpAbout)
71 END_EVENT_TABLE()
72
73 // MyFrame constructor
74 MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
75 const wxSize& size, long style)
76 : wxFrame(frame, wxID_ANY, title, pos, size, style)
77 {
78 SetIcon(wxIcon(sample_xpm));
79
80 // Make the "File" menu
81 wxMenu *fileMenu = new wxMenu;
82 fileMenu->Append(wxID_OPEN, wxT("&Open..."));
83 fileMenu->AppendSeparator();
84 fileMenu->Append(wxID_EXIT, wxT("E&xit\tALT-X"));
85 // Make the "Help" menu
86 wxMenu *helpMenu = new wxMenu;
87 helpMenu->Append(wxID_HELP, wxT("&About..."));
88
89 wxMenuBar *menuBar = new wxMenuBar;
90 menuBar->Append(fileMenu, wxT("&File"));
91 menuBar->Append(helpMenu, wxT("&Help"));
92 SetMenuBar(menuBar);
93
94 m_canvas = new TestGLCanvas(this, wxID_ANY, wxDefaultPosition,
95 wxSize(300, 300), wxSUNKEN_BORDER);
96 }
97
98 // File|Open... command
99 void MyFrame::OnMenuFileOpen( wxCommandEvent& WXUNUSED(event) )
100 {
101 wxString filename = wxFileSelector(wxT("Choose DXF Model"), wxT(""), wxT(""), wxT(""),
102 #if wxUSE_ZLIB
103 wxT("DXF Drawing (*.dxf;*.dxf.gz)|*.dxf;*.dxf.gz|All files (*.*)|*.*"),
104 #else
105 wxT("DXF Drawing (*.dxf)|*.dxf)|All files (*.*)|*.*"),
106 #endif
107 wxFD_OPEN);
108 if (!filename.IsEmpty())
109 {
110 m_canvas->LoadDXF(filename);
111 m_canvas->Refresh(false);
112 }
113 }
114
115 // File|Exit command
116 void MyFrame::OnMenuFileExit( wxCommandEvent& WXUNUSED(event) )
117 {
118 // true is to force the frame to close
119 Close(true);
120 }
121
122 // Help|About... command
123 void MyFrame::OnMenuHelpAbout( wxCommandEvent& WXUNUSED(event) )
124 {
125 wxMessageBox(wxT("OpenGL Penguin Sample (c) Robert Roebling, Sandro Sigala et al"));
126 }
127
128 // ---------------------------------------------------------------------------
129 // TestGLCanvas
130 // ---------------------------------------------------------------------------
131
132 BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
133 EVT_SIZE(TestGLCanvas::OnSize)
134 EVT_PAINT(TestGLCanvas::OnPaint)
135 EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground)
136 EVT_MOUSE_EVENTS(TestGLCanvas::OnMouse)
137 END_EVENT_TABLE()
138
139 TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id,
140 const wxPoint& pos, const wxSize& size, long style, const wxString& name)
141 : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name)
142 {
143 m_gldata.initialized = false;
144
145 // initialize view matrix
146 m_gldata.beginx = 0.0f;
147 m_gldata.beginy = 0.0f;
148 m_gldata.zoom = 45.0f;
149 trackball(m_gldata.quat, 0.0f, 0.0f, 0.0f, 0.0f);
150 }
151
152 TestGLCanvas::~TestGLCanvas()
153 {
154 }
155
156 void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
157 {
158 // must always be here
159 wxPaintDC dc(this);
160
161 #ifndef __WXMOTIF__
162 if (!GetContext()) return;
163 #endif
164
165 SetCurrent();
166
167 // Initialize OpenGL
168 if (!m_gldata.initialized)
169 {
170 InitGL();
171 ResetProjectionMode();
172 m_gldata.initialized = true;
173 }
174
175 // Clear
176 glClearColor( 0.3f, 0.4f, 0.6f, 1.0f );
177 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
178
179 // Transformations
180 glLoadIdentity();
181 glTranslatef( 0.0f, 0.0f, -20.0f );
182 GLfloat m[4][4];
183 build_rotmatrix( m, m_gldata.quat );
184 glMultMatrixf( &m[0][0] );
185
186 m_renderer.Render();
187
188 // Flush
189 glFlush();
190
191 // Swap
192 SwapBuffers();
193 }
194
195 void TestGLCanvas::OnSize(wxSizeEvent& event)
196 {
197 // this is also necessary to update the context on some platforms
198 wxGLCanvas::OnSize(event);
199 // Reset the OpenGL view aspect
200 ResetProjectionMode();
201 }
202
203 void TestGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
204 {
205 // Do nothing, to avoid flashing on MSW
206 }
207
208 // Load the DXF file. If the zlib support is compiled in wxWidgets,
209 // supports also the ".dxf.gz" gzip compressed files.
210 void TestGLCanvas::LoadDXF(const wxString& filename)
211 {
212 wxFileInputStream stream(filename);
213 if (stream.Ok())
214 #if wxUSE_ZLIB
215 {
216 if (filename.Right(3).Lower() == wxT(".gz"))
217 {
218 wxZlibInputStream zstream(stream);
219 m_renderer.Load(zstream);
220 } else
221 {
222 m_renderer.Load(stream);
223 }
224 }
225 #else
226 {
227 m_renderer.Load(stream);
228 }
229 #endif
230 }
231
232 void TestGLCanvas::OnMouse(wxMouseEvent& event)
233 {
234 if (event.Dragging())
235 {
236 wxSize sz(GetClientSize());
237
238 /* drag in progress, simulate trackball */
239 float spin_quat[4];
240 trackball(spin_quat,
241 (2.0*m_gldata.beginx - sz.x) / sz.x,
242 (sz.y - 2.0*m_gldata.beginy) / sz.y,
243 (2.0*event.GetX() - sz.x) / sz.x,
244 (sz.y - 2.0*event.GetY()) / sz.y);
245
246 add_quats(spin_quat, m_gldata.quat, m_gldata.quat);
247
248 /* orientation has changed, redraw mesh */
249 Refresh(false);
250 }
251
252 m_gldata.beginx = event.GetX();
253 m_gldata.beginy = event.GetY();
254 }
255
256 void TestGLCanvas::InitGL()
257 {
258 static const GLfloat light0_pos[4] = { -50.0f, 50.0f, 0.0f, 0.0f };
259
260 // white light
261 static const GLfloat light0_color[4] = { 0.6f, 0.6f, 0.6f, 1.0f };
262
263 static const GLfloat light1_pos[4] = { 50.0f, 50.0f, 0.0f, 0.0f };
264
265 // cold blue light
266 static const GLfloat light1_color[4] = { 0.4f, 0.4f, 1.0f, 1.0f };
267
268 /* remove back faces */
269 glDisable(GL_CULL_FACE);
270 glEnable(GL_DEPTH_TEST);
271
272 /* speedups */
273 glEnable(GL_DITHER);
274 glShadeModel(GL_SMOOTH);
275 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
276 glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
277
278 /* light */
279 glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
280 glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
281 glLightfv(GL_LIGHT1, GL_POSITION, light1_pos);
282 glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_color);
283 glEnable(GL_LIGHT0);
284 glEnable(GL_LIGHT1);
285 glEnable(GL_LIGHTING);
286
287 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
288 glEnable(GL_COLOR_MATERIAL);
289 }
290
291 void TestGLCanvas::ResetProjectionMode()
292 {
293 int w, h;
294 GetClientSize(&w, &h);
295 #ifndef __WXMOTIF__
296 if ( GetContext() )
297 #endif
298 {
299 SetCurrent();
300 glViewport(0, 0, (GLint) w, (GLint) h);
301 glMatrixMode(GL_PROJECTION);
302 glLoadIdentity();
303 gluPerspective(45.0f, (GLfloat)w/h, 1.0, 100.0);
304 glMatrixMode(GL_MODELVIEW);
305 glLoadIdentity();
306 }
307 }