]> git.saurik.com Git - wxWidgets.git/blame - samples/opengl/isosurf/isosurf.cpp
added container class source
[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
9// Licence: wxWindows licence
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
5fa399c9
JS
28#if !wxUSE_GLCANVAS
29#error Please set wxUSE_GLCANVAS to 1 in setup.h.
30#endif
31
8b089c5e
JS
32#include "wx/timer.h"
33#include "wx/glcanvas.h"
34
cb712074
GD
35#ifdef __WXMAC__
36# ifdef __DARWIN__
37# include <OpenGL/gl.h>
38# include <OpenGL/glu.h>
39# else
40# include <gl.h>
41# include <glu.h>
42# endif
43#else
44# include <GL/gl.h>
45# include <GL/glu.h>
46#endif
8b089c5e
JS
47
48#include "isosurf.h"
49
50// The following part is taken largely unchanged from the original C Version
51
52#include <math.h>
53
54GLboolean speed_test = GL_FALSE;
55GLboolean use_vertex_arrays = GL_FALSE;
56
57GLboolean doubleBuffer = GL_TRUE;
58
59GLboolean smooth = GL_TRUE;
60GLboolean lighting = GL_TRUE;
61
62
63#define MAXVERTS 10000
64
65static GLfloat verts[MAXVERTS][3];
66static GLfloat norms[MAXVERTS][3];
67static GLint numverts;
68
69static GLfloat xrot;
70static GLfloat yrot;
71
72
73static void read_surface( char *filename )
74{
75 FILE *f;
76
77 f = fopen(filename,"r");
78 if (!f) {
79 wxString msg("Couldn't read ");
80 msg += filename;
81 wxMessageBox(msg);
82 return;
83 }
84
85 numverts = 0;
86 while (!feof(f) && numverts<MAXVERTS) {
87 fscanf( f, "%f %f %f %f %f %f",
88 &verts[numverts][0], &verts[numverts][1], &verts[numverts][2],
89 &norms[numverts][0], &norms[numverts][1], &norms[numverts][2] );
90 numverts++;
91 }
92 numverts--;
93
94 printf("%d vertices, %d triangles\n", numverts, numverts-2);
95 fclose(f);
96}
97
98
99static void draw_surface( void )
100{
101 GLint i;
102
103#ifdef GL_EXT_vertex_array
104 if (use_vertex_arrays) {
105 glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
106 }
107 else {
108#endif
109 glBegin( GL_TRIANGLE_STRIP );
110 for (i=0;i<numverts;i++) {
111 glNormal3fv( norms[i] );
112 glVertex3fv( verts[i] );
113 }
114 glEnd();
115#ifdef GL_EXT_vertex_array
116 }
117#endif
118}
119
120
121static void draw1(void)
122{
123 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
124 glPushMatrix();
125 glRotatef( yrot, 0.0, 1.0, 0.0 );
126 glRotatef( xrot, 1.0, 0.0, 0.0 );
127
128 draw_surface();
129
130 glPopMatrix();
131
132 glFlush();
133}
134
135
136static void InitMaterials(void)
137{
138 static float ambient[] = {0.1, 0.1, 0.1, 1.0};
139 static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
140 static float position0[] = {0.0, 0.0, 20.0, 0.0};
141 static float position1[] = {0.0, 0.0, -20.0, 0.0};
142 static float front_mat_shininess[] = {60.0};
143 static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
144 static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
145 /*
146 static float back_mat_shininess[] = {60.0};
147 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
148 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
149 */
150 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
151 static float lmodel_twoside[] = {GL_FALSE};
152
153 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
154 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
155 glLightfv(GL_LIGHT0, GL_POSITION, position0);
156 glEnable(GL_LIGHT0);
157
158 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
159 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
160 glLightfv(GL_LIGHT1, GL_POSITION, position1);
161 glEnable(GL_LIGHT1);
162
163 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
164 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
165 glEnable(GL_LIGHTING);
166
167 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
168 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
169 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
170}
171
172
173static void Init(void)
174{
175 glClearColor(0.0, 0.0, 0.0, 0.0);
176
177 glShadeModel(GL_SMOOTH);
178 glEnable(GL_DEPTH_TEST);
179
180 InitMaterials();
181
182 glMatrixMode(GL_PROJECTION);
183 glLoadIdentity();
184 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
185
186 glMatrixMode(GL_MODELVIEW);
187 glLoadIdentity();
188 glTranslatef( 0.0, 0.0, -6.0 );
189
190#ifdef GL_EXT_vertex_array
191 if (use_vertex_arrays) {
192 glVertexPointerEXT( 3, GL_FLOAT, 0, numverts, verts );
193 glNormalPointerEXT( GL_FLOAT, 0, numverts, norms );
194 glEnable( GL_VERTEX_ARRAY_EXT );
195 glEnable( GL_NORMAL_ARRAY_EXT );
196 }
197#endif
198}
199
200
201static void Reshape(int width, int height)
202{
203 glViewport(0, 0, (GLint)width, (GLint)height);
204}
205
206
207static GLenum Args(int argc, char **argv)
208{
209 GLint i;
210
211 for (i = 1; i < argc; i++) {
212 if (strcmp(argv[i], "-sb") == 0) {
213 doubleBuffer = GL_FALSE;
214 }
215 else if (strcmp(argv[i], "-db") == 0) {
216 doubleBuffer = GL_TRUE;
217 }
218 else if (strcmp(argv[i], "-speed") == 0) {
219 speed_test = GL_TRUE;
220 doubleBuffer = GL_TRUE;
221 }
222 else if (strcmp(argv[i], "-va") == 0) {
223 use_vertex_arrays = GL_TRUE;
224 }
225 else {
226 wxString msg("Bad option: ");
227 msg += argv[i];
228 wxMessageBox(msg);
229 return GL_FALSE;
230 }
231 }
232
233 return GL_TRUE;
234}
235
236// The following part was written for wxWindows 1.66
237MyFrame *frame = NULL;
238
239IMPLEMENT_APP(MyApp)
240
241// `Main program' equivalent, creating windows and returning main app frame
242bool MyApp::OnInit(void)
243{
244 Args(argc, argv);
245
246 // Create the main frame window
247 frame = new MyFrame(NULL, "Isosurf GL Sample", wxPoint(50, 50), wxSize(200, 200));
248
249 // Give it an icon
250 frame->SetIcon(wxIcon("mondrian"));
251
252 // Make a menubar
253 wxMenu *fileMenu = new wxMenu;
254
255 fileMenu->Append(wxID_EXIT, "E&xit");
256 wxMenuBar *menuBar = new wxMenuBar;
257 menuBar->Append(fileMenu, "&File");
258 frame->SetMenuBar(menuBar);
259
260 // Make a TestGLCanvas
261
262 // JACS
263#ifdef __WXMSW__
264 int *gl_attrib = NULL;
265#else
919ae91a
UN
266 int gl_attrib[20] = { WX_GL_RGBA, WX_GL_MIN_RED, 1, WX_GL_MIN_GREEN, 1,
267 WX_GL_MIN_BLUE, 1, WX_GL_DEPTH_SIZE, 1,
cb712074
GD
268 WX_GL_DOUBLEBUFFER,
269# ifdef __WXMAC__
270 GL_NONE };
271# else
272 None };
273# endif
8b089c5e
JS
274#endif
275
276 if(!doubleBuffer)
277 {
278 printf("don't have double buffer, disabling\n");
279#ifdef __WXGTK__
280 gl_attrib[9] = None;
281#endif
282 doubleBuffer = GL_FALSE;
283 }
919ae91a
UN
284
285 frame->m_canvas = new TestGLCanvas(frame, -1, wxPoint(0, 0), wxSize(200, 200),
286 0, "TestGLCanvas", gl_attrib );
8b089c5e
JS
287
288 // Show the frame
289 frame->Show(TRUE);
290
291 frame->m_canvas->SetCurrent();
292 read_surface( "isosurf.dat" );
293
294 Init();
295
296 return TRUE;
297}
298
299BEGIN_EVENT_TABLE(MyFrame, wxFrame)
300 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
301END_EVENT_TABLE()
302
303// My frame constructor
304MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
305 const wxSize& size, long style):
306 wxFrame(frame, -1, title, pos, size, style)
307{
308 m_canvas = NULL;
309}
310
311// Intercept menu commands
312void MyFrame::OnExit(wxCommandEvent& event)
313{
314 Destroy();
315}
316
317/*
318 * TestGLCanvas implementation
319 */
320
321BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
322 EVT_SIZE(TestGLCanvas::OnSize)
323 EVT_PAINT(TestGLCanvas::OnPaint)
324 EVT_CHAR(TestGLCanvas::OnChar)
325 EVT_MOUSE_EVENTS(TestGLCanvas::OnMouseEvent)
326 EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground)
327END_EVENT_TABLE()
328
329TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id,
330 const wxPoint& pos, const wxSize& size, long style, const wxString& name, int* gl_attrib):
331 wxGLCanvas(parent, id, pos, size, style, name, gl_attrib)
332{
333 parent->Show(TRUE);
334 SetCurrent();
919ae91a 335
8b089c5e
JS
336 /* Make sure server supports the vertex array extension */
337 char* extensions = (char *) glGetString( GL_EXTENSIONS );
338 if (!extensions || !strstr( extensions, "GL_EXT_vertex_array" )) {
339 use_vertex_arrays = GL_FALSE;
340 }
341}
342
343
344TestGLCanvas::~TestGLCanvas(void)
345{
346}
347
348void TestGLCanvas::OnPaint( wxPaintEvent& event )
349{
350 // This is a dummy, to avoid an endless succession of paint messages.
351 // OnPaint handlers must always create a wxPaintDC.
352 wxPaintDC dc(this);
353
c661ecca
RR
354#ifndef __WXMOTIF__
355 if (!GetContext()) return;
356#endif
357
919ae91a
UN
358 SetCurrent();
359
8b089c5e
JS
360 draw1();
361 SwapBuffers();
362}
363
364void TestGLCanvas::OnSize(wxSizeEvent& event)
365{
c661ecca
RR
366#ifndef __WXMOTIF__
367 if (!GetContext()) return;
368#endif
369
8b089c5e
JS
370 SetCurrent();
371 int width, height;
372 GetClientSize(& width, & height);
373 Reshape(width, height);
374}
375
376void TestGLCanvas::OnChar(wxKeyEvent& event)
377{
378 switch(event.KeyCode()) {
379 case WXK_ESCAPE:
380 exit(0);
381 case WXK_LEFT:
382 yrot -= 15.0;
383 break;
384 case WXK_RIGHT:
385 yrot += 15.0;
386 break;
387 case WXK_UP:
388 xrot += 15.0;
389 break;
390 case WXK_DOWN:
391 xrot -= 15.0;
392 break;
393 case 's': case 'S':
394 smooth = !smooth;
395 if (smooth) {
396 glShadeModel(GL_SMOOTH);
397 } else {
398 glShadeModel(GL_FLAT);
399 }
400 break;
401 case 'l': case 'L':
402 lighting = !lighting;
403 if (lighting) {
404 glEnable(GL_LIGHTING);
405 } else {
406 glDisable(GL_LIGHTING);
407 }
408 break;
409 default:
410 {
411 event.Skip();
412 return;
413 }
414 }
415
416 Refresh(FALSE);
417}
418
419void TestGLCanvas::OnMouseEvent(wxMouseEvent& event)
420{
421 static int dragging = 0;
422 static float last_x, last_y;
423
424 //printf("%f %f %d\n", event.GetX(), event.GetY(), (int)event.LeftIsDown());
425 if(event.LeftIsDown()) {
426 if(!dragging) {
427 dragging = 1;
428 } else {
429 yrot += (event.GetX() - last_x)*1.0;
430 xrot += (event.GetY() - last_y)*1.0;
431 Refresh(FALSE);
432 }
433 last_x = event.GetX();
434 last_y = event.GetY();
435 } else
436 dragging = 0;
437}
438
439void TestGLCanvas::OnEraseBackground(wxEraseEvent& event)
440{
441 // Do nothing, to avoid flashing.
442}
443