3

私は現在、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)

問題 (私は信じています) は、3 次元の各点を手動で 2 次元に変換し、OpenGL を使用してそれらの点をプロットしていることです。

私の質問は、OpenGL の 3 次元ポイントをフィードしてから、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
4

1 に答える 1

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.

このlookAt関数は、カメラの位置と方向を変更し、カメラの属性を指定します。はperspective、カメラとウィンドウに関する情報を取得し、適切な透視投影を作成する機能です。プロジェクションを十分に制御できない場合は、代わりにfrustumfromを使用できます。Graphics.Rendering.OpenGL.GL.CoordTrans

PS .:これを行う正しい方法はsetup、投影行列を設定する関数を持ち、必要に応じて表示関数でモデルビュー行列を変更することです。ただし、上記のコードは機能するはずです。

PS2 .: コメントで指摘されているように、これを実装する方法は OpenGL のバージョンに大きく依存しており、OpenGL Haskell のどのバージョンがサポートされているかわかりません。この実装は、OpenGL 2.1 以下に基づいています。

于 2013-11-12T11:07:19.277 に答える