]> git.saurik.com Git - wxWidgets.git/commitdiff
OpenGl works now under GTK
authorRobert Roebling <robert@roebling.de>
Sun, 10 Jan 1999 10:49:57 +0000 (10:49 +0000)
committerRobert Roebling <robert@roebling.de>
Sun, 10 Jan 1999 10:49:57 +0000 (10:49 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1360 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

24 files changed:
include/wx/gtk/app.h
include/wx/gtk1/app.h
src/gtk/app.cpp
src/gtk/win_gtk.c
src/gtk/window.cpp
src/gtk1/app.cpp
src/gtk1/win_gtk.c
src/gtk1/window.cpp
utils/glcanvas/Makefile [deleted file]
utils/glcanvas/docs/notes.txt
utils/glcanvas/samples/cube/Makefile [new file with mode: 0644]
utils/glcanvas/samples/cube/cube.cpp
utils/glcanvas/samples/isosurf/Makefile [new file with mode: 0644]
utils/glcanvas/samples/penguin/Makefile [new file with mode: 0644]
utils/glcanvas/samples/penguin/lw.c [new file with mode: 0644]
utils/glcanvas/samples/penguin/lw.h [new file with mode: 0644]
utils/glcanvas/samples/penguin/penguin.cpp [new file with mode: 0644]
utils/glcanvas/samples/penguin/penguin.h [new file with mode: 0644]
utils/glcanvas/samples/penguin/trackball.c [new file with mode: 0644]
utils/glcanvas/samples/penguin/trackball.h [new file with mode: 0644]
utils/glcanvas/src/Makefile [deleted file]
utils/glcanvas/src/Makefile.in [deleted file]
utils/glcanvas/src/glcanvas.cpp
utils/glcanvas/src/glcanvas.h

index 4884ccf091e0daa91e16e3fddad650df35794386..07d586dcb81f0d0665e8bab1f3478f9aa3533bc7 100644 (file)
@@ -31,9 +31,6 @@ class wxLog;
 
 extern wxApp *wxTheApp;
 
-extern GdkVisual *wxVisualSetByExternal;
-extern GdkColormap *wxColormapSetByExternal;
-
 //-----------------------------------------------------------------------------
 // global functions
 //-----------------------------------------------------------------------------
@@ -66,8 +63,7 @@ class wxApp: public wxEvtHandler
 
     /* this may have to be overwritten when special, non-default visuals have
        to be set. it is also platform dependent as only X knows about displays
-       and visuals. by standard, this routine looks at wxVisualSetByExternal
-       which might have been set in the wxModule code of the OpenGL canvas */
+       and visuals. */
     virtual bool InitVisual();
 
     virtual bool OnInit();
index 4884ccf091e0daa91e16e3fddad650df35794386..07d586dcb81f0d0665e8bab1f3478f9aa3533bc7 100644 (file)
@@ -31,9 +31,6 @@ class wxLog;
 
 extern wxApp *wxTheApp;
 
-extern GdkVisual *wxVisualSetByExternal;
-extern GdkColormap *wxColormapSetByExternal;
-
 //-----------------------------------------------------------------------------
 // global functions
 //-----------------------------------------------------------------------------
@@ -66,8 +63,7 @@ class wxApp: public wxEvtHandler
 
     /* this may have to be overwritten when special, non-default visuals have
        to be set. it is also platform dependent as only X knows about displays
-       and visuals. by standard, this routine looks at wxVisualSetByExternal
-       which might have been set in the wxModule code of the OpenGL canvas */
+       and visuals. */
     virtual bool InitVisual();
 
     virtual bool OnInit();
index dec83867a09766dfb70044a0bd1c1faffbc6e1cb..74560c6d6ee27c1a11d6eed840824a4677b27a4d 100644 (file)
@@ -44,9 +44,6 @@ wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
 extern wxList wxPendingDelete;
 extern wxResourceCache *wxTheResourceCache;
 
-GdkVisual *wxVisualSetByExternal = (GdkVisual*) NULL;
-GdkColormap *wxColormapSetByExternal = (GdkColormap*) NULL;
-
 unsigned char g_palette[64*3] =
 {
   0x0,  0x0,  0x0,
@@ -174,45 +171,28 @@ wxApp::~wxApp(void)
 
 bool wxApp::InitVisual()
 {
-    if (wxVisualSetByExternal)
-    {
-        /* this happens in the wxModule code of the OpenGl canvas. 
-          it chooses the best display for OpenGl and stores it 
-          in wxDisplaySetByExternal. we then have to make it the
-          default for the system */
-          
-       gtk_widget_set_default_visual( wxVisualSetByExternal );
-    }
-    
-    if (wxColormapSetByExternal)
-    {
-        /* OpenGl also gives us a colormap */
-       
-       gtk_widget_set_default_colormap( wxColormapSetByExternal );
-    }
-    else
-    {
-        /* this initiates the standard palette as defined by GdkImlib
-          in the GNOME libraries. it ensures that all GNOME applications
-          use the same 64 colormap entries on 8-bit displays so you
-          can use several rather graphics-heavy applications at the
-          same time */
+    return TRUE;
+
+    /* this initiates the standard palette as defined by GdkImlib
+       in the GNOME libraries. it ensures that all GNOME applications
+       use the same 64 colormap entries on 8-bit displays so you
+       can use several rather graphics-heavy applications at the
+       same time */
     
-        GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
+    GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
 
-        for (int i = 0; i < 64; i++)
-        {
-            GdkColor col;
-            col.red    = g_palette[i*3 + 0] << 8;
-            col.green  = g_palette[i*3 + 1] << 8;
-            col.blue   = g_palette[i*3 + 2] << 8;
-            col.pixel  = 0;
+    for (int i = 0; i < 64; i++)
+    {
+        GdkColor col;
+        col.red    = g_palette[i*3 + 0] << 8;
+        col.green  = g_palette[i*3 + 1] << 8;
+        col.blue   = g_palette[i*3 + 2] << 8;
+        col.pixel  = 0;
 
-            gdk_color_alloc( cmap, &col );
-        }
-       
-        gtk_widget_set_default_colormap( cmap );
+        gdk_color_alloc( cmap, &col );
     }
+       
+    gtk_widget_set_default_colormap( cmap );
     
     return TRUE;
 }
@@ -467,15 +447,15 @@ int wxEntry( int argc, char *argv[] )
 
     gtk_init( &argc, &argv );
 
-    wxModule::RegisterModules();
-    if (!wxModule::InitializeModules()) return FALSE;
-    
     if (!wxTheApp->InitVisual()) return 0;
 
     wxApp::CommonInit();
 
     if (!wxTheApp->OnInitGui()) return 0;
 
+    wxModule::RegisterModules();
+    if (!wxModule::InitializeModules()) return FALSE;
+    
     // Here frames insert themselves automatically
     // into wxTopLevelWindows by getting created
     // in OnInit().
index 40c65a87858cc0f76f24cc217655363849dd73bc..0f2d927beaa22400e9fa5391403cb7629da1497c 100644 (file)
@@ -288,6 +288,7 @@ gtk_myfixed_realize (GtkWidget *widget)
   attributes.event_mask |= 
   GDK_EXPOSURE_MASK    |
   GDK_POINTER_MOTION_MASK      |
+  GDK_POINTER_MOTION_HINT_MASK  |
   GDK_BUTTON_MOTION_MASK       |
   GDK_BUTTON1_MOTION_MASK      |
   GDK_BUTTON2_MOTION_MASK      |
index 5d074e2afca671f3dfeeab5981db94d48b9a382e..f49fb9cf9bfb3063dd44b74f41a6ad7c91d5da12 100644 (file)
@@ -634,6 +634,17 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
 
 static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
 {
+    if (gdk_event->is_hint) 
+    {
+       int x = 0;
+       int y = 0;
+       GdkModifierType state;
+       gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
+       gdk_event->x = x;
+       gdk_event->y = y;
+       gdk_event->state = state;
+    }
+    
     if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
 
     if (g_blockEventsOnDrag) return TRUE;
@@ -646,7 +657,7 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
       printf( win->GetClassInfo()->GetClassName() );
     printf( ".\n" );
-*/    
+*/
 
     wxMouseEvent event( wxEVT_MOTION );
     event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
index dec83867a09766dfb70044a0bd1c1faffbc6e1cb..74560c6d6ee27c1a11d6eed840824a4677b27a4d 100644 (file)
@@ -44,9 +44,6 @@ wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
 extern wxList wxPendingDelete;
 extern wxResourceCache *wxTheResourceCache;
 
-GdkVisual *wxVisualSetByExternal = (GdkVisual*) NULL;
-GdkColormap *wxColormapSetByExternal = (GdkColormap*) NULL;
-
 unsigned char g_palette[64*3] =
 {
   0x0,  0x0,  0x0,
@@ -174,45 +171,28 @@ wxApp::~wxApp(void)
 
 bool wxApp::InitVisual()
 {
-    if (wxVisualSetByExternal)
-    {
-        /* this happens in the wxModule code of the OpenGl canvas. 
-          it chooses the best display for OpenGl and stores it 
-          in wxDisplaySetByExternal. we then have to make it the
-          default for the system */
-          
-       gtk_widget_set_default_visual( wxVisualSetByExternal );
-    }
-    
-    if (wxColormapSetByExternal)
-    {
-        /* OpenGl also gives us a colormap */
-       
-       gtk_widget_set_default_colormap( wxColormapSetByExternal );
-    }
-    else
-    {
-        /* this initiates the standard palette as defined by GdkImlib
-          in the GNOME libraries. it ensures that all GNOME applications
-          use the same 64 colormap entries on 8-bit displays so you
-          can use several rather graphics-heavy applications at the
-          same time */
+    return TRUE;
+
+    /* this initiates the standard palette as defined by GdkImlib
+       in the GNOME libraries. it ensures that all GNOME applications
+       use the same 64 colormap entries on 8-bit displays so you
+       can use several rather graphics-heavy applications at the
+       same time */
     
-        GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
+    GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
 
-        for (int i = 0; i < 64; i++)
-        {
-            GdkColor col;
-            col.red    = g_palette[i*3 + 0] << 8;
-            col.green  = g_palette[i*3 + 1] << 8;
-            col.blue   = g_palette[i*3 + 2] << 8;
-            col.pixel  = 0;
+    for (int i = 0; i < 64; i++)
+    {
+        GdkColor col;
+        col.red    = g_palette[i*3 + 0] << 8;
+        col.green  = g_palette[i*3 + 1] << 8;
+        col.blue   = g_palette[i*3 + 2] << 8;
+        col.pixel  = 0;
 
-            gdk_color_alloc( cmap, &col );
-        }
-       
-        gtk_widget_set_default_colormap( cmap );
+        gdk_color_alloc( cmap, &col );
     }
+       
+    gtk_widget_set_default_colormap( cmap );
     
     return TRUE;
 }
@@ -467,15 +447,15 @@ int wxEntry( int argc, char *argv[] )
 
     gtk_init( &argc, &argv );
 
-    wxModule::RegisterModules();
-    if (!wxModule::InitializeModules()) return FALSE;
-    
     if (!wxTheApp->InitVisual()) return 0;
 
     wxApp::CommonInit();
 
     if (!wxTheApp->OnInitGui()) return 0;
 
+    wxModule::RegisterModules();
+    if (!wxModule::InitializeModules()) return FALSE;
+    
     // Here frames insert themselves automatically
     // into wxTopLevelWindows by getting created
     // in OnInit().
index 40c65a87858cc0f76f24cc217655363849dd73bc..0f2d927beaa22400e9fa5391403cb7629da1497c 100644 (file)
@@ -288,6 +288,7 @@ gtk_myfixed_realize (GtkWidget *widget)
   attributes.event_mask |= 
   GDK_EXPOSURE_MASK    |
   GDK_POINTER_MOTION_MASK      |
+  GDK_POINTER_MOTION_HINT_MASK  |
   GDK_BUTTON_MOTION_MASK       |
   GDK_BUTTON1_MOTION_MASK      |
   GDK_BUTTON2_MOTION_MASK      |
index 5d074e2afca671f3dfeeab5981db94d48b9a382e..f49fb9cf9bfb3063dd44b74f41a6ad7c91d5da12 100644 (file)
@@ -634,6 +634,17 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
 
 static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
 {
+    if (gdk_event->is_hint) 
+    {
+       int x = 0;
+       int y = 0;
+       GdkModifierType state;
+       gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
+       gdk_event->x = x;
+       gdk_event->y = y;
+       gdk_event->state = state;
+    }
+    
     if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
 
     if (g_blockEventsOnDrag) return TRUE;
@@ -646,7 +657,7 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
       printf( win->GetClassInfo()->GetClassName() );
     printf( ".\n" );
-*/    
+*/
 
     wxMouseEvent event( wxEVT_MOTION );
     event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
diff --git a/utils/glcanvas/Makefile b/utils/glcanvas/Makefile
deleted file mode 100644 (file)
index 3f7a4dc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-include ../../setup/general/makedirs
index c2049028dcf3ae0b1d7a3f0f0658ffff7a3a225c..7bcb165caf19afcc8d037d2e84e83d345a854b5d 100644 (file)
@@ -2,4 +2,4 @@ wxGLCanvas
 ----------
 
 No known issues, though probably palettes aren't correctly
-handled under Windows.
+handled under Windows. They are ignored under GTK.
diff --git a/utils/glcanvas/samples/cube/Makefile b/utils/glcanvas/samples/cube/Makefile
new file mode 100644 (file)
index 0000000..f24f7eb
--- /dev/null
@@ -0,0 +1,16 @@
+
+CC = g++
+
+cube: cube.o glcanvas.o
+       $(CC) -o cube \
+       cube.o glcanvas.o \
+       `wx-config --libs` -lMesaGL -lMesaGLU
+
+cube.o: cube.cpp
+       $(CC) `wx-config --cflags` -I../../src -c cube.cpp
+
+glcanvas.o: ../../src/glcanvas.cpp
+       $(CC) `wx-config --cflags` `gtk-config --cflags` -I../../src -c ../../src/glcanvas.cpp
+
+clean: 
+       rm -f *.o cube
index 6a756b2893e0f462577caaee864aa59371762685..675cdaba73d8b2c00da617baf5af5e9adc6bc496 100644 (file)
@@ -29,8 +29,6 @@
 
 #include "cube.h"
 
-IMPLEMENT_APP(MyApp)
-
 // `Main program' equivalent, creating windows and returning main app frame
 bool MyApp::OnInit(void)
 {
@@ -54,7 +52,7 @@ bool MyApp::OnInit(void)
 
   frame->m_canvas = new TestGLCanvas(frame, -1, wxPoint(0, 0), wxSize(200, 200));
 
-  InitGL();
+//  InitGL();
 
   // Show the frame
   frame->Show(TRUE);
@@ -81,6 +79,8 @@ void MyApp::InitGL(void)
     glEnable(GL_LIGHT0);
 }
 
+IMPLEMENT_APP(MyApp)
+
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(wxID_EXIT, MyFrame::OnExit)
 END_EVENT_TABLE()
@@ -169,8 +169,11 @@ void TestGLCanvas::OnSize(wxSizeEvent& event)
     int width, height;
     GetClientSize(& width, & height);
 
-    if ( GetContext() )
+    if (GetContext())
+    {
+        SetCurrent();
         glViewport(0, 0, width, height);
+    }
 }
 
 void TestGLCanvas::OnEraseBackground(wxEraseEvent& event)
diff --git a/utils/glcanvas/samples/isosurf/Makefile b/utils/glcanvas/samples/isosurf/Makefile
new file mode 100644 (file)
index 0000000..7722db1
--- /dev/null
@@ -0,0 +1,16 @@
+
+CC = g++
+
+isosurf: isosurf.o glcanvas.o
+       $(CC) -o isosurf \
+       isosurf.o glcanvas.o \
+       `wx-config --libs` -lMesaGL -lMesaGLU
+
+isosurf.o: isosurf.cpp
+       $(CC) `wx-config --cflags` -I../../src -c isosurf.cpp
+
+glcanvas.o: ../../src/glcanvas.cpp
+       $(CC) `wx-config --cflags` `gtk-config --cflags` -I../../src -c ../../src/glcanvas.cpp
+
+clean: 
+       rm -f *.o cube
diff --git a/utils/glcanvas/samples/penguin/Makefile b/utils/glcanvas/samples/penguin/Makefile
new file mode 100644 (file)
index 0000000..5a3cfc9
--- /dev/null
@@ -0,0 +1,23 @@
+
+CPP = g++
+CC = gcc
+
+Penguin: penguin.o trackball.o lw.o glcanvas.o
+       $(CPP) -o Penguin \
+       penguin.o trackball.o lw.o glcanvas.o \
+       `wx-config --libs` -lMesaGL -lMesaGLU
+
+penguin.o: penguin.cpp
+       $(CPP) `wx-config --cflags` -I../../src -c penguin.cpp
+
+lw.o: lw.c
+       $(CC) `wx-config --cflags` -I../../src -c lw.c
+
+trackball.o: trackball.c
+       $(CC) `wx-config --cflags` -I../../src -c trackball.c
+
+glcanvas.o: ../../src/glcanvas.cpp
+       $(CPP) `wx-config --cflags` `gtk-config --cflags` -I../../src -c ../../src/glcanvas.cpp
+
+clean: 
+       rm -f *.o penguin
diff --git a/utils/glcanvas/samples/penguin/lw.c b/utils/glcanvas/samples/penguin/lw.c
new file mode 100644 (file)
index 0000000..01decb7
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 1998 Janne Löf <jlof@mail.student.oulu.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+
+
+#include "lw.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#define wxInt32 int
+#define wxUint32 unsigned int
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#define MK_ID(a,b,c,d) ((((wxUint32)(a))<<24)| \
+                       (((wxUint32)(b))<<16)| \
+                       (((wxUint32)(c))<< 8)| \
+                       (((wxUint32)(d))    ))
+
+#define ID_FORM MK_ID('F','O','R','M')
+#define ID_LWOB MK_ID('L','W','O','B')
+#define ID_PNTS MK_ID('P','N','T','S')
+#define ID_SRFS MK_ID('S','R','F','S')
+#define ID_SURF MK_ID('S','U','R','F')
+#define ID_POLS MK_ID('P','O','L','S')
+#define ID_COLR MK_ID('C','O','L','R')
+
+static wxInt32 read_char(FILE *f)
+{
+  int c = fgetc(f);
+  return c;
+}
+
+static wxInt32 read_short(FILE *f)
+{
+  return (read_char(f)<<8) | read_char(f);
+}
+
+static wxInt32 read_long(FILE *f)
+{
+  return (read_char(f)<<24) | (read_char(f)<<16) | (read_char(f)<<8) | read_char(f);
+}
+
+static GLfloat read_float(FILE *f)
+{
+  wxInt32 x = read_long(f);
+  return *(GLfloat*)&x;
+}
+
+static int read_string(FILE *f, char *s)
+{
+  int c;
+  int cnt = 0;
+  do {
+    c = read_char(f);
+    if (cnt < LW_MAX_NAME_LEN)
+      s[cnt] = c;
+    else
+      s[LW_MAX_NAME_LEN-1] = 0;
+    cnt++;
+  } while (c != 0);
+  /* if length of string (including \0) is odd skip another byte */
+  if (cnt%2) {
+    read_char(f);
+    cnt++;
+  }
+  return cnt;
+}
+
+static void read_srfs(FILE *f, int nbytes, lwObject *lwo)
+{
+  int guess_cnt = lwo->material_cnt;
+
+  while (nbytes > 0) {
+    lwMaterial *material;
+
+    /* allocate more memory for materials if needed */
+    if (guess_cnt <= lwo->material_cnt) {
+      guess_cnt += guess_cnt/2 + 4;
+      lwo->material = realloc(lwo->material, sizeof(lwMaterial)*guess_cnt);
+    }
+    material = lwo->material + lwo->material_cnt++;
+
+    /* read name */
+    nbytes -= read_string(f,material->name);
+
+    /* defaults */
+    material->r = 0.7;
+    material->g = 0.7;
+    material->b = 0.7;
+  }
+  lwo->material = realloc(lwo->material, sizeof(lwMaterial)*lwo->material_cnt);
+}
+
+
+static void read_surf(FILE *f, int nbytes, lwObject *lwo)
+{
+  int i;
+  char name[LW_MAX_NAME_LEN];
+  lwMaterial *material = NULL;
+
+  /* read surface name */
+  nbytes -= read_string(f,name);
+
+  /* find material */
+  for (i=0; i< lwo->material_cnt; i++) {
+    if (strcmp(lwo->material[i].name,name) == 0) {
+      material = &lwo->material[i];
+      break;
+    }
+  }
+
+  /* read values */
+  while (nbytes > 0) {
+    int id = read_long(f);
+    int len = read_short(f);
+    nbytes -= 6 + len + (len%2);
+
+    switch (id) {
+    case ID_COLR:
+      material->r = read_char(f) / 255.0;
+      material->g = read_char(f) / 255.0;
+      material->b = read_char(f) / 255.0;
+      read_char(f); /* dummy */
+      break;
+    default:
+      fseek(f, len+(len%2), SEEK_CUR);
+    }
+  }
+}
+
+
+static void read_pols(FILE *f, int nbytes, lwObject *lwo)
+{
+  int guess_cnt = lwo->face_cnt;
+  
+  while (nbytes > 0) {
+    lwFace *face;
+    int i;
+
+    /* allocate more memory for polygons if necessary */
+    if (guess_cnt <= lwo->face_cnt) {
+      guess_cnt += guess_cnt + 4;
+      lwo->face = realloc(lwo->face, sizeof(lwFace)*guess_cnt);
+    }
+    face = lwo->face + lwo->face_cnt++;
+
+    /* number of points in this face */
+    face->index_cnt = read_short(f);
+    nbytes -= 2;
+
+    /* allocate space for points */
+    face->index = calloc(sizeof(int)*face->index_cnt,1);
+    
+    /* read points in */
+    for (i=0; i<face->index_cnt; i++) {
+      face->index[i] = read_short(f);
+      nbytes -= 2;
+    }
+    
+    /* read surface material */
+    face->material = read_short(f);
+    nbytes -= 2;
+    
+    /* skip over detail  polygons */
+    if (face->material < 0) {
+      int det_cnt;
+      face->material = -face->material;
+      det_cnt = read_short(f);
+      nbytes -= 2;
+      while (det_cnt-- > 0) {
+       int cnt = read_short(f);
+       fseek(f, cnt*2+2, SEEK_CUR);
+       nbytes -= cnt*2+2;
+      }
+    }
+    face->material -= 1;
+  }
+  /* readjust to true size */
+  lwo->face = realloc(lwo->face, sizeof(lwFace)*lwo->face_cnt);
+}
+
+
+
+static void read_pnts(FILE *f, int nbytes, lwObject *lwo)
+{
+  int i;
+  lwo->vertex_cnt = nbytes / 12;
+  lwo->vertex = calloc(sizeof(GLfloat)*lwo->vertex_cnt*3, 1);
+  for (i=0; i<lwo->vertex_cnt; i++) {
+    lwo->vertex[i*3+0] = read_float(f);
+    lwo->vertex[i*3+1] = read_float(f);
+    lwo->vertex[i*3+2] = read_float(f);
+  }
+}
+
+
+
+
+
+
+int lw_is_lwobject(const char *lw_file)
+{
+  FILE *f = fopen(lw_file, "rb");
+  if (f) {
+    wxInt32 form = read_long(f);
+    wxInt32 nlen = read_long(f);
+    wxInt32 lwob = read_long(f);
+    fclose(f);
+    if (form == ID_FORM && nlen != 0 && lwob == ID_LWOB)
+      return TRUE;
+  }
+  return FALSE;
+}
+
+
+lwObject *lw_object_read(const char *lw_file)
+{
+  FILE *f = NULL;
+  lwObject *lw_object = NULL;
+
+  wxInt32 form_bytes = 0;
+  wxInt32 read_bytes = 0;
+
+  /* open file */
+  f = fopen(lw_file, "rb");
+  if (f == NULL) {
+    return NULL;
+  }
+
+  /* check for headers */
+  if (read_long(f) != ID_FORM) {
+    fclose(f);
+    return NULL;
+  }
+  form_bytes = read_long(f);
+  read_bytes += 4;
+
+  if (read_long(f) != ID_LWOB) {
+    fclose(f);
+    return NULL;
+  }
+
+  /* create new lwObject */
+  lw_object = calloc(sizeof(lwObject),1);
+
+  /* read chunks */
+  while (read_bytes < form_bytes) {
+    wxInt32  id     = read_long(f);
+    wxInt32  nbytes = read_long(f);
+    read_bytes += 8 + nbytes + (nbytes%2);
+
+    switch (id) {
+    case ID_PNTS:
+      read_pnts(f, nbytes, lw_object);
+      break;
+    case ID_POLS:
+      read_pols(f, nbytes, lw_object);
+      break;
+    case ID_SRFS:
+      read_srfs(f, nbytes, lw_object);
+      break;
+    case ID_SURF:
+      read_surf(f, nbytes, lw_object);
+      break;
+    default:
+      fseek(f, nbytes + (nbytes%2), SEEK_CUR);
+    }
+  }
+
+  fclose(f);
+  return lw_object;
+}
+
+
+
+void lw_object_free(lwObject *lw_object)
+{
+  if (lw_object->face) {
+    int i;
+    for (i=0; i<lw_object->face_cnt; i++)
+      free(lw_object->face[i].index);
+    free(lw_object->face);
+  }
+  free(lw_object->material);
+  free(lw_object->vertex);
+  free(lw_object);
+}
+
+
+
+
+
+#define PX(i) (lw_object->vertex[face->index[i]*3+0])
+#define PY(i) (lw_object->vertex[face->index[i]*3+1])
+#define PZ(i) (lw_object->vertex[face->index[i]*3+2])
+void lw_object_show(const lwObject *lw_object)
+{
+  int i,j;
+  int prev_index_cnt = -1;
+  int prev_material  = -1;
+  GLfloat prev_nx = 0;
+  GLfloat prev_ny = 0;
+  GLfloat prev_nz = 0;
+
+  for (i=0; i<lw_object->face_cnt; i++) {
+    GLfloat ax,ay,az,bx,by,bz,nx,ny,nz,r;
+    const lwFace *face = lw_object->face+i;
+
+    /* ignore faces with less than 3 points */
+    if (face->index_cnt < 3)
+      continue;
+
+    /* calculate normal */
+    ax = PX(1) - PX(0);
+    ay = PY(1) - PY(0);
+    az = PZ(1) - PZ(0);
+
+    bx = PX(face->index_cnt-1) - PX(0);
+    by = PY(face->index_cnt-1) - PY(0);
+    bz = PZ(face->index_cnt-1) - PZ(0);
+
+    nx = ay * bz - az * by;
+    ny = az * bx - ax * bz;
+    nz = ax * by - ay * bx;
+
+    r = sqrt(nx*nx + ny*ny + nz*nz);
+    if (r < 0.000001) /* avoid division by zero */
+      continue;
+    nx /= r;
+    ny /= r;
+    nz /= r;
+
+    /* glBegin/glEnd */
+    if (prev_index_cnt != face->index_cnt || prev_index_cnt > 4) {
+      if (prev_index_cnt > 0) glEnd();
+      prev_index_cnt = face->index_cnt;
+      switch (face->index_cnt) {
+      case 3:
+       glBegin(GL_TRIANGLES);
+       break;
+      case 4:
+       glBegin(GL_QUADS);
+       break;
+      default:
+       glBegin(GL_POLYGON);
+      }
+    }
+
+    /* update material if necessary */
+    if (prev_material != face->material) {
+      prev_material = face->material;
+      glColor3f(lw_object->material[face->material].r,
+               lw_object->material[face->material].g,
+               lw_object->material[face->material].b);
+    }
+
+    /* update normal if necessary */
+    if (nx != prev_nx || ny != prev_ny || nz != prev_nz) {
+      prev_nx = nx;
+      prev_ny = ny;
+      prev_nz = nz;
+      glNormal3f(nx,ny,nz);
+    }
+
+    /* draw polygon/triangle/quad */
+    for (j=0; j<face->index_cnt; j++)
+      glVertex3f(PX(j),PY(j),PZ(j));
+
+  }
+
+  /* if glBegin was called call glEnd */
+  if (prev_index_cnt > 0)
+    glEnd();
+}
+
+
+GLfloat lw_object_radius(const lwObject *lwo)
+{
+  int i;
+  double max_radius = 0.0;
+
+  for (i=0; i<lwo->vertex_cnt; i++) {
+    GLfloat *v = &lwo->vertex[i*3];
+    double r = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+    if (r > max_radius)
+      max_radius = r;
+  }
+  return sqrt(max_radius);
+}
+
+void lw_object_scale(lwObject *lwo, GLfloat scale)
+{
+  int i;
+
+  for (i=0; i<lwo->vertex_cnt; i++) {
+    lwo->vertex[i*3+0] *= scale;
+    lwo->vertex[i*3+1] *= scale;
+    lwo->vertex[i*3+2] *= scale;
+  }
+}
+
+
diff --git a/utils/glcanvas/samples/penguin/lw.h b/utils/glcanvas/samples/penguin/lw.h
new file mode 100644 (file)
index 0000000..9202019
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1998 Janne Löf <jlof@mail.student.oulu.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifndef LW_H
+#define LW_H
+
+#include <GL/gl.h>
+
+#define LW_MAX_POINTS   200
+#define LW_MAX_NAME_LEN 500
+
+typedef struct {
+  char name[LW_MAX_NAME_LEN];
+  GLfloat r,g,b;
+} lwMaterial;
+
+typedef struct {
+  int material;         /* material of this face */
+  int index_cnt;        /* number of vertices */
+  int *index;           /* index to vertex */
+  float *texcoord;      /* u,v texture coordinates */
+} lwFace;
+
+typedef struct {
+  int face_cnt;
+  lwFace *face;
+
+  int material_cnt;
+  lwMaterial *material;
+
+  int vertex_cnt;
+  GLfloat *vertex;
+
+} lwObject;
+
+
+int       lw_is_lwobject(const char     *lw_file);
+lwObject *lw_object_read(const char     *lw_file);
+void      lw_object_free(      lwObject *lw_object);
+void      lw_object_show(const lwObject *lw_object);
+
+GLfloat   lw_object_radius(const lwObject *lw_object);
+void      lw_object_scale (lwObject *lw_object, GLfloat scale);
+
+#endif /* LW_H */
+
diff --git a/utils/glcanvas/samples/penguin/penguin.cpp b/utils/glcanvas/samples/penguin/penguin.cpp
new file mode 100644 (file)
index 0000000..9444b7e
--- /dev/null
@@ -0,0 +1,236 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        penguin.cpp
+// Purpose:     wxGLCanvas demo program
+// Author:      Robert Roebling
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Robert Roebling
+// Licence:    wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#pragma interface
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "penguin.h"
+#include <GL/glu.h>
+
+#define VIEW_ASPECT 1.3
+
+/* `Main program' equivalent, creating windows and returning main app frame */
+bool MyApp::OnInit(void)
+{
+
+  /* Create the main frame window */
+  MyFrame *frame = new MyFrame(NULL, "wxWindows OpenGL Demo", wxPoint(50, 50), wxSize(400, 300));
+
+  /* Make a menubar */
+  wxMenu *fileMenu = new wxMenu;
+
+  fileMenu->Append(wxID_EXIT, "E&xit");
+  wxMenuBar *menuBar = new wxMenuBar;
+  menuBar->Append(fileMenu, "&File");
+  frame->SetMenuBar(menuBar);
+
+  frame->m_canvas = new TestGLCanvas(frame, -1, wxPoint(0, 0), wxSize(200, 200));
+
+  /* Load file wiht mesh data */
+  frame->m_canvas->LoadLWO( "penguin.lwo" );
+
+  /* Show the frame */
+  frame->Show(TRUE);
+  
+  return TRUE;
+}
+
+IMPLEMENT_APP(MyApp)
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+    EVT_MENU(wxID_EXIT, MyFrame::OnExit)
+END_EVENT_TABLE()
+
+/* My frame constructor */
+MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
+    const wxSize& size, long style):
+  wxFrame(frame, -1, title, pos, size, style)
+{
+    m_canvas = NULL;
+}
+
+/* Intercept menu commands */
+void MyFrame::OnExit(wxCommandEvent& event)
+{
+    Destroy();
+}
+
+bool MyFrame::OnClose(void)
+{
+    return TRUE;
+}
+
+BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
+    EVT_SIZE(TestGLCanvas::OnSize)
+    EVT_PAINT(TestGLCanvas::OnPaint)
+    EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground)
+    EVT_MOUSE_EVENTS(TestGLCanvas::OnMouse)
+END_EVENT_TABLE()
+
+TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id,
+    const wxPoint& pos, const wxSize& size, long style, const wxString& name):
+  wxGLCanvas(parent, id, pos, size, style, name)
+{
+   block = FALSE;
+}
+
+TestGLCanvas::~TestGLCanvas(void)
+{
+    /* destroy mesh */
+    lw_object_free(info.lwobject);
+}
+
+void TestGLCanvas::OnPaint( wxPaintEvent& event )
+{
+    /* must always be here */
+    wxPaintDC dc(this);
+
+    if (!GetContext()) return;
+
+    SetCurrent();
+    
+    /* initialize OpenGL */
+    if (info.do_init == TRUE) 
+    {
+        InitGL();
+        info.do_init = FALSE;
+    }
+  
+    /* view */
+    glMatrixMode( GL_PROJECTION );
+    glLoadIdentity();
+    gluPerspective( info.zoom, VIEW_ASPECT, 1, 100 );
+    glMatrixMode( GL_MODELVIEW );
+
+    /* clear */
+    glClearColor( .3, .4, .6, 1 );
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+    /* transformations */
+    GLfloat m[4][4];
+    glLoadIdentity();
+    glTranslatef( 0, 0, -30 );
+    build_rotmatrix( m,info.quat );
+    glMultMatrixf( &m[0][0] );
+
+    /* draw object */
+    lw_object_show( info.lwobject );
+    
+    /* flush */
+    glFlush();
+
+    /* swap */
+    SwapBuffers();
+}
+
+void TestGLCanvas::OnSize(wxSizeEvent& event)
+{
+    int width, height;
+    GetClientSize(& width, & height);
+
+    if (GetContext())
+    {
+        SetCurrent();
+        glViewport(0, 0, width, height);
+    }
+}
+
+void TestGLCanvas::OnEraseBackground(wxEraseEvent& event)
+{
+    /* Do nothing, to avoid flashing on MSW */
+}
+
+void TestGLCanvas::LoadLWO(const wxString &filename)
+{
+    /* test if lightwave object */
+    if (!lw_is_lwobject(filename)) return;
+  
+    /* read lightwave object */
+    lwObject *lwobject = lw_object_read(filename);
+    
+    /* scale */
+    lw_object_scale(lwobject, 10.0 / lw_object_radius(lwobject));
+    
+    /* set up mesh info */
+    info.do_init = TRUE;
+    info.lwobject = lwobject;
+    info.beginx = 0;
+    info.beginy = 0;
+    info.zoom   = 45;
+    trackball( info.quat, 0.0, 0.0, 0.0, 0.0 );
+}
+
+void TestGLCanvas::OnMouse( wxMouseEvent& event )
+{
+    if (event.Dragging())
+    {
+        /* drag in progress, simulate trackball */
+        float spin_quat[4];
+        trackball(spin_quat,
+             (2.0*info.beginx -       m_width) / m_width,
+             (     m_height - 2.0*info.beginy) / m_height,
+             (     2.0*event.GetX() - m_width) / m_width,
+             (    m_height - 2.0*event.GetY()) / m_height);
+             
+        add_quats( spin_quat, info.quat, info.quat );
+       
+        /* orientation has changed, redraw mesh */
+       Refresh();
+    }
+    
+    info.beginx = event.GetX();
+    info.beginy = event.GetY();
+}
+
+void TestGLCanvas::InitGL(void)
+{
+    GLfloat light0_pos[4]   = { -50.0, 50.0, 0.0, 0.0 };
+    GLfloat light0_color[4] = { .6, .6, .6, 1.0 }; /* white light */
+    GLfloat light1_pos[4]   = {  50.0, 50.0, 0.0, 0.0 };
+    GLfloat light1_color[4] = { .4, .4, 1, 1.0 };  /* cold blue light */
+
+    /* remove back faces */
+    glDisable(GL_CULL_FACE);
+    glEnable(GL_DEPTH_TEST);
+  
+    /* speedups */
+    glEnable(GL_DITHER);
+    glShadeModel(GL_SMOOTH);
+    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+    glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
+
+    /* light */
+    glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE,  light0_color);  
+    glLightfv(GL_LIGHT1, GL_POSITION, light1_pos);
+    glLightfv(GL_LIGHT1, GL_DIFFUSE,  light1_color);
+    glEnable(GL_LIGHT0);
+    glEnable(GL_LIGHT1);
+    glEnable(GL_LIGHTING);
+    
+    glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
+    glEnable(GL_COLOR_MATERIAL);  
+}
+
+
diff --git a/utils/glcanvas/samples/penguin/penguin.h b/utils/glcanvas/samples/penguin/penguin.h
new file mode 100644 (file)
index 0000000..83b0708
--- /dev/null
@@ -0,0 +1,84 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        penguin.h
+// Purpose:     wxGLCanvas demo program
+// Author:      Robert Roebling
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Robert Roebling
+// Licence:    wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PENGUIN_H_
+#define _WX_PENGUIN_H_
+
+
+#include "wx/defs.h"
+#include "wx/app.h"
+#include "wx/menu.h"
+#include "wx/dcclient.h"
+
+#include "glcanvas.h"
+
+extern "C" {
+#include "lw.h"
+#include "trackball.h"
+}
+
+/* information needed to display lightwave mesh */
+typedef struct 
+{
+  gint do_init;         /* true if initgl not yet called */
+  lwObject *lwobject;   /* lightwave object mesh */
+  float beginx,beginy;  /* position of mouse */
+  float quat[4];        /* orientation of object */
+  float zoom;           /* field of view in degrees */
+} mesh_info;
+
+
+/* Define a new application type */
+class MyApp: public wxApp
+{
+public:
+    bool OnInit(void);
+};
+
+/* Define a new frame type */
+class TestGLCanvas;
+class MyFrame: public wxFrame
+{
+public:
+    MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size,
+        long style = wxDEFAULT_FRAME_STYLE);
+
+    void OnExit(wxCommandEvent& event);
+    bool OnClose(void);
+public:
+    TestGLCanvas*    m_canvas;
+
+DECLARE_EVENT_TABLE()
+};
+
+
+class TestGLCanvas: public wxGLCanvas
+{
+ public:
+   TestGLCanvas(wxWindow *parent, const wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition,
+      const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "TestGLCanvas");
+   ~TestGLCanvas(void);
+
+   void OnPaint(wxPaintEvent& event);
+   void OnSize(wxSizeEvent& event);
+   void OnEraseBackground(wxEraseEvent& event);
+   void LoadLWO( const wxString &filename);
+   void OnMouse( wxMouseEvent& event );
+   void InitGL(void);
+   
+   mesh_info  info;
+   bool       block;
+
+DECLARE_EVENT_TABLE()
+};
+
+#endif
+
diff --git a/utils/glcanvas/samples/penguin/trackball.c b/utils/glcanvas/samples/penguin/trackball.c
new file mode 100644 (file)
index 0000000..f23d3db
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ * Trackball code:
+ *
+ * Implementation of a virtual trackball.
+ * Implemented by Gavin Bell, lots of ideas from Thant Tessman and
+ *   the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
+ *
+ * Vector manip code:
+ *
+ * Original code from:
+ * David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli
+ *
+ * Much mucking with by:
+ * Gavin Bell
+ */
+#include <math.h>
+#include "trackball.h"
+
+/*
+ * This size should really be based on the distance from the center of
+ * rotation to the point on the object underneath the mouse.  That
+ * point would then track the mouse as closely as possible.  This is a
+ * simple example, though, so that is left as an Exercise for the
+ * Programmer.
+ */
+#define TRACKBALLSIZE  (0.8)
+
+/*
+ * Local function prototypes (not defined in trackball.h)
+ */
+static float tb_project_to_sphere(float, float, float);
+static void normalize_quat(float [4]);
+
+void
+vzero(float *v)
+{
+    v[0] = 0.0;
+    v[1] = 0.0;
+    v[2] = 0.0;
+}
+
+void
+vset(float *v, float x, float y, float z)
+{
+    v[0] = x;
+    v[1] = y;
+    v[2] = z;
+}
+
+void
+vsub(const float *src1, const float *src2, float *dst)
+{
+    dst[0] = src1[0] - src2[0];
+    dst[1] = src1[1] - src2[1];
+    dst[2] = src1[2] - src2[2];
+}
+
+void
+vcopy(const float *v1, float *v2)
+{
+    register int i;
+    for (i = 0 ; i < 3 ; i++)
+        v2[i] = v1[i];
+}
+
+void
+vcross(const float *v1, const float *v2, float *cross)
+{
+    float temp[3];
+
+    temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
+    temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
+    temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
+    vcopy(temp, cross);
+}
+
+float
+vlength(const float *v)
+{
+    return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+}
+
+void
+vscale(float *v, float div)
+{
+    v[0] *= div;
+    v[1] *= div;
+    v[2] *= div;
+}
+
+void
+vnormal(float *v)
+{
+    vscale(v,1.0/vlength(v));
+}
+
+float
+vdot(const float *v1, const float *v2)
+{
+    return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
+}
+
+void
+vadd(const float *src1, const float *src2, float *dst)
+{
+    dst[0] = src1[0] + src2[0];
+    dst[1] = src1[1] + src2[1];
+    dst[2] = src1[2] + src2[2];
+}
+
+/*
+ * Ok, simulate a track-ball.  Project the points onto the virtual
+ * trackball, then figure out the axis of rotation, which is the cross
+ * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
+ * Note:  This is a deformed trackball-- is a trackball in the center,
+ * but is deformed into a hyperbolic sheet of rotation away from the
+ * center.  This particular function was chosen after trying out
+ * several variations.
+ *
+ * It is assumed that the arguments to this routine are in the range
+ * (-1.0 ... 1.0)
+ */
+void
+trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
+{
+    float a[3]; /* Axis of rotation */
+    float phi;  /* how much to rotate about axis */
+    float p1[3], p2[3], d[3];
+    float t;
+
+    if (p1x == p2x && p1y == p2y) {
+        /* Zero rotation */
+        vzero(q);
+        q[3] = 1.0;
+        return;
+    }
+
+    /*
+     * First, figure out z-coordinates for projection of P1 and P2 to
+     * deformed sphere
+     */
+    vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
+    vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y));
+
+    /*
+     *  Now, we want the cross product of P1 and P2
+     */
+    vcross(p2,p1,a);
+
+    /*
+     *  Figure out how much to rotate around that axis.
+     */
+    vsub(p1,p2,d);
+    t = vlength(d) / (2.0*TRACKBALLSIZE);
+
+    /*
+     * Avoid problems with out-of-control values...
+     */
+    if (t > 1.0) t = 1.0;
+    if (t < -1.0) t = -1.0;
+    phi = 2.0 * asin(t);
+
+    axis_to_quat(a,phi,q);
+}
+
+/*
+ *  Given an axis and angle, compute quaternion.
+ */
+void
+axis_to_quat(float a[3], float phi, float q[4])
+{
+    vnormal(a);
+    vcopy(a,q);
+    vscale(q,sin(phi/2.0));
+    q[3] = cos(phi/2.0);
+}
+
+/*
+ * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
+ * if we are away from the center of the sphere.
+ */
+static float
+tb_project_to_sphere(float r, float x, float y)
+{
+    float d, t, z;
+
+    d = sqrt(x*x + y*y);
+    if (d < r * 0.70710678118654752440) {    /* Inside sphere */
+        z = sqrt(r*r - d*d);
+    } else {           /* On hyperbola */
+        t = r / 1.41421356237309504880;
+        z = t*t / d;
+    }
+    return z;
+}
+
+/*
+ * Given two rotations, e1 and e2, expressed as quaternion rotations,
+ * figure out the equivalent single rotation and stuff it into dest.
+ *
+ * This routine also normalizes the result every RENORMCOUNT times it is
+ * called, to keep error from creeping in.
+ *
+ * NOTE: This routine is written so that q1 or q2 may be the same
+ * as dest (or each other).
+ */
+
+#define RENORMCOUNT 97
+
+void
+add_quats(float q1[4], float q2[4], float dest[4])
+{
+    static int count=0;
+    float t1[4], t2[4], t3[4];
+    float tf[4];
+
+    vcopy(q1,t1);
+    vscale(t1,q2[3]);
+
+    vcopy(q2,t2);
+    vscale(t2,q1[3]);
+
+    vcross(q2,q1,t3);
+    vadd(t1,t2,tf);
+    vadd(t3,tf,tf);
+    tf[3] = q1[3] * q2[3] - vdot(q1,q2);
+
+    dest[0] = tf[0];
+    dest[1] = tf[1];
+    dest[2] = tf[2];
+    dest[3] = tf[3];
+
+    if (++count > RENORMCOUNT) {
+        count = 0;
+        normalize_quat(dest);
+    }
+}
+
+/*
+ * Quaternions always obey:  a^2 + b^2 + c^2 + d^2 = 1.0
+ * If they don't add up to 1.0, dividing by their magnitued will
+ * renormalize them.
+ *
+ * Note: See the following for more information on quaternions:
+ *
+ * - Shoemake, K., Animating rotation with quaternion curves, Computer
+ *   Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
+ * - Pletinckx, D., Quaternion calculus as a basic tool in computer
+ *   graphics, The Visual Computer 5, 2-13, 1989.
+ */
+static void
+normalize_quat(float q[4])
+{
+    int i;
+    float mag;
+
+    mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
+    for (i = 0; i < 4; i++) q[i] /= mag;
+}
+
+/*
+ * Build a rotation matrix, given a quaternion rotation.
+ *
+ */
+void
+build_rotmatrix(float m[4][4], float q[4])
+{
+    m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
+    m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
+    m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
+    m[0][3] = 0.0;
+
+    m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
+    m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
+    m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
+    m[1][3] = 0.0;
+
+    m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
+    m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
+    m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
+    m[2][3] = 0.0;
+
+    m[3][0] = 0.0;
+    m[3][1] = 0.0;
+    m[3][2] = 0.0;
+    m[3][3] = 1.0;
+}
+
diff --git a/utils/glcanvas/samples/penguin/trackball.h b/utils/glcanvas/samples/penguin/trackball.h
new file mode 100644 (file)
index 0000000..b676fb4
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ * trackball.h
+ * A virtual trackball implementation
+ * Written by Gavin Bell for Silicon Graphics, November 1988.
+ */
+
+/*
+ * Pass the x and y coordinates of the last and current positions of
+ * the mouse, scaled so they are from (-1.0 ... 1.0).
+ *
+ * The resulting rotation is returned as a quaternion rotation in the
+ * first paramater.
+ */
+void
+trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
+
+/*
+ * Given two quaternions, add them together to get a third quaternion.
+ * Adding quaternions to get a compound rotation is analagous to adding
+ * translations to get a compound translation.  When incrementally
+ * adding rotations, the first argument here should be the new
+ * rotation, the second and third the total rotation (which will be
+ * over-written with the resulting new total rotation).
+ */
+void
+add_quats(float *q1, float *q2, float *dest);
+
+/*
+ * A useful function, builds a rotation matrix in Matrix based on
+ * given quaternion.
+ */
+void
+build_rotmatrix(float m[4][4], float q[4]);
+
+/*
+ * This function computes a quaternion based on an axis (defined by
+ * the given vector) and an angle about which to rotate.  The angle is
+ * expressed in radians.  The result is put into the third argument.
+ */
+void
+axis_to_quat(float a[3], float phi, float q[4]);
+
diff --git a/utils/glcanvas/src/Makefile b/utils/glcanvas/src/Makefile
deleted file mode 100644 (file)
index 35ce106..0000000
+++ /dev/null
@@ -1 +0,0 @@
-include ../../../setup/general/makedirs
diff --git a/utils/glcanvas/src/Makefile.in b/utils/glcanvas/src/Makefile.in
deleted file mode 100644 (file)
index 79d15e4..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-#  wxGLCanvas source makefile for Unix
-#
-#  Copyright 1998, Robert Roebling
-#
-
-# wxWindows base directory
-WXBASEDIR=@WXBASEDIR@
-
-# set the OS type for compilation
-OS=@OS@
-
-# compile a library only
-RULE=gslib
-
-# needed for unactivated
-NONE=
-
-# define library name
-LIB_TARGET=wx_opengl_gtk
-LIB_MAJOR=1
-LIB_MINOR=0
-
-# define library sources
-
-LIB_CPP_SRC= \
-\
- glcanvas.cpp
-
-#define library objects
-LIB_OBJ= \
-\
- $(LIB_CPP_SRC:.cpp=.o)
-
-all::
-
-clean::
-
-#additional things needed for compile
-ADD_COMPILE=
-
-# include the definitions now
-include ../../../../template.mak
-
-install::
-       @echo "Installing library files and headers for libwx_opengl_gtk.."
-       @echo "  Creating directory.."
-       @$(WXBASEDIR)/mkinstalldirs /usr/local/include/wx_opengl
-       @echo "  Copying headers from /include/wx"
-       @cd $(WXBASEDIR)/utils/glcanvas/src ; \
-       for f in *.h ; do \
-         rm -f /usr/local/include/wx_opengl/$$f ; \
-         $(INSTALL_DATA) $$f /usr/local/include/wx_opengl/$$f ; \
-       done
-       @echo "  Copying static library files to /usr/local/lib"
-       @cd $(WXBASEDIR)/lib/$(OS) ; \
-       for f in libwx_opengl_gtk.a ; do \
-         rm -f /usr/local/lib/$$f ; \
-         $(INSTALL_DATA) $$f /usr/local/lib/$$f ; \
-       done
-       @echo "  Copying shared libraries to /usr/local/lib"
-       @cd $(WXBASEDIR)/lib/$(OS) ; \
-       for f in libwx_opengl_gtk.so* ; do \
-         rm -f /usr/local/lib/$$f ; \
-         $(INSTALL_PROGRAM) $$f /usr/local/lib/$$f ; \
-       done
-
index a668badcabc56ed0a0e8b8bb0b20a1f79ded7413..9e16370d1e1b4315e81640e0af21de299e7baab4 100644 (file)
 #include "wx/module.h"
 #include "wx/app.h"
 
