如何处理OpenGL中的透视投影?

sda*_*das 3 opengl 3d graphics haskell projection

我目前正在使用Haskell的OpenGL绑定编写基本的渲染演示.问题是它几乎不能处理2000多个顶点.我的伪代码相当于:

terrain = The set of points generated from [-1...1] x [-1...1] x [-1...1].
camera = Camera at position (xc, yc) with angles (ax, ay, az).
while running:
    input = anything that moves the camera's position or angles
    projected = []
    for point in terrain:
        projected.append(camera.perspectiveProjection(point))
    renderPoints(projected)
Run Code Online (Sandbox Code Playgroud)

问题(我相信)是我手动将每个三维点转换为二维,然后使用OpenGL绘制这些点.

我的问题是:我应该提供OpenGL三维点,然后使用OpenGL烘焙过的任何投影吗?

(我觉得我理解透视投影是如何工作的 - 我只是不确定我是否应该手动执行此操作.)

编辑:

以下是我的代码.我已经省略了我认为只有函数定义才能解释清楚的部分.

main :: IO()
main = do
    (_progName, _args) <- getArgsAndInitialize
    initialDisplayMode $= [DoubleBuffered]
    _window <- createWindow "Hello, World"
    -- The camera position followed by pitch, yaw and roll.
    camera <- newIORef Camera [0,0,0] 0 0 0
    displayCallback $= display camera
    mainLoop

display :: IORef Camera -> DisplayCallback
display camIO = do
    camera <- get camIO
    clear [ColorBuffer, DepthBuffer]
    clear [ColorBuffer]
    renderPrimitive Points $ mapM_ vertex 
        $ map perspectiveProjection camera points
    swapBuffers
    postRedisplay Nothing
Run Code Online (Sandbox Code Playgroud)

Cha*_*ton 5

正如您猜对的那样,推出自己的投影算法可能会非常缓慢.此外,除非你正在做一些非常复杂的事情,OpenGL(或更具体的GLU)有一套功能可以解决你的大部分问题.

进行传统透视投影的最简单方法是使摄像机具有位置,观察点和向上矢量.就个人而言,我发现这比使用旋转角度定义摄像机轴更简单.一旦你有了这个,你就可以拥有这样的显示功能:

import Graphics.Rendering.OpenGL.GLU.Matrix

display :: IORef Camera -> DisplayCallback
display camIO = do
    camera <- get camIO
    perspective fov aspect zNear zFar
    lookAt (position camera) (lookAt camera) (upVector camera)
    -- call clear functions
    -- call renderPrimitive with the untransformed points.
Run Code Online (Sandbox Code Playgroud)

lookAt功能改变摄像机的位置和方向,给出摄像机属性.该perspective功能可以获取有关摄像机和窗口的信息,并创建正确的透视投影.如果你发现它不提供关于投影足够的控制,你可以使用frustum来自Graphics.Rendering.OpenGL.GL.CoordTrans代替.

PS.:正确的方法是setup设置一个功能,设置投影矩阵,并在必要时使显示功能改变模型视图矩阵.但是,上面的代码应该可行.

PS2:正如评论中所指出的,实现这一点的方式在很大程度上取决于OpenGL版本,而且我不知道OpenGL支持哪些版本的OpenGL.此实现基于OpenGL 2.1及更低版本.