+ support for the freeglut extensions (patch by Michalis Kamburelis,

mantis #18108)

git-svn-id: trunk@16535 -
This commit is contained in:
Jonas Maebe 2010-12-10 15:29:19 +00:00
parent e6e02a6176
commit deece746a3
6 changed files with 514 additions and 5 deletions

2
.gitattributes vendored
View File

@ -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

View File

@ -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)

View File

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

View File

@ -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.

View File

@ -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.

View File

@ -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.