home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / samples / opengl / isosurf / isosurf.cpp next >
C/C++ Source or Header  |  2002-03-17  |  11KB  |  448 lines

  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: isosurf.cpp,v 1.7 2002/03/17 14:15:53 VZ Exp $
  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.  
  28. #if !wxUSE_GLCANVAS
  29. #error Please set wxUSE_GLCANVAS to 1 in setup.h.
  30. #endif
  31.  
  32. #include "wx/timer.h"
  33. #include "wx/glcanvas.h"
  34.  
  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
  47.  
  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
  52. #endif
  53.  
  54. #include "isosurf.h"
  55.  
  56. // The following part is taken largely unchanged from the original C Version
  57.  
  58. #include <math.h>
  59.  
  60. GLboolean speed_test = GL_FALSE;
  61. GLboolean use_vertex_arrays = GL_FALSE;
  62.  
  63. GLboolean doubleBuffer = GL_TRUE;
  64.  
  65. GLboolean smooth = GL_TRUE;
  66. GLboolean lighting = GL_TRUE;
  67.  
  68.  
  69. #define MAXVERTS 10000
  70.  
  71. static GLfloat verts[MAXVERTS][3];
  72. static GLfloat norms[MAXVERTS][3];
  73. static GLint numverts;
  74.  
  75. static GLfloat xrot;
  76. static GLfloat yrot;
  77.  
  78.  
  79. static void read_surface( char *filename )
  80. {
  81.    FILE *f;
  82.  
  83.    f = fopen(filename,"r");
  84.    if (!f) {
  85.       wxString msg("Couldn't read ");
  86.       msg += filename;
  87.       wxMessageBox(msg);
  88.       return;
  89.    }
  90.  
  91.    numverts = 0;
  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] );
  96.       numverts++;
  97.    }
  98.    numverts--;
  99.  
  100.    printf("%d vertices, %d triangles\n", numverts, numverts-2);
  101.    fclose(f);
  102. }
  103.  
  104.  
  105. static void draw_surface( void )
  106. {
  107.    GLint i;
  108.  
  109. #ifdef GL_EXT_vertex_array
  110.    if (use_vertex_arrays) {
  111.       glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
  112.    }
  113.    else {
  114. #endif
  115.       glBegin( GL_TRIANGLE_STRIP );
  116.       for (i=0;i<numverts;i++) {
  117.          glNormal3fv( norms[i] );
  118.          glVertex3fv( verts[i] );
  119.       }
  120.       glEnd();
  121. #ifdef GL_EXT_vertex_array
  122.    }
  123. #endif
  124. }
  125.  
  126.  
  127. static void draw1(void)
  128. {
  129.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  130.     glPushMatrix();
  131.     glRotatef( yrot, 0.0, 1.0, 0.0 );
  132.     glRotatef( xrot, 1.0, 0.0, 0.0 );
  133.  
  134.     draw_surface();
  135.  
  136.     glPopMatrix();
  137.  
  138.     glFlush();
  139. }
  140.  
  141.  
  142. static void InitMaterials(void)
  143. {
  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};
  151.     /*
  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};
  155.     */
  156.     static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
  157.     static float lmodel_twoside[] = {GL_FALSE};
  158.  
  159.     glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  160.     glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  161.     glLightfv(GL_LIGHT0, GL_POSITION, position0);
  162.     glEnable(GL_LIGHT0);
  163.     
  164.     glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
  165.     glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
  166.     glLightfv(GL_LIGHT1, GL_POSITION, position1);
  167.     glEnable(GL_LIGHT1);
  168.     
  169.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  170.     glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  171.     glEnable(GL_LIGHTING);
  172.  
  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);
  176. }
  177.  
  178.  
  179. static void Init(void)
  180. {
  181.    glClearColor(0.0, 0.0, 0.0, 0.0);
  182.  
  183.    glShadeModel(GL_SMOOTH);
  184.    glEnable(GL_DEPTH_TEST);
  185.  
  186.    InitMaterials();
  187.  
  188.    glMatrixMode(GL_PROJECTION);
  189.    glLoadIdentity();
  190.    glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
  191.  
  192.    glMatrixMode(GL_MODELVIEW);
  193.    glLoadIdentity();
  194.    glTranslatef( 0.0, 0.0, -6.0 );
  195.  
  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 );
  202.    }
  203. #endif
  204. }
  205.  
  206. static GLenum Args(int argc, char **argv)
  207. {
  208.    GLint i;
  209.  
  210.    for (i = 1; i < argc; i++) {
  211.       if (strcmp(argv[i], "-sb") == 0) {
  212.          doubleBuffer = GL_FALSE;
  213.       }
  214.       else if (strcmp(argv[i], "-db") == 0) {
  215.          doubleBuffer = GL_TRUE;
  216.       }
  217.       else if (strcmp(argv[i], "-speed") == 0) {
  218.          speed_test = GL_TRUE;
  219.          doubleBuffer = GL_TRUE;
  220.       }
  221.       else if (strcmp(argv[i], "-va") == 0) {
  222.          use_vertex_arrays = GL_TRUE;
  223.       }
  224.       else {
  225.          wxString msg("Bad option: ");
  226.          msg += argv[i];
  227.          wxMessageBox(msg);
  228.          return GL_FALSE;
  229.       }
  230.    }
  231.  
  232.    return GL_TRUE;
  233. }
  234.  
  235. // The following part was written for wxWindows 1.66
  236. MyFrame *frame = NULL;
  237.  
  238. IMPLEMENT_APP(MyApp)
  239.  
  240. // `Main program' equivalent, creating windows and returning main app frame
  241. bool MyApp::OnInit(void)
  242. {
  243.   Args(argc, argv);
  244.  
  245.   // Create the main frame window
  246.   frame = new MyFrame(NULL, "Isosurf GL Sample", wxPoint(50, 50), wxSize(200, 200));
  247.  
  248.   // Give it an icon
  249.   frame->SetIcon(wxIcon("mondrian"));
  250.  
  251.   // Make a menubar
  252.   wxMenu *fileMenu = new wxMenu;
  253.  
  254.   fileMenu->Append(wxID_EXIT, "E&xit");
  255.   wxMenuBar *menuBar = new wxMenuBar;
  256.   menuBar->Append(fileMenu, "&File");
  257.   frame->SetMenuBar(menuBar);
  258.  
  259.   // Make a TestGLCanvas
  260.  
  261.   // JACS
  262. #ifdef __WXMSW__
  263.   int *gl_attrib = NULL;
  264. #else
  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,
  267.             WX_GL_DOUBLEBUFFER,
  268. #  ifdef __WXMAC__
  269.             GL_NONE };
  270. #  else
  271.             None };
  272. #  endif
  273. #endif
  274.  
  275.   if(!doubleBuffer)
  276.    {
  277.       printf("don't have double buffer, disabling\n");
  278. #ifdef __WXGTK__
  279.       gl_attrib[9] = None;
  280. #endif
  281.       doubleBuffer = GL_FALSE;
  282.   }
  283.  
  284.   frame->m_canvas = new TestGLCanvas(frame, -1, wxDefaultPosition, wxDefaultSize,
  285.                                      0, "TestGLCanvas", gl_attrib );
  286.  
  287.   // Show the frame
  288.   frame->Show(TRUE);
  289.  
  290.   frame->m_canvas->SetCurrent();
  291.   read_surface( "isosurf.dat" );
  292.  
  293.   Init();
  294.  
  295.   return TRUE;
  296. }
  297.  
  298. BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  299.     EVT_MENU(wxID_EXIT, MyFrame::OnExit)
  300. END_EVENT_TABLE()
  301.  
  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)
  306. {
  307.     m_canvas = NULL;
  308. }
  309.  
  310. // Intercept menu commands
  311. void MyFrame::OnExit(wxCommandEvent& event)
  312. {
  313.     Destroy();
  314. }
  315.  
  316. /*
  317.  * TestGLCanvas implementation
  318.  */
  319.  
  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)
  326. END_EVENT_TABLE()
  327.  
  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)
  331. {
  332.    parent->Show(TRUE);
  333.    SetCurrent();
  334.  
  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;
  339.    }
  340. }
  341.  
  342.  
  343. TestGLCanvas::~TestGLCanvas(void)
  344. {
  345. }
  346.  
  347. void TestGLCanvas::OnPaint( wxPaintEvent& event )
  348. {
  349.     // This is a dummy, to avoid an endless succession of paint messages.
  350.     // OnPaint handlers must always create a wxPaintDC.
  351.     wxPaintDC dc(this);
  352.  
  353. #ifndef __WXMOTIF__
  354.     if (!GetContext()) return;
  355. #endif
  356.  
  357.     SetCurrent();
  358.  
  359.     draw1();
  360.     SwapBuffers();
  361. }
  362.  
  363. void TestGLCanvas::OnSize(wxSizeEvent& event)
  364. {
  365.     // this is also necessary to update the context on some platforms
  366.     wxGLCanvas::OnSize(event);
  367.     
  368.     // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
  369.     int w, h;
  370.     GetClientSize(&w, &h);
  371. #ifndef __WXMOTIF__
  372.     if (GetContext())
  373. #endif
  374.     {
  375.         SetCurrent();
  376.         glViewport(0, 0, (GLint) w, (GLint) h);
  377.     }
  378. }
  379.  
  380. void TestGLCanvas::OnChar(wxKeyEvent& event)
  381. {
  382.     switch(event.KeyCode()) {
  383.     case WXK_ESCAPE:
  384.     exit(0);
  385.     case WXK_LEFT:
  386.     yrot -= 15.0;
  387.     break;
  388.     case WXK_RIGHT:
  389.     yrot += 15.0;
  390.     break;
  391.     case WXK_UP:
  392.     xrot += 15.0;
  393.     break;
  394.     case WXK_DOWN:
  395.     xrot -= 15.0;
  396.     break;
  397.     case 's': case 'S':
  398.     smooth = !smooth;
  399.     if (smooth) {
  400.         glShadeModel(GL_SMOOTH);
  401.     } else {
  402.         glShadeModel(GL_FLAT);
  403.     }
  404.     break;
  405.     case 'l': case 'L':
  406.     lighting = !lighting;
  407.     if (lighting) {
  408.         glEnable(GL_LIGHTING);
  409.     } else {
  410.         glDisable(GL_LIGHTING);
  411.     }
  412.     break;
  413.      default:
  414.       {
  415.         event.Skip();
  416.     return;
  417.       }
  418.     }
  419.  
  420.     Refresh(FALSE);
  421. }
  422.  
  423. void TestGLCanvas::OnMouseEvent(wxMouseEvent& event)
  424. {
  425.     static int dragging = 0;
  426.     static float last_x, last_y;
  427.  
  428.     //printf("%f %f %d\n", event.GetX(), event.GetY(), (int)event.LeftIsDown());
  429.     if(event.LeftIsDown()) {
  430.     if(!dragging) {
  431.         dragging = 1;
  432.     } else {
  433.         yrot += (event.GetX() - last_x)*1.0;
  434.         xrot += (event.GetY() - last_y)*1.0;
  435.         Refresh(FALSE);
  436.     }
  437.     last_x = event.GetX();
  438.     last_y = event.GetY();
  439.     } else
  440.     dragging = 0;
  441. }
  442.  
  443. void TestGLCanvas::OnEraseBackground(wxEraseEvent& event)
  444. {
  445.     // Do nothing, to avoid flashing.
  446. }
  447.  
  448.