5

我正在为 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)
4

1 回答 1

2

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

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

截锥体由边界参数(topbottomleftrightnear和定义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将降低深度缓冲区的精度,但仅此而已)。所以现在你可以定义near0.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中就可以了。然后可以通过屏幕宽度定义骰子的大小,因此它在所有设备上看起来都相似。例如,使用screenWidth/10骰子大小,您将始终能够在屏幕上水平放置 10 个骰子。

于 2016-06-09T10:09:18.803 回答