Android 将屏幕坐标转换为OpenGL坐标

Android 将屏幕坐标转换为OpenGL坐标,android,opengl-es,bulletphysics,jbullet,Android,Opengl Es,Bulletphysics,Jbullet,我正在为Android创建掷骰子应用程序。使用Kotlin、OpenGL ES和jBullet。 我已经实现了骰子。 现在我需要创建墙,否则骰子会从屏幕上滚出来 因为屏幕可以有不同的纵横比,所以我试图用glUnProject来确定墙壁的位置,但我想不出来。 我收到的坐标不正确 gl.glViewport(0,0,width,height) //Reset The Current Viewport gl.glMatrixMode(GL10.GL_PROJECTION)

我正在为Android创建掷骰子应用程序。使用Kotlin、OpenGL ES和jBullet。 我已经实现了骰子。 现在我需要创建墙,否则骰子会从屏幕上滚出来

因为屏幕可以有不同的纵横比,所以我试图用
glUnProject
来确定墙壁的位置,但我想不出来。 我收到的坐标不正确

    gl.glViewport(0,0,width,height)    //Reset The Current Viewport
    gl.glMatrixMode(GL10.GL_PROJECTION)    //Select The Projection Matrix
    gl.glLoadIdentity()                    //Reset The Projection Matrix

    //Calculate The Aspect Ratio Of The Window
    GLU.gluPerspective(gl, 35.0f, width.toFloat() / height.toFloat(), 0.1f, 100.0f)

    GLU.gluLookAt(gl,
           0.0f, 30.0f,  0.0f, //Pos
           0.0f,  0.0f,  0.0f, //Look at
           0.0f,  0.0f,  1.0f  //Up
    );

    gl.glMatrixMode(GL10.GL_MODELVIEW)    //Select The Modelview Matrix
    gl.glLoadIdentity()                    //Reset The Modelview Matrix

    // Get matrices
    gl.glGetFloatv(GL11.GL_PROJECTION_MATRIX, glProjectionMatrix,0)
    gl.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, glModelMatrix,0)
    gl.glGetIntegerv(GL11.GL_VIEWPORT, glViewPort,0)

    // Allocate matrices
    var modelMatrix = glModelMatrix
    var projMatrix  = glProjectionMatrix
    var view = glViewPort

    // Pre allocate wall positions
    var wallDown = FloatArray(4)

    // The needed point
    var wallDownP = Vector3f(view[2].toFloat(), view[3].toFloat(), 0.2888888f)

    GLU.gluUnProject(wallDownP.x, wallDownP.y, wallDownP.z, modelMatrix, 0, projMatrix, 0, view, 0, wallDown, 0)

在您的情况下,
透视图
可能有点不幸。这是视野定义的
平截头体
操作带来的便利

从您目前的设置来看,这一切都是可行的,但我建议您直接使用
平截头体
,因为这样更容易计算:

平截头体由边界参数(
top
bottom
left
right
),
near
far
定义。带有边框参数的矩形(距离
)将完全显示全屏。因此,最好从董事会本身开始。如果您将电路板的尺寸定义为
(viewWidth,viewHeight)
,并且想要一个宽度为
fov=35
的视野,那么到该对象的距离
d
应该是
d*tan(35/2)=viewWidth/2
所以
d=viewWidth/(2*tan(35/2))
现在是一个相对较大的值。距离
d
现在可以用作
far
,因为我假设您将不会在板后面绘制任何东西,只是为了确保用户
d*2
。(增加
far
将降低深度缓冲区的精度,但除此之外没有其他影响)。因此,现在可以将
near
定义为类似
0.1
的内容,其中对象投影的比例为
scale=near/d
,边界值为原始值乘以比例:

  • left=-screenWidth/2*比例
  • right=屏幕宽度/2*比例
  • top=屏幕高度/2*比例
  • bottom=-屏幕高度/2*比例

因此,通过此设置,您将在距离
d
的距离处使用大小为
(viewWidth,viewHeight)
的矩形,就像全屏一样。因此,将
d
插入
lookAt
参数,就这些了。然后,骰子的大小可以由屏幕宽度定义,以便在所有设备上显示相似的大小。例如,使用
screenWidth/10
作为骰子大小,您将始终能够在屏幕上水平放置正好10个骰子。

从何处获得0.288888F?如果您想要墙,为什么将视口设置为2?你说的墙可能是指你的相机视图的侧面?