summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-05-21 04:08:24 -0400
committerJoe Crayne <joe@jerkface.net>2019-05-21 04:08:24 -0400
commitcba699022b784bb63cc783071b48bfc9d7958599 (patch)
treeb2c77291770d1a7b4c89d6ed1f7f19b154e78d66
parent1e229efbbe69b5fac07a3604ce50e3e8ded06eef (diff)
GTK compatibility: render to non-default framebuffer.
-rw-r--r--src/LambdaCube/GL/Backend.hs43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/LambdaCube/GL/Backend.hs b/src/LambdaCube/GL/Backend.hs
index 8c533f2..faeccff 100644
--- a/src/LambdaCube/GL/Backend.hs
+++ b/src/LambdaCube/GL/Backend.hs
@@ -337,7 +337,11 @@ compileRenderTarget texs glTexs (RenderTarget targets) = do
337 let bufs = [cvt img | TargetItem Color img <- V.toList targets] 337 let bufs = [cvt img | TargetItem Color img <- V.toList targets]
338 cvt a = case a of 338 cvt a = case a of
339 Nothing -> GL_NONE 339 Nothing -> GL_NONE
340 Just (Framebuffer Color) -> GL_BACK_LEFT 340 Just (Framebuffer Color) -> GL_BACK_LEFT -- GTK compatibility: this tentative value
341 -- may be changed to GL_COLOR_ATTACHMENT0 later. We
342 -- avoid doing it now to allow for 'allocRenderer' to
343 -- be called from GTK's "realize" signal before the
344 -- actual frame buffer target is known.
341 _ -> error "internal error (compileRenderTarget)!" 345 _ -> error "internal error (compileRenderTarget)!"
342 return $ GLRenderTarget 346 return $ GLRenderTarget
343 { framebufferObject = 0 347 { framebufferObject = 0
@@ -787,9 +791,10 @@ renderSlot glDrawCallCounterRef glVertexBufferRef glIndexBufferRef cmds = forM_
787 --isOk <- checkGL 791 --isOk <- checkGL
788 --putStrLn $ isOk ++ " - " ++ show cmd 792 --putStrLn $ isOk ++ " - " ++ show cmd
789 793
790setupRenderTarget :: IORef (Maybe InputConnection) 794setupRenderTarget :: Maybe GLuint
795 -> IORef (Maybe InputConnection)
791 -> GLRenderTarget -> IO () 796 -> GLRenderTarget -> IO ()
792setupRenderTarget glInput GLRenderTarget{..} = do 797setupRenderTarget boundfb glInput GLRenderTarget{..} = do
793 -- set target viewport 798 -- set target viewport
794 ic' <- readIORef glInput 799 ic' <- readIORef glInput
795 case ic' of 800 case ic' of
@@ -799,17 +804,24 @@ setupRenderTarget glInput GLRenderTarget{..} = do
799 (w,h) <- readIORef $ screenSize input 804 (w,h) <- readIORef $ screenSize input
800 glViewport 0 0 (fromIntegral w) (fromIntegral h) 805 glViewport 0 0 (fromIntegral w) (fromIntegral h)
801 -- TODO: set FBO target viewport 806 -- TODO: set FBO target viewport
802 glBindFramebuffer GL_DRAW_FRAMEBUFFER framebufferObject 807 glBindFramebuffer GL_DRAW_FRAMEBUFFER
808 -- GTK compatibility: substitute initially bound framebuffer for default binding.
809 $ maybe id (\def -> \case { 0 -> def ; x -> x }) boundfb framebufferObject
803 case framebufferDrawbuffers of 810 case framebufferDrawbuffers of
804 Nothing -> return () 811 Nothing -> return ()
805 Just bl -> withArray bl $ glDrawBuffers (fromIntegral $ length bl) 812 Just bl -> withArray -- GTK compatibility: avoid using default-only buffer for a non-default binding.
806 813 (case boundfb of
807setupDrawContext :: IORef Bool 814 Nothing -> bl
815 Just _ -> \case { GL_BACK_LEFT -> GL_COLOR_ATTACHMENT0 ; x -> x } `map` bl)
816 $ glDrawBuffers (fromIntegral $ length bl)
817
818setupDrawContext :: Maybe GLuint
819 -> IORef Bool
808 -> IORef GLDrawContext 820 -> IORef GLDrawContext
809 -> IORef (Maybe InputConnection) 821 -> IORef (Maybe InputConnection)
810 -> GLDrawContext 822 -> GLDrawContext
811 -> IO () 823 -> IO ()
812setupDrawContext glForceSetup glDrawContextRef glInput new = do 824setupDrawContext boundfb glForceSetup glDrawContextRef glInput new = do
813 old <- readIORef glDrawContextRef 825 old <- readIORef glDrawContextRef
814 writeIORef glDrawContextRef new 826 writeIORef glDrawContextRef new
815 force <- readIORef glForceSetup 827 force <- readIORef glForceSetup
@@ -822,7 +834,7 @@ setupDrawContext glForceSetup glDrawContextRef glInput new = do
822 let a = f new 834 let a = f new
823 unless (a == f old) $ m a 835 unless (a == f old) $ m a
824 836
825 setup glRenderTarget $ setupRenderTarget glInput 837 setup glRenderTarget $ setupRenderTarget boundfb glInput
826 setup glRasterContext $ setupRasterContext 838 setup glRasterContext $ setupRasterContext
827 setup glAccumulationContext setupAccumulationContext 839 setup glAccumulationContext setupAccumulationContext
828 setup glProgram glUseProgram 840 setup glProgram glUseProgram
@@ -847,16 +859,23 @@ renderFrame GLRenderer{..} = do
847 writeIORef glVertexBufferRef 0 859 writeIORef glVertexBufferRef 0
848 writeIORef glIndexBufferRef 0 860 writeIORef glIndexBufferRef 0
849 writeIORef glDrawCallCounterRef 0 861 writeIORef glDrawCallCounterRef 0
862 fb <- do
863 -- For GTK compatibility, we detect the currently bound draw buffer and use it instead of
864 -- the default framebuffer.
865 fbo <- alloca $! \pbo -> glGetIntegerv GL_DRAW_FRAMEBUFFER_BINDING pbo >> peek pbo
866 return $ case fbo of
867 0 -> Nothing
868 _ -> Just $ fromIntegral fbo
850 glBindVertexArray glVAO 869 glBindVertexArray glVAO
851 forM_ glCommands $ \cmd -> do 870 forM_ glCommands $ \cmd -> do
852 case cmd of 871 case cmd of
853 GLClearRenderTarget rt vals -> do 872 GLClearRenderTarget rt vals -> do
854 setupRenderTarget glInput rt 873 setupRenderTarget fb glInput rt
855 clearRenderTarget rt vals 874 clearRenderTarget rt vals
856 modifyIORef glDrawContextRef $ \ctx -> ctx {glRenderTarget = rt} 875 modifyIORef glDrawContextRef $ \ctx -> ctx {glRenderTarget = rt}
857 876
858 GLRenderStream ctx streamIdx progIdx -> do 877 GLRenderStream ctx streamIdx progIdx -> do
859 setupDrawContext glForceSetup glDrawContextRef glInput ctx 878 setupDrawContext fb glForceSetup glDrawContextRef glInput ctx
860 drawcmd <- readIORef (glStreamCommands $ glStreams ! streamIdx) 879 drawcmd <- readIORef (glStreamCommands $ glStreams ! streamIdx)
861 renderSlot glDrawCallCounterRef glVertexBufferRef glIndexBufferRef drawcmd 880 renderSlot glDrawCallCounterRef glVertexBufferRef glIndexBufferRef drawcmd
862 881
@@ -868,7 +887,7 @@ renderFrame GLRenderer{..} = do
868 let draw setupDone obj = readIORef (objEnabled obj) >>= \case 887 let draw setupDone obj = readIORef (objEnabled obj) >>= \case
869 False -> return setupDone 888 False -> return setupDone
870 True -> do 889 True -> do
871 unless setupDone $ setupDrawContext glForceSetup glDrawContextRef glInput ctx 890 unless setupDone $ setupDrawContext fb glForceSetup glDrawContextRef glInput ctx
872 drawcmd <- readIORef $ objCommands obj 891 drawcmd <- readIORef $ objCommands obj
873 --putStrLn "Render object" 892 --putStrLn "Render object"
874 renderSlot glDrawCallCounterRef glVertexBufferRef glIndexBufferRef ((drawcmd ! icId ic) ! progIdx) 893 renderSlot glDrawCallCounterRef glVertexBufferRef glIndexBufferRef ((drawcmd ! icId ic) ! progIdx)