1

我有 2 个问题。一个是关于为什么我的代码没有按预期工作的具体问题,另一个是设计问题。

1(具体问题):我正在尝试将屏幕坐标映射到基于 2D 瓦片的引擎中的世界坐标(使用 x/y 轴,z = 0)。我已经使用了 Nehe 的教程端口来了解如何实现这一点,但我得到的结果并不像预期的那样。

我有一个名为 MouseController 的类。每当触发鼠标事件时(通过 swing 的 MouseListener),我将 MouseEvent 传递给我的 MouseController。

在我的 GLCanvas 的绘制函数中,我调用 MouseController.processClick(GL) 函数以便能够将当前 gl 上下文传递到 processClick 函数并获取模型视图、投影矩阵和视口。

当我单击屏幕上呈现的块时,返回给我的世界坐标几乎没有意义。一方面,我希望 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 画布的绘制函数中处理点击似乎没有意义。我似乎需要该函数中的 GL 才能检索 gluUnProject 运行所需的矩阵。大家会怎么设计这个?理想情况下,我觉得我应该能够让这个运行完全独立于绘图功能。将 gl 对象的引用存储到我的 MouseController 中,并在 MouseListener 接收到它时处理单击。

关于你们将如何处理它的输入也将不胜感激!

4

1 回答 1

0

我决定只使用 gluOrtho2D 来设置我的投影以简化解决这个问题。

唯一“棘手”的事情是将实际屏幕分辨率传递给 gluOrtho2D,可以通过以下方式检索(和存储):

getContentPane().getSize()

来自我使用的 JFrame。

在面板上设置首选尺寸然后包装框架获得了接近的结果,但面板本身仍然略微偏离。

于 2012-03-11T02:03:42.393 回答