Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在OpenGL中处理透视投影?_Opengl_Haskell_Graphics_3d_Projection - Fatal编程技术网

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

如何在OpenGL中处理透视投影?,opengl,haskell,graphics,3d,projection,Opengl,Haskell,Graphics,3d,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

我目前正在使用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)
问题是(我相信)我正在手动将每个三维点转换为二维,然后使用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
main::IO()
main=do

(_progName,_args)正如您正确猜测的那样,推出自己的投影算法可能非常缓慢。此外,除非您正在做一些非常复杂的事情,否则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.
import Graphics.Rendering.OpenGL.GLU.Matrix
显示::IORef摄像头->显示回调
显示camIO=do

摄影机opengl是一个光栅化器,它为您完成所有投影。请看一个相当简洁的演示“我的问题是:我是否应该输入OpenGL三维点,然后使用OpenGL烘焙的任何投影?”很有可能,但由于缺乏细节,我很难判断。你想完成什么?你目前是如何做到的?您给出了一些粗略的伪代码,但是告诉我们更多关于您正在使用的确切API调用的信息会有所帮助。您试图呈现的内容也不清楚。@JasonDagit我已经在我的代码示例中编辑过了,希望这更有意义。我的目标是在三维空间中绘制一组顶点(
)。然后,我想听到按键声,并在该空间内移动
相机
对象。这些点应该根据相机的位置和角度进行渲染。只是为了确保:您是否推出了自己的(基于CPU的)投影算法?是的,这可能非常慢。谢谢您的回答。不过,我更倾向于以OpenGL 3+为目标。@sdadas OpenGL 2.1在大多数系统中作为默认启用,如果驱动程序允许,您可以使用其他版本。如果确实要将其作为目标,可以创建着色器并对其执行所有变换。粗略地看一下API就知道haskell并不完全支持它。我明白了,那么我会接受这个答案,因为它非常有用。顺便说一句,我还发现这很有用(尽管我不知道它使用的是哪个版本的OpenGL):