2つの質問があります。1つは、コードが意図したとおりに機能しない理由に関する具体的な質問であり、もう1つは設計上の質問です。
1(特定の質問):2Dタイルベースのエンジン(x / y軸、z = 0を使用)で画面座標をワールド座標にマッピングしようとしています。これを実現する方法についてNeheのチュートリアルポートを使用しましたが、期待どおりの結果が得られません。
MouseControllerというクラスがあります。マウスイベントがトリガーされるたびに(swingのMouseListenerを介して)、MouseEventをMouseControllerに渡します。
GLCanvasの描画関数で、MouseController.processClick(GL)関数を呼び出して、現在のglコンテキストをprocessClick関数に渡し、modelview、射影行列、およびビューポートを取得できるようにします。
画面に表示されているブロックをクリックすると、返される世界座標はほとんど意味がありません。1つは、z値が0であると予想しますが、その9(カメラが設定されている高さ)であり、x値とy値は常に0に非常に近いです(ときどき1〜9に跳ね上がります。わずかな動き、そして0に非常に近い数に戻ります)。
なぜこれが当てはまるのか誰かが知っていますか?processClick関数は以下のとおりです。
public void processClick(GL gl) {
int x = e.getX();
int y = e.getY();
if(e.getButton() == MouseEvent.BUTTON1) {
gl.glGetIntegerv(GL.GL_VIEWPORT, viewPort, 0);
gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvMatrix, 0);
gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, prMatrix, 0);
int realy = viewPort[3] - y;
glu.gluUnProject((double)x, (double)realy, 0, mvMatrix, 0, prMatrix, 0, viewPort, 0, wCoord, 0);
System.out.println(x + " " + y);
System.out.println(x + " " + realy);
System.out.println(wCoord[0] + " " + wCoord[1] + " " + wCoord[2]);
}
e = null;
}
ワールド座標(4,5,0)で正方形をレンダリングした画面をクリックすると、上記の関数から得られる出力例は次のとおりです。
878 56
878 636
0.0445182388817236 0.055475957454737095 8.900000001489369
ありがとう!
編集: glReadPixelsを使用して深度バッファーを読み取り、それをz(1を返す)として使用すると、ある程度正しい結果が得られますが、20倍大きすぎます。
EDIT2:遠方のクリッピング平面をカメラの高さと同じ値に設定すると、機能しているように見えます(ただし、これは実際には適合しません)。
2(デザインの質問):OpenGLキャンバスの描画機能でクリックを処理するのは意味がないように感じます。gluUnProjectの実行に必要な行列を取得できるようにするには、その関数からGLが必要なようです。どうやってこれをデザインしますか?理想的には、これを描画機能とは完全に分離して実行できるはずだと感じています。glオブジェクトへの参照をMouseControllerに保存し、MouseListenerがそれを取得したときにクリックを処理します。
あなたたちがそれをどのように扱うか/行うかについての入力も大いにありがたいです!