Opengl 使用2次gluUnproject调用在世界坐标中获取鼠标以创建光线
我尝试使用许多人似乎找到的好方法,我用不同的z值调用GlunProject 2次,然后尝试从这2个向量计算光线的方向向量 我阅读并尝试将其中的结构用于我自己的代码:Opengl 使用2次gluUnproject调用在世界坐标中获取鼠标以创建光线,opengl,lwjgl,glu,ray-picking,mouse-picking,Opengl,Lwjgl,Glu,Ray Picking,Mouse Picking,我尝试使用许多人似乎找到的好方法,我用不同的z值调用GlunProject 2次,然后尝试从这2个向量计算光线的方向向量 我阅读并尝试将其中的结构用于我自己的代码: glGetFloat(GL_MODELVIEW_MATRIX, modelBuffer); glGetFloat(GL_PROJECTION_MATRIX, projBuffer); glGetInteger(GL_VIEWPORT, viewBuffer); glu
glGetFloat(GL_MODELVIEW_MATRIX, modelBuffer);
glGetFloat(GL_PROJECTION_MATRIX, projBuffer);
glGetInteger(GL_VIEWPORT, viewBuffer);
gluUnProject(mouseX, mouseY, 0.0f, modelBuffer, projBuffer, viewBuffer, startBuffer);
gluUnProject(mouseX, mouseY, 1.0f, modelBuffer, projBuffer, viewBuffer, endBuffer);
start = vecmath.vector(startBuffer.get(0), startBuffer.get(1), startBuffer.get(2));
end = vecmath.vector(endBuffer.get(0), endBuffer.get(1), endBuffer.get(2));
direction = vecmath.vector(end.x()-start.x(), end.y()-start.y(), end.z()-start.z());
但这只返回齐次剪辑坐标(我相信),因为它们在每个轴上的范围仅为-1到1
如何实际获取坐标,从中创建光线
编辑:我就是这样构造矩阵的:
Matrix projectionMatrix = vecmath.perspectiveMatrix(60f, aspect, 0.1f,
100f);
//The matrix of the camera = viewMatrix
setTransformation(vecmath.lookatMatrix(eye, center, up));
//And every object sets a ModelMatrix in it's display method
Matrix modelMatrix = parentMatrix.mult(vecmath
.translationMatrix(translation));
modelMatrix = modelMatrix.mult(vecmath.rotationMatrix(1, 0, 1, angle));
编辑2:
下面是函数当前的外观:
private void calcMouseInWorldPosition(float mouseX, float mouseY, Matrix proj, Matrix view) {
Vector start = vecmath.vector(0, 0, 0);
Vector end = vecmath.vector(0, 0, 0);
FloatBuffer modelBuffer = BufferUtils.createFloatBuffer(16);
modelBuffer.put(view.asArray());
modelBuffer.rewind();
FloatBuffer projBuffer = BufferUtils.createFloatBuffer(16);
projBuffer.put(proj.asArray());
projBuffer.rewind();
FloatBuffer startBuffer = BufferUtils.createFloatBuffer(16);
FloatBuffer endBuffer = BufferUtils.createFloatBuffer(16);
IntBuffer viewBuffer = BufferUtils.createIntBuffer(16);
//The two calls for projection and modelView matrix are disabled here,
as I use my own matrices in this case
// glGetFloat(GL_MODELVIEW_MATRIX, modelBuffer);
// glGetFloat(GL_PROJECTION_MATRIX, projBuffer);
glGetInteger(GL_VIEWPORT, viewBuffer);
//I know this is really ugly and bad, but I know that the height and width is always 600
// and this is just for testing purposes
mouseY = 600 - mouseY;
gluUnProject(mouseX, mouseY, 0.0f, modelBuffer, projBuffer, viewBuffer, startBuffer);
gluUnProject(mouseX, mouseY, 1.0f, modelBuffer, projBuffer, viewBuffer, endBuffer);
start = vecmath.vector(startBuffer.get(0), startBuffer.get(1), startBuffer.get(2));
end = vecmath.vector(endBuffer.get(0), endBuffer.get(1), endBuffer.get(2));
direction = vecmath.vector(end.x()-start.x(), end.y()-start.y(), end.z()-start.z());
}
我试图使用我自己的投影和视图矩阵,但这似乎只会给出更奇怪的结果。有了GlGet。。。我点击右上角得到的东西:
开始:(0.97333336,-0.98,-1.0)
完:(0.97333336,-0.98,1.0) 当我使用自己的东西时,我得到了同样的位置:
起始值:(-2.4399707,-0.55425626,-14.202201)
结束:(-2.4399707,-0.55425626,-16.198204) 现在我实际上需要一个模型视图矩阵,而不仅仅是视图矩阵,但我不知道该如何获得它,因为它在每个对象的每次显示调用中都会被更改和重新创建。
但这真的是问题所在吗?在教程中,他说“通常情况下,要从眼睛空间进入剪辑空间,我们用投影矩阵乘以向量。我们可以通过乘以这个矩阵的倒数来返回。”在下一步中,他再次乘以视图矩阵的倒数,所以我想这是我实际应该做的 编辑3:
在这里,我尝试了user42813的建议:
Matrix view = cam.getTransformation();
view = view.invertRigid();
mouseY = height - mouseY - 1;
//Here I only these values, because the Z and W values would be 0
//following your suggestion, so no use adding them here
float tempX = view.get(0, 0) * mouseX + view.get(1, 0) * mouseY;
float tempY = view.get(0, 1) * mouseX + view.get(1, 1) * mouseY;
float tempZ = view.get(0, 2) * mouseX + view.get(1, 2) * mouseY;
origin = vecmath.vector(tempX, tempY, tempZ);
direction = cam.getDirection();
但现在方向和原点值始终相同:产地:(-0.04557252,--0.0020000197,-0.9989586)
方向:(-0.04557252,-0.0020000197,-0.9989586)我真的不使用不推荐的opengl,但我愿意分享我的想法, 首先,如果您向我们展示如何构建视图矩阵,这将非常有用, 第二个视图矩阵位于摄影机的局部空间, 现在,通常将鼠标X和(屏幕高度-mouseY-1)乘以视图矩阵(我认为是该矩阵的倒数,对不起,不确定!),然后将鼠标坐标放在相机空间中,然后将前向向量添加到鼠标创建的向量中,然后得到它,看起来是这样的:
float mouseCoord[] = { mouseX, screen_heihgt - mouseY - 1, 0, 0 }; /* 0, 0 because we multipling by a matrix 4.*/
mouseCoord = multiply( ViewMatrix /*Or: inverse(ViewMatrix)*/, mouseCoord );
float ray[] = add( mouseCoord, forwardVector );
好的,我终于解决了这个问题,也许这会对某人有所帮助。
我找到了一些公式,并用我得到的坐标,从-1到1:
float tempX = (float) (start.x() * 0.1f * Math.tan(Math.PI * 60f / 360));
float tempY = (float) (start.y() * 0.1f * Math.tan(Math.PI * 60f / 360) * height / width);
float tempZ = -0.1f;
direction = vecmath.vector(tempX, tempY, tempZ); //create new vector with these x,y,z
direction = view.transformDirection(direction);
//multiply this new vector with the INVERSED viewMatrix
origin = view.getPosition(); //set the origin to the position values of the matrix (the right column)
glunproject
应该一直返回到对象空间坐标。您很可能有一个身份模型视图/投影矩阵。您的目标是什么版本的GL?例如,如果您使用的是GL3.2内核,我可以很容易地看到glGetFloat(…)
返回未初始化的矩阵。在这种情况下,将只定义视口,这将解释为什么只返回clip-space。@AndonM.Coleman我的版本是3.1.0。是否与扩展字符串中的扩展兼容?此外,如果您使用单独的库构建矩阵,为什么要尝试从OpenGL中查询它们?@AndonM.Coleman抱歉,我不知道扩展字符串的含义。我不知道我应该如何得到GlunProject方法所需的矩阵,尤其是modelMatrix,因为它随每个对象而变化。我可以在那里得到视图和投影矩阵,但我仍然需要ModelView矩阵,我应该如何创建/获得它?不幸的是,您必须更清楚地解释您的情况(在您的问题中,因为这些注释变得一团糟)。我甚至不确定此时是否使用固定函数或着色器管道。但是如果你有视图矩阵,你应该能够将它乘以你的对象的模型矩阵,得到模型视图矩阵。在任何情况下,如果有那么多实际工作(sans model matrix),它将在世界空间中,而不是像您描述的那样在剪辑空间中:-\n我的代码中有哪些不推荐使用?glGetxxx()方法?现代的方法是什么?gluPerspective(…)、gluUnProject(…)、glMatrixMode(…)、glTranslateX(…)、glRotateX(…),…,现代的方法是创建自己的数学库,或者使用已经定义好的数学库,例如glm,如果您使用C/C++或查看LibGDX数学库,它是一个伟大的库,您还必须使用不带gl_ModelViewMatrix/gl_NormalMatrix/gl_Vertex的着色器…,列表如下,您可以在这里获得一些很棒的Tut,还请注意,如果我提供的代码有效,那么光线将位于摄影机空间。关于您提供的代码,请注意,在每帧创建directe缓冲区是一个好主意,您应该做什么,创建静态引用并重用它们。还有一件事,如果您使用鼠标控制相机旋转,那么代码将简化为(ray=cameraForward)。我编辑了我的问题并尝试了您的建议。但它并没有真正起作用:/