Java OpenGL屏幕使用gluUnProject +设计讨论进行世界转换(Java OpenGL screen to world transformation using gluUnProjec

编程入门 行业动态 更新时间:2024-10-23 17:36:13
Java OpenGL屏幕使用gluUnProject +设计讨论进行世界转换(Java OpenGL screen to world transformation using gluUnProject + design discussion)

我有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.900000001489369

Thanks!

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.

更多推荐

本文发布于:2023-07-29 20:08:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1319391.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:屏幕   世界   gluUnProject   Java   OpenGL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!