Pārlūkot izejas kodu

+ support for the freeglut extensions (patch by Michalis Kamburelis,
mantis #18108)

git-svn-id: trunk@16535 -

Jonas Maebe 14 gadi atpakaļ
vecāks
revīzija
deece746a3

+ 2 - 0
.gitattributes

@@ -4785,6 +4785,7 @@ packages/opengl/Makefile.fpc svneol=native#text/plain
 packages/opengl/examples/Makefile svneol=native#text/plain
 packages/opengl/examples/Makefile.fpc svneol=native#text/plain
 packages/opengl/examples/bounce.pp svneol=native#text/plain
+packages/opengl/examples/freeglutdemo.pp svneol=native#text/plain
 packages/opengl/examples/glutdemo.pp svneol=native#text/plain
 packages/opengl/examples/glutdemova.pp svneol=native#text/plain
 packages/opengl/examples/glxtest.pp svneol=native#text/plain
@@ -4793,6 +4794,7 @@ packages/opengl/examples/radblur.pp svneol=native#text/plain
 packages/opengl/fpmake.pp svneol=native#text/plain
 packages/opengl/glunits.txt svneol=native#text/plain
 packages/opengl/readme svneol=native#text/plain
+packages/opengl/src/freeglut.pp svneol=native#text/plain
 packages/opengl/src/gl.pp svneol=native#text/plain
 packages/opengl/src/glext.pp svneol=native#text/plain
 packages/opengl/src/glu.pp svneol=native#text/plain

+ 187 - 1
packages/opengl/Makefile

@@ -1,5 +1,5 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2010/09/29]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2010/12/10]
 #
 default: all
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-solaris x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded mipsel-linux
@@ -453,6 +453,192 @@ ifeq ($(FULL_TARGET),mipsel-linux)
 override TARGET_UNITS+=gl glu glut  glx glext
 endif
 ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-nativent)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-iphonesim)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),x86_64-solaris)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),mipsel-linux)
+override TARGET_IMPLICITUNITS+=freeglut
+endif
+ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_EXAMPLEDIRS+=examples
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)

+ 2 - 0
packages/opengl/Makefile.fpc

@@ -25,6 +25,8 @@ units_openbsd=glx glext
 units_darwin=glx glext
 exampledirs=examples
 
+implicitunits=freeglut
+
 [install]
 fpcpackage=y
 

+ 106 - 0
packages/opengl/examples/freeglutdemo.pp

@@ -0,0 +1,106 @@
+{ Trivial demo of some freeglut extensions, by Michalis Kamburelis,
+  parts based on glutdemo.pp. Public domain.
+
+  freeglut features:
+  - when you press escape key, program returns gracefully to main begin...end.
+  - we show special geometric objects: Sierpinski sponge, cylinder.
+  - mouse wheel up/down can be used to zoom in/out.
+}
+
+{$mode objfpc}
+
+program FreeGlutDemo;
+
+uses
+  GL, GLU, GLUT, FreeGlut;
+
+var
+  T: GLFloat;
+  Zoom: GLFloat = -3;
+
+procedure Display; cdecl;
+const
+  Offset: TGLDouble3 = (0, 0, 0);
+begin
+  glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT);
+
+  glPushMatrix;
+    glTranslatef(-1, -1, Zoom);
+    glRotatef(T, 0, 1, 0);
+    glutWireCylinder(0.5, 1, 32, 8);
+  glPopMatrix;
+
+  glPushMatrix;
+    glTranslatef(-1,  1, Zoom);
+    glRotatef(T, 0, 1, 0);
+    glutSolidCylinder(0.5, 1, 32, 8);
+  glPopMatrix;
+
+  glPushMatrix;
+    glTranslatef(1, -1, Zoom);
+    glRotatef(T, 0, 1, 0);
+    glutWireSierpinskiSponge(3, @Offset, 1);
+  glPopMatrix;
+
+  glPushMatrix;
+    glTranslatef(1,  1, Zoom);
+    glRotatef(T, 0, 1, 0);
+    glutSolidSierpinskiSponge(3, @Offset, 1);
+  glPopMatrix;
+
+  glutSwapBuffers;
+end;
+
+procedure Timer(Value: Integer); cdecl;
+begin
+  glutPostRedisplay;
+  T := T + 1.0;
+  glutTimerFunc(20, @Timer, 0);
+end;
+
+procedure Key(K: Byte; X, Y: Integer); cdecl;
+begin
+  case K of
+    27: glutLeaveMainLoop(); // using freeglut you can exit cleanly
+  end;
+end;
+
+procedure Wheel(Wheel, Direction, X, Y: Integer); cdecl;
+begin
+  if Wheel = 0 then
+  begin
+    Zoom := Zoom + Direction / 2;
+    glutPostRedisplay();
+  end;
+end;
+
+begin
+  glutInit(@argc, argv);
+  glutInitWindowSize(400, 400);
+  glutInitDisplayMode(GLUT_RGB or GLUT_DOUBLE or GLUT_DEPTH);
+  glutCreateWindow('FreeGlut demo');
+
+  glutDisplayFunc(@Display);
+  glutTimerFunc(20, @Timer, 0);
+  glutKeyboardFunc(@Key);
+  glutMouseWheelFunc(@Wheel);
+
+  glEnable(GL_CULL_FACE); // Enable backface culling
+
+  // Set up depth buffer
+  glEnable(GL_DEPTH_TEST);
+  glDepthFunc(GL_LESS);
+
+  // Set up projection matrix
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity;
+  gluPerspective(90, 1.3, 0.1, 100);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity;
+
+  glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
+
+  WriteLn('Starting...');
+  glutMainLoop;
+  Writeln('glutMainLoop finished');
+end.

