この技術大丈夫なのか?

OS XでJOGLを使うための環境構築

OS X 10.7, JDK 1.6.0

経緯

せっかくOpenGLを多少なりとも使えるようになったから、ちょっと会社のWindows PCの人たちにも簡単なデモアプリを見せてやりたい、と思いました。で、まあ、私は普段OS Xを使っているので、Javaで作ればWindowsでも動くだろう、と考えたのです。しかしながら、Java 3Dという言葉は聞いたことがあるけれど、JavaOpenGLってどうやって使うのかは全く知らなかったので、「Java OpenGL」でGooglingしました。結果、出てきた情報といえば、@ITの2006年の記事でしたよ。情報が少なすぎる。なんだJOGLって!? JavaOpenGLってそんなに流行ってないの!? まあ、きっと今時ならWebGLの方がナウなんでしょうね。しかし、JOGLくん、wikiですら出て来ないって・・・。


何をダウンロードすれば良いのかすらわからない

たぶんここが公式サイトだと思います。
@ITの記事通りに環境構築したつもりでしたが、デモアプリは動きませんでした。そりゃそうだ。7年も前の記事だもの。環境が変わっていたって不思議じゃない。やや途方に暮れていたのですが、こちらの方の記事が大変的を得ていました。Windows向けに書かれていましたが、結果的にOS Xでも必要なファイルはほぼ同じでした。はてなの人たちってすごいね。

さて、いくつかのJARファイルと、いくつかのネイティブライブラリが必要なわけですが、どういうわけか、公式で配布されているJARファイルをそのまま使おうとしてもダメでした。どうダメだったかというと、JARが壊れているのか、なんなのか、JARの中身を見ようとするとZipExceptionが発生してしまいます。

$jar tvf jogl-all.jar 
java.util.zip.ZipException: error in opening zip file
	at java.util.zip.ZipFile.open(Native Method)
	at java.util.zip.ZipFile.<init>(ZipFile.java:127)
	at java.util.zip.ZipFile.<init>(ZipFile.java:88)
	at sun.tools.jar.Main.list(Main.java:977)
	at sun.tools.jar.Main.run(Main.java:222)
	at sun.tools.jar.Main.main(Main.java:1147)

導入手順

上記の通り、直接JARを落としてもダメだったので、最終的に、7z形式の方を落として解凍することにしました。Windows系の圧縮形式を使うのは少々屈辱的ですが、仕方ありません。

・まず、MacPortsで7zを解凍できるソフトウェアを導入しておきます。

$sudo ports install p7zip

・公式から jogamp-all-platforms.7z をダウンロードします。
・ダウンロードした7zファイルを解凍します。

$7z x jogamp-all-platforms.7z

※lib/macosx-universal内のREADME.txtを見ると、このディレクトリ内のネイティブライブラリは推奨されないとのことでした。どうやら、現行バージョン(2.0-rc11)では、ネイティブJARファイルを、gluegen-rt.jar, jogl-all.jarの2つと同じディレクトリに配置しておけば良いようです。

・以下のJARファイルを適当なディレクトリ(ここでは~/libとします)にコピーします。

jar/gluegen-rt.jar
jar/jogl-all.jar
jar/gluegen-rt-natives-macosx-universal.jar
jar/jogl-all-natives-macosx-universal.jar

・JARファイルのクラスパスを通します。

$export CLASSPATH=$CLASSPATH:~/lib/gluegen-rt.jar:~/lib/jogl-all.jar

以上で環境構築完了です。


デモアプリを実行してみる

・環境確認のため、デモアプリをダウンロードします。
・公式から jogl-demos.7z をダウンロードします。
・ダウンロードした7zファイルを解凍して実行してみます。

$7z x jogl-demos.7z
$cd jogl-demos/jar
$export CLASSPATH=$CLASSPATH:./jogl-demos.jar:./jogl-demos-util.jar:./jogl-demos-data.jar
$java demos.gears.Gears

おお〜動いた


しかしながら、demos.hdr.HDRの方は動きませんでした。
理由はよくわかりません。

Exception in thread "main-AWTAnimator-1" java.lang.RuntimeException: javax.media.opengl.GLException: Floating-point support (GL_APPLE_float_pixels) not available
	at jogamp.common.awt.AWTEDTExecutor.invoke(AWTEDTExecutor.java:58)
	at jogamp.opengl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:103)
	at jogamp.opengl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:205)
	at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:172)
	at javax.media.opengl.Threading.invoke(Threading.java:191)
	at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:449)
	at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:74)
	at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:142)
	at com.jogamp.opengl.util.Animator$MainLoop.run(Animator.java:176)
	at java.lang.Thread.run(Thread.java:680)
Caused by: javax.media.opengl.GLException: Floating-point support (GL_APPLE_float_pixels) not available
	at jogamp.opengl.macosx.cgl.MacOSXPbufferCGLDrawable.createPbuffer(MacOSXPbufferCGLDrawable.java:159)
	at jogamp.opengl.macosx.cgl.MacOSXPbufferCGLDrawable.setRealizedImpl(MacOSXPbufferCGLDrawable.java:84)
	at jogamp.opengl.GLDrawableImpl.setRealized(GLDrawableImpl.java:182)
	at jogamp.opengl.GLDrawableFactoryImpl.createGLPbuffer(GLDrawableFactoryImpl.java:248)
	at demos.hdr.HDR.init(HDR.java:338)
	at jogamp.opengl.GLDrawableHelper.init(GLDrawableHelper.java:332)
	at jogamp.opengl.GLDrawableHelper.init(GLDrawableHelper.java:352)
	at javax.media.opengl.awt.GLCanvas$6.run(GLCanvas.java:966)
	at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:653)
	at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:594)
	at javax.media.opengl.awt.GLCanvas$8.run(GLCanvas.java:996)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:702)
	at java.awt.EventQueue.access$400(EventQueue.java:82)
	at java.awt.EventQueue$2.run(EventQueue.java:663)
	at java.awt.EventQueue$2.run(EventQueue.java:661)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:672)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)