summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-04-22 03:13:44 -0400
committerJoe Crayne <joe@jerkface.net>2019-04-22 03:36:23 -0400
commitac89ee199abfe893b03cdbb89a426cd0594e06c9 (patch)
treec3542c880eb610e9a2d5d863ec9ba518a32a0b02
parent36bd8e7133eca5d4e04252c555ee0cc2cc78106e (diff)
objdemo: pass view matrix from haskell.
-rw-r--r--GLWidget.hs5
-rw-r--r--LambdaCube/GL/HMatrix.hs49
-rw-r--r--Matrix.hs230
-rw-r--r--TimeKeeper.hs3
-rw-r--r--hello_obj2.lc16
-rw-r--r--lambda-gtk.cabal8
-rw-r--r--mainObj.hs35
7 files changed, 323 insertions, 23 deletions
diff --git a/GLWidget.hs b/GLWidget.hs
index 19ef129..8620c1a 100644
--- a/GLWidget.hs
+++ b/GLWidget.hs
@@ -82,7 +82,10 @@ oopsG e = do
82oops :: String -> IO () 82oops :: String -> IO ()
83oops s = hPutStrLn stderr s 83oops s = hPutStrLn stderr s
84 84
85runGLApp :: IsWidget b => (GLArea -> IO b) -> WidgetMethods b -> IO () 85runGLApp :: IsWidget b => (GLArea -> IO b) -- ^ Initialize a state object that will be passed
86 -- to all the event handlers.
87 -> WidgetMethods b
88 -> IO ()
86runGLApp mk methods = do 89runGLApp mk methods = do
87 _ <- Gtk.init Nothing 90 _ <- Gtk.init Nothing
88 91
diff --git a/LambdaCube/GL/HMatrix.hs b/LambdaCube/GL/HMatrix.hs
new file mode 100644
index 0000000..ff5e7a7
--- /dev/null
+++ b/LambdaCube/GL/HMatrix.hs
@@ -0,0 +1,49 @@
1{-# LANGUAGE PatternSynonyms #-}
2{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
4module LambdaCube.GL.HMatrix where
5
6import GHC.TypeLits
7
8import LambdaCube.GL.Uniform
9import Numeric.LinearAlgebra
10import Numeric.LinearAlgebra.Devel
11
12import Graphics.Rendering.OpenGL.GL (GLboolean)
13
14instance Uniformable (Matrix Float) where
15 uniformContexts _ = contexts floatMatrices
16
17instance (KnownNat r, KnownNat c) => IsUniform (Matrix Float) (UMatrix r c Float) where
18 marshalUniform abi mat = case matrixDimensions abi of
19 (r,c) | fromIntegral (natVal r) /= rows mat -> Nothing
20 | fromIntegral (natVal c) /= cols mat -> Nothing
21 _ -> let isRowOrder = case orderOf mat of
22 RowMajor -> 1 :: GLboolean
23 ColumnMajor -> 0 :: GLboolean
24 in Just $ MarshalUMatrix
25 $ \f -> apply mat (\ptr -> f 1 isRowOrder ptr) (\r c sr sc ptr -> ptr)
26
27{-
28
29-- apply :: Storable a => Matrix a -> (f -> IO r) -> (CInt -> CInt -> CInt -> CInt -> Ptr a -> f) -> IO r
30{-# INLINE amat #-}
31amat :: Storable a => Matrix a -> (f -> IO r) -> (CInt -> CInt -> CInt -> CInt -> Ptr a -> f) -> IO r
32amat x f g = unsafeWith (xdat x) (f . g r c sr sc)
33 where
34 r = fi (rows x)
35 c = fi (cols x)
36 sr = fi (xRow x)
37 sc = fi (xCol x)
38
39
40apply (0 :: Matrix Float)
41 :: (b -> IO r)
42 -> (Foreign.C.Types.CInt
43 -> Foreign.C.Types.CInt
44 -> Foreign.C.Types.CInt
45 -> Foreign.C.Types.CInt
46 -> GHC.Ptr.Ptr Float
47 -> b)
48 -> IO r
49-}
diff --git a/Matrix.hs b/Matrix.hs
new file mode 100644
index 0000000..b47e223
--- /dev/null
+++ b/Matrix.hs
@@ -0,0 +1,230 @@
1{-# LANGUAGE BangPatterns, FlexibleContexts #-}
2module Matrix where
3
4import Numeric.LinearAlgebra
5import Foreign.Storable
6import Data.Vector.Generic as V (snoc,init)
7import Prelude hiding ((<>))
8
9rotMatrixX :: (Storable a, Floating a) => a -> Matrix a
10rotMatrixX a = (4><4)
11 [ 1 , 0 , 0 , 0
12 , 0 , c , -s , 0
13 , 0 , s , c , 0
14 , 0 , 0 , 0 , 1 ] where (c,s) = (cos a, sin a)
15
16
17rotMatrixY :: (Storable a, Floating a) => a -> Matrix a
18rotMatrixY a = (4><4)
19 [ c , 0 , s , 0
20 , 0 , 1 , 0 , 0
21 , -s , 0 , c , 0
22 , 0 , 0 , 0 , 1 ] where (c,s) = (cos a, sin a)
23
24rotMatrixZ :: (Storable a, Floating a) => a -> Matrix a
25rotMatrixZ a = (4><4)
26 [ c , -s , 0 , 0
27 , s , c , 0 , 0
28 , 0 , 0 , 1 , 0
29 , 0 , 0 , 0 , 1 ] where (c,s) = (cos a, sin a)
30
31
32-- | Equivalent to
33--
34-- > translateBefore3to4 v m = translation v <> homoMatrix m
35--
36-- where translation and homoMatrix are taken as the usual transformations into
37-- the 4-dimensional homogeneous coordinate space.
38translateBefore3to4 :: Numeric t =>
39 Vector t -- 3 vector (translation)
40 -> Matrix t -- 3><3 matrix (projection)
41 -> Matrix t -- 4><4 matrix (projection)
42translateBefore3to4 v p3 = fromRows $ rs ++ [u]
43 where
44 !u = snoc (v <# p3) 1
45 rs = map (`snoc` 0) $ toRows p3
46{-# SPECIALIZE translateBefore3to4 :: Vector R -> Matrix R -> Matrix R #-}
47
48{-
49lookat pos target up = translateBefore3to4 (negate pos) r
50 where
51 backward = normalize $ pos - target
52 rightward = normalize $ up `cross` backward
53 upward = backward `cross` rightward
54 r = fromColumns [rightward,upward,backward]
55
56 -- Rebind 'normalize' in order to support Float which has no Field
57 -- instance.
58 normalize :: (Linear t c, Fractional t, Normed (c t)) => c t -> c t
59 normalize v = scale (1 / realToFrac (norm_2 v)) v
60-}
61
62-- | Camera transformation matrix (4x4).
63lookat :: (Numeric t, Num (Vector t), Fractional t, Normed (Vector t)) =>
64 Vector t -- ^ Camera position 3-vector.
65 -> Vector t -- ^ Target position 3-vector.
66 -> Vector t -- ^ Upward direction 3-vector.
67 -> Matrix t
68lookat pos target up = fromRows
69 [ snoc rightward (- dot rightward pos)
70 , snoc upward (- dot upward pos)
71 , snoc backward (- dot backward pos)
72 , snoc (fromList[0,0,0]) 1
73 ]
74 where
75 backward = normalize $ pos - target
76 rightward = normalize $ up `cross` backward
77 upward = backward `cross` rightward
78
79 -- Rebind 'normalize' in order to support Float which has no Field
80 -- instance.
81 normalize :: (Linear t c, Fractional t, Normed (c t)) => c t -> c t
82 normalize v = scale (1 / realToFrac (norm_2 v)) v
83
84{-# SPECIALIZE lookat :: Vector R -> Vector R -> Vector R -> Matrix R #-}
85
86
87
88
89
90-- lookat pos target up <> rot t
91-- == lookat ((((pos - target) <# rot (-t))) + target)
92-- target
93--
94-- | Perspective transformation 4x4 matrix.
95perspective :: (Storable a, Floating a) =>
96 a -- ^ Near plane clipping distance (always positive).
97 -> a -- ^ Far plane clipping distance (always positive).
98 -> a -- ^ Field of view of the y axis, in radians.
99 -> a -- ^ Aspect ratio, i.e. screen's width\/height.
100 -> Matrix a
101perspective n f fovy aspect = (4><4)
102 [ (2*n/(r-l)) , 0 , 0 , 0
103 , 0 , (2*n/(t-b)) , 0 , 0
104 , (-(r+l)/(r-l)) , ((t+b)/(t-b)) , (-(f+n)/(f-n)) , (-1)
105 , 0 , 0 , (-2*f*n/(f-n)) , 0 ]
106 where
107 t = n*tan(fovy/2)
108 b = -t
109 r = aspect*t
110 l = -r
111
112
113
114-- | Build a look at view matrix
115{-
116lookat2
117 :: (Epsilon a, Floating a)
118 => V3 a -- ^ Eye
119 -> V3 a -- ^ Center
120 -> V3 a -- ^ Up
121 -> M44 a
122-}
123lookat2 :: (Normed (Vector a), Field a, Num (Vector a)) =>
124 Vector a -> Vector a -> Vector a -> Matrix a
125lookat2 eye center up = fromColumns
126 [ snoc xa xd
127 , snoc ya yd
128 , snoc (-za) zd
129 , fromList [ 0 , 0 , 0 , 1 ] ]
130 where za = normalize $ center - eye
131 xa = normalize $ cross za up
132 ya = cross xa za
133 xd = -dot xa eye
134 yd = -dot ya eye
135 zd = dot za eye
136
137{-
138
139-- | Build a look at view matrix
140lookAt
141 :: (Epsilon a, Floating a)
142 => V3 a -- ^ Eye
143 -> V3 a -- ^ Center
144 -> V3 a -- ^ Up
145 -> M44 a
146lookAt eye center up =
147 V4 (V4 (xa^._x) (xa^._y) (xa^._z) xd)
148 (V4 (ya^._x) (ya^._y) (ya^._z) yd)
149 (V4 (-za^._x) (-za^._y) (-za^._z) zd)
150 (V4 0 0 0 1)
151 where za = normalize $ center - eye
152 xa = normalize $ cross za up
153 ya = cross xa za
154 xd = -dot xa eye
155 yd = -dot ya eye
156 zd = dot za eye
157
158-- | Build a matrix for a symmetric perspective-view frustum
159perspective
160 :: Floating a
161 => a -- ^ FOV (y direction, in radians)
162 -> a -- ^ Aspect ratio
163 -> a -- ^ Near plane
164 -> a -- ^ Far plane
165 -> M44 a
166perspective fovy aspect near far =
167 V4 (V4 x 0 0 0)
168 (V4 0 y 0 0)
169 (V4 0 0 z w)
170 (V4 0 0 (-1) 0)
171 where tanHalfFovy = tan $ fovy / 2
172 x = 1 / (aspect * tanHalfFovy)
173 y = 1 / tanHalfFovy
174 fpn = far + near
175 fmn = far - near
176 oon = 0.5/near
177 oof = 0.5/far
178 -- z = 1 / (near/fpn - far/fpn) -- would be better by .5 bits
179 z = -fpn/fmn
180 w = 1/(oof-oon) -- 13 bits error reduced to 0.17
181 -- w = -(2 * far * near) / fmn
182
183
184-- | Perspective transformation matrix in row major order.
185perspective :: Float -- ^ Near plane clipping distance (always positive).
186 -> Float -- ^ Far plane clipping distance (always positive).
187 -> Float -- ^ Field of view of the y axis, in radians.
188 -> Float -- ^ Aspect ratio, i.e. screen's width\/height.
189 -> Mat4
190perspective n f fovy aspect = transpose $
191 Mat4 (Vec4 (2*n/(r-l)) 0 (-(r+l)/(r-l)) 0)
192 (Vec4 0 (2*n/(t-b)) ((t+b)/(t-b)) 0)
193 (Vec4 0 0 (-(f+n)/(f-n)) (-2*f*n/(f-n)))
194 (Vec4 0 0 (-1) 0)
195 where
196 t = n*tan(fovy/2)
197 b = -t
198 r = aspect*t
199 l = -r
200
201-}
202
203lookAtRotate :: (Normed (Vector t), Num (Vector t), Numeric t,
204 Floating t) =>
205 Vector t -> Vector t -> Vector t -> t -> Matrix t
206lookAtRotate pos target up t = lookat pos target up <> m
207 where
208 m = rotMatrixX t {- <> rotMatrixZ t -}
209
210rotateLookAt :: (Normed (Vector t), Floating t, Num (Vector t),
211 Numeric t) =>
212 Vector t -> Vector t -> Vector t -> t -> Matrix t
213rotateLookAt pos target up t = lookat pos' target up'
214 where
215 m = rotMatrixX (-t)
216 pos' = V.init $ (m #> snoc pos 0)
217 up' = V.init (m #> snoc up 0)
218
219
220{-
221void UniformMatrix{234}{fd}v( int location, sizei count, boolean transpose, const float *value );
222void UniformMatrix{2x3,3x2,2x4,4x2,3x4,4x3}{fd}v( int location, sizei count, boolean transpose, const float *value );
223
224The UniformMatrix{234}fv and UniformMatrix{234}dv commands will load count 2 ×
2252, 3 × 3, or 4 × 4 matrices (corresponding to 2, 3, or 4 in the command name)
226of single- or double-precision floating-point values, respectively, into a
227uniform defined as a matrix or an array of matrices. If transpose is FALSE ,
228the matrix is specified in column major order, otherwise in row major order.
229
230-}
diff --git a/TimeKeeper.hs b/TimeKeeper.hs
index d85f61f..36e7e8a 100644
--- a/TimeKeeper.hs
+++ b/TimeKeeper.hs
@@ -24,6 +24,9 @@ newTimeKeeper = do
24 ff <- newMVar 0 24 ff <- newMVar 0
25 return $ TimeKeeper s ff 25 return $ TimeKeeper s ff
26 26
27getSeconds :: TimeKeeper -> IO Double
28getSeconds tk = readMVar (tmSeconds tk)
29
27tick :: TimeKeeper -> Widget -> FrameClock -> IO Bool 30tick :: TimeKeeper -> Widget -> FrameClock -> IO Bool
28tick tm widget clock = widgetGetWindow widget >>= \case 31tick tm widget clock = widgetGetWindow widget >>= \case
29 Nothing -> return SOURCE_REMOVE 32 Nothing -> return SOURCE_REMOVE
diff --git a/hello_obj2.lc b/hello_obj2.lc
index ebee807..7adf8b1 100644
--- a/hello_obj2.lc
+++ b/hello_obj2.lc
@@ -1,15 +1,11 @@
1deg30 = 0.5235987755982988 -- pi/6 1deg30 = 0.5235987755982988 -- pi/6
2 2
3coordmap (time::Float) (p::Vec 4 Float) 3coordmap (cam::Mat 4 4 Float) (p::Vec 4 Float)
4 = perspective 0.1 -- near plane 4 = perspective 0.1 -- near plane
5 100 -- far plane 5 100 -- far plane
6 deg30 -- y fov radians 6 deg30 -- y fov radians
7 1 -- aspect ratio w/h 7 1 -- aspect ratio w/h
8 *. lookat (V3 0 0 10) -- camera position 8 *. cam
9 (V3 0 0 0) -- target position
10 (V3 0 1 0) -- upward direction
11 *. rotMatrixX time -- time = radians
12 *. rotMatrixZ time -- time = radians
13 *. p 9 *. p
14 10
15blendplane = -- NoBlending -- BlendLogicOp Xor 11blendplane = -- NoBlending -- BlendLogicOp Xor
@@ -17,7 +13,7 @@ blendplane = -- NoBlending -- BlendLogicOp Xor
17 ((OneBF,SrcAlpha),(DstAlpha,DstAlpha)) 13 ((OneBF,SrcAlpha),(DstAlpha,DstAlpha))
18 (V4 0 0 0 0) 14 (V4 0 0 0 0)
19 15
20makeFrame (time :: Float) 16makeFrame (cam :: Mat 4 4 Float)
21 (color :: Vec 4 Float) 17 (color :: Vec 4 Float)
22 (texture :: Texture) 18 (texture :: Texture)
23 (prims :: PrimitiveStream Triangle (Vec 4 Float, Vec 3 Float, Vec 3 Float)) 19 (prims :: PrimitiveStream Triangle (Vec 4 Float, Vec 3 Float, Vec 3 Float))
@@ -26,13 +22,13 @@ makeFrame (time :: Float)
26 = imageFrame (emptyDepthImage 1, emptyColorImage (V4 0 0 0.4 1)) 22 = imageFrame (emptyDepthImage 1, emptyColorImage (V4 0 0 0.4 1))
27 `overlay` 23 `overlay`
28 prims 24 prims
29 & mapPrimitives (\(p,n,uvw) -> ( coordmap time p, V2 uvw%x (1 - uvw%y) )) 25 & mapPrimitives (\(p,n,uvw) -> ( coordmap cam p, V2 uvw%x (1 - uvw%y) ))
30 & rasterizePrimitives (TriangleCtx CullBack PolygonFill NoOffset LastVertex) ((Smooth)) 26 & rasterizePrimitives (TriangleCtx CullBack PolygonFill NoOffset LastVertex) ((Smooth))
31 & mapFragments (\((uv)) -> ((color * texture2D (Sampler PointFilter MirroredRepeat texture) uv ))) 27 & mapFragments (\((uv)) -> ((color * texture2D (Sampler PointFilter MirroredRepeat texture) uv )))
32 & accumulateWith (DepthOp Less True, ColorOp NoBlending (V4 True True True True)) 28 & accumulateWith (DepthOp Less True, ColorOp NoBlending (V4 True True True True))
33 `overlay` 29 `overlay`
34 plane 30 plane
35 & mapPrimitives (\((p)) -> (coordmap time p, p%xy )) 31 & mapPrimitives (\((p)) -> (coordmap cam p, p%xy ))
36 & rasterizePrimitives (TriangleCtx CullNone PolygonFill NoOffset LastVertex) ((Smooth)) 32 & rasterizePrimitives (TriangleCtx CullNone PolygonFill NoOffset LastVertex) ((Smooth))
37 -- & mapFragments (\((uv)) -> ((texture2D (Sampler PointFilter MirroredRepeat texture) uv ))) 33 -- & mapFragments (\((uv)) -> ((texture2D (Sampler PointFilter MirroredRepeat texture) uv )))
38 -- & mapFragments (\((uv)) -> ((V4 uv%x uv%y 0 1))) -- ((rgb 1 0 0))) 34 -- & mapFragments (\((uv)) -> ((V4 uv%x uv%y 0 1))) -- ((rgb 1 0 0)))
@@ -46,7 +42,7 @@ makeFrame (time :: Float)
46 42
47 43
48main = renderFrame $ 44main = renderFrame $
49 makeFrame (Uniform "time") 45 makeFrame (Uniform "cam")
50 (Uniform "diffuseColor") 46 (Uniform "diffuseColor")
51 (Texture2DSlot "diffuseTexture") 47 (Texture2DSlot "diffuseTexture")
52 (fetch "objects" (Attribute "position", Attribute "normal", Attribute "uvw")) 48 (fetch "objects" (Attribute "position", Attribute "normal", Attribute "uvw"))
diff --git a/lambda-gtk.cabal b/lambda-gtk.cabal
index bc86d57..83eb922 100644
--- a/lambda-gtk.cabal
+++ b/lambda-gtk.cabal
@@ -25,7 +25,7 @@ executable lambda-gtk
25 -- GUI 25 -- GUI
26 gi-gdk , gi-glib , gi-gobject , gi-gtk , haskell-gi-base 26 gi-gdk , gi-glib , gi-gobject , gi-gtk , haskell-gi-base
27 -- , gi-gtk-declarative, gi-gtk-declarative-app-simple, 27 -- , gi-gtk-declarative, gi-gtk-declarative-app-simple,
28 28 default-language: Haskell2010
29 -- hs-source-dirs: 29 -- hs-source-dirs:
30 30
31 31
@@ -48,15 +48,15 @@ executable gldemo
48executable objdemo 48executable objdemo
49 main-is: mainObj.hs 49 main-is: mainObj.hs
50 other-modules: InfinitePlane LambdaCubeWidget GLWidget LambdaCube.Gtk TimeKeeper 50 other-modules: InfinitePlane LambdaCubeWidget GLWidget LambdaCube.Gtk TimeKeeper
51 LoadMesh MtlParser 51 LoadMesh MtlParser Matrix LambdaCube.GL.HMatrix
52 extensions: NondecreasingIndentation 52 extensions: NondecreasingIndentation
53 other-extensions: OverloadedLabels, OverloadedLists, OverloadedStrings 53 other-extensions: OverloadedLabels, OverloadedLists, OverloadedStrings
54 build-depends: base, containers >=0.5 && <0.6, bytestring >=0.10 && <0.11, 54 build-depends: base, containers >=0.5 && <0.6, bytestring >=0.10 && <0.11,
55 vector, aeson, JuicyPixels, text, contravariant, 55 vector, aeson, JuicyPixels, text, contravariant, hmatrix,
56 -- writer monad 56 -- writer monad
57 mtl, 57 mtl,
58 -- rendering 58 -- rendering
59 lambdacube-ir, lambdacube-gl, OpenGL, wavefront, 59 lambdacube-ir, lambdacube-gl >=0.5.4, OpenGL, wavefront,
60 -- GUI 60 -- GUI
61 gi-gdk , gi-glib , gi-gobject , gi-gtk , haskell-gi-base 61 gi-gdk , gi-glib , gi-gobject , gi-gtk , haskell-gi-base
62 62
diff --git a/mainObj.hs b/mainObj.hs
index 1513075..caa4fa4 100644
--- a/mainObj.hs
+++ b/mainObj.hs
@@ -13,23 +13,31 @@ import Data.Text (Text)
13import Data.Map.Strict (Map) 13import Data.Map.Strict (Map)
14import qualified Data.Map.Strict as Map 14import qualified Data.Map.Strict as Map
15import qualified Data.Vector as V 15import qualified Data.Vector as V
16import Data.Vector.Generic as VG (init,snoc)
16import GI.Gdk.Objects 17import GI.Gdk.Objects
17import GI.GLib.Constants 18import GI.GLib.Constants
18import GI.Gtk as Gtk hiding (main) 19import GI.Gtk as Gtk hiding (main)
19import LambdaCube.GL as LC 20import LambdaCube.GL as LC
20import LambdaCube.GL.Mesh as LC 21import LambdaCube.GL.Mesh as LC
22import Numeric.LinearAlgebra hiding ((<>))
21import System.Environment 23import System.Environment
22import System.IO 24import System.IO
23import System.IO.Error 25import System.IO.Error
24 26
25import GLWidget 27import GLWidget
28import LambdaCube.GL.HMatrix
26import LambdaCubeWidget 29import LambdaCubeWidget
27import TimeKeeper 30import TimeKeeper
28import LoadMesh 31import LoadMesh
29import InfinitePlane 32import InfinitePlane
30import MtlParser (ObjMaterial(..)) 33import MtlParser (ObjMaterial(..))
34import Matrix
31 35
32type State = (TimeKeeper, TickCallbackHandle) 36-- State created by uploadState.
37data State = State
38 { stTimeKeeper :: TimeKeeper
39 , stTickCallback :: TickCallbackHandle
40 }
33 41
34addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) -> IO [LC.Object] 42addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) -> IO [LC.Object]
35addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) -> do 43addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) -> do
@@ -57,17 +65,28 @@ uploadState obj glarea storage = do
57 -- setup FrameClock 65 -- setup FrameClock
58 tm <- newTimeKeeper 66 tm <- newTimeKeeper
59 tickcb <- widgetAddTickCallback glarea (tick tm) 67 tickcb <- widgetAddTickCallback glarea (tick tm)
60 return (tm,tickcb) 68
69 return State
70 { stTimeKeeper = tm
71 , stTickCallback = tickcb
72 }
61 73
62destroyState :: GLArea -> State -> IO () 74destroyState :: GLArea -> State -> IO ()
63destroyState glarea (tm,tickcb) = do 75destroyState glarea st = do
64 widgetRemoveTickCallback glarea tickcb 76 widgetRemoveTickCallback glarea (stTickCallback st)
65 77
66setUniforms :: glctx -> GLStorage -> State -> IO () 78setUniforms :: glctx -> GLStorage -> State -> IO ()
67setUniforms gl storage (tm,_) = do 79setUniforms gl storage st = do
68 t <- withMVar (tmSeconds tm) return 80 t <- getSeconds $ stTimeKeeper st
81 let tf = realToFrac t :: Float
82 roZ = rotMatrixZ (-tf)
83 roX = rotMatrixX (-tf)
84 ro = roZ <> roX
85 pos = VG.init (ro #> fromList [0,0,10,0])
86 up = VG.init (ro #> fromList [0,1,0,0])
87 cam = lookat pos 0 up
69 LC.updateUniforms storage $ do 88 LC.updateUniforms storage $ do
70 "time" @= return (realToFrac t :: Float) 89 "cam" @= return (cam :: Matrix Float)
71 90
72main :: IO () 91main :: IO ()
73main = do 92main = do
@@ -82,7 +101,7 @@ main = do
82 defObjectArray "plane" Triangles $ do 101 defObjectArray "plane" Triangles $ do
83 "position" @: Attribute_V4F 102 "position" @: Attribute_V4F
84 defUniforms $ do 103 defUniforms $ do
85 "time" @: Float 104 "cam" @: M44F
86 "diffuseTexture" @: FTexture2D 105 "diffuseTexture" @: FTexture2D
87 "diffuseColor" @: V4F 106 "diffuseColor" @: V4F
88 return $ (,) <$> mobj <*> mpipeline 107 return $ (,) <$> mobj <*> mpipeline