将屏幕坐标转换为OpenGL坐标

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)

你从哪里得到了那个0.2888888f? - 246tNt
如果你想要墙壁,为什么要将视口除以2?而且你所说的“墙壁”可能指的是相机视图的两侧? - Spidfire
1个回答

2
gluPerspective 在你的情况下可能有点不太方便。这是一种从视场定义的框台变换中得到的便利方法。
目前你拥有的设置都可以实现,但我建议你直接使用 frustum,因为它计算更容易: frustum 由边界参数(topbottomleftright)、nearfar 定义。具有距离为 near 的边界参数矩形将恰好占据整个屏幕。所以最好从板子自身开始。如果你定义板子大小为 (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*scale
  • right=screenWidth/2*scale
  • top=screenHeight/2*scale
  • bottom=-screenHeight/2*scale
这样设置后,您将在距离 d 处看到大小为 (viewWidth, viewHeight) 的矩形,恰好占据整个屏幕。因此,将 d 插入到 lookAt 参数中即可。骰子的大小可以根据屏幕宽度定义,以便在所有设备上显示类似。例如,使用 screenWidth/10 作为骰子大小,您将始终能够在屏幕上恰好显示 10 个骰子。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接