diff options
Diffstat (limited to 'src/LambdaCube')
-rw-r--r-- | src/LambdaCube/GL/Backend.hs | 43 |
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 | ||
790 | setupRenderTarget :: IORef (Maybe InputConnection) | 794 | setupRenderTarget :: Maybe GLuint |
795 | -> IORef (Maybe InputConnection) | ||
791 | -> GLRenderTarget -> IO () | 796 | -> GLRenderTarget -> IO () |
792 | setupRenderTarget glInput GLRenderTarget{..} = do | 797 | setupRenderTarget 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 | |
807 | setupDrawContext :: IORef Bool | 814 | Nothing -> bl |
815 | Just _ -> \case { GL_BACK_LEFT -> GL_COLOR_ATTACHMENT0 ; x -> x } `map` bl) | ||
816 | $ glDrawBuffers (fromIntegral $ length bl) | ||
817 | |||
818 | setupDrawContext :: 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 () |
812 | setupDrawContext glForceSetup glDrawContextRef glInput new = do | 824 | setupDrawContext 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) |