• 締切済み

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

  • vroad
  • お礼率27% (5/18)
  • Java
  • 回答数1
  • ありがとう数0

みんなの回答

  • 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

  • JOGL OpenGLプログラミングについて

    こんにちは。 私は、現在行っている研究にOpenGLによる経路探査シミュレーションを取り入れたいと考えております。 プログラミングの経験はjavaでの知識半年(全てネット上で)しかなく,sunの提供しているJOGL(Java bindings for OpenGL)に挑戦しています。 しかし、JOGLのネット上での情報には限りがあり,JOGLのdocを見ても所々のクラスやメソッドに、interface C language と書いてあったりするだけですので、 Cベースのマニュアルを参照しておりますが言語的になかなか理解することが出来ません。 結局OpenGLは、一からC/C++を勉強してその環境でやるべきか悩んでいます。 これまでEclipse上でjavaプログラミングをしていたのでVisualStudio(Visual C++)に挑戦しようと思ってもなかなか補完などの処理にどうしてもとっつきづらい感があります。 JOGLのプログラミングマニュアルやサイト(英語可)で有能なものがありましたら教えていただけませんでしょうか? またJOGLよりも有能なjava bindingがありましたら教えていただけませんでしょうか? もし,C/C++をお奨めされる方の中でEclipse + CDTを使っていらっしゃる方がいましたらCDTに関するお奨めのサイトもしくは本がありましたら,教えていただけませんでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • JOGLで描画した立方体の中心座標

    JOGLに関する質問です。 GLUTクラスのメソッドglutSolidCubeで描画した立方体の中心座標を知る方法はありませんか? たくさんの立方体を描画し、マウスポインタの下にある立方体が選択状態になるようにしたいのですが、 立方体の中心座標を使ってそれを実現しようと思っています。

    • ベストアンサー
    • Java
  • eclipseでのjogl利用について

    ネットで調べた通りにビルドパスを構成したつもりなんですけど Exception in thread "main" java.lang.UnsatisfiedLinkError: no jogl in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682) at java.lang.Runtime.loadLibrary0(Runtime.java:822) at java.lang.System.loadLibrary(System.java:993) at com.sun.opengl.impl.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:189) at com.sun.opengl.impl.NativeLibLoader.access$000(NativeLibLoader.java:49) at com.sun.opengl.impl.NativeLibLoader$DefaultAction.loadLibrary(NativeLibLoader.java:80) at com.sun.opengl.impl.NativeLibLoader.loadLibrary(NativeLibLoader.java:103) at com.sun.opengl.impl.NativeLibLoader.access$200(NativeLibLoader.java:49) at com.sun.opengl.impl.NativeLibLoader$1.run(NativeLibLoader.java:111) at java.security.AccessController.doPrivileged(Native Method) at com.sun.opengl.impl.NativeLibLoader.loadCore(NativeLibLoader.java:109) at com.sun.opengl.impl.windows.WindowsGLDrawableFactory.<clinit>(WindowsGLDrawableFactory.java:60) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:164) at javax.media.opengl.GLDrawableFactory.getFactory(GLDrawableFactory.java:106) at javax.media.opengl.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:520) at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:131) at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:90) at javax.media.opengl.GLCanvas.<init>(GLCanvas.java:83) at demos.gears.Gears.main(Gears.java:19) このような、エラーが出ました。 どうしたら、いいかわかりません。教えていただけないでしょうか!!

  • OpenGLで登録したコールバック関数の引数

    OpenGLで画面を描画をする際に, 以下のソースのように,glutDisplayFuncに関数を登録しています. main関数で,定義した定数や,そのポインタを display_funcに渡したいと思うのですが, どのような方法があるのでしょうか? 現在,私は,グローバル変数を定義して,それをmain関数とdisplay関数で いじっています. ソースコードの整理,関数化のため,できれば,ポインタや引数を渡したいです. どうぞよろしくお願いします. --------------------------------------------- #include <GL/glut.h> void display_func(void) { 描画内容を記述 } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutCreateWindow(argv[0]); glutDisplayFunc(display_func); glutMainLoop(); return 0; } ---------------------------------------------

  • awt+joglでの3D+2D描画に関して

    joglを使って簡単なポリゴンにテクスチャを貼り付けて、 マウスイベントによって回転・移動を行えるプログラムを 作っています。操作を始めるとマウスカーソルの代わりに 独自の画像をマウスカーソルが表示されていた部分に 表示されるようにしたいと考えています。 質問は、マウスカーソルの代わりに表示させる画像の 表示方法についてです。 開発環境 SDKとして、eclipse日本語化プロジェクトのpleiadesの バージョン3.5の最新のものを使用しています。(jreあり) PCは、自作でスペックは以下の通りです。 CPU:penD940 3.2GHz メモリ:2GB HD:320GB G/B:GForce6600 質問の意図をわかりやすくするために簡単な説明と これまでの進展を説明したいと思います。 まず、joglを使用する方法としてGLCanvasとGLJPanelの どちらかにGLEventListenerをaddして利用する方法があると 思います。2Dの描画を加える場合、たとえば、GLCanvasを継承した クラスを独自に作成し、paintメソッドをオーバーライドして 3D描画に2D描画を上書きする方法があると思います。この方法だと、 GLCanvasではダブルバッファが有効ではないため、非常にちらついた 表示になってしまいます。GLJPanelを利用すればその問題が解消 されますが、残念なことに処理が重くなり操作性が著しく落ちてしまいます。 そこで、GLCanvasをベースにGLPbufferクラスを利用してjoglの描画を オフスクリーンに描画するというように独自にダブルバッファの 処理を作成しました。この方法では、GLJPanelよりも多少軽く 動作しているものの、残念ながら操作性が維持できる処理速度を 確保することができませんでした。 おそらく、問題点はオフスクリーンとして使っているBufferedImageの 書き換え時の処理に時間がかかっているものと推測しました。 そこで、さらにBufferStrategyクラスも利用してみましたが、 GLPbufferの描画をbufferedImageに書き込む処理でつまずいてしまう ようであまり効果がありませんでした。 joglでポリゴンにテクスチャを貼り付けるということで擬似2D的なことは 可能ですが、作っているプログラムの特性上、画像サイズの管理やマウス ポインタの位置との連動を行うことになるため複雑になるのは避けたいです。 というところで、現在こんな具合で作業を進めて参りました。 質問内容としてましては、上記以外の方法で、 「3D描画と2D描画を組み合わせて軽快な処理ができる方法」 をご教授していただきたいです。 何卒よろしくお願いします。

  • X Window上でのOpenGLの使用

    お世話になっております. C++で書いたOpenGLを用いたプログラムをlinux上で演算させ, x WindowでWindowsのPC上に3次元描画をするために, 現在,試行錯誤をしております. (3次元描画と格好いい文言ですが,所詮,点列や辺の描画なんですが・・・) そのプログラムの実行過程で, 描画関数において,エラーが出ていて,それに関する質問です. 現在の状況として, プログラムのコンパイルは出来ております.一応,コンパイラはicpcを使ってます. で,実行エラーとして, freeglut (./a.out): OpenGL GLX extension not supported by display '***.***.***.***:0.0' と出ております. このエラーは,glCreatWindow()という関数でエラーが返されており, X Windowを用いて表示するためには,他のライブラリが必要であると考えました. そこで,調査したところ, XGLというライブラリの存在を知りました. 私の理解では, XGLとは,X WindowでOpenGLを使用するためのドライバー的なライブラリだと理解しております. そこで,使い方を調査しているのですが, ネット検索の段階で,全く掲載ページがない, (書籍の調査は明日以降かなと・・・) ということで,ここに質問させていただきました. 具体的なプログラミングの仕方,参考Webページ,書籍等 や, そもそも,XGLなんて間違っていて,他に使用すべきライブラリがある, とか... 出来れば,C++で書いた現在のプログラムに, 少しだけの変更で収められるようなモノが良いな...と欲張りなことも思っています... ご存じであれば,教えていただきたく,お願い申し上げます. ソースコードは... 数千行のプログラムなので,ちょっと勘弁願いたく...

  • JOGLのグラフィクスのプログラムについての質問

    以下のプログラミングコードについて質問です。以下のコードはJavaのJOGLで立方体を描くためのプログラムなのですが、これを編集して正四面体を描けるコードにかえたいです。どのように編集すればいいでしょうか?何行目のどこをどう書き換えるといいというようにできるだけ詳しくお願いします。 import java.awt.*; import java.awt.event.*; import javax.media.opengl.*; import javax.media.opengl.glu.*; import javax.media.opengl.awt.*; public class CubePosition extends GLCanvas implements GLEventListener { public static void main(String[] args) { if (args.length == 3) (new CubePosition("CubePosition", args)).showFrame(); else (new CubePosition("CubePosition")).showFrame(); } private Frame f; protected GL2 gl; protected GLU glu; protected double eye_x = 4.0, eye_y = 3.0, eye_z = 7.0; protected CubePosition(String name) { super(); setSize(500, 500); addGLEventListener(this); f = new Frame(name); f.add(this); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } protected CubePosition(String name, String[] args) { this(name); eye_x = Double.parseDouble(args[0]); eye_y = Double.parseDouble(args[1]); eye_z = Double.parseDouble(args[2]); } protected void showFrame() { f.setVisible(true); } public void init(GLAutoDrawable drawable) { gl = drawable.getGL().getGL2(); glu = new GLU(); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glEnable(GL2.GL_DEPTH_TEST); gl.glEnable(GL2.GL_CULL_FACE); } public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { final double fieldOfView = 25.0, near = 1.0, far = 20.0; double aspect = (double) w / (double) h; gl.glViewport(0, 0, w, h); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(fieldOfView, aspect, near, far); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt(eye_x, eye_y, eye_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } public void diplay(GLAutoDrawable drawable) { gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); cubeDisplay(); } static float[][] vertices = {{ -1.0f, -1.0f, -1.0f },{ 1.0f, -1.0f, -1.0f },{ 1.0f, 1.0f, -1.0f }, { -1.0f, 1.0f, -1.0f },{-1.0f, -1.0f, 1.0f },{ 1.0f, -1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f },{ -1.0f, 1.0f, 1.0f }}; static int[][] faces = {{ 1, 2, 6, 5 },{ 2, 3, 7, 6 },{ 4, 5, 6, 7 },{ 0, 4, 7, 3 }, { 0, 1, 5, 4 },{ 0, 3, 2, 1 }}; static float[][] colors = {{ 0.0f, 1.0f, 1.0f },{ 1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 0.0f }, { 0.0f, 0.5f, 0.5f },{ 0.5f, 0.0f, 0.5f },{ 0.5f, 0.5f, 0.0f }}; protected void cubeDisplay() { gl.glBegin(GL2.GL_QUADS); for (int i =0; i < faces.length; i++) { gl.glColor3fv(colors[i], 0); for (int j = 0; j < faces[i].length; j++) gl.glVertex3fv(vertices[faces[i][j]], 0); } gl.glEnd(); gl.glFlush(); } public void dispose(GLAutoDrawable drawable) { } }

  • OpenGLで描画した画像のピクセル(RGB)を配列に格納したい。

    初めまして。taka-0910と申します。 現在、OpenGLを使って描画した画像のピクセル情報を取得しようと考えています。 しかし、取得したRGBの値が描画したものとまったく異なる値となってしまいます。 glReadPixels()という関数で試していますが、何度修正してもうまくいきません。よろしくお願いします。 プログラムの一部ですがこのようになっています。プログラムが一部分で申し訳ありません width, heightというのは、画像のサイズです。 *pixelsに画素(RGB)の値を格納したいと考えています。 GLubyte *pixels; pixels = ( GLubyte* )malloc( width * height * 3 * (sizeof(GLubyte))); glReadBuffer(GL_FRONT); glPixelStorei( GL_PACK_ALIGNMENT,1 ); glReadPixels( 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels ); glFlush();

  • プログラミングのopenglで困っています.

    OpenGlの超初心者です. openglで,円を一つ作ってあるsampleプログラムを拾ってきたのですが, 円をもう一つ,別の座標で作りたいのですが,以下のプログラムをどのように編集すればいいですか? 誰か助けてください. ========================================== #include <GLUT/glut.h> #include "glut.h" #include <math.h> //--初期化処理------------------------------------------------------------------ void myinit(void){ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//背景色の設定(R,G,B,ALPHA) 0.0-1.0の範囲で } //--描画内容-------------------------------------------------------------------- void display(void){ float x1,y1,x2,y2; float th1,th2; float th1_rad, th2_rad; float hankei = 0.1; glClear(GL_COLOR_BUFFER_BIT);//画面全体を背景色で塗りつぶす glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //単位行列を行列スタックに読み込む glColor3f(0.0f, 0.0f, 0.0f);//頂点カラーの指定( R, G, B すべてが1.0fなら白) for (th1 = 0.0; th1 <= 360.0; th1 = th1 + 10.0){ th2 = th1 + 10.0; th1_rad = th1 / 180.0 * 3.1415926; // 「度」を「ラジアン」に直す th2_rad = th2 / 180.0 * 3.1415926; x1 = hankei * cos(th1_rad); y1 = hankei * sin(th1_rad); x2 = hankei * cos(th2_rad); y2 = hankei * sin(th2_rad); glBegin(GL_LINES);//glBegin(GL_LINES)とglEnd()の間に glVertex2f( x1, y1 ); //描画したい直線の頂点を並べる glVertex2f( x2, y2 ); glEnd(); //ここまでで,ひとつのオブジェクトの宣言がおわる } glFlush();//OpenGLで実際に描画を行う } //--再描画---------------------------------------------------------------------- void myReshape(GLsizei w, GLsizei h){ glViewport(0,0,w,h); //ウィンドウ全体をビューポートにする glMatrixMode(GL_PROJECTION); glLoadIdentity();//単位行列を行列スタックに読み込む glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); } //--メイン関数------------------------------------------------------------------ int main(int argc, char **argv){ glutInitWindowPosition(100, 100); //(図形が描画される)ウィンドウ位置の設定 glutInitWindowSize(600, 600); //(図形が描画される)ウィンドウサイズの設定 glutInit(&argc, argv);//環境の初期化 glutInitDisplayMode(GLUT_RGBA|GLUT_SINGLE); //表示モードの設定 glutCreateWindow("kadai"); //ウィンドウを開く glutDisplayFunc(display); //図形表示関数の指定 myinit(); glutReshapeFunc(myReshape); //座標軸・ビューポート設定関数の指定 glutMainLoop();//無限ループ return 0; } ==========================================

  • openGLの回転の仕組みが分からなくて、困っています

    openGL初心者です。描画関数で以下のような書き方でx軸、y軸、z軸それぞれに角度を与えてオブジェクトを描画しているのですが、意図した角度に回転してくれません。 一応自分の認識では、openGLでは以下のような書き方をすると、まずオブジェクトの描画がされて、次にz軸の回転→y軸の回転→x軸の回転と、処理の順番とは逆に計算が行われると知ったのですが、まずその認識は正しいでしょうか? そこで、実際にx、y、z軸にそれぞれ角度を与えてオブジェクトを回転させてみるのですが、どうも意図した回転にならないのです。 例えばz軸に90度の値を与えて、オブジェクトを横に倒したとします。 まず、その状態でローカル座標系のx軸とy軸がz軸を中心に90度回っていると思っています。 その後、y軸に90度の値を与えても、ローカル座標系のy軸を中心に回らず、まるでワールド座標系のy軸を中心に90度回りまわっているように見えます。また、x軸も同様にワールド座標系のx軸を中心に90度回ります。 そこで、ワールド座標系で回るのかと思い、今度は、ニュートラルの状態から、y軸を90度回します。ローカル座標ではx軸、z軸がy軸を中心に90度回ると思います。次にx軸に対して、角度を与えてやると今度はローカル座標系のx軸を中心にまわるのです。 何故このような回転をするのかイメージできません。。どなたか回答いただけませんでしょうか? それと本当にやりたいことは、オブジェクトがどのような姿勢で回転していても(ローカル座標系がどうであれ)ワールド座標系のx、y、z軸を中心に回転させたいのですが、宜しければその辺も合わせて教えて頂けたら幸いです。 (数学の知識も乏しいので、数式がちゃんとあるのなら、その名前を教えていただければ直幸いです。) 乱文失礼します。 public void display(GLAutoDrawable drawable) { gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gluLookAt((double) 0.0f, (double) 0.0f, (double) 5.5f, (double) 0.0f, (double) 0.0f, (double) 0.0f, (double) 0.0f, (double) 1.0f, (double) 0.0f); gl.glEnableClientState(GL.GL_VERTEX_ARRAY); gl.glEnableClientState(GL.GL_COLOR_ARRAY); gl.glRotatef(AngleX, 1, 0, 0); gl.glRotatef(AngleY, 0, 1, 0); gl.glRotatef(AngleZ, 0, 0, 1); // オブジェクト描画 draw(gl); gl.glDisableClientState(GL.GL_COLOR_ARRAY); gl.glDisableClientState(GL.GL_VERTEX_ARRAY); }

専門家に質問してみよう