packages feed

lambdacube-examples-0.1.1: src/lambdacube-basic.hs

import Data.Maybe
import Data.Map
import Control.Applicative
import Control.Monad

import Graphics.UI.GLFW as GLFW
import Graphics.Rendering.OpenGL as GL hiding (light)
import System.Log.Logger
import FRP.Elerea

import Graphics.LambdaCube
import Graphics.LambdaCube.RenderSystem.GL
import qualified Graphics.LambdaCube.Loader.StbImage as Stb

import Paths_lambdacube_examples (getDataFileName)

import Utils

integral v0 s = transfer v0 (\dt v v0 -> v0+v*realToFrac dt) s

baseMousePos = Position 200 200
width = 150
height = 150
main = do
    updateGlobalLogger rootLoggerName (setLevel DEBUG)
    initialize
    openWindow (Size 640 480) [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24] Window
    windowTitle $= "LambdaCube Engine Basic Example"
    GLFW.mousePos $= baseMousePos
    GLFW.disableSpecial MouseCursor

    initGL 640 480
    (windowSize,windowSizeSink) <- external (0,0)
    (mousePosition,mousePositionSink) <- external (0,0)
    (mousePress,mousePressSink) <- external False
    (fblrPress,fblrPressSink) <- external (False,False,False,False,False)

    windowSizeCallback $= resizeGLScene windowSizeSink
    let --mkNodeR = mkNode "Root"
        idMatrix4 = transl 0 0 0

    mediaPath <- getDataFileName "media"

    renderSystem <- mkGLRenderSystem
    world' <- addRenderWindow "MainWindow" 640 480 [mkViewport 0 0 1 0.5 "Camera1" ["Glass"{- "Tiling","Glass" -}], mkViewport 0 0.5 1 0.5 "Camera2" []]
        =<< addRenderTexture "RenderTex01" 640 480
        =<< addScene ([-- mkNode "Root" "Car"      idMatrix4 [mesh "scooby_body.mesh.xml"]
                        mkNode "Root" "Robot"    idMatrix4 [mesh "robot.mesh.xml"]
--                      , mkNodeR "OgreHead" idMatrix4 [mesh "BigRamp_N.mesh.xml"] 
--                      , mkNodeR "Plane"    (transl 41.5 (-50) (-146)) [entity "robot.mesh.xml"]
                      , mkNode "Root" "OgreHead" (scal 0.05) [mesh "ogrehead.mesh.xml",mesh "Quad.mesh.xml"] 
--                      , mkNodeR "Light1"   transl 5 5 10 $ [sun ]
                      , mkNode "Root" "Light1"   (transl 5 5 10) [light,mesh "ogrehead.mesh.xml"]
--                      , mkNode "Root" "Light2"   (transl (-5) 15 10) [light,mesh "Cube.mesh.xml"]
--                      , mkNodeR "CustomMeshNode" idMatrix4 [customMesh (plane) "RenderTex01Material"]
                      , mkNode "Root" "CameraNode1" idMatrix4 [simpleCamera "Camera1"]
                      , mkNode "Root" "CameraEye" idMatrix4 [mesh "Box.mesh.xml"]
--                      , mkNode "Root" "CameraNode1" idMatrix4 [wireCamera "Camera1"]
                      , mkNode "Root" "CameraNode2" (transl 0 0 (-10)) [simpleCamera "Camera2"] ] 
--                      , mkNode "Root" "CameraNode2" (transl 0 0 10) [simpleCamera "Camera2"] ] 
--                   ++ [ mkNode "Root" ("Robot" ++ show i) (transl ((i-100)*20) (-50) (-166)) [mesh "robot.mesh.xml"] | i <- [1..200] ])
                   ++ [ mkNode "Root" ("Knot" ++ show i) idMatrix4 [meshMat "knot.mesh.xml" (repeat "Examples/TransparentTest")] | i <- [1..200]::[Int] ])
        =<< addResourceLibrary [("General",[(PathDir,mediaPath)])]
--          =<< addConfig "resources.cfg"
        =<< mkWorld renderSystem [Stb.loadImage]
    (world,worldSink) <- external world'

    re1 <- createSignal $ integral 0 $ pure (1.5)-- :: Float)
    re2 <- createSignal $ integral 10 $ pure (-1.0)-- :: Float)
    re3 <- createSignal $ integral 110 $ pure (0.8)-- :: Float)
    time <- createSignal $ stateful 0 (+)
    cam <- cameraSignal (-4,0,0) mousePosition fblrPress

    s <- fpsState

    driveNetwork (drawGLScene worldSink <$> world <*> windowSize <*> mousePosition <*> re1 <*> re2 <*> re3 <*> cam)-- <*> zsin <*> cam)
                 (readInput s mousePositionSink mousePressSink fblrPressSink)

    closeWindow

readInput s mousePos mouseBut fblrPress = do
    t <- get GLFW.time
    updateFPS s t
    GLFW.time $= 0
    let Position x0 y0 = baseMousePos
        f = (==) Press
    Position x y <- get GLFW.mousePos
    GLFW.mousePos $= baseMousePos
    mousePos (fromIntegral (x-x0),fromIntegral (y-x0))
    b <- GLFW.getMouseButton GLFW.ButtonLeft
    mouseBut (b == GLFW.Press)
    k <- getKey ESC
    kw <- getKey UP -- $ CharKey 'w'
    ks <- getKey DOWN -- $ CharKey 's'
    ka <- getKey LEFT -- $ CharKey 'a'
    kd <- getKey RIGHT -- $ CharKey 'd'
    turbo <- getKey RSHIFT
    --print (ka,kw,ks,kd)
    fblrPress (f ka,f kw,f ks,f kd,f turbo)
    return (if k == Press then Nothing else Just t)

drawGLScene worldSink world (w,h) (cx,cy) re1 re2 re3 (cam,dir,up,_) {-zsin camMat-} = do
    w' <- updateTargetSize "MainWindow" w h
      =<< updateTransforms
        ([ {-("Car",       rotY re3 <> scal 0.4 <> transl (cx/w*2-1) (h/w-cy/w*2) zsin)
        , -}("Robot",     scal 0.1 <> rotY re2 <> transl 3.5 (-5) (-7))
        , ("Light1",    transl 0 100 200 <> rotX re2)
--        , ("OgreHead",  rotX (cy/50) <> rotY (-cx/50) <> transl (-0.5) 0 (-160))
--        , ("OgreHead",  rotY re2 <>  transl (-0.5) 0 (-160))
--        , ("CameraNode1", rotX (cy/50) <> rotY (-cx/50) <> transl 0 0 (cx/30))--camMat)
        , ("CameraEye", scal (1) <> (\(Vec4 x y z _) -> transl x y z) cam)
        , ("CameraNode1", lookat cam dir up)
        ]
        ++ [ (("Knot" ++ show i),(rotY re3 <> transl ((fromIntegral $ (i`mod`14)-7)*width) (height*(fromIntegral $ i`div`14 -7)) (-166))) | i <- [1..200] ])
        world
    w <- renderWorld 0 "MainWindow" (flattenScene $ wrScene w') w'
    worldSink w
    swapBuffers