]>
git.saurik.com Git - wxWidgets.git/blob - samples/opengl/cube/cube.cpp
61f6494835e8547a6173e542ef46255f9738554c
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
);
153 // ----------------------------------------------------------------------------
155 // ----------------------------------------------------------------------------
157 TestGLContext::TestGLContext(wxGLCanvas
*canvas
)
158 : wxGLContext(canvas
)
162 // set up the parameters we want to use
163 glEnable(GL_DEPTH_TEST
);
164 glEnable(GL_LIGHTING
);
166 glEnable(GL_TEXTURE_2D
);
168 // add slightly more light, the default lightning is rather dark
169 GLfloat ambient
[] = { 0.5, 0.5, 0.5, 0.5 };
170 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
172 // set viewing projection
173 glMatrixMode(GL_PROJECTION
);
175 glFrustum(-0.5f
, 0.5f
, -0.5f
, 0.5f
, 1.0f
, 3.0f
);
177 // create the textures to use for cube sides: they will be reused by all
178 // canvases (which is probably not critical in the case of simple textures
179 // we use here but could be really important for a real application where
180 // each texture could take many megabytes)
181 glGenTextures(WXSIZEOF(m_textures
), m_textures
);
183 for ( unsigned i
= 0; i
< WXSIZEOF(m_textures
); i
++ )
185 glBindTexture(GL_TEXTURE_2D
, m_textures
[i
]);
187 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
188 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP
);
189 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP
);
190 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
191 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
193 const wxImage
img(DrawDice(256, i
+ 1));
195 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
196 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, img
.GetWidth(), img
.GetHeight(),
197 0, GL_RGB
, GL_UNSIGNED_BYTE
, img
.GetData());
203 void TestGLContext::DrawRotatedCube(float xangle
, float yangle
)
205 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
207 glMatrixMode(GL_MODELVIEW
);
209 glTranslatef(0.0f
, 0.0f
, -2.0f
);
210 glRotatef(xangle
, 1.0f
, 0.0f
, 0.0f
);
211 glRotatef(yangle
, 0.0f
, 1.0f
, 0.0f
);
213 // draw six faces of a cube of size 1 centered at (0, 0, 0)
214 glBindTexture(GL_TEXTURE_2D
, m_textures
[0]);
216 glNormal3f( 0.0f
, 0.0f
, 1.0f
);
217 glTexCoord2f(0, 0); glVertex3f( 0.5f
, 0.5f
, 0.5f
);
218 glTexCoord2f(1, 0); glVertex3f(-0.5f
, 0.5f
, 0.5f
);
219 glTexCoord2f(1, 1); glVertex3f(-0.5f
,-0.5f
, 0.5f
);
220 glTexCoord2f(0, 1); glVertex3f( 0.5f
,-0.5f
, 0.5f
);
223 glBindTexture(GL_TEXTURE_2D
, m_textures
[1]);
225 glNormal3f( 0.0f
, 0.0f
,-1.0f
);
226 glTexCoord2f(0, 0); glVertex3f(-0.5f
,-0.5f
,-0.5f
);
227 glTexCoord2f(1, 0); glVertex3f(-0.5f
, 0.5f
,-0.5f
);
228 glTexCoord2f(1, 1); glVertex3f( 0.5f
, 0.5f
,-0.5f
);
229 glTexCoord2f(0, 1); glVertex3f( 0.5f
,-0.5f
,-0.5f
);
232 glBindTexture(GL_TEXTURE_2D
, m_textures
[2]);
234 glNormal3f( 0.0f
, 1.0f
, 0.0f
);
235 glTexCoord2f(0, 0); glVertex3f( 0.5f
, 0.5f
, 0.5f
);
236 glTexCoord2f(1, 0); glVertex3f( 0.5f
, 0.5f
,-0.5f
);
237 glTexCoord2f(1, 1); glVertex3f(-0.5f
, 0.5f
,-0.5f
);
238 glTexCoord2f(0, 1); glVertex3f(-0.5f
, 0.5f
, 0.5f
);
241 glBindTexture(GL_TEXTURE_2D
, m_textures
[3]);
243 glNormal3f( 0.0f
,-1.0f
, 0.0f
);
244 glTexCoord2f(0, 0); glVertex3f(-0.5f
,-0.5f
,-0.5f
);
245 glTexCoord2f(1, 0); glVertex3f( 0.5f
,-0.5f
,-0.5f
);
246 glTexCoord2f(1, 1); glVertex3f( 0.5f
,-0.5f
, 0.5f
);
247 glTexCoord2f(0, 1); glVertex3f(-0.5f
,-0.5f
, 0.5f
);
250 glBindTexture(GL_TEXTURE_2D
, m_textures
[4]);
252 glNormal3f( 1.0f
, 0.0f
, 0.0f
);
253 glTexCoord2f(0, 0); glVertex3f( 0.5f
, 0.5f
, 0.5f
);
254 glTexCoord2f(1, 0); glVertex3f( 0.5f
,-0.5f
, 0.5f
);
255 glTexCoord2f(1, 1); glVertex3f( 0.5f
,-0.5f
,-0.5f
);
256 glTexCoord2f(0, 1); glVertex3f( 0.5f
, 0.5f
,-0.5f
);
259 glBindTexture(GL_TEXTURE_2D
, m_textures
[5]);
261 glNormal3f(-1.0f
, 0.0f
, 0.0f
);
262 glTexCoord2f(0, 0); glVertex3f(-0.5f
,-0.5f
,-0.5f
);
263 glTexCoord2f(1, 0); glVertex3f(-0.5f
,-0.5f
, 0.5f
);
264 glTexCoord2f(1, 1); glVertex3f(-0.5f
, 0.5f
, 0.5f
);
265 glTexCoord2f(0, 1); glVertex3f(-0.5f
, 0.5f
,-0.5f
);
273 // ----------------------------------------------------------------------------
275 // ----------------------------------------------------------------------------
277 BEGIN_EVENT_TABLE(TestGLCanvas
, wxGLCanvas
)
278 EVT_SIZE(TestGLCanvas::OnSize
)
279 EVT_PAINT(TestGLCanvas::OnPaint
)
281 EVT_KEY_DOWN(TestGLCanvas::OnKeyDown
)
284 TestGLCanvas::TestGLCanvas(wxWindow
*parent
)
285 : wxGLCanvas(parent
, wxID_ANY
, NULL
/* attribs */)
291 void TestGLCanvas::OnPaint(wxPaintEvent
& WXUNUSED(event
))
295 wxGetApp().GetContext(this).DrawRotatedCube(m_xangle
, m_yangle
);
300 void TestGLCanvas::OnSize(wxSizeEvent
& event
)
302 // don't prevent default processing from taking place
308 // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
310 GetClientSize(&w
, &h
);
312 wxGetApp().GetContext(this);
313 glViewport(0, 0, w
, h
);
316 void TestGLCanvas::OnKeyDown( wxKeyEvent
& event
)
320 bool inverse
= false;
322 switch ( event
.GetKeyCode() )
329 // rotate around Y axis
338 // rotate around X axis
356 // ----------------------------------------------------------------------------
357 // MyFrame: main application window
358 // ----------------------------------------------------------------------------
360 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
361 EVT_MENU(wxID_NEW
, MyFrame::OnNewWindow
)
362 EVT_MENU(wxID_CLOSE
, MyFrame::OnClose
)
366 : wxFrame(NULL
, wxID_ANY
, _T("wxWidgets OpenGL Cube Sample"))
368 new TestGLCanvas(this);
370 SetIcon(wxICON(sample
));
373 wxMenu
*menu
= new wxMenu
;
374 menu
->Append(wxID_NEW
);
375 menu
->AppendSeparator();
376 menu
->Append(wxID_CLOSE
);
377 wxMenuBar
*menuBar
= new wxMenuBar
;
378 menuBar
->Append(menu
, _T("&Cube"));
384 SetClientSize(400, 400);
388 void MyFrame::OnClose(wxCommandEvent
& WXUNUSED(event
))
390 // true is to force the frame to close
394 void MyFrame::OnNewWindow( wxCommandEvent
& WXUNUSED(event
) )
396 (void) new MyFrame();