+ 208 - 0
packages/opengl/src/freeglut.pp

@@ -0,0 +1,208 @@
+{ FreeGlut extensions, see http://freeglut.sourceforge.net/ .
+  Complements the Glut unit that defines standard Glut functionality.
+  Function entry points will be nil if freeglut is not
+  actually available (or if freeglut version necessary for specific extension
+  is not available).
+
+  Includes all the extensions up to FreeGlut 2.6.0 version.
+  Omitted is only deprecated stuff, and glutGetProcAddress
+  (which is not needed as we have nice glext unit in FPC). }
+
+unit FreeGlut;
+
+{$mode Delphi} {< to keep assignments to proc vars look the same as in glut.pp }
+{$MACRO ON}
+{ Keep this synched with glut.pp "extdecl" definition. }
+{$IFDEF Windows}
+  {$DEFINE extdecl := stdcall}
+{$ELSE}
+  {$DEFINE extdecl := cdecl}
+{$ENDIF}
+
+interface
+
+uses DynLibs, GL, Glut;
+
+type
+  TGLdouble3 = array [0..2] of GLdouble;
+  PGLdouble3 = ^TGLdouble3;
+
+const
+  // Additional GLUT Key definitions for the Special key function
+  GLUT_KEY_NUM_LOCK = $006D;
+  GLUT_KEY_BEGIN    = $006E;
+  GLUT_KEY_DELETE   = $006F;
+
+  // GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window
+  GLUT_ACTION_EXIT                 = 0;
+  GLUT_ACTION_GLUTMAINLOOP_RETURNS = 1;
+  GLUT_ACTION_CONTINUE_EXECUTION   = 2;
+
+  // Create a new rendering context when the user opens a new window?
+  GLUT_CREATE_NEW_CONTEXT  = 0;
+  GLUT_USE_CURRENT_CONTEXT = 1;
+
+  // Direct/Indirect rendering context options (has meaning only in Unix/X11)
+  GLUT_FORCE_INDIRECT_CONTEXT  = 0;
+  GLUT_ALLOW_DIRECT_CONTEXT    = 1;
+  GLUT_TRY_DIRECT_CONTEXT      = 2;
+  GLUT_FORCE_DIRECT_CONTEXT    = 3;
+
+  // GLUT API Extension macro definitions -- the glutGet parameters
+  GLUT_INIT_STATE = $007C;
+
+  GLUT_ACTION_ON_WINDOW_CLOSE = $01F9;
+
+  GLUT_WINDOW_BORDER_WIDTH  = $01FA;
+  GLUT_WINDOW_HEADER_HEIGHT = $01FB;
+
+  GLUT_VERSION = $01FC;
+
+  GLUT_RENDERING_CONTEXT = $01FD;
+  GLUT_DIRECT_RENDERING  = $01FE;
+
+  GLUT_FULL_SCREEN = $01FF;
+
+  // New tokens for glutInitDisplayMode.
+  // Only one GLUT_AUXn bit may be used at a time.
+  // Value 0x0400 is defined in OpenGLUT.
+  GLUT_AUX  = $1000;
+
+  GLUT_AUX1 = $1000;
+  GLUT_AUX2 = $2000;
+  GLUT_AUX3 = $4000;
+  GLUT_AUX4 = $8000;
+
+  // Context-related flags
+  GLUT_INIT_MAJOR_VERSION = $0200;
+  GLUT_INIT_MINOR_VERSION = $0201;
+  GLUT_INIT_FLAGS         = $0202;
+  GLUT_INIT_PROFILE       = $0203;
+
+  // Flags for glutInitContextFlags
+  GLUT_DEBUG              = $0001;
+  GLUT_FORWARD_COMPATIBLE = $0002;
+
+  // Flags for glutInitContextProfile
+  GLUT_CORE_PROFILE          = $0001;
+  GLUT_COMPATIBILITY_PROFILE = $0002;
+
+  // GLUT API macro definitions -- the display mode definitions
+  GLUT_CAPTIONLESS = $0400;
+  GLUT_BORDERLESS  = $0800;
+  GLUT_SRGB        = $1000;
+
+var
+  // Process loop function
+  glutMainLoopEvent: procedure; extdecl;
+  glutLeaveMainLoop: procedure; extdecl;
+  glutExit:  procedure; extdecl;
+
+  // Window management functions
+  glutFullScreenToggle: procedure; extdecl;
+
+  // Window-specific callback functions
+  glutMouseWheelFunc: procedure(callback: TGlut4IntCallback); extdecl;
+  glutCloseFunc: procedure(callback: TGlutVoidCallback); extdecl;
+  // A. Donev: Also a destruction callback for menus
+  glutMenuDestroyFunc: procedure(callback: TGlutVoidCallback); extdecl;
+
+  // State setting and retrieval functions
+  glutSetOption: procedure(option_flag: GLenum; value: Integer); extdecl;
+  glutGetModeValues: function(mode: GLenum; size: PInteger): Integer; extdecl;
+  // A.Donev: User-data manipulation
+  glutGetWindowData: function: Pointer; extdecl;
+  glutSetWindowData: procedure(data: Pointer); extdecl;
+  glutGetMenuData: function: Pointer; extdecl;
+  glutSetMenuData: procedure(data: Pointer); extdecl;
+
+  // Font stuff
+  glutBitmapHeight: function(font : pointer): Integer; extdecl;
+  glutStrokeHeight: function(font : pointer): GLfloat; extdecl;
+  glutBitmapString: procedure(font : pointer; const str: PChar); extdecl;
+  glutStrokeString: procedure(font : pointer; const str: PChar); extdecl;
+
+  // Geometry functions
+  glutWireRhombicDodecahedron: procedure; extdecl;
+  glutSolidRhombicDodecahedron: procedure; extdecl;
+  glutWireSierpinskiSponge: procedure(num_levels: Integer; offset: PGLdouble3; scale: GLdouble); extdecl;
+  glutSolidSierpinskiSponge: procedure(num_levels: Integer; offset: PGLdouble3; scale: GLdouble); extdecl;
+  glutWireCylinder: procedure(radius: GLdouble; height: GLdouble; slices: GLint; stacks: GLint); extdecl;
+  glutSolidCylinder: procedure(radius: GLdouble; height: GLdouble; slices: GLint; stacks: GLint); extdecl;
+
+  // Initialization functions
+  glutInitContextVersion: procedure(majorVersion: Integer; minorVersion: Integer); extdecl;
+  glutInitContextFlags: procedure(flags: Integer); extdecl;
+  glutInitContextProfile: procedure(profile: Integer); extdecl;
+
+{ Load all freeglut functions from given library.
+  Called automatically from Glut unit when standard Glut stuff is loaded. }
+procedure LoadFreeGlut(hDLL: TLibHandle);
+
+{ Set to nil all freeglut functions.
+  Called automatically from Glut unit when standard Glut stuff is unloaded. }
+procedure UnloadFreeGlut;
+
+implementation
+
+procedure LoadFreeGlut(hDLL: TLibHandle);
+begin
+  @glutMainLoopEvent := GetProcAddress(hDLL, 'glutMainLoopEvent');
+  @glutLeaveMainLoop := GetProcAddress(hDLL, 'glutLeaveMainLoop');
+  @glutExit := GetProcAddress(hDLL, 'glutExit');
+  @glutFullScreenToggle := GetProcAddress(hDLL, 'glutFullScreenToggle');
+  @glutMouseWheelFunc := GetProcAddress(hDLL, 'glutMouseWheelFunc');
+  @glutCloseFunc := GetProcAddress(hDLL, 'glutCloseFunc');
+  @glutMenuDestroyFunc := GetProcAddress(hDLL, 'glutMenuDestroyFunc');
+  @glutSetOption := GetProcAddress(hDLL, 'glutSetOption');
+  @glutGetModeValues := GetProcAddress(hDLL, 'glutGetModeValues');
+  @glutGetWindowData := GetProcAddress(hDLL, 'glutGetWindowData');
+  @glutSetWindowData := GetProcAddress(hDLL, 'glutSetWindowData');
+  @glutGetMenuData := GetProcAddress(hDLL, 'glutGetMenuData');
+  @glutSetMenuData := GetProcAddress(hDLL, 'glutSetMenuData');
+  @glutBitmapHeight := GetProcAddress(hDLL, 'glutBitmapHeight');
+  @glutStrokeHeight := GetProcAddress(hDLL, 'glutStrokeHeight');
+  @glutBitmapString := GetProcAddress(hDLL, 'glutBitmapString');
+  @glutStrokeString := GetProcAddress(hDLL, 'glutStrokeString');
+  @glutWireRhombicDodecahedron := GetProcAddress(hDLL, 'glutWireRhombicDodecahedron');
+  @glutSolidRhombicDodecahedron := GetProcAddress(hDLL, 'glutSolidRhombicDodecahedron');
+  @glutWireSierpinskiSponge := GetProcAddress(hDLL, 'glutWireSierpinskiSponge');
+  @glutSolidSierpinskiSponge := GetProcAddress(hDLL, 'glutSolidSierpinskiSponge');
+  @glutWireCylinder := GetProcAddress(hDLL, 'glutWireCylinder');
+  @glutSolidCylinder := GetProcAddress(hDLL, 'glutSolidCylinder');
+  @glutInitContextVersion := GetProcAddress(hDLL, 'glutInitContextVersion');
+  @glutInitContextFlags := GetProcAddress(hDLL, 'glutInitContextFlags');
+  @glutInitContextProfile := GetProcAddress(hDLL, 'glutInitContextProfile');
+end;
+
+procedure UnloadFreeGlut;
+begin
+  @glutMainLoopEvent := nil;
+  @glutLeaveMainLoop := nil;
+  @glutExit := nil;
+  @glutFullScreenToggle := nil;
+  @glutMouseWheelFunc := nil;
+  @glutCloseFunc := nil;
+  @glutMenuDestroyFunc := nil;
+  @glutSetOption := nil;
+  @glutGetModeValues := nil;
+  @glutGetWindowData := nil;
+  @glutSetWindowData := nil;
+  @glutGetMenuData := nil;
+  @glutSetMenuData := nil;
+  @glutBitmapHeight := nil;
+  @glutStrokeHeight := nil;
+  @glutBitmapString := nil;
+  @glutStrokeString := nil;
+  @glutWireRhombicDodecahedron := nil;
+  @glutSolidRhombicDodecahedron := nil;
+  @glutWireSierpinskiSponge := nil;
+  @glutSolidSierpinskiSponge := nil;
+  @glutWireCylinder := nil;
+  @glutSolidCylinder := nil;
+  @glutInitContextVersion := nil;
+  @glutInitContextFlags := nil;
+  @glutInitContextProfile := nil;
+end;
+
+end.

