ところが、ウィンドウを閉じてもプロセスが終了しません。GLUTバインディングのAPIドキュメントを見ると、closeCallbackを指定するとうまくいきそうに見えます。というわけで、こんな感じにしてみます。
import Graphics.Rendering.OpenGL import Graphics.UI.GLUT import System.Exit main = do (progName, _) <- getArgsAndInitialize createWindow "Hello World" displayCallback $= clear [ColorBuffer] closeCallback $= Just exitSuccess mainLoop
これを実行すると、
opengl1.exe: user error (unknown GLUT entry glutCloseFunc)
というエラーになります。どうやら、glut32.dllからglutCloseFuncというエントリがエクスポートされていないようです。色々調べてみると、glutCloseFuncというのは、OpenGLUTというGLUTから派生したプロジェクトで追加されたAPIのようです。そこでバイナリをダウンロードして、OpenGLUT.dllをglut32.dllにリネームして実行してみると、今度は、
opengl1.exe: user error (unknown GLUT entry glutInit)
というエラーが発生します。Dependency Walkerで調べてみると、OpenGLUTのDLLは、stdcallの命名規約そのままで関数をエクスポートしているようで、例えばglutInitは、_glutInit@8という名前でエクスポートされています。
仕方がないのでソースをダウンロードしてきて、以下のようなDEFファイルをリンカのオプションで指定してビルドしてみました。
LIBRARY OpenGLUT EXPORTS glutInit glutInitDisplayMode glutInitDisplayString glutInitWindowPosition glutInitWindowSize glutMainLoop glutCreateWindow glutCreateSubWindow glutDestroyWindow glutPostRedisplay glutPostWindowRedisplay glutSwapBuffers glutGetWindow glutSetWindow glutSetWindowTitle glutSetIconTitle glutPositionWindow glutReshapeWindow glutPopWindow glutPushWindow glutIconifyWindow glutShowWindow glutHideWindow glutFullScreen glutSetCursor glutWarpPointer glutEstablishOverlay glutRemoveOverlay glutUseLayer glutPostOverlayRedisplay glutPostWindowOverlayRedisplay glutShowOverlay glutHideOverlay glutCreateMenu glutDestroyMenu glutGetMenu glutSetMenu glutAddMenuEntry glutAddSubMenu glutChangeToMenuEntry glutChangeToSubMenu glutRemoveMenuItem glutAttachMenu glutDetachMenu glutDisplayFunc glutReshapeFunc glutKeyboardFunc glutMouseFunc glutMotionFunc glutPassiveMotionFunc glutEntryFunc glutVisibilityFunc glutIdleFunc glutTimerFunc glutMenuStateFunc glutSpecialFunc glutSpaceballMotionFunc glutSpaceballRotateFunc glutSpaceballButtonFunc glutButtonBoxFunc glutDialsFunc glutTabletMotionFunc glutTabletButtonFunc glutMenuStatusFunc glutOverlayDisplayFunc glutWindowStatusFunc glutKeyboardUpFunc glutSpecialUpFunc glutJoystickFunc glutSetColor glutGetColor glutCopyColormap glutGet glutDeviceGet glutExtensionSupported glutGetModifiers glutLayerGet glutBitmapCharacter glutBitmapWidth glutStrokeCharacter glutStrokeWidth glutBitmapLength glutStrokeLength glutWireSphere glutSolidSphere glutWireCone glutSolidCone glutWireCube glutSolidCube glutWireTorus glutSolidTorus glutWireDodecahedron glutSolidDodecahedron glutWireTeapot glutSolidTeapot glutWireOctahedron glutSolidOctahedron glutWireTetrahedron glutSolidTetrahedron glutWireIcosahedron glutSolidIcosahedron glutVideoResizeGet glutSetupVideoResizing glutStopVideoResizing glutVideoResize glutVideoPan glutReportErrors glutIgnoreKeyRepeat glutSetKeyRepeat glutForceJoystickFunc glutGameModeString glutEnterGameMode glutLeaveGameMode glutGameModeGet glutMainLoopEvent glutLeaveMainLoop glutCloseFunc glutWMCloseFunc glutMenuDestroyFunc glutSetOption glutSetWindowData glutGetWindowData glutSetMenuData glutGetMenuData glutBitmapHeight glutStrokeHeight glutBitmapString glutStrokeString glutWireRhombicDodecahedron glutSolidRhombicDodecahedron glutWireSierpinskiSponge glutSolidSierpinskiSponge glutGetProcAddress glutMouseWheelFunc
できたOpenGLUT.dllをglut32.dllにリネームしてから実行すると、最初のサンプルも実行できるようになりました。しかし、どうやらOpenGLUTでは最初からこの問題に対処してあるようで、closeCallbackを指定しなくても、ウィンドウを閉じるとプロセスが終了するようになっていました。