]>
git.saurik.com Git - wxWidgets.git/blob - samples/opengl/cube/cube.cpp
1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGLCanvas demo program
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin to use new wxGLCanvas API (2007-04-09)
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
32 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
37 #if !defined(__WXMSW__) && !defined(__WXPM__)
38 #include "../../sample.xpm"
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 static void CheckGLError()
47 GLenum errLast
= GL_NO_ERROR
;
51 GLenum err
= glGetError();
52 if ( err
== GL_NO_ERROR
)
55 // normally the error is reset by the call to glGetError() but if
56 // glGetError() itself returns an error, we risk looping forever here
57 // so check that we get a different error than the last time
60 wxLogError(_T("OpenGL error state couldn't be reset."));
66 wxLogError(_T("OpenGL error %d"), err
);
70 // function to draw the texture for cube faces
71 static wxImage
DrawDice(int size
, unsigned num
)
73 wxASSERT_MSG( num
>= 1 && num
<= 6, _T("invalid dice index") );
75 const int dot
= size
/16; // radius of a single dot
76 const int gap
= 5*size
/32; // gap between dots
78 wxBitmap
bmp(size
, size
);
81 dc
.SetBackground(*wxWHITE_BRUSH
);
83 dc
.SetBrush(*wxBLACK_BRUSH
);
85 // the upper left and lower right points
88 dc
.DrawCircle(gap
+ dot
, gap
+ dot
, dot
);
89 dc
.DrawCircle(size
- gap
- dot
, size
- gap
- dot
, dot
);
92 // draw the central point for odd dices
95 dc
.DrawCircle(size
/2, size
/2, dot
);
98 // the upper right and lower left points
101 dc
.DrawCircle(size
- gap
- dot
, gap
+ dot
, dot
);
102 dc
.DrawCircle(gap
+ dot
, size
- gap
- dot
, dot
);
105 // finally those 2 are only for the last dice
108 dc
.DrawCircle(gap
+ dot
, size
/2, dot
);
109 dc
.DrawCircle(size
- gap
- dot
, size
/2, dot
);
112 dc
.SelectObject(wxNullBitmap
);
114 return bmp
.ConvertToImage();
117 // ============================================================================
119 // ============================================================================
121 // ----------------------------------------------------------------------------
122 // MyApp: the application object
123 // ----------------------------------------------------------------------------
129 if ( !wxApp::OnInit() )
132 // Create the main window
142 return wxApp::OnExit();
145 TestGLContext
& MyApp::GetContext(wxGLCanvas
*canvas
)
148 m_glContext
= new TestGLContext(canvas
);
150 m_glContext
->SetCurrent(*canvas
);
155 // ----------------------------------------------------------------------------
157 // ----------------------------------------------------------------------------
159 TestGLContext::TestGLContext(wxGLCanvas
*canvas
)
160 : wxGLContext(canvas
)
164 // set up the parameters we want to use
165 glEnable(GL_DEPTH_TEST
);
166 glEnable(GL_LIGHTING
);
168 glEnable(GL_TEXTURE_2D
);
170 // add slightly more light, the default lightning is rather dark
171 GLfloat ambient
[] = { 0.5, 0.5, 0.5, 0.5 };
172 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
174 // set viewing projection
175 glMatrixMode(GL_PROJECTION
);
177 glFrustum(-0.5f
, 0.5f
, -0.5f
, 0.5f
, 1.0f
, 3.0f
);
179 // create the textures to use for cube sides: they will be reused by all
180 // canvases (which is probably not critical in the case of simple textures
181 // we use here but could be really important for a real application where
182 // each texture could take many megabytes)
183 glGenTextures(WXSIZEOF(m_textures
), m_textures
);
185 for ( unsigned i
= 0; i
< WXSIZEOF(m_textures
); i
++ )
187 glBindTexture(GL_TEXTURE_2D
, m_textures
[i
]);
189 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
190 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP
);
191 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP
);
192 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
193 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
195 const wxImage
img(DrawDice(256, i
+ 1));
197 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
198 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, img
.GetWidth(), img
.GetHeight(),
199 0, GL_RGB
, GL_UNSIGNED_BYTE
, img
.GetData());
205 void TestGLContext::DrawRotatedCube(float xangle
, float yangle
)
207 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
209 glMatrixMode(GL_MODELVIEW
);
211 glTranslatef(0.0f
, 0.0f
, -2.0f
);
212 glRotatef(xangle
, 1.0f
, 0.0f
, 0.0f
);
213 glRotatef(yangle
, 0.0f
, 1.0f
, 0.0f
);
215 // draw six faces of a cube of size 1 centered at (0, 0, 0)
216 glBindTexture(GL_TEXTURE_2D
, m_textures
[0]);
218 glNormal3f( 0.0f
, 0.0f
, 1.0f
);
219 glTexCoord2f(0, 0); glVertex3f( 0.5f
, 0.5f
, 0.5f
);
220 glTexCoord2f(1, 0); glVertex3f(-0.5f
, 0.5f
, 0.5f
);
221 glTexCoord2f(1, 1); glVertex3f(-0.5f
,-0.5f
, 0.5f
);
222 glTexCoord2f(0, 1); glVertex3f( 0.5f
,-0.5f
, 0.5f
);
225 glBindTexture(GL_TEXTURE_2D
, m_textures
[1]);
227 glNormal3f( 0.0f
, 0.0f
,-1.0f
);
228 glTexCoord2f(0, 0); glVertex3f(-0.5f
,-0.5f
,-0.5f
);
229 glTexCoord2f(1, 0); glVertex3f(-0.5f
, 0.5f
,-0.5f
);
230 glTexCoord2f(1, 1); glVertex3f( 0.5f
, 0.5f
,-0.5f
);
231 glTexCoord2f(0, 1); glVertex3f( 0.5f
,-0.5f
,-0.5f
);
234 glBindTexture(GL_TEXTURE_2D
, m_textures
[2]);
236 glNormal3f( 0.0f
, 1.0f
, 0.0f
);
237 glTexCoord2f(0, 0); glVertex3f( 0.5f
, 0.5f
, 0.5f
);
238 glTexCoord2f(1, 0); glVertex3f( 0.5f
, 0.5f
,-0.5f
);
239 glTexCoord2f(1, 1); glVertex3f(-0.5f
, 0.5f
,-0.5f
);
240 glTexCoord2f(0, 1); glVertex3f(-0.5f
, 0.5f
, 0.5f
);
243 glBindTexture(GL_TEXTURE_2D
, m_textures
[3]);
245 glNormal3f( 0.0f
,-1.0f
, 0.0f
);
246 glTexCoord2f(0, 0); glVertex3f(-0.5f
,-0.5f
,-0.5f
);
247 glTexCoord2f(1, 0); glVertex3f( 0.5f
,-0.5f
,-0.5f
);
248 glTexCoord2f(1, 1); glVertex3f( 0.5f
,-0.5f
, 0.5f
);
249 glTexCoord2f(0, 1); glVertex3f(-0.5f
,-0.5f
, 0.5f
);
252 glBindTexture(GL_TEXTURE_2D
, m_textures
[4]);
254 glNormal3f( 1.0f
, 0.0f
, 0.0f
);
255 glTexCoord2f(0, 0); glVertex3f( 0.5f
, 0.5f
, 0.5f
);
256 glTexCoord2f(1, 0); glVertex3f( 0.5f
,-0.5f
, 0.5f
);
257 glTexCoord2f(1, 1); glVertex3f( 0.5f
,-0.5f
,-0.5f
);
258 glTexCoord2f(0, 1); glVertex3f( 0.5f
, 0.5f
,-0.5f
);
261 glBindTexture(GL_TEXTURE_2D
, m_textures
[5]);
263 glNormal3f(-1.0f
, 0.0f
, 0.0f
);
264 glTexCoord2f(0, 0); glVertex3f(-0.5f
,-0.5f
,-0.5f
);
265 glTexCoord2f(1, 0); glVertex3f(-0.5f
,-0.5f
, 0.5f
);
266 glTexCoord2f(1, 1); glVertex3f(-0.5f
, 0.5f
, 0.5f
);
267 glTexCoord2f(0, 1); glVertex3f(-0.5f
, 0.5f
,-0.5f
);
275 // ----------------------------------------------------------------------------
277 // ----------------------------------------------------------------------------
279 BEGIN_EVENT_TABLE(TestGLCanvas
, wxGLCanvas
)
280 EVT_SIZE(TestGLCanvas::OnSize
)
281 EVT_PAINT(TestGLCanvas::OnPaint
)
283 EVT_KEY_DOWN(TestGLCanvas::OnKeyDown
)
286 TestGLCanvas::TestGLCanvas(wxWindow
*parent
)
287 : wxGLCanvas(parent
, wxID_ANY
, NULL
/* attribs */)
293 void TestGLCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
297 wxGetApp().GetContext(this).DrawRotatedCube(m_xangle
, m_yangle
);
302 void TestGLCanvas::OnSize(wxSizeEvent
& event
)
304 // don't prevent default processing from taking place
307 if ( !IsShownOnScreen() )
310 // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
312 GetClientSize(&w
, &h
);
314 wxGetApp().GetContext(this);
315 glViewport(0, 0, w
, h
);
318 void TestGLCanvas::OnKeyDown( wxKeyEvent
& event
)
322 bool inverse
= false;
324 switch ( event
.GetKeyCode() )
331 // rotate around Y axis
340 // rotate around X axis
358 // ----------------------------------------------------------------------------
359 // MyFrame: main application window
360 // ----------------------------------------------------------------------------
362 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
363 EVT_MENU(wxID_NEW
, MyFrame::OnNewWindow
)
364 EVT_MENU(wxID_CLOSE
, MyFrame::OnClose
)
368 : wxFrame(NULL
, wxID_ANY
, _T("wxWidgets OpenGL Cube Sample"))
370 new TestGLCanvas(this);
372 SetIcon(wxICON(sample
));
375 wxMenu
*menu
= new wxMenu
;
376 menu
->Append(wxID_NEW
);
377 menu
->AppendSeparator();
378 menu
->Append(wxID_CLOSE
);
379 wxMenuBar
*menuBar
= new wxMenuBar
;
380 menuBar
->Append(menu
, _T("&Cube"));
386 SetClientSize(400, 400);
389 // test IsDisplaySupported() function:
390 static const int attribs
[] = { WX_GL_RGBA
, WX_GL_DOUBLEBUFFER
, 0 };
391 wxLogStatus("Double-buffered display %s supported",
392 wxGLCanvas::IsDisplaySupported(attribs
) ? "is" : "not");
395 void MyFrame::OnClose(wxCommandEvent
& WXUNUSED(event
))
397 // true is to force the frame to close
401 void MyFrame::OnNewWindow( wxCommandEvent
& WXUNUSED(event
) )
403 (void) new MyFrame();