+ 9 - 4
packages/opengl/src/glut.pp

@@ -457,7 +457,7 @@ var
 {$ENDIF MORPHOS}
 
 procedure LoadGlut(const dll: String);
-procedure FreeGlut;
+procedure UnloadGlut;
 
 implementation
 
@@ -468,11 +468,13 @@ implementation
 {$INCLUDE tinygl.inc}
 
 {$ELSE MORPHOS}
+uses FreeGlut;
+
 var
   hDLL: TLibHandle;
 {$ENDIF MORPHOS}
 
-procedure FreeGlut;
+procedure UnloadGlut;
 begin
 {$IFDEF MORPHOS}
   // MorphOS's GL will closed down by TinyGL unit, nothing is needed here.
@@ -595,6 +597,8 @@ begin
   @glutEnterGameMode := nil;
   @glutLeaveGameMode := nil;
   @glutGameModeGet := nil;
+  
+  UnloadFreeGlut;
 {$ENDIF MORPHOS}
 end;
 
@@ -615,7 +619,7 @@ var
 
 begin
 
-  FreeGlut;
+  UnloadGlut;
 
   hDLL := LoadLibrary(PChar(dll));
   if hDLL = 0 then raise Exception.Create('Could not load Glut from ' + dll);
@@ -748,6 +752,7 @@ begin
   except
     raise Exception.Create('Could not load ' + MethodName + ' from ' + dll);
   end;
+  LoadFreeGlut(hDLL);
 end;
 {$ENDIF MORPHOS}
 
@@ -772,6 +777,6 @@ initialization
 
 finalization
 
-  FreeGlut;
+  UnloadGlut;
 
 end.