]> git.saurik.com Git - wxWidgets.git/blame - samples/opengl/isosurf/isosurf.cpp
no real changes, moved Robin's changes to bakefile and regenerated using bakefile...
[wxWidgets.git] / samples / opengl / isosurf / isosurf.cpp
CommitLineData
8b089c5e
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: isosurf.cpp
3// Purpose: wxGLCanvas demo program
4// Author: Brian Paul (original gltk version), Wolfram Gloger
5// Modified by: Julian Smart
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
2f6c54eb 9// Licence: wxWindows licence
8b089c5e
JS
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation
14#pragma interface
15#endif
16
17// For compilers that support precompilation, includes "wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21#pragma hdrstop
22#endif
23
24#ifndef WX_PRECOMP
25#include "wx/wx.h"
26#endif
27
28#include "wx/timer.h"
29#include "wx/glcanvas.h"
30
cb712074
GD
31#ifdef __WXMAC__
32# ifdef __DARWIN__
33# include <OpenGL/gl.h>
34# include <OpenGL/glu.h>
35# else
36# include <gl.h>
37# include <glu.h>
38# endif
39#else
40# include <GL/gl.h>
41# include <GL/glu.h>
42#endif
8b089c5e 43
9d705dfa
GD
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
48#endif
49
8b089c5e
JS
50#include "isosurf.h"
51
52// The following part is taken largely unchanged from the original C Version
53
54#include <math.h>
55
56GLboolean speed_test = GL_FALSE;
57GLboolean use_vertex_arrays = GL_FALSE;
58
59GLboolean doubleBuffer = GL_TRUE;
60
61GLboolean smooth = GL_TRUE;
62GLboolean lighting = GL_TRUE;
63
64
65#define MAXVERTS 10000
66
67static GLfloat verts[MAXVERTS][3];
68static GLfloat norms[MAXVERTS][3];
69static GLint numverts;
70
71static GLfloat xrot;
72static GLfloat yrot;
73
74
2db98bf5 75static void read_surface( wxChar *filename )
8b089c5e
JS
76{
77 FILE *f;
78
2db98bf5 79 f = wxFopen(filename,_T("r"));
8b089c5e 80 if (!f) {
2db98bf5 81 wxString msg(_T("Couldn't read "));
8b089c5e
JS
82 msg += filename;
83 wxMessageBox(msg);
84 return;
85 }
86
87 numverts = 0;
88 while (!feof(f) && numverts<MAXVERTS) {
89 fscanf( f, "%f %f %f %f %f %f",
2f6c54eb
VZ
90 &verts[numverts][0], &verts[numverts][1], &verts[numverts][2],
91 &norms[numverts][0], &norms[numverts][1], &norms[numverts][2] );
8b089c5e
JS
92 numverts++;
93 }
94 numverts--;
95
2db98bf5 96 wxPrintf(_T("%d vertices, %d triangles\n"), numverts, numverts-2);
8b089c5e
JS
97 fclose(f);
98}
99
100
101static void draw_surface( void )
102{
103 GLint i;
104
105#ifdef GL_EXT_vertex_array
106 if (use_vertex_arrays) {
107 glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
108 }
109 else {
110#endif
111 glBegin( GL_TRIANGLE_STRIP );
112 for (i=0;i<numverts;i++) {
113 glNormal3fv( norms[i] );
114 glVertex3fv( verts[i] );
115 }
116 glEnd();
117#ifdef GL_EXT_vertex_array
118 }
119#endif
120}
121
122
123static void draw1(void)
124{
125 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
126 glPushMatrix();
127 glRotatef( yrot, 0.0, 1.0, 0.0 );
128 glRotatef( xrot, 1.0, 0.0, 0.0 );
129
130 draw_surface();
131
132 glPopMatrix();
133
134 glFlush();
135}
136
137
138static void InitMaterials(void)
139{
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};
147 /*
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};
151 */
152 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
153 static float lmodel_twoside[] = {GL_FALSE};
154
155 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
156 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
157 glLightfv(GL_LIGHT0, GL_POSITION, position0);
158 glEnable(GL_LIGHT0);
159
160 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
161 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
162 glLightfv(GL_LIGHT1, GL_POSITION, position1);
163 glEnable(GL_LIGHT1);
164
165 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
166 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
167 glEnable(GL_LIGHTING);
168
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);
172}
173
174
175static void Init(void)
176{
177 glClearColor(0.0, 0.0, 0.0, 0.0);
178
179 glShadeModel(GL_SMOOTH);
180 glEnable(GL_DEPTH_TEST);
181
182 InitMaterials();
183
184 glMatrixMode(GL_PROJECTION);
185 glLoadIdentity();
186 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
187
188 glMatrixMode(GL_MODELVIEW);
189 glLoadIdentity();
190 glTranslatef( 0.0, 0.0, -6.0 );
191
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 );
198 }
199#endif
200}
201
2db98bf5 202static GLenum Args(int argc, wxChar **argv)
8b089c5e
JS
203{
204 GLint i;
205
206 for (i = 1; i < argc; i++) {
2db98bf5 207 if (wxStrcmp(argv[i], _T("-sb")) == 0) {
8b089c5e
JS
208 doubleBuffer = GL_FALSE;
209 }
2db98bf5 210 else if (wxStrcmp(argv[i], _T("-db")) == 0) {
8b089c5e
JS
211 doubleBuffer = GL_TRUE;
212 }
2db98bf5 213 else if (wxStrcmp(argv[i], _T("-speed")) == 0) {
8b089c5e
JS
214 speed_test = GL_TRUE;
215 doubleBuffer = GL_TRUE;
216 }
2db98bf5 217 else if (wxStrcmp(argv[i], _T("-va")) == 0) {
8b089c5e
JS
218 use_vertex_arrays = GL_TRUE;
219 }
220 else {
2db98bf5 221 wxString msg(_T("Bad option: "));
8b089c5e
JS
222 msg += argv[i];
223 wxMessageBox(msg);
224 return GL_FALSE;
225 }
226 }
227
228 return GL_TRUE;
229}
230
231// The following part was written for wxWindows 1.66
232MyFrame *frame = NULL;
233
234IMPLEMENT_APP(MyApp)
235
236// `Main program' equivalent, creating windows and returning main app frame
237bool MyApp::OnInit(void)
238{
239 Args(argc, argv);
240
241 // Create the main frame window
2db98bf5 242 frame = new MyFrame(NULL, _T("Isosurf GL Sample"), wxPoint(50, 50), wxSize(200, 200));
8b089c5e
JS
243
244 // Give it an icon
2db98bf5 245 frame->SetIcon(wxIcon(_T("mondrian")));
8b089c5e
JS
246
247 // Make a menubar
248 wxMenu *fileMenu = new wxMenu;
249
2db98bf5 250 fileMenu->Append(wxID_EXIT, _T("E&xit"));
8b089c5e 251 wxMenuBar *menuBar = new wxMenuBar;
2db98bf5 252 menuBar->Append(fileMenu, _T("&File"));
8b089c5e
JS
253 frame->SetMenuBar(menuBar);
254
255 // Make a TestGLCanvas
256
257 // JACS
258#ifdef __WXMSW__
259 int *gl_attrib = NULL;
260#else
919ae91a 261 int gl_attrib[20] = { WX_GL_RGBA, WX_GL_MIN_RED, 1, WX_GL_MIN_GREEN, 1,
2f6c54eb
VZ
262 WX_GL_MIN_BLUE, 1, WX_GL_DEPTH_SIZE, 1,
263 WX_GL_DOUBLEBUFFER,
cb712074 264# ifdef __WXMAC__
2f6c54eb 265 GL_NONE };
cb712074 266# else
2f6c54eb 267 None };
cb712074 268# endif
8b089c5e
JS
269#endif
270
271 if(!doubleBuffer)
272 {
273 printf("don't have double buffer, disabling\n");
274#ifdef __WXGTK__
275 gl_attrib[9] = None;
276#endif
277 doubleBuffer = GL_FALSE;
278 }
919ae91a 279
2db98bf5
JS
280#if wxUSE_GLCANVAS
281
9d705dfa 282 frame->m_canvas = new TestGLCanvas(frame, -1, wxDefaultPosition, wxDefaultSize,
2db98bf5 283 0, _T("TestGLCanvas"), gl_attrib );
8b089c5e
JS
284
285 // Show the frame
286 frame->Show(TRUE);
287
288 frame->m_canvas->SetCurrent();
2db98bf5 289 read_surface( _T("isosurf.dat") );
8b089c5e
JS
290
291 Init();
292
293 return TRUE;
2db98bf5
JS
294
295#else
296
297 wxMessageBox( _T("This sample has to be compiled with wxUSE_GLCANVAS"), _T("Building error"), wxOK);
298
299 return FALSE;
300#endif
8b089c5e
JS
301}
302
303BEGIN_EVENT_TABLE(MyFrame, wxFrame)
304 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
305END_EVENT_TABLE()
306
307// My frame constructor
308MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
309 const wxSize& size, long style):
310 wxFrame(frame, -1, title, pos, size, style)
311{
2db98bf5 312#if wxUSE_GLCANVAS
8b089c5e 313 m_canvas = NULL;
2db98bf5 314#endif
8b089c5e
JS
315}
316
317// Intercept menu commands
2db98bf5 318void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
8b089c5e
JS
319{
320 Destroy();
321}
322
323/*
324 * TestGLCanvas implementation
325 */
326
2db98bf5
JS
327#if wxUSE_GLCANVAS
328
8b089c5e
JS
329BEGIN_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)
335END_EVENT_TABLE()
336
337TestGLCanvas::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)
340{
341 parent->Show(TRUE);
342 SetCurrent();
919ae91a 343
8b089c5e
JS
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;
348 }
349}
350
351
352TestGLCanvas::~TestGLCanvas(void)
353{
354}
355
2db98bf5 356void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
8b089c5e
JS
357{
358 // This is a dummy, to avoid an endless succession of paint messages.
359 // OnPaint handlers must always create a wxPaintDC.
360 wxPaintDC dc(this);
361
c661ecca
RR
362#ifndef __WXMOTIF__
363 if (!GetContext()) return;
364#endif
365
919ae91a
UN
366 SetCurrent();
367
8b089c5e
JS
368 draw1();
369 SwapBuffers();
370}
371
372void TestGLCanvas::OnSize(wxSizeEvent& event)
373{
9d705dfa
GD
374 // this is also necessary to update the context on some platforms
375 wxGLCanvas::OnSize(event);
376
377 // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
2f6c54eb
VZ
378 int w, h;
379 GetClientSize(&w, &h);
c661ecca 380#ifndef __WXMOTIF__
9d705dfa 381 if (GetContext())
c661ecca 382#endif
9d705dfa 383 {
2f6c54eb 384 SetCurrent();
9d705dfa
GD
385 glViewport(0, 0, (GLint) w, (GLint) h);
386 }
8b089c5e
JS
387}
388
389void TestGLCanvas::OnChar(wxKeyEvent& event)
390{
b1d4dd7a 391 switch(event.GetKeyCode()) {
8b089c5e 392 case WXK_ESCAPE:
2f6c54eb 393 exit(0);
8b089c5e 394 case WXK_LEFT:
2f6c54eb
VZ
395 yrot -= 15.0;
396 break;
8b089c5e 397 case WXK_RIGHT:
2f6c54eb
VZ
398 yrot += 15.0;
399 break;
8b089c5e 400 case WXK_UP:
2f6c54eb
VZ
401 xrot += 15.0;
402 break;
8b089c5e 403 case WXK_DOWN:
2f6c54eb
VZ
404 xrot -= 15.0;
405 break;
8b089c5e 406 case 's': case 'S':
2f6c54eb
VZ
407 smooth = !smooth;
408 if (smooth) {
409 glShadeModel(GL_SMOOTH);
410 } else {
411 glShadeModel(GL_FLAT);
412 }
413 break;
8b089c5e 414 case 'l': case 'L':
2f6c54eb
VZ
415 lighting = !lighting;
416 if (lighting) {
417 glEnable(GL_LIGHTING);
418 } else {
419 glDisable(GL_LIGHTING);
420 }
421 break;
8b089c5e
JS
422 default:
423 {
424 event.Skip();
2f6c54eb 425 return;
8b089c5e
JS
426 }
427 }
428
429 Refresh(FALSE);
430}
431
432void TestGLCanvas::OnMouseEvent(wxMouseEvent& event)
433{
434 static int dragging = 0;
435 static float last_x, last_y;
436
437 //printf("%f %f %d\n", event.GetX(), event.GetY(), (int)event.LeftIsDown());
438 if(event.LeftIsDown()) {
2f6c54eb
VZ
439 if(!dragging) {
440 dragging = 1;
441 } else {
442 yrot += (event.GetX() - last_x)*1.0;
443 xrot += (event.GetY() - last_y)*1.0;
444 Refresh(FALSE);
445 }
446 last_x = event.GetX();
447 last_y = event.GetY();
8b089c5e 448 } else
2f6c54eb 449 dragging = 0;
8b089c5e
JS
450}
451
2db98bf5 452void TestGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
8b089c5e
JS
453{
454 // Do nothing, to avoid flashing.
455}
456
2db98bf5 457#endif