diff options
author | Joe Crayne <joe@jerkface.net> | 2019-04-17 18:39:12 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-04-17 18:41:18 -0400 |
commit | 395f3b525090097c88434b03c88fe2fb8b8d7aba (patch) | |
tree | 0f60388ddd09bc69e7257be32959e95574a73a73 /mainObj.hs | |
parent | 64f1a100fc887fb2a8bc87e2ac6975e872010ef5 (diff) |
Refactored object-loading demo.
Diffstat (limited to 'mainObj.hs')
-rw-r--r-- | mainObj.hs | 102 |
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 #-} | ||
5 | module Main where | ||
6 | |||
7 | import Codec.Picture as Juicy | ||
8 | import Control.Concurrent | ||
9 | import Control.Monad | ||
10 | import Data.Word | ||
11 | import Data.Function | ||
12 | import Data.Text (Text) | ||
13 | import Data.Map.Strict (Map) | ||
14 | import qualified Data.Map.Strict as Map | ||
15 | import qualified Data.Vector as V | ||
16 | import GI.Gdk.Objects | ||
17 | import GI.GLib.Constants | ||
18 | import GI.Gtk as Gtk hiding (main) | ||
19 | import LambdaCube.GL as LC | ||
20 | import LambdaCube.GL.Mesh as LC | ||
21 | import System.Environment | ||
22 | import System.IO | ||
23 | import System.IO.Error | ||
24 | |||
25 | import GLWidget | ||
26 | import LambdaCubeWidget | ||
27 | import TimeKeeper | ||
28 | import LoadMesh | ||
29 | import InfinitePlane | ||
30 | import MtlParser (ObjMaterial(..)) | ||
31 | |||
32 | type State = (TimeKeeper, TickCallbackHandle) | ||
33 | |||
34 | addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) -> IO [LC.Object] | ||
35 | addOBJToObjectArray 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 | |||
46 | uploadState :: IsWidget glarea => MeshData -> glarea -> GLStorage -> IO State | ||
47 | uploadState 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 | |||
62 | destroyState :: GLArea -> State -> IO () | ||
63 | destroyState glarea (tm,tickcb) = do | ||
64 | widgetRemoveTickCallback glarea tickcb | ||
65 | |||
66 | setUniforms :: glctx -> GLStorage -> State -> IO () | ||
67 | setUniforms gl storage (tm,_) = do | ||
68 | t <- withMVar (tmSeconds tm) return | ||
69 | LC.updateUniforms storage $ do | ||
70 | "time" @= return (realToFrac t :: Float) | ||
71 | |||
72 | main :: IO () | ||
73 | main = 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 | } | ||