+extern "C" {
 #include "gtk/gtk.h"
 #include "gdk/gdk.h"
-extern "C" {
 #include "gdk/gdkx.h"
 }
 
+#include "wx/gtk/win_gtk.h"
+
 //---------------------------------------------------------------------------
-// global variables
+// global data
 //---------------------------------------------------------------------------
 
-XVisualInfo *g_visual_info = (XVisualInfo*) NULL;
+XVisualInfo *g_vi = (XVisualInfo*) NULL;
 
 //---------------------------------------------------------------------------
 // wxGLContext
@@ -41,25 +43,25 @@ IMPLEMENT_CLASS(wxGLContext,wxObject)
 wxGLContext::wxGLContext( bool WXUNUSED(isRGB), wxWindow *win, const wxPalette& WXUNUSED(palette) )
 {
     m_window = win;
-    m_widget = win->m_wxwindow;
+    m_widget = ((wxGLCanvas*)win)->m_glWidget;
   
-    wxCHECK_RET( g_visual_info != NULL, "invalid visual for OpenGl" );
+    wxCHECK_RET( g_vi, "invalid visual for OpenGl" );
     
-    m_glContext = glXCreateContext( GDK_DISPLAY(), g_visual_info, None, GL_TRUE );
+    m_glContext = glXCreateContext( GDK_DISPLAY(), g_vi, None, GL_TRUE );
   
-    wxCHECK_RET( m_glContext != NULL, "Couldn't create OpenGl context" );
-
-    glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget->window), m_glContext );
+    wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" );
 }
 
 wxGLContext::~wxGLContext()
 {
-    if (m_glContext)
-    {
-        glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget->window), m_glContext );
+    if (!m_glContext) return;
     
