• 締切済み

JOGLで、GLJpanelの外でOpenGLの関数を呼ぶには

JOGLでは、GLJPanelの各種メソッド(init,display,reshapeなど)でしか、OpenGLの関数を呼べないみたいですが、どうしてもGLJPanelの外でOpenGL の関数を呼びたいんです。携帯電話とPCの両方で動かすことができる2D描画のライブラリをつくっているので、特定のクラスの派生クラスにしなくちゃいけないとかではなく、ユーザーが自作したクラスからOpenGLを呼べるようにしたいんです。 試しに以下のコードを参考にして、initで取得したGLクラスの参照を使って、GLJPanelの外でOpenGLの関数を呼んだら、AccessVioration(アクセス違反)のエラーが出てJavaのVMが落ちてしまいました。しかも、GLJPanelのinitが呼び出されるタイミングが分からず、最初はglがnullになっていることもあります。何かいい方法はないでしょうか・・? http://d.hatena.ne.jp/SofiyaCat/20090425/1240646625

みんなの回答

  • komi1341
  • ベストアンサー率65% (25/38)
回答No.1

あまり自信がないのですが経験からのコメントです。 GLクラスのオブジェクトは描画時に都度作成されるため、例えばGLJPanel.display()内でGLクラスのオブジェクトをメンバ変数か何かに保持したとしても、その変数を使ってOpenGLの機能を呼ぶことはできません。おそらく次の描画が始まったときには、前に保持したGLの値は破棄されているのでしょう。無理やり使っても結果は不定になります。AccessViorationになることもあるでしょうし、一見何事も起こらなかったように見えることもあります。 ですので参考サイトのやり方は明らかにまずいです。作者も薄々気づいているのかTODOと書いてありますね。 描画を目的としたライブラリであれば、GLJPanelを継承するのが無難だと思います。他のクラスを継承する=ユーザが自作したクラスからOpenGLを呼べなくなる、ということではないと思うので、なぜ継承では駄目なのか、も書かれた方がよいように思います。

vroad
質問者

補足

>GLクラスのオブジェクトは描画時に都度作成されるため、例えばGLJPanel.display()内でGLクラスのオブジェクトをメンバ変数か何かに保持したとしても、その変数を使ってOpenGLの機能を呼ぶことはできません。 間違ってました。display等はGLEventListenerのメソッドでした。 GLクラスを変数に保存して使っても、それをほかのクラスに渡さずに使う分には問題ないようです。(でも全てのメソッドでGLDrawableを渡しているのは、違うインスタンスが渡されることもあるという事なんでしょうか・・?) その後、一応表示はできるようになりましたが、これがベストの方法ではないと思います。 描画ライブラリの処理が実行されているスレッドとGLJPanelの処理が実行されているスレッドが別なのに気づいたので、GLDrawable.createContextで、コンテキストを複製して、ライブラリが実行されているスレッドでGLContext.makeCurrentを呼び出しました。(C++でOpenGLを使っていたときの経験で、ひとつのコンテキストを二つ以上のスレッドで有効にすることは出来ないというのは知っていました。)しかし、このメソッドを呼び出したときに例外が発生してしまいます。 Exception in thread "Thread-0" javax.media.opengl.GLException:wglShareLists(0x40000, 0x10001) failed: error code 0 Object.waitを使って、GLEventListener.initが完了するまで待つようにしはしたんですが・・。それで、makeCurrentの前に500msぐらいThread.Sleepで待つと、うまく行くこともあります。しかしもっと他にいい方法が無いものでしょうか。 ユーザーが自作したクラスにGLJPanel(GLEventListener?)を継承するのを強制させるのが駄目なのは、他のAPIを使った描画も利用できるようにする予定なのに、それだとJOGLべったりになってしまうからです。携帯だとJOGLは使えないので。

すると、全ての回答が全文表示されます。

関連するQ&A