我有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倍。
编辑2:如果我将远剪裁平面设置为与摄像机高度相同的值,它似乎工作(但这不是一个合适的)。
2(设计问题):我觉得在OpenGL画布的绘图功能中处理点击是没有意义的。 我似乎要求该函数的GL能够检索gluUnProject运行所必需的矩阵。 你们怎么设计这个? 理想情况下,我觉得我应该能够将此运行与绘图功能完全分开。 将gl对象的引用存储到MouseController中,并在MouseListener选中它时处理单击。
关于你们如何处理它的输入也将非常感激!
I've got 2 questions. One's a specific question about why my code isn't working as intended and the other is a design question.
1 (Specific Question): I'm trying to map screen coordinates to world coordinates in a 2D tile-based engine (uses the x/y axis, z = 0). I've used a Nehe's tutorial port on how to achieve this but the results I get aren't as expected.
I have a class called MouseController. Whenever a mouse event is trigger (via swing's MouseListener), I pass the MouseEvent into my MouseController.
In my GLCanvas's draw function, I call the MouseController.processClick(GL) function to be able to pass the current gl context into the processClick function and grab the modelview, projection matrices and viewport.
When I click on a block rendered on the screen, the world coordinates that are given back to me make little to no sense. For one, I would expect the z value to be 0, but its 9 (which is how high my camera is set to), and my x and y values are always really close to 0 (occasionally jumping up to 1-9 with very slight movements, then back to a number very close to 0).
Anyone have any idea why this might be the case? The processClick function is below:
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; }Sample output I get from the above function when I click on the screen where I rendered a square at world coordinates (4,5,0):
878 56 878 636 0.0445182388817236 0.055475957454737095 8.900000001489369Thanks!
EDIT: Reading in the depth buffer using glReadPixels and using that as the z (which returns 1) gets me results that are kind of right, but are too big by a factor of 20.
EDIT2: If I set the far clipping plane to the same value as the height of the camera, it seems to work (but this isn't really a fit).
2 (Design Question): I feel as if it doesn't make sense to process clicks in the OpenGL canvas' draw function. I seem to require the GL from that function to be able to retrieve the matrices necessary for gluUnProject to run. How would you guys design this? Ideally I feel as if I should be able to have this run completely separate of the draw function. Store a reference to the gl object into my MouseController and process the click when the MouseListener picks up on it.
Input about how you guys would/do handle it would be much appreciated too!
最满意答案
我决定使用gluOrtho2D来设置我的投影以简化解决这个问题。
唯一“棘手”的事情是将实际的屏幕分辨率传递给gluOrtho2D,可以通过以下方式检索(和存储):
getContentPane().getSize()从我使用的JFrame。
在面板上设置首选尺寸然后包装框架获得了接近的结果,但面板本身仍然略微偏离。
I decided just to use gluOrtho2D to setup my projection to simplify solving this problem.
The only "tricky" thing was passing in the actual screen resolution to gluOrtho2D, which could be retrieved (and stored) with:
getContentPane().getSize()From the JFrame I used.
Setting the preferred size on the panel then packing the frame achieved close results, but the panel itself was still slightly off.
更多推荐
发布评论