]> git.saurik.com Git - wxWidgets.git/blame - samples/opengl/penguin/penguin.cpp
Return an empty string from GetValue if the textctrl is set to the
[wxWidgets.git] / samples / opengl / penguin / penguin.cpp
CommitLineData
8b089c5e
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: penguin.cpp
3// Purpose: wxGLCanvas demo program
4// Author: Robert Roebling
4b764db3 5// Modified by: Sandro Sigala
8b089c5e
JS
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Robert Roebling
2f6c54eb 9// Licence: wxWindows licence
8b089c5e
JS
10/////////////////////////////////////////////////////////////////////////////
11
8b089c5e
JS
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
806e2f15
VZ
23#if !wxUSE_GLCANVAS
24 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
25#endif
26
8b089c5e 27#include "penguin.h"
65f4ce38
VZ
28#ifdef __DARWIN__
29 #include <OpenGL/glu.h>
3dec57ad 30#else
65f4ce38 31 #include <GL/glu.h>
3dec57ad 32#endif
8b089c5e 33
3a992940
JS
34#include "../../sample.xpm"
35
4b764db3
JS
36// ---------------------------------------------------------------------------
37// MyApp
38// ---------------------------------------------------------------------------
8b089c5e 39
5cf036d0 40// `Main program' equivalent, creating windows and returning main app frame
bcc4c541 41bool MyApp::OnInit()
8b089c5e 42{
5cf036d0 43 // Create the main frame window
4b764db3 44 MyFrame *frame = new MyFrame(NULL, wxT("wxWidgets Penguin Sample"),
5cf036d0 45 wxDefaultPosition, wxDefaultSize);
8b089c5e 46
4b764db3
JS
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
8b089c5e 54
5cf036d0
DS
55 /* Show the frame */
56 frame->Show(true);
57
58 return true;
8b089c5e
JS
59}
60
61IMPLEMENT_APP(MyApp)
62
4b764db3
JS
63// ---------------------------------------------------------------------------
64// MyFrame
65// ---------------------------------------------------------------------------
66
8b089c5e 67BEGIN_EVENT_TABLE(MyFrame, wxFrame)
4b764db3
JS
68 EVT_MENU(wxID_OPEN, MyFrame::OnMenuFileOpen)
69 EVT_MENU(wxID_EXIT, MyFrame::OnMenuFileExit)
70 EVT_MENU(wxID_HELP, MyFrame::OnMenuHelpAbout)
8b089c5e
JS
71END_EVENT_TABLE()
72
4b764db3 73// MyFrame constructor
8b089c5e 74MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
5cf036d0
DS
75 const wxSize& size, long style)
76 : wxFrame(frame, wxID_ANY, title, pos, size, style)
8b089c5e 77{
3a992940 78 SetIcon(wxIcon(sample_xpm));
4b764db3
JS
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);
8b089c5e
JS
96}
97
4b764db3
JS
98// File|Open... command
99void 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
ff3e84ff 107 wxFD_OPEN);
4b764db3
JS
108 if (!filename.IsEmpty())
109 {
110 m_canvas->LoadDXF(filename);
111 m_canvas->Refresh(false);
112 }
113}
114
115// File|Exit command
116void MyFrame::OnMenuFileExit( wxCommandEvent& WXUNUSED(event) )
8b089c5e 117{
5cf036d0
DS
118 // true is to force the frame to close
119 Close(true);
8b089c5e
JS
120}
121
4b764db3
JS
122// Help|About... command
123void 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
8b089c5e
JS
132BEGIN_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)
137END_EVENT_TABLE()
138
139TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id,
5cf036d0 140 const wxPoint& pos, const wxSize& size, long style, const wxString& name)
3a992940 141 : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name)
8b089c5e 142{
4b764db3
JS
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);
8b089c5e
JS
150}
151
5cf036d0 152TestGLCanvas::~TestGLCanvas()
8b089c5e 153{
8b089c5e
JS
154}
155
2db98bf5 156void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
8b089c5e 157{
4b764db3 158 // must always be here
8b089c5e
JS
159 wxPaintDC dc(this);
160
161#ifndef __WXMOTIF__
162 if (!GetContext()) return;
163#endif
164
165 SetCurrent();
5cf036d0
DS
166
167 // Initialize OpenGL
4b764db3 168 if (!m_gldata.initialized)
8b089c5e
JS
169 {
170 InitGL();
4b764db3
JS
171 ResetProjectionMode();
172 m_gldata.initialized = true;
8b089c5e 173 }
5cf036d0 174
5cf036d0
DS
175 // Clear
176 glClearColor( 0.3f, 0.4f, 0.6f, 1.0f );
8b089c5e
JS
177 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
178
5cf036d0 179 // Transformations
8b089c5e 180 glLoadIdentity();
4b764db3
JS
181 glTranslatef( 0.0f, 0.0f, -20.0f );
182 GLfloat m[4][4];
183 build_rotmatrix( m, m_gldata.quat );
8b089c5e
JS
184 glMultMatrixf( &m[0][0] );
185
4b764db3 186 m_renderer.Render();
5cf036d0
DS
187
188 // Flush
8b089c5e
JS
189 glFlush();
190
5cf036d0 191 // Swap
8b089c5e
JS
192 SwapBuffers();
193}
194
195void TestGLCanvas::OnSize(wxSizeEvent& event)
196{
3dec57ad
SC
197 // this is also necessary to update the context on some platforms
198 wxGLCanvas::OnSize(event);
4b764db3
JS
199 // Reset the OpenGL view aspect
200 ResetProjectionMode();
8b089c5e
JS
201}
202
2db98bf5 203void TestGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
8b089c5e 204{
4b764db3 205 // Do nothing, to avoid flashing on MSW
8b089c5e
JS
206}
207
4b764db3
JS
208// Load the DXF file. If the zlib support is compiled in wxWidgets,
209// supports also the ".dxf.gz" gzip compressed files.
210void TestGLCanvas::LoadDXF(const wxString& filename)
8b089c5e 211{
4b764db3
JS
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
8b089c5e
JS
230}
231
4b764db3 232void TestGLCanvas::OnMouse(wxMouseEvent& event)
8b089c5e 233{
4b764db3 234 if (event.Dragging())
8b089c5e 235 {
4b764db3 236 wxSize sz(GetClientSize());
5cf036d0 237
8b089c5e
JS
238 /* drag in progress, simulate trackball */
239 float spin_quat[4];
240 trackball(spin_quat,
4b764db3
JS
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);
5cf036d0 245
4b764db3 246 add_quats(spin_quat, m_gldata.quat, m_gldata.quat);
2f6c54eb 247
8b089c5e 248 /* orientation has changed, redraw mesh */
5cf036d0 249 Refresh(false);
8b089c5e 250 }
2f6c54eb 251
4b764db3
JS
252 m_gldata.beginx = event.GetX();
253 m_gldata.beginy = event.GetY();
8b089c5e
JS
254}
255
5cf036d0 256void TestGLCanvas::InitGL()
8b089c5e 257{
5cf036d0
DS
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 };
8b089c5e
JS
267
268 /* remove back faces */
269 glDisable(GL_CULL_FACE);
270 glEnable(GL_DEPTH_TEST);
5cf036d0 271
8b089c5e
JS
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);
5cf036d0 280 glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
8b089c5e
JS
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);
5cf036d0
DS
286
287 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
288 glEnable(GL_COLOR_MATERIAL);
8b089c5e
JS
289}
290
4b764db3
JS
291void 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}