summaryrefslogtreecommitdiff
path: root/mainObj.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-04-29 16:44:20 -0400
committerJoe Crayne <joe@jerkface.net>2019-04-29 16:44:20 -0400
commit2c277a7d3c25aa792c9d2d324b8e70296d4b453c (patch)
tree3f156ff2a984bfea7f14e0d80f54ec18a6ad0418 /mainObj.hs
parentedbc09c280c1699933c443795686394c1e9e8de5 (diff)
WIP: Abandon GLWidget in favor of (non-working) MeshSketch design.
Diffstat (limited to 'mainObj.hs')
-rw-r--r--mainObj.hs142
1 files changed, 22 insertions, 120 deletions
diff --git a/mainObj.hs b/mainObj.hs
index 970f94c..caf6501 100644
--- a/mainObj.hs
+++ b/mainObj.hs
@@ -1,127 +1,29 @@
1{-# LANGUAGE OverloadedLabels #-} 1{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedLabels #-}
2{-# LANGUAGE OverloadedStrings #-} 3{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE LambdaCase #-} 4{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE RecordWildCards #-}
5module Main where 5module Main where
6 6
7import Codec.Picture as Juicy 7import qualified GI.Gtk as Gtk (main)
8import Control.Concurrent 8 ;import GI.Gtk as Gtk hiding (main)
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 Numeric.LinearAlgebra hiding ((<>))
22import System.Environment
23import System.IO
24import System.IO.Error
25 9
26import GLWidget 10import qualified MeshSketch
27import LambdaCube.GL.HMatrix
28import LambdaCubeWidget
29import TimeKeeper
30import LoadMesh
31import InfinitePlane
32import MtlParser (ObjMaterial(..))
33import Matrix
34
35-- State created by uploadState.
36data State = State
37 { stTimeKeeper :: TimeKeeper
38 , stTickCallback :: TickCallbackHandle
39 }
40
41addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) -> IO [LC.Object]
42addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) -> do
43 obj <- LC.addMeshToObjectArray storage slotName ["diffuseTexture","diffuseColor"] mesh
44 -- diffuseTexture and diffuseColor values can change on each model
45 case mat >>= flip Map.lookup mtlLib of
46 Nothing -> return ()
47 Just (ObjMaterial{..},t) -> LC.updateObjectUniforms obj $ do
48 "diffuseTexture" @= return t -- set model's diffuse texture
49 "diffuseColor" @= let (r,g,b) = mtl_Kd in return (V4 r g b mtl_Tr)
50 return obj
51
52
53uploadState :: IsWidget glarea => MeshData -> glarea -> GLStorage -> IO State
54uploadState obj glarea storage = do
55 -- load OBJ geometry and material descriptions
56 (objMesh,mtlLib) <- uploadOBJToGPU obj
57 -- load materials textures
58 gpuMtlLib <- uploadMtlLib mtlLib
59 -- add OBJ to pipeline input
60 addOBJToObjectArray storage "objects" objMesh gpuMtlLib
61 -- grid plane
62 uploadMeshToGPU xzplane >>= addMeshToObjectArray storage "plane" []
63
64 -- setup FrameClock
65 tm <- newTimeKeeper
66 tickcb <- widgetAddTickCallback glarea (tick tm)
67
68 return State
69 { stTimeKeeper = tm
70 , stTickCallback = tickcb
71 }
72
73destroyState :: GLArea -> State -> IO ()
74destroyState glarea st = do
75 widgetRemoveTickCallback glarea (stTickCallback st)
76
77deg30 :: Float
78deg30 = pi/6
79
80setUniforms :: glctx -> GLStorage -> State -> IO ()
81setUniforms gl storage st = do
82 t <- (/ 10.0) <$> getSeconds (stTimeKeeper st)
83 let tf = realToFrac t :: Float
84 rot = rotMatrixZ (-tf) <> rotMatrixX (-tf)
85 pos = rot #> fromList [2,2,10]
86 up = rot #> fromList [0,1,0]
87 cam = lookat pos 0 up
88 aspect = 1
89 proj = perspective 0.1 100 deg30 aspect
90 mvp = proj <> cam
91
92 LC.updateUniforms storage $ do
93 "CameraPosition" @= return (pos :: Vector Float)
94 "ViewProjection" @= return (mvp :: Matrix Float)
95 11
96main :: IO () 12main :: IO ()
97main = do 13main = do
98 m <- do 14 _ <- Gtk.init Nothing
99 objName <- head . (++ ["cube.obj"]) <$> getArgs 15
100 mobj <- loadOBJ objName 16 let mkChild = MeshSketch.mmWidget <$> MeshSketch.new
101 mpipeline <- loadPipeline "hello_obj2.json" $ do 17
102 defObjectArray "objects" Triangles $ do 18 window <- do
103 "position" @: Attribute_V4F 19 w <- Gtk.windowNew WindowTypeToplevel
104 "normal" @: Attribute_V3F 20 windowSetDefaultSize w 720 720
105 "uvw" @: Attribute_V3F 21 Gtk.windowSetTitle w "MeshSketch"
106 defObjectArray "plane" Triangles $ do 22 containerSetBorderWidth w 0
107 "position" @: Attribute_V4F 23 _ <- on w #deleteEvent $ \_ -> mainQuit >> return True
108 defUniforms $ do 24 child <- mkChild
109 "CameraPosition" @: V3F 25 containerAdd w child
110 "ViewProjection" @: M44F 26 return w
111 "diffuseTexture" @: FTexture2D 27
112 "diffuseColor" @: V4F 28 widgetShowAll window
113 return $ (,) <$> mobj <*> mpipeline 29 Gtk.main
114 either (\e _ -> hPutStrLn stderr e) (&) m $ \(obj,pipeline) -> do
115 app <- do
116 mvar <- newEmptyMVar
117 return $ \glarea -> LCMethods
118 { lcRealized = mvar
119 , lcUploadState = uploadState obj glarea
120 , lcDestroyState = destroyState glarea
121 , lcSetUniforms = setUniforms
122 , lcPipeline = pipeline
123 }
124
125 runGLApp return (lambdaRender app glmethods)
126 { glTitle = "LambdaCube 3D DSL OBJ viewer"
127 }