glu.Look适用于任意垂直轴方向的倾斜架空相机

时间:2012-09-22 09:00:19

标签: opengl camera glulookat gambas

[编辑09/23/12]想象一下,从上到下的角度来看FPS控制(strafe,转弯)。现在想象一下,当播放器转动整个屏幕时,它们总是面向显示器的顶部。现在想象一下投影的“相机”总是相对于他们的方向在玩家上方和后方10英尺处。这意味着相机以45度角向下俯视景观,随着玩家的转动而旋转。我正在试图掌握为此所需的代码而失去理智,这就是我迄今为止所得到的结果好坏参与:

Public Sub Mode_Perspective()

  ' Set OpenGL matrices to perspective mode.

  ' Set projection mode.
  Gl.MatrixMode(Gl.PROJECTION)
  Gl.LoadIdentity()
  Glu.Perspective(45, sWidth / sHeight, Camera.Near, Camera.Far)
  Gl.MatrixMode(Gl.MODELVIEW)
  Gl.LoadIdentity()
  Gl.Scalef(1, -1, 1 * ElevationScale)

End


Public Sub Update_Camera()

  ' Calculate translated camera position.
  CameraXY = Calculate.TranslateInDirection(Camera.WorldX, Camera.WorldY, 10, Camera.Orientation + 90)

  ' Calculate up vector.
  CameraTarget[0] = Client.PlayerData[Client.Number].WorldX_Current
  CameraTarget[1] = Client.PlayerData[Client.Number].WorldY_Current
  CameraTarget[2] = Client.PlayerData[Client.Number].WorldZ_Current
  CameraLeft[0] = Calculate.RotateX(CameraXY[0], CameraXY[1], Camera.WorldX, Camera.WorldY, 1)
  CameraLeft[1] = Calculate.RotateY(CameraXY[0], CameraXY[1], Camera.WorldX, Camera.WorldY, 1)
  CameraLeft[2] = Camera.WorldZ
  CameraRight[0] = Calculate.RotateX(CameraXY[0], CameraXY[1], Camera.WorldX, Camera.WorldY, -1)
  CameraRight[1] = Calculate.RotateY(CameraXY[0], CameraXY[1], Camera.WorldX, Camera.WorldY, -1)
  CameraRight[2] = Camera.WorldZ
  UpVector = Calculate.Normal(CameraTarget, CameraLeft, CameraRight)

  ' Update OpenGL matrix.
  Glu.LookAt(CameraXY[0], CameraXY[1], Camera.WorldZ, Client.PlayerData[Client.Number].WorldX_Current, Client.PlayerData[Client.Number].WorldY_Current, Client.PlayerData[Client.Number].WorldZ_Current, UpVector[0], UpVector[1], UpVector[2])

End


Public Function TranslateInDirection(StartX As Single, StartY As Single, Distance As Single, Direction As Single) As Single[]

  ' Translate specified coordinates by specified units at specified direction.

  ' General declarations.
  Dim NewXY As New Single[2]

  NewXY[0] = StartX + Distance * Cos(Rad(Direction))
  NewXY[1] = StartY + Distance * Sin(Rad(Direction))

  ' Return new coordinates.
  Return NewXY

End


Public Function RotateX(PWOX As Single, PWOY As Single, OriginX As Single, OriginY As Single, Orientation As Single) As Single

  ' Rotate specified point about specified point and return new X coordinate.

  Return (OriginX + (Cos(Rad(Orientation)) * (PWOX - OriginX) - Sin(Rad(Orientation)) * (PWOY - OriginY)))

End


Public Function RotateY(PWOX As Single, PWOY As Single, OriginX As Single, OriginY As Single, Orientation As Single) As Single

  ' Rotate specified point about specified point and return new Y coordinate.

  Return (OriginY + (Sin(Rad(Orientation)) * (PWOX - OriginX) + Cos(Rad(Orientation)) * (PWOY - OriginY)))

End


Public Function Normal(p1 As Single[], p2 As Single[], p3 As Single[]) As Single[]

  ' Calculate and return surface normal of specified triangle.

  ' General declarations.
  Dim N As New Single[3]
  Dim Magnitude As Single

  ' Calculate normal.
  N[0] = (p2[1] - p1[1]) * (p3[2] - p1[2]) - (p2[2] - p1[2]) * (p3[1] - p1[1])
  N[1] = (p2[2] - p1[2]) * (p3[0] - p1[0]) - (p2[0] - p1[0]) * (p3[2] - p1[2])
  N[2] = ((p2[0] - p1[0]) * (p3[1] - p1[1]) - (p2[1] - p1[1]) * (p3[0] - p1[0])) * -1

  ' Normalize normal.
  Magnitude = Sqr(N[0] ^ 2 + N[1] ^ 2 + N[2] ^ 2)
  N[0] = N[0] / Magnitude
  N[1] = N[1] / Magnitude
  N[2] = N[2] / Magnitude

  Return N

End

以下是我正在使用Update_Camera程序进行的总结:

1)暂时将相机移到自身后方10英尺处(它松散地跟随播放器)。

2)计算三个点。一个是玩家的位置或相机目标。第二个和第三个是移动的摄像机位置,一个绕着播放器顺时针旋转,另一个稍微逆时针旋转。

3)使用步骤2中的三个点计算“向上”向量。

4)使用glu.LookAt正确定位和定位“相机”。

这一开始似乎运作良好,但是当我降低相机或增加它与播放器的距离时,事情开始变形。相机似乎放大,并且景观的垂直比例似乎增加。与景观平行渲染的精灵四边形仍然呈现为好像相机正好在它们上方,当它们应该在降低相机时以增加的角度渲染。我能错过什么?

0 个答案:

没有答案