-        glXDestroyContext( GDK_DISPLAY(), m_glContext );
+    if (m_glContext == glXGetCurrentContext())
+    {
+        glXMakeCurrent( GDK_DISPLAY(), None, NULL);
     }
+       
+    glXDestroyContext( GDK_DISPLAY(), m_glContext );
 }
 
 void wxGLContext::SwapBuffers()
@@ -116,12 +118,71 @@ BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow)
     EVT_SIZE(wxGLCanvas::OnSize)
 END_EVENT_TABLE()
 
-wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
-    const wxPoint& pos, const wxSize& size, long style, const wxString& name,
-    int *WXUNUSED(attribList), const wxPalette& palette):
-  wxScrolledWindow(parent, id, pos, size, style, name)
+wxGLCanvas::wxGLCanvas( wxWindow *parent, wxWindowID id,
+                        const wxPoint& pos, const wxSize& size, 
+                       long style, const wxString& name,
+                        int *attribList, 
+                       const wxPalette& palette )
+{
+    Create( parent, id, pos, size, style, name, attribList, palette );
+}
+
+bool wxGLCanvas::Create( wxWindow *parent, wxWindowID id,
+                         const wxPoint& pos, const wxSize& size, 
+                        long style, const wxString& name,
+                         int *attribList, 
+                        const wxPalette& palette )
 {
+    if (!attribList)
+    {
+        int data[] = { GLX_RGBA, 
+                      GLX_DOUBLEBUFFER, 
+                      GLX_DEPTH_SIZE, 1,
+                      None };
+       attribList = (int*) data;
+    }
+    
+    Display *dpy = GDK_DISPLAY();
+    
+    g_vi = glXChooseVisual( dpy, DefaultScreen(dpy), attribList );
+    
+    GdkVisual *visual = gdkx_visual_get( g_vi->visualid );
+    GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(g_vi->visualid), TRUE );
+    
+    gtk_widget_push_colormap( colormap );
+    gtk_widget_push_visual( visual );
+    
+    m_glWidget = gtk_drawing_area_new();
+    gtk_widget_set_events( m_glWidget,
+      GDK_EXPOSURE_MASK        |
+      GDK_POINTER_MOTION_HINT_MASK |
+      GDK_POINTER_MOTION_MASK  |
+      GDK_BUTTON_MOTION_MASK   |
+      GDK_BUTTON1_MOTION_MASK  |
+      GDK_BUTTON2_MOTION_MASK  |
+      GDK_BUTTON3_MOTION_MASK  |
+      GDK_BUTTON_PRESS_MASK    |
+      GDK_BUTTON_RELEASE_MASK  |
+      GDK_KEY_PRESS_MASK       |
+      GDK_KEY_RELEASE_MASK     |
+      GDK_ENTER_NOTIFY_MASK    |
+      GDK_LEAVE_NOTIFY_MASK );
+    
+    gtk_widget_pop_visual();
+    gtk_widget_pop_colormap();
+    
+    wxScrolledWindow::Create( parent, id, pos, size, style, name );
+  
+    gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), m_glWidget, 0, 0 );
+    
+    gtk_widget_show( m_glWidget );
+    
     m_glContext = new wxGLContext( TRUE, this, palette );
+    
+    XFree( g_vi );
+    g_vi = (XVisualInfo*) NULL;
+    
+    return TRUE;
 }
 
 wxGLCanvas::~wxGLCanvas()
@@ -137,13 +198,12 @@ void wxGLCanvas::SwapBuffers()
 void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
 {
     int width, height;
-    GetClientSize(& width, & height);
-
-    if (m_glContext)
+    GetClientSize( &width, &height );
+    if (m_glContext && GTK_WIDGET_REALIZED(m_glWidget) )
     {
-        m_glContext->SetCurrent();
-
-        glViewport(0, 0, (GLint)width, (GLint)height);
+        SetCurrent(); 
+       
+        glViewport(0, 0, (GLint)width, (GLint)height );
         glMatrixMode(GL_PROJECTION);
         glLoadIdentity();
         glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
@@ -161,39 +221,92 @@ void wxGLCanvas::SetColour( const char *colour )
     if (m_glContext) m_glContext->SetColour( colour );
 }
 
-//--------------------------------------------------------------------
-// wxGLModule 
-//--------------------------------------------------------------------
-
-class wxGLModule : public wxModule
+void wxGLCanvas::SetSize( int x, int y, int width, int height, int sizeFlags )
 {
-public:
-    virtual bool OnInit();
-    virtual void OnExit();
+    if (m_resizing) return; // I don't like recursions
+    m_resizing = TRUE;
+
+    if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook
+    {
+        // don't set the size for children of wxNotebook, just take the values.
+        m_x = x;
+        m_y = y;
+        m_width = width;
+        m_height = height;
+    }
+    else
+    {
+        int old_width = m_width;
+        int old_height = m_height;
+
+        if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
+        {
+            if (x != -1) m_x = x;
+            if (y != -1) m_y = y;
+            if (width != -1) m_width = width;
+            if (height != -1) m_height = height;
+        }
+        else
+        {
+            m_x = x;
+            m_y = y;
+            m_width = width;
+            m_height = height;
+        }
+
+        if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
+        {
+             if (width == -1) m_width = 80;
+        }
+
+        if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
+        {
+             if (height == -1) m_height = 26;
+        }
+
+        if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
+        if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
+        if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
+        if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
+
+        wxPoint pt( m_parent->GetClientAreaOrigin() );
+        gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x, m_y+pt.y );
+
+        if ((old_width != m_width) || (old_height != m_height))
+       {
+            gtk_widget_set_usize( m_widget, m_width, m_height );
+           
+            gtk_drawing_area_size( GTK_DRAWING_AREA(m_glWidget), m_width, m_height );
+           
+           GtkAllocation allo;
+           allo.x = 0;
+           allo.y = 0;
+           allo.width = m_width;
+           allo.height = m_height;
+            gtk_widget_size_allocate( m_glWidget, &allo );
+       }
+    }
 
-private:
-    DECLARE_DYNAMIC_CLASS(wxGLModule)
-};
+    m_sizeSet = TRUE;
 
-IMPLEMENT_DYNAMIC_CLASS(wxGLModule, wxModule)
+    wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+    event.SetEventObject( this );
+    GetEventHandler()->ProcessEvent( event );
 
-bool wxGLModule::OnInit() 
-{
-    int data[] = { GLX_RGBA,GLX_RED_SIZE,1,GLX_GREEN_SIZE,1,
-                   GLX_BLUE_SIZE,1,GLX_DOUBLEBUFFER,None};
+    m_resizing = FALSE;
+}
 
-    g_visual_info = glXChooseVisual( GDK_DISPLAY(), DefaultScreen(GDK_DISPLAY()), data );
-  
-    wxCHECK_MSG( g_visual_info != NULL, FALSE, "Couldn't choose visual for OpenGl" );
-  
-    wxVisualSetByExternal = gdkx_visual_get(g_visual_info->visualid);
-  
-    wxColormapSetByExternal = gdk_colormap_new( gdkx_visual_get(g_visual_info->visualid), TRUE );
-    
-    return TRUE;
+void wxGLCanvas::SetSize( int width, int height )
+{
+    SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
 }
 
-void wxGLModule::OnExit()
+GtkWidget *wxGLCanvas::GetConnectWidget()
 {
+    return m_glWidget;
 }
 
+bool wxGLCanvas::IsOwnGtkWindow( GdkWindow *window )
+{
+    return (window == m_glWidget->window);
+}
index f277c771c9e10d996909ca7cace09ce3ca5dd95f..c32e176a61f2654b2cbecb872da4ddb88a72a615 100644 (file)
 #include "wx/defs.h"
 #include "wx/scrolwin.h"
 
+extern "C" {
 #include "GL/gl.h"
 #include "GL/glx.h"
 #include "GL/glu.h"
+}
 
 //---------------------------------------------------------------------------
 // classes
@@ -75,9 +77,20 @@ class wxGLCanvas: public wxScrolledWindow
    DECLARE_CLASS(wxGLCanvas)
    
  public:
-   wxGLCanvas(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition,
-        const wxSize& size = wxDefaultSize, long style = 0,
-        const wxString& name = "GLCanvas", int *attribList = 0, const wxPalette& palette = wxNullPalette);
+   wxGLCanvas( wxWindow *parent, wxWindowID id = -1, 
+        const wxPoint& pos = wxDefaultPosition,
+        const wxSize& size = wxDefaultSize, 
+       long style = 0, const wxString& name = "GLCanvas", 
+       int *attribList = (int*) NULL, 
+       const wxPalette& palette = wxNullPalette );
+       
+   bool Create( wxWindow *parent, wxWindowID id = -1, 
+        const wxPoint& pos = wxDefaultPosition,
+        const wxSize& size = wxDefaultSize, 
+       long style = 0, const wxString& name = "GLCanvas", 
+       int *attribList = (int*) NULL,
+       const wxPalette& palette = wxNullPalette );
+       
    ~wxGLCanvas();
 
    void SetCurrent();
@@ -86,11 +99,19 @@ class wxGLCanvas: public wxScrolledWindow
 
    void OnSize(wxSizeEvent& event);
 
-   inline wxGLContext* GetContext() const { return m_glContext; }
+   inline wxGLContext* GetContext() const { return m_glContext; } 
 
-  protected:
+ // implementation
   
-    wxGLContext*   m_glContext;  // this is typedef-ed ptr, in fact
+    virtual void SetSize( int x, int y, int width, int height,
+      int sizeFlags = wxSIZE_AUTO );
+    virtual void SetSize( int width, int height );
+    
+    virtual GtkWidget *GetConnectWidget();
+    bool IsOwnGtkWindow( GdkWindow *window );
+  
+    wxGLContext      *m_glContext; 
+    GtkWidget        *m_glWidget;
 
   DECLARE_EVENT_TABLE()
 };