diff options
author | Joe Crayne <joe@jerkface.net> | 2019-05-21 04:21:48 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-05-21 04:21:48 -0400 |
commit | a2aa65ffc5a4fc6cd0f41ccab1516f85a27989b2 (patch) | |
tree | 3b02233126690fea8a96ad2d2765be858ec41ab4 | |
parent | bc6fd1c71e22ef54a4aed8774dcec4dd190b9dbc (diff) |
Added colors to pen points + various updates.
-rw-r--r-- | GLWidget.hs | 7 | ||||
-rw-r--r-- | MaskableStream.hs | 1 | ||||
-rw-r--r-- | MeshSketch.hs | 81 | ||||
-rw-r--r-- | hello_obj2.lc | 8 |
4 files changed, 75 insertions, 22 deletions
diff --git a/GLWidget.hs b/GLWidget.hs index 8620c1a..ebd6694 100644 --- a/GLWidget.hs +++ b/GLWidget.hs | |||
@@ -63,8 +63,11 @@ newGLWidget mk w = do | |||
63 | withCurrentGL :: GLArea -> IO () -> IO () | 63 | withCurrentGL :: GLArea -> IO () -> IO () |
64 | withCurrentGL glarea action = do | 64 | withCurrentGL glarea action = do |
65 | gLAreaMakeCurrent glarea | 65 | gLAreaMakeCurrent glarea |
66 | e <- gLAreaGetError glarea | 66 | gLAreaGetError glarea >>= maybe action oopsG |
67 | maybe action oopsG e | 67 | -- -- The following causes realize and resize to each be triggered |
68 | -- -- twice before the first render signal. | ||
69 | -- gLAreaAttachBuffers glarea | ||
70 | -- gLAreaGetError glarea >>= maybe action oopsG | ||
68 | 71 | ||
69 | nullableContext :: IO (Maybe GLContext) -> IO GLContext | 72 | nullableContext :: IO (Maybe GLContext) -> IO GLContext |
70 | nullableContext mk = mk >>= maybe mknull return | 73 | nullableContext mk = mk >>= maybe mknull return |
diff --git a/MaskableStream.hs b/MaskableStream.hs index d836f37..6c03769 100644 --- a/MaskableStream.hs +++ b/MaskableStream.hs | |||
@@ -331,7 +331,6 @@ updateAttributes i writer = forM_ (execWriter writer) $ \case | |||
331 | 331 | ||
332 | Just (MarshalGLVector with) -> with $ \sz ptr -> do | 332 | Just (MarshalGLVector with) -> with $ \sz ptr -> do |
333 | let sz' = fromIntegral $ attribSize * (fromIntegral sz) | 333 | let sz' = fromIntegral $ attribSize * (fromIntegral sz) |
334 | putStrLn $ "vector sz = " ++ show sz | ||
335 | glBufferSubData GL_ARRAY_BUFFER (base + fromIntegral i * sz') sz' ptr | 334 | glBufferSubData GL_ARRAY_BUFFER (base + fromIntegral i * sz') sz' ptr |
336 | 335 | ||
337 | Just (MarshalGLMatrix with) -> with $ \sz isrowcol ptr -> case isrowcol of | 336 | Just (MarshalGLMatrix with) -> with $ \sz isrowcol ptr -> case isrowcol of |
diff --git a/MeshSketch.hs b/MeshSketch.hs index 2b29f0a..8df74b3 100644 --- a/MeshSketch.hs +++ b/MeshSketch.hs | |||
@@ -17,6 +17,7 @@ import Data.Function ((&)) | |||
17 | import Data.Functor ((<&>)) | 17 | import Data.Functor ((<&>)) |
18 | import Data.Int | 18 | import Data.Int |
19 | import Data.IORef | 19 | import Data.IORef |
20 | import Data.Maybe | ||
20 | import Data.Text (Text) | 21 | import Data.Text (Text) |
21 | import Data.Map.Strict (Map) | 22 | import Data.Map.Strict (Map) |
22 | import qualified Data.Map.Strict as Map | 23 | import qualified Data.Map.Strict as Map |
@@ -25,6 +26,7 @@ import qualified Data.Vector.Generic as G | |||
25 | import Foreign.Marshal.Array | 26 | import Foreign.Marshal.Array |
26 | import Foreign.Storable | 27 | import Foreign.Storable |
27 | import GI.Gdk | 28 | import GI.Gdk |
29 | import GI.GObject.Functions (signalHandlerDisconnect) | ||
28 | import GI.Gdk.Objects | 30 | import GI.Gdk.Objects |
29 | import GI.GLib.Constants | 31 | import GI.GLib.Constants |
30 | import GI.Gtk hiding (IsWindow,windowFullscreen,windowUnfullscreen) | 32 | import GI.Gtk hiding (IsWindow,windowFullscreen,windowUnfullscreen) |
@@ -40,10 +42,11 @@ import LambdaCube.IR as LC | |||
40 | import LambdaCube.Gtk | 42 | import LambdaCube.Gtk |
41 | import LambdaCube.GL.Data (uploadCubeMapToGPU,uploadTextureBufferToGPU,updateTextureBuffer) | 43 | import LambdaCube.GL.Data (uploadCubeMapToGPU,uploadTextureBufferToGPU,updateTextureBuffer) |
42 | import LambdaCube.GL.Type (TextureCubeData(..),Object(..)) | 44 | import LambdaCube.GL.Type (TextureCubeData(..),Object(..)) |
43 | -- import Text.Show.Pretty (ppShow) | 45 | import Text.Show.Pretty (ppShow) |
44 | import qualified Graphics.Rendering.OpenGL as GL | 46 | import qualified Graphics.Rendering.OpenGL as GL |
45 | import Data.Char | 47 | import Data.Char |
46 | import Text.Printf | 48 | import Text.Printf |
49 | import qualified Foreign.C.Types | ||
47 | 50 | ||
48 | import CubeMap | 51 | import CubeMap |
49 | import GLWidget (nullableContext, withCurrentGL) | 52 | import GLWidget (nullableContext, withCurrentGL) |
@@ -82,6 +85,7 @@ type Plane = Vector Float | |||
82 | 85 | ||
83 | data RingPoint = RingPoint | 86 | data RingPoint = RingPoint |
84 | { rpPosition :: AttributeKey (GLVector 3 Float) | 87 | { rpPosition :: AttributeKey (GLVector 3 Float) |
88 | , rpColor :: AttributeKey (GLVector 3 Float) | ||
85 | } | 89 | } |
86 | deriving Data | 90 | deriving Data |
87 | 91 | ||
@@ -293,14 +297,18 @@ data MeshSketch = MeshSketch | |||
293 | , mmRealized :: IORef (Maybe Realized) | 297 | , mmRealized :: IORef (Maybe Realized) |
294 | } | 298 | } |
295 | 299 | ||
300 | type SignalHandlerId = Foreign.C.Types.CULong | ||
301 | |||
296 | data Realized = Realized | 302 | data Realized = Realized |
297 | { stStorage :: GLStorage | 303 | { stStorage :: GLStorage |
298 | , stRenderer :: GLRenderer | 304 | , stRenderer :: GLRenderer |
299 | , stState :: State | 305 | , stState :: State |
306 | , stSigs :: [SignalHandlerId] -- Signals attached by onRealize. | ||
300 | } | 307 | } |
301 | 308 | ||
302 | new :: IO GLArea | 309 | new :: IO GLArea |
303 | new = do | 310 | new = do |
311 | putStrLn "new!" | ||
304 | m <- do | 312 | m <- do |
305 | objName <- head . (++ ["cube.obj"]) <$> getArgs | 313 | objName <- head . (++ ["cube.obj"]) <$> getArgs |
306 | mobj <- loadOBJ objName | 314 | mobj <- loadOBJ objName |
@@ -316,6 +324,7 @@ new = do | |||
316 | "position" @: Attribute_V4F | 324 | "position" @: Attribute_V4F |
317 | defObjectArray "Points" Points $ do | 325 | defObjectArray "Points" Points $ do |
318 | "position" @: Attribute_V3F | 326 | "position" @: Attribute_V3F |
327 | "color" @: Attribute_V3F | ||
319 | defUniforms $ do | 328 | defUniforms $ do |
320 | "PointBuffer" @: FTextureBuffer | 329 | "PointBuffer" @: FTextureBuffer |
321 | "CubeMap" @: FTextureCube | 330 | "CubeMap" @: FTextureCube |
@@ -329,7 +338,23 @@ new = do | |||
329 | return $ (,) <$> mobj <*> mpipeline | 338 | return $ (,) <$> mobj <*> mpipeline |
330 | either (\e _ -> hPutStrLn stderr e >> throwIO (userError e)) (&) m $ \(obj,pipeline) -> do | 339 | either (\e _ -> hPutStrLn stderr e >> throwIO (userError e)) (&) m $ \(obj,pipeline) -> do |
331 | 340 | ||
341 | {- | ||
342 | let pipeline = pipeline0 { dynamicPipeline = (dynamicPipeline pipeline0) | ||
343 | { targets = fmap nocolorv (targets $ dynamicPipeline pipeline0) } } | ||
344 | nocolorv (RenderTarget v) = RenderTarget (fmap nocolor v) | ||
345 | nocolor (TargetItem LC.Color (Just (Framebuffer LC.Color))) = TargetItem LC.Color Nothing | ||
346 | nocolor x = x -} | ||
347 | |||
332 | -- putStrLn $ ppShow (dynamicPipeline pipeline) | 348 | -- putStrLn $ ppShow (dynamicPipeline pipeline) |
349 | mapM_ (putStrLn . ppShow) (targets $ dynamicPipeline pipeline) | ||
350 | {- | ||
351 | RenderTarget | ||
352 | { renderTargets = | ||
353 | [ TargetItem { targetSemantic = Depth , targetRef = Just (Framebuffer Depth) } | ||
354 | , TargetItem { targetSemantic = Color , targetRef = Just (Framebuffer Color) } | ||
355 | ] | ||
356 | } | ||
357 | -} | ||
333 | 358 | ||
334 | ref <- newIORef Nothing | 359 | ref <- newIORef Nothing |
335 | -- glarea <- newGLWidget return (lambdaRender app glmethods) | 360 | -- glarea <- newGLWidget return (lambdaRender app glmethods) |
@@ -340,29 +365,38 @@ new = do | |||
340 | st <- return g | 365 | st <- return g |
341 | _ <- on g #realize $ withCurrentGL g (onRealize obj (dynamicPipeline pipeline) (dynamicSchema pipeline) mm) | 366 | _ <- on g #realize $ withCurrentGL g (onRealize obj (dynamicPipeline pipeline) (dynamicSchema pipeline) mm) |
342 | _ <- on g #unrealize $ onUnrealize mm | 367 | _ <- on g #unrealize $ onUnrealize mm |
343 | -- _ <- on g #createContext $ nullableContext (glCreateContext w st) | 368 | _ <- on g #createContext $ nullableContext (onCreateContext g) |
344 | return g | 369 | return g |
345 | 370 | ||
346 | onUnrealize :: MeshSketch -> IO () | 371 | onUnrealize :: MeshSketch -> IO () |
347 | onUnrealize mm = do | 372 | onUnrealize mm = do |
373 | putStrLn "onUnrealize!" | ||
348 | m <- readIORef (mmRealized mm) | 374 | m <- readIORef (mmRealized mm) |
349 | forM_ m $ \st -> do | 375 | forM_ m $ \st -> do |
350 | LC.disposeStorage (stStorage st) | 376 | forM_ (stSigs st) $ \sig -> do |
377 | signalHandlerDisconnect (mmWidget mm) sig | ||
351 | LC.disposeRenderer (stRenderer st) | 378 | LC.disposeRenderer (stRenderer st) |
379 | LC.disposeStorage (stStorage st) | ||
352 | -- lcDestroyState lc x | 380 | -- lcDestroyState lc x |
381 | writeIORef (mmRealized mm) Nothing | ||
353 | 382 | ||
354 | onRealize :: MeshData -> Pipeline -> PipelineSchema -> MeshSketch -> IO () | 383 | onRealize :: MeshData -> Pipeline -> PipelineSchema -> MeshSketch -> IO () |
355 | onRealize mesh pipeline schema mm = do | 384 | onRealize mesh pipeline schema mm = do |
385 | putStrLn "onRealize!" | ||
356 | onUnrealize mm | 386 | onUnrealize mm |
357 | setupGLDebugging | 387 | setupGLDebugging |
358 | storage <- LC.allocStorage schema | 388 | storage <- LC.allocStorage schema |
389 | -- do fbo <- GL.get $ GL.bindFramebuffer GL.DrawFramebuffer | ||
390 | -- putStrLn $ "allocRenderer fbo = " ++ show fbo | ||
359 | renderer <- LC.allocRenderer pipeline | 391 | renderer <- LC.allocRenderer pipeline |
360 | compat <- LC.setStorage renderer storage -- check schema compatibility | 392 | compat <- LC.setStorage renderer storage -- check schema compatibility |
393 | -- putStrLn $ "setStorage compat = " ++ show compat | ||
361 | x <- uploadState mesh (mmWidget mm) storage | 394 | x <- uploadState mesh (mmWidget mm) storage |
362 | let r = Realized | 395 | let r = Realized |
363 | { stStorage = storage | 396 | { stStorage = storage |
364 | , stRenderer = renderer | 397 | , stRenderer = renderer |
365 | , stState = x | 398 | , stState = x |
399 | , stSigs = [] | ||
366 | } | 400 | } |
367 | w = mmWidget mm | 401 | w = mmWidget mm |
368 | set w [ #canFocus := True ] -- For keyboard events. | 402 | set w [ #canFocus := True ] -- For keyboard events. |
@@ -374,21 +408,29 @@ onRealize mesh pipeline schema mm = do | |||
374 | , EventMaskScrollMask | 408 | , EventMaskScrollMask |
375 | , EventMaskKeyPressMask -- , EventMaskKeyReleaseMask | 409 | , EventMaskKeyPressMask -- , EventMaskKeyReleaseMask |
376 | ] | 410 | ] |
377 | _ <- on w #event $ \ev -> do gLAreaMakeCurrent w | 411 | sige <- on w #event $ \ev -> do gLAreaMakeCurrent w |
378 | onEvent w r ev | 412 | gLAreaAttachBuffers w |
379 | _ <- on w #render $ onRender w r | 413 | onEvent w r ev |
380 | _ <- on w #resize $ onResize w r | 414 | sigr <- on w #render $ onRender w r |
381 | writeIORef (mmRealized mm) $ Just r | 415 | sigs <- on w #resize $ onResize w r |
416 | |||
417 | writeIORef (mmRealized mm) $ Just r { stSigs = [sige,sigr,sigs] } | ||
382 | 418 | ||
383 | onRender :: w -> Realized -> GLContext -> IO Bool | 419 | onRender :: w -> Realized -> GLContext -> IO Bool |
384 | onRender w realized gl = do | 420 | onRender w realized gl = do |
385 | r <- fixupRenderTarget (stRenderer realized) | 421 | -- putStrLn "onRender!" |
422 | r <- -- Patched lambdacube-gl: No longer need this hack. | ||
423 | -- fixupRenderTarget (stRenderer realized) | ||
424 | return (stRenderer realized) | ||
386 | setUniforms gl (stStorage realized) (stState realized) | 425 | setUniforms gl (stStorage realized) (stState realized) |
426 | -- do fbo <- GL.get $ GL.bindFramebuffer GL.DrawFramebuffer | ||
427 | -- putStrLn $ "renderFrame fbo = " ++ show fbo | ||
387 | LC.renderFrame r | 428 | LC.renderFrame r |
388 | return True | 429 | return True |
389 | 430 | ||
390 | onResize :: GLArea -> Realized -> Int32 -> Int32 -> IO () | 431 | onResize :: GLArea -> Realized -> Int32 -> Int32 -> IO () |
391 | onResize glarea realized w h = do | 432 | onResize glarea realized w h = do |
433 | -- putStrLn "onResize!" | ||
392 | -- Plenty of options here. I went with the last one. | 434 | -- Plenty of options here. I went with the last one. |
393 | -- 1. gLContextGetWindow :: HasCallStack => GLContext -> IO (Maybe Window) | 435 | -- 1. gLContextGetWindow :: HasCallStack => GLContext -> IO (Maybe Window) |
394 | -- 2. getGLContextWindow :: GLContext -> IO (Maybe Window) | 436 | -- 2. getGLContextWindow :: GLContext -> IO (Maybe Window) |
@@ -568,16 +610,19 @@ worldCoordinates st h k mplane = do | |||
568 | -- Write on the camDistance sphere. | 610 | -- Write on the camDistance sphere. |
569 | Nothing -> p + scale (camDistance cam) d̂ | 611 | Nothing -> p + scale (camDistance cam) d̂ |
570 | 612 | ||
571 | pushRing :: IsWidget w => w -> State -> Double -> Double -> IO (Vector Float) | 613 | pushRing :: IsWidget w => w -> State -> Double -> Double -> Vector Float -> IO (Vector Float) |
572 | pushRing w st h k = do | 614 | pushRing w st h k c = do |
573 | plane <- readIORef (stPlane st) | 615 | plane <- readIORef (stPlane st) |
574 | d <- worldCoordinates st h k plane | 616 | d <- worldCoordinates st h k plane |
575 | Just win <- getWidgetWindow w | 617 | Just win <- getWidgetWindow w |
576 | pushBack (stRingBuffer st) $ \RingPoint{..} -> do | 618 | pushBack (stRingBuffer st) $ \RingPoint{..} -> do |
577 | rpPosition @<- d | 619 | rpPosition @<- d |
620 | rpColor @<- c | ||
578 | windowInvalidateRect win Nothing False | 621 | windowInvalidateRect win Nothing False |
579 | return d | 622 | return d |
580 | 623 | ||
624 | yellow = fromList [1,1,0] :: Vector Float | ||
625 | red = fromList [1,0,0] :: Vector Float | ||
581 | 626 | ||
582 | onEvent :: IsWidget w => w -> Realized -> Event -> IO Bool | 627 | onEvent :: IsWidget w => w -> Realized -> Event -> IO Bool |
583 | onEvent w realized ev = do | 628 | onEvent w realized ev = do |
@@ -601,10 +646,10 @@ onEvent w realized ev = do | |||
601 | Just InputSourcePen -> do | 646 | Just InputSourcePen -> do |
602 | isDown <- readIORef (stPenDown st) | 647 | isDown <- readIORef (stPenDown st) |
603 | when isDown $ do | 648 | when isDown $ do |
604 | d <- pushRing w st h k | 649 | d <- pushRing w st h k yellow |
605 | put (etype,(h,k),d) | 650 | put (etype,(h,k),d) |
606 | _ -> do | 651 | _ -> do |
607 | put (h,k) | 652 | -- put (h,k) |
608 | updateCameraRotation w st h k | 653 | updateCameraRotation w st h k |
609 | return () | 654 | return () |
610 | Just (from,plane) -> do | 655 | Just (from,plane) -> do |
@@ -629,7 +674,7 @@ onEvent w realized ev = do | |||
629 | case inputSource of | 674 | case inputSource of |
630 | Just InputSourcePen -> do | 675 | Just InputSourcePen -> do |
631 | writeIORef (stPenDown st) True | 676 | writeIORef (stPenDown st) True |
632 | d <- pushRing w st h k | 677 | d <- pushRing w st h k red |
633 | Just win <- getWidgetWindow w | 678 | Just win <- getWidgetWindow w |
634 | windowInvalidateRect win Nothing False | 679 | windowInvalidateRect win Nothing False |
635 | put (etype,(h,k),d) | 680 | put (etype,(h,k),d) |
@@ -656,7 +701,7 @@ onEvent w realized ev = do | |||
656 | Nothing -> case inputSource of | 701 | Nothing -> case inputSource of |
657 | Just InputSourcePen -> do | 702 | Just InputSourcePen -> do |
658 | writeIORef (stPenDown st) False | 703 | writeIORef (stPenDown st) False |
659 | d <- pushRing w st h k | 704 | d <- pushRing w st h k red |
660 | Just win <- getWidgetWindow w | 705 | Just win <- getWidgetWindow w |
661 | windowInvalidateRect win Nothing False | 706 | windowInvalidateRect win Nothing False |
662 | _ -> do | 707 | _ -> do |
@@ -721,3 +766,9 @@ onEvent w realized ev = do | |||
721 | e -> return () | 766 | e -> return () |
722 | 767 | ||
723 | return False | 768 | return False |
769 | |||
770 | onCreateContext :: IsWidget a => a -> IO (Maybe GLContext) | ||
771 | onCreateContext w = do | ||
772 | putStrLn "onCreateContext!" | ||
773 | mwin <- widgetGetWindow w | ||
774 | forM mwin $ \win -> windowCreateGlContext win | ||
diff --git a/hello_obj2.lc b/hello_obj2.lc index fdf08d6..72a87ee 100644 --- a/hello_obj2.lc +++ b/hello_obj2.lc | |||
@@ -19,7 +19,7 @@ makeFrame (cubemap :: TextureCube) | |||
19 | (texture :: Texture) | 19 | (texture :: Texture) |
20 | (prims :: PrimitiveStream Triangle (Vec 4 Float, Vec 3 Float, Vec 3 Float)) | 20 | (prims :: PrimitiveStream Triangle (Vec 4 Float, Vec 3 Float, Vec 3 Float)) |
21 | (plane :: PrimitiveStream Triangle ((Vec 4 Float))) | 21 | (plane :: PrimitiveStream Triangle ((Vec 4 Float))) |
22 | (points :: PrimitiveStream Point ((Vec 3 Float))) | 22 | (points :: PrimitiveStream Point (Vec 3 Float, Vec 3 Float)) |
23 | (plane_mat :: Mat 4 4 Float) | 23 | (plane_mat :: Mat 4 4 Float) |
24 | 24 | ||
25 | = imageFrame (emptyDepthImage 1, emptyColorImage (V4 0 0 0.4 1)) | 25 | = imageFrame (emptyDepthImage 1, emptyColorImage (V4 0 0 0.4 1)) |
@@ -47,8 +47,8 @@ makeFrame (cubemap :: TextureCube) | |||
47 | & accumulateWith (DepthOp Less True, ColorOp blendplane (V4 True True True True)) | 47 | & accumulateWith (DepthOp Less True, ColorOp blendplane (V4 True True True True)) |
48 | `overlay` | 48 | `overlay` |
49 | points | 49 | points |
50 | & mapPrimitives (\((p)) -> let p' = coordmap cam $ point p | 50 | & mapPrimitives (\(p,c) -> let p' = coordmap cam $ point p |
51 | in (p', V4 1 1 0 1 :: Vec 4 Float)) | 51 | in (p', point c)) |
52 | 52 | ||
53 | & renderPoints cam | 53 | & renderPoints cam |
54 | 54 | ||
@@ -73,5 +73,5 @@ main = renderFrame $ | |||
73 | (Texture2DSlot "diffuseTexture") | 73 | (Texture2DSlot "diffuseTexture") |
74 | (fetch "objects" (Attribute "position", Attribute "normal", Attribute "uvw")) | 74 | (fetch "objects" (Attribute "position", Attribute "normal", Attribute "uvw")) |
75 | (fetch "plane" ((Attribute "position"))) | 75 | (fetch "plane" ((Attribute "position"))) |
76 | (fetch "Points" ((Attribute "position"))) | 76 | (fetch "Points" (Attribute "position", Attribute "color")) |
77 | (Uniform "PlaneModel") | 77 | (Uniform "PlaneModel") |