summaryrefslogtreecommitdiff
path: root/mainObj.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-04-17 18:39:12 -0400
committerJoe Crayne <joe@jerkface.net>2019-04-17 18:41:18 -0400
commit395f3b525090097c88434b03c88fe2fb8b8d7aba (patch)
tree0f60388ddd09bc69e7257be32959e95574a73a73 /mainObj.hs
parent64f1a100fc887fb2a8bc87e2ac6975e872010ef5 (diff)
Refactored object-loading demo.
Diffstat (limited to 'mainObj.hs')
-rw-r--r--mainObj.hs102
1 files changed, 102 insertions, 0 deletions
diff --git a/mainObj.hs b/mainObj.hs
new file mode 100644
index 0000000..1513075
--- /dev/null
+++ b/mainObj.hs
@@ -0,0 +1,102 @@
1{-# LANGUAGE OverloadedLabels #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE LambdaCase #-}
4{-# LANGUAGE RecordWildCards #-}
5module Main where
6
7import Codec.Picture as Juicy
8import Control.Concurrent
9import Control.Monad
10import Data.Word
11import Data.Function
12import Data.Text (Text)
13import Data.Map.Strict (Map)
14import qualified Data.Map.Strict as Map
15import qualified Data.Vector as V
16import GI.Gdk.Objects
17import GI.GLib.Constants
18import GI.Gtk as Gtk hiding (main)
19import LambdaCube.GL as LC
20import LambdaCube.GL.Mesh as LC
21import System.Environment
22import System.IO
23import System.IO.Error
24
25import GLWidget
26import LambdaCubeWidget
27import TimeKeeper
28import LoadMesh
29import InfinitePlane
30import MtlParser (ObjMaterial(..))
31
32type State = (TimeKeeper, TickCallbackHandle)
33
34addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) -> IO [LC.Object]
35addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) -> do
36 obj <- LC.addMeshToObjectArray storage slotName ["diffuseTexture","diffuseColor"] mesh
37 -- diffuseTexture and diffuseColor values can change on each model
38 case mat >>= flip Map.lookup mtlLib of
39 Nothing -> return ()
40 Just (ObjMaterial{..},t) -> LC.updateObjectUniforms obj $ do
41 "diffuseTexture" @= return t -- set model's diffuse texture
42 "diffuseColor" @= let (r,g,b) = mtl_Kd in return (V4 r g b mtl_Tr)
43 return obj
44
45
46uploadState :: IsWidget glarea => MeshData -> glarea -> GLStorage -> IO State
47uploadState obj glarea storage = do
48 -- load OBJ geometry and material descriptions
49 (objMesh,mtlLib) <- uploadOBJToGPU obj
50 -- load materials textures
51 gpuMtlLib <- uploadMtlLib mtlLib
52 -- add OBJ to pipeline input
53 addOBJToObjectArray storage "objects" objMesh gpuMtlLib
54 -- grid plane
55 uploadMeshToGPU xyplane >>= addMeshToObjectArray storage "plane" []
56
57 -- setup FrameClock
58 tm <- newTimeKeeper
59 tickcb <- widgetAddTickCallback glarea (tick tm)
60 return (tm,tickcb)
61
62destroyState :: GLArea -> State -> IO ()
63destroyState glarea (tm,tickcb) = do
64 widgetRemoveTickCallback glarea tickcb
65
66setUniforms :: glctx -> GLStorage -> State -> IO ()
67setUniforms gl storage (tm,_) = do
68 t <- withMVar (tmSeconds tm) return
69 LC.updateUniforms storage $ do
70 "time" @= return (realToFrac t :: Float)
71
72main :: IO ()
73main = do
74 m <- do
75 objName <- head . (++ ["cube.obj"]) <$> getArgs
76 mobj <- loadOBJ objName
77 mpipeline <- loadPipeline "hello_obj2.json" $ do
78 defObjectArray "objects" Triangles $ do
79 "position" @: Attribute_V4F
80 "normal" @: Attribute_V3F
81 "uvw" @: Attribute_V3F
82 defObjectArray "plane" Triangles $ do
83 "position" @: Attribute_V4F
84 defUniforms $ do
85 "time" @: Float
86 "diffuseTexture" @: FTexture2D
87 "diffuseColor" @: V4F
88 return $ (,) <$> mobj <*> mpipeline
89 either (\e _ -> hPutStrLn stderr e) (&) m $ \(obj,pipeline) -> do
90 app <- do
91 mvar <- newEmptyMVar
92 return $ \glarea -> LCMethods
93 { lcRealized = mvar
94 , lcUploadState = uploadState obj glarea
95 , lcDestroyState = destroyState glarea
96 , lcSetUniforms = setUniforms
97 , lcPipeline = pipeline
98 }
99
100 runGLApp return (lambdaRender app glmethods)
101 { glTitle = "LambdaCube 3D DSL OBJ viewer"
102 }