1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGLCanvas demo program
4 // Author: Brian Paul (original gltk version), Wolfram Gloger
5 // Modified by: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
29 #include "wx/glcanvas.h"
33 # include <OpenGL/gl.h>
34 # include <OpenGL/glu.h>
44 // disabled because this has apparently changed in OpenGL 1.2, so doesn't link
45 // correctly if this is on...
46 #ifdef GL_EXT_vertex_array
47 #undef GL_EXT_vertex_array
52 // The following part is taken largely unchanged from the original C Version
56 GLboolean speed_test
= GL_FALSE
;
57 GLboolean use_vertex_arrays
= GL_FALSE
;
59 GLboolean doubleBuffer
= GL_TRUE
;
61 GLboolean smooth
= GL_TRUE
;
62 GLboolean lighting
= GL_TRUE
;
65 #define MAXVERTS 10000
67 static GLfloat verts
[MAXVERTS
][3];
68 static GLfloat norms
[MAXVERTS
][3];
69 static GLint numverts
;
75 static void read_surface( wxChar
*filename
)
79 f
= wxFopen(filename
,_T("r"));
81 wxString
msg(_T("Couldn't read "));
88 while (!feof(f
) && numverts
<MAXVERTS
) {
89 fscanf( f
, "%f %f %f %f %f %f",
90 &verts
[numverts
][0], &verts
[numverts
][1], &verts
[numverts
][2],
91 &norms
[numverts
][0], &norms
[numverts
][1], &norms
[numverts
][2] );
96 wxPrintf(_T("%d vertices, %d triangles\n"), numverts
, numverts
-2);
101 static void draw_surface( void )
105 #ifdef GL_EXT_vertex_array
106 if (use_vertex_arrays
) {
107 glDrawArraysEXT( GL_TRIANGLE_STRIP
, 0, numverts
);
111 glBegin( GL_TRIANGLE_STRIP
);
112 for (i
=0;i
<numverts
;i
++) {
113 glNormal3fv( norms
[i
] );
114 glVertex3fv( verts
[i
] );
117 #ifdef GL_EXT_vertex_array
123 static void draw1(void)
125 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
127 glRotatef( yrot
, 0.0, 1.0, 0.0 );
128 glRotatef( xrot
, 1.0, 0.0, 0.0 );
138 static void InitMaterials(void)
140 static float ambient
[] = {0.1, 0.1, 0.1, 1.0};
141 static float diffuse
[] = {0.5, 1.0, 1.0, 1.0};
142 static float position0
[] = {0.0, 0.0, 20.0, 0.0};
143 static float position1
[] = {0.0, 0.0, -20.0, 0.0};
144 static float front_mat_shininess
[] = {60.0};
145 static float front_mat_specular
[] = {0.2, 0.2, 0.2, 1.0};
146 static float front_mat_diffuse
[] = {0.5, 0.28, 0.38, 1.0};
148 static float back_mat_shininess[] = {60.0};
149 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
150 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
152 static float lmodel_ambient
[] = {1.0, 1.0, 1.0, 1.0};
153 static float lmodel_twoside
[] = {GL_FALSE
};
155 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
156 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
157 glLightfv(GL_LIGHT0
, GL_POSITION
, position0
);
160 glLightfv(GL_LIGHT1
, GL_AMBIENT
, ambient
);
161 glLightfv(GL_LIGHT1
, GL_DIFFUSE
, diffuse
);
162 glLightfv(GL_LIGHT1
, GL_POSITION
, position1
);
165 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
166 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
167 glEnable(GL_LIGHTING
);
169 glMaterialfv(GL_FRONT_AND_BACK
, GL_SHININESS
, front_mat_shininess
);
170 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, front_mat_specular
);
171 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, front_mat_diffuse
);
175 static void Init(void)
177 glClearColor(0.0, 0.0, 0.0, 0.0);
179 glShadeModel(GL_SMOOTH
);
180 glEnable(GL_DEPTH_TEST
);
184 glMatrixMode(GL_PROJECTION
);
186 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
188 glMatrixMode(GL_MODELVIEW
);
190 glTranslatef( 0.0, 0.0, -6.0 );
192 #ifdef GL_EXT_vertex_array
193 if (use_vertex_arrays
) {
194 glVertexPointerEXT( 3, GL_FLOAT
, 0, numverts
, verts
);
195 glNormalPointerEXT( GL_FLOAT
, 0, numverts
, norms
);
196 glEnable( GL_VERTEX_ARRAY_EXT
);
197 glEnable( GL_NORMAL_ARRAY_EXT
);
202 static GLenum
Args(int argc
, wxChar
**argv
)
206 for (i
= 1; i
< argc
; i
++) {
207 if (wxStrcmp(argv
[i
], _T("-sb")) == 0) {
208 doubleBuffer
= GL_FALSE
;
210 else if (wxStrcmp(argv
[i
], _T("-db")) == 0) {
211 doubleBuffer
= GL_TRUE
;
213 else if (wxStrcmp(argv
[i
], _T("-speed")) == 0) {
214 speed_test
= GL_TRUE
;
215 doubleBuffer
= GL_TRUE
;
217 else if (wxStrcmp(argv
[i
], _T("-va")) == 0) {
218 use_vertex_arrays
= GL_TRUE
;
221 wxString
msg(_T("Bad option: "));
231 // The following part was written for wxWindows 1.66
232 MyFrame
*frame
= NULL
;
236 // `Main program' equivalent, creating windows and returning main app frame
237 bool MyApp::OnInit(void)
241 // Create the main frame window
242 frame
= new MyFrame(NULL
, _T("Isosurf GL Sample"), wxPoint(50, 50), wxSize(200, 200));
245 frame
->SetIcon(wxIcon(_T("mondrian")));
248 wxMenu
*fileMenu
= new wxMenu
;
250 fileMenu
->Append(wxID_EXIT
, _T("E&xit"));
251 wxMenuBar
*menuBar
= new wxMenuBar
;
252 menuBar
->Append(fileMenu
, _T("&File"));
253 frame
->SetMenuBar(menuBar
);
255 // Make a TestGLCanvas
259 int *gl_attrib
= NULL
;
261 int gl_attrib
[20] = { WX_GL_RGBA
, WX_GL_MIN_RED
, 1, WX_GL_MIN_GREEN
, 1,
262 WX_GL_MIN_BLUE
, 1, WX_GL_DEPTH_SIZE
, 1,
273 printf("don't have double buffer, disabling\n");
277 doubleBuffer
= GL_FALSE
;
282 frame
->m_canvas
= new TestGLCanvas(frame
, -1, wxDefaultPosition
, wxDefaultSize
,
283 0, _T("TestGLCanvas"), gl_attrib
);
288 frame
->m_canvas
->SetCurrent();
289 read_surface( _T("isosurf.dat") );
297 wxMessageBox( _T("This sample has to be compiled with wxUSE_GLCANVAS"), _T("Building error"), wxOK
);
303 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
304 EVT_MENU(wxID_EXIT
, MyFrame::OnExit
)
307 // My frame constructor
308 MyFrame::MyFrame(wxFrame
*frame
, const wxString
& title
, const wxPoint
& pos
,
309 const wxSize
& size
, long style
):
310 wxFrame(frame
, -1, title
, pos
, size
, style
)
317 // Intercept menu commands
318 void MyFrame::OnExit(wxCommandEvent
& WXUNUSED(event
))
324 * TestGLCanvas implementation
329 BEGIN_EVENT_TABLE(TestGLCanvas
, wxGLCanvas
)
330 EVT_SIZE(TestGLCanvas::OnSize
)
331 EVT_PAINT(TestGLCanvas::OnPaint
)
332 EVT_CHAR(TestGLCanvas::OnChar
)
333 EVT_MOUSE_EVENTS(TestGLCanvas::OnMouseEvent
)
334 EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground
)
337 TestGLCanvas::TestGLCanvas(wxWindow
*parent
, wxWindowID id
,
338 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
, int* gl_attrib
):
339 wxGLCanvas(parent
, id
, pos
, size
, style
, name
, gl_attrib
)
344 /* Make sure server supports the vertex array extension */
345 char* extensions
= (char *) glGetString( GL_EXTENSIONS
);
346 if (!extensions
|| !strstr( extensions
, "GL_EXT_vertex_array" )) {
347 use_vertex_arrays
= GL_FALSE
;
352 TestGLCanvas::~TestGLCanvas(void)
356 void TestGLCanvas::OnPaint( wxPaintEvent
& WXUNUSED(event
) )
358 // This is a dummy, to avoid an endless succession of paint messages.
359 // OnPaint handlers must always create a wxPaintDC.
363 if (!GetContext()) return;
372 void TestGLCanvas::OnSize(wxSizeEvent
& event
)
374 // this is also necessary to update the context on some platforms
375 wxGLCanvas::OnSize(event
);
377 // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
379 GetClientSize(&w
, &h
);
385 glViewport(0, 0, (GLint
) w
, (GLint
) h
);
389 void TestGLCanvas::OnChar(wxKeyEvent
& event
)
391 switch(event
.GetKeyCode()) {
409 glShadeModel(GL_SMOOTH
);
411 glShadeModel(GL_FLAT
);
415 lighting
= !lighting
;
417 glEnable(GL_LIGHTING
);
419 glDisable(GL_LIGHTING
);
432 void TestGLCanvas::OnMouseEvent(wxMouseEvent
& event
)
434 static int dragging
= 0;
435 static float last_x
, last_y
;
437 //printf("%f %f %d\n", event.GetX(), event.GetY(), (int)event.LeftIsDown());
438 if(event
.LeftIsDown()) {
442 yrot
+= (event
.GetX() - last_x
)*1.0;
443 xrot
+= (event
.GetY() - last_y
)*1.0;
446 last_x
= event
.GetX();
447 last_y
= event
.GetY();
452 void TestGLCanvas::OnEraseBackground(wxEraseEvent
& WXUNUSED(event
))
454 // Do nothing, to avoid flashing.