将屏幕坐标转换为OpenGL坐标

问题描述:

我正在为Android创建一个Dice滚轮应用程序。使用Kotlin,OpenGL-ES和jBullet。 我已经实现了骰子。 现在我需要创建墙壁,否则骰子会滚出屏幕。将屏幕坐标转换为OpenGL坐标

由于屏幕可以有不同的长宽比,我试图确定墙壁的位置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

你从哪里得到0.2888888f? – 246tNt

+0

如果你想要墙壁,你为什么用2来划分视口?通过墙你可能意味着你的相机视图的两侧? – Spidfire

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

这是从你目前拥有的是建立所有可行的,但我建议你还是用frustum直接,因为它会更容易计算:

的视锥是由边界参数(topbottomleft定义,right),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个骰子。

+0

谢谢,适合我。 –