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 #error Please set wxUSE_GLCANVAS to 1 in setup.h.
33 #include "wx/glcanvas.h"
37 # include <OpenGL/gl.h>
38 # include <OpenGL/glu.h>
48 // disabled because this has apparently changed in OpenGL 1.2, so doesn't link
49 // correctly if this is on...
50 #ifdef GL_EXT_vertex_array
51 #undef GL_EXT_vertex_array
56 // The following part is taken largely unchanged from the original C Version
60 GLboolean speed_test
= GL_FALSE
;
61 GLboolean use_vertex_arrays
= GL_FALSE
;
63 GLboolean doubleBuffer
= GL_TRUE
;
65 GLboolean smooth
= GL_TRUE
;
66 GLboolean lighting
= GL_TRUE
;
69 #define MAXVERTS 10000
71 static GLfloat verts
[MAXVERTS
][3];
72 static GLfloat norms
[MAXVERTS
][3];
73 static GLint numverts
;
79 static void read_surface( char *filename
)
83 f
= fopen(filename
,"r");
85 wxString
msg("Couldn't read ");
92 while (!feof(f
) && numverts
<MAXVERTS
) {
93 fscanf( f
, "%f %f %f %f %f %f",
94 &verts
[numverts
][0], &verts
[numverts
][1], &verts
[numverts
][2],
95 &norms
[numverts
][0], &norms
[numverts
][1], &norms
[numverts
][2] );
100 printf("%d vertices, %d triangles\n", numverts
, numverts
-2);
105 static void draw_surface( void )
109 #ifdef GL_EXT_vertex_array
110 if (use_vertex_arrays
) {
111 glDrawArraysEXT( GL_TRIANGLE_STRIP
, 0, numverts
);
115 glBegin( GL_TRIANGLE_STRIP
);
116 for (i
=0;i
<numverts
;i
++) {
117 glNormal3fv( norms
[i
] );
118 glVertex3fv( verts
[i
] );
121 #ifdef GL_EXT_vertex_array
127 static void draw1(void)
129 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
131 glRotatef( yrot
, 0.0, 1.0, 0.0 );
132 glRotatef( xrot
, 1.0, 0.0, 0.0 );
142 static void InitMaterials(void)
144 static float ambient
[] = {0.1, 0.1, 0.1, 1.0};
145 static float diffuse
[] = {0.5, 1.0, 1.0, 1.0};
146 static float position0
[] = {0.0, 0.0, 20.0, 0.0};
147 static float position1
[] = {0.0, 0.0, -20.0, 0.0};
148 static float front_mat_shininess
[] = {60.0};
149 static float front_mat_specular
[] = {0.2, 0.2, 0.2, 1.0};
150 static float front_mat_diffuse
[] = {0.5, 0.28, 0.38, 1.0};
152 static float back_mat_shininess[] = {60.0};
153 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
154 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
156 static float lmodel_ambient
[] = {1.0, 1.0, 1.0, 1.0};
157 static float lmodel_twoside
[] = {GL_FALSE
};
159 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
160 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
161 glLightfv(GL_LIGHT0
, GL_POSITION
, position0
);
164 glLightfv(GL_LIGHT1
, GL_AMBIENT
, ambient
);
165 glLightfv(GL_LIGHT1
, GL_DIFFUSE
, diffuse
);
166 glLightfv(GL_LIGHT1
, GL_POSITION
, position1
);
169 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
170 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
171 glEnable(GL_LIGHTING
);
173 glMaterialfv(GL_FRONT_AND_BACK
, GL_SHININESS
, front_mat_shininess
);
174 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, front_mat_specular
);
175 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, front_mat_diffuse
);
179 static void Init(void)
181 glClearColor(0.0, 0.0, 0.0, 0.0);
183 glShadeModel(GL_SMOOTH
);
184 glEnable(GL_DEPTH_TEST
);
188 glMatrixMode(GL_PROJECTION
);
190 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
192 glMatrixMode(GL_MODELVIEW
);
194 glTranslatef( 0.0, 0.0, -6.0 );
196 #ifdef GL_EXT_vertex_array
197 if (use_vertex_arrays
) {
198 glVertexPointerEXT( 3, GL_FLOAT
, 0, numverts
, verts
);
199 glNormalPointerEXT( GL_FLOAT
, 0, numverts
, norms
);
200 glEnable( GL_VERTEX_ARRAY_EXT
);
201 glEnable( GL_NORMAL_ARRAY_EXT
);
206 static GLenum
Args(int argc
, char **argv
)
210 for (i
= 1; i
< argc
; i
++) {
211 if (strcmp(argv
[i
], "-sb") == 0) {
212 doubleBuffer
= GL_FALSE
;
214 else if (strcmp(argv
[i
], "-db") == 0) {
215 doubleBuffer
= GL_TRUE
;
217 else if (strcmp(argv
[i
], "-speed") == 0) {
218 speed_test
= GL_TRUE
;
219 doubleBuffer
= GL_TRUE
;
221 else if (strcmp(argv
[i
], "-va") == 0) {
222 use_vertex_arrays
= GL_TRUE
;
225 wxString
msg("Bad option: ");
235 // The following part was written for wxWindows 1.66
236 MyFrame
*frame
= NULL
;
240 // `Main program' equivalent, creating windows and returning main app frame
241 bool MyApp::OnInit(void)
245 // Create the main frame window
246 frame
= new MyFrame(NULL
, "Isosurf GL Sample", wxPoint(50, 50), wxSize(200, 200));
249 frame
->SetIcon(wxIcon("mondrian"));
252 wxMenu
*fileMenu
= new wxMenu
;
254 fileMenu
->Append(wxID_EXIT
, "E&xit");
255 wxMenuBar
*menuBar
= new wxMenuBar
;
256 menuBar
->Append(fileMenu
, "&File");
257 frame
->SetMenuBar(menuBar
);
259 // Make a TestGLCanvas
263 int *gl_attrib
= NULL
;
265 int gl_attrib
[20] = { WX_GL_RGBA
, WX_GL_MIN_RED
, 1, WX_GL_MIN_GREEN
, 1,
266 WX_GL_MIN_BLUE
, 1, WX_GL_DEPTH_SIZE
, 1,
277 printf("don't have double buffer, disabling\n");
281 doubleBuffer
= GL_FALSE
;
284 frame
->m_canvas
= new TestGLCanvas(frame
, -1, wxDefaultPosition
, wxDefaultSize
,
285 0, "TestGLCanvas", gl_attrib
);
290 frame
->m_canvas
->SetCurrent();
291 read_surface( "isosurf.dat" );
298 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
299 EVT_MENU(wxID_EXIT
, MyFrame::OnExit
)
302 // My frame constructor
303 MyFrame::MyFrame(wxFrame
*frame
, const wxString
& title
, const wxPoint
& pos
,
304 const wxSize
& size
, long style
):
305 wxFrame(frame
, -1, title
, pos
, size
, style
)
310 // Intercept menu commands
311 void MyFrame::OnExit(wxCommandEvent
& event
)
317 * TestGLCanvas implementation
320 BEGIN_EVENT_TABLE(TestGLCanvas
, wxGLCanvas
)
321 EVT_SIZE(TestGLCanvas::OnSize
)
322 EVT_PAINT(TestGLCanvas::OnPaint
)
323 EVT_CHAR(TestGLCanvas::OnChar
)
324 EVT_MOUSE_EVENTS(TestGLCanvas::OnMouseEvent
)
325 EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground
)
328 TestGLCanvas::TestGLCanvas(wxWindow
*parent
, wxWindowID id
,
329 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
, int* gl_attrib
):
330 wxGLCanvas(parent
, id
, pos
, size
, style
, name
, gl_attrib
)
335 /* Make sure server supports the vertex array extension */
336 char* extensions
= (char *) glGetString( GL_EXTENSIONS
);
337 if (!extensions
|| !strstr( extensions
, "GL_EXT_vertex_array" )) {
338 use_vertex_arrays
= GL_FALSE
;
343 TestGLCanvas::~TestGLCanvas(void)
347 void TestGLCanvas::OnPaint( wxPaintEvent
& event
)
349 // This is a dummy, to avoid an endless succession of paint messages.
350 // OnPaint handlers must always create a wxPaintDC.
354 if (!GetContext()) return;
363 void TestGLCanvas::OnSize(wxSizeEvent
& event
)
365 // this is also necessary to update the context on some platforms
366 wxGLCanvas::OnSize(event
);
368 // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
370 GetClientSize(&w
, &h
);
376 glViewport(0, 0, (GLint
) w
, (GLint
) h
);
380 void TestGLCanvas::OnChar(wxKeyEvent
& event
)
382 switch(event
.KeyCode()) {
400 glShadeModel(GL_SMOOTH
);
402 glShadeModel(GL_FLAT
);
406 lighting
= !lighting
;
408 glEnable(GL_LIGHTING
);
410 glDisable(GL_LIGHTING
);
423 void TestGLCanvas::OnMouseEvent(wxMouseEvent
& event
)
425 static int dragging
= 0;
426 static float last_x
, last_y
;
428 //printf("%f %f %d\n", event.GetX(), event.GetY(), (int)event.LeftIsDown());
429 if(event
.LeftIsDown()) {
433 yrot
+= (event
.GetX() - last_x
)*1.0;
434 xrot
+= (event
.GetY() - last_y
)*1.0;
437 last_x
= event
.GetX();
438 last_y
= event
.GetY();
443 void TestGLCanvas::OnEraseBackground(wxEraseEvent
& event
)
445 // Do nothing, to avoid flashing.