将屏幕坐标转换为OpenGL坐标

时间:2016-06-08 10:01:03

标签: android opengl-es bulletphysics jbullet

我正在为Android创建一个Dice Roller应用。使用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)

1 个答案:

答案 0 :(得分:2)

gluPerspective在你的情况下可能有点不幸。这是视野定义的frustum操作的便利。

这一切都可以通过您目前的设置完成,但我建议您直接使用frustum,因为它更容易计算:

视锥体由边界参数(topbottomleftright),nearfar定义。边界参数与near距离的矩形将完全是全屏。所以最好从董事会本身开始。如果您将电路板定义为大小为(viewWidth, viewHeight)且想要宽度为fov=35的视野,则此对象的距离d应为d*tan(35/2)=viewWidth/2,{{1}这是一个相对较大的价值。距离d=viewWidth/(2*tan(35/2))现在可以用作d,因为我假设您不会在棋盘后面绘制任何内容,只是为了确保用户far。 (增加d*2将降低深度缓冲区的精度,但没有其他内容)。现在,您可以将far定义为near,其中对象投影的比例为0.1,边框值则为原始值乘以比例:

  • scale=near/d
  • left = -screenWidth/2*scale
  • right = screenWidth/2*scale
  • top = screenHeight/2*scale

因此,进行此设置后,您将在距离bottom = -screenHeight/2*scale处将大小为(viewWidth, viewHeight)的矩形设为完全全屏。因此,请将d插入d参数,这应该是全部。然后可以通过屏幕宽度来定义骰子的大小,使其在所有设备上看起来相似。例如,对于骰子大小使用lookAt,您将始终能够在屏幕上水平放置10个骰子。