将屏幕坐标转换为OpenGL坐标

Maa*_*ing 5 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)
Run Code Online (Sandbox Code Playgroud)

Mat*_*lak 2

对于你的情况来说可能gluPerspective有点不幸。frustum这是由视场定义的操作的便利。

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

截锥体由边界参数 ( topbottomleftright)near和定义far。边框参数距离为 的矩形near将完全全屏。所以最好从主板本身开始。如果您将板的尺寸定义为宽度(viewWidth, viewHeight)并且想要视野fov=35宽度,那么到该对象的距离d应该是d*tan(35/2)=viewWidth/2这样的d=viewWidth/(2*tan(35/2)),这现在是一个相对较大的值。d现在可以使用该距离far,因为我假设您不会在板后面绘制任何内容,但只是为了确保 user d*2。(增加far会降低深度缓冲区的精度,但不会降低其他值)。因此,现在您可以将对象投影的比例定义near为类似的值,然后将边界值定义为原始值乘以比例:0.1scale=near/d

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

(viewWidth, viewHeight)因此,通过此设置,您将把远处的矩形尺寸设置d为完全全屏。因此,将 插入dlookAt参数中就可以了。然后,骰子的大小可以由屏幕宽度来定义,因此它在所有设备上看起来都相似。例如,使用screenWidth/10骰子大小时,您始终能够在屏幕上水平放置 10 个骰子。