summaryrefslogtreecommitdiff
path: root/src/LambdaCube/GL/Backend.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/LambdaCube/GL/Backend.hs')
-rw-r--r--src/LambdaCube/GL/Backend.hs83
1 files changed, 64 insertions, 19 deletions
diff --git a/src/LambdaCube/GL/Backend.hs b/src/LambdaCube/GL/Backend.hs
index 324b3e6..0584a34 100644
--- a/src/LambdaCube/GL/Backend.hs
+++ b/src/LambdaCube/GL/Backend.hs
@@ -126,7 +126,7 @@ setupAccumulationContext (AccumulationContext n ops) = cvt ops
126 glDepthFunc $! comparisonFunctionToGLType df 126 glDepthFunc $! comparisonFunctionToGLType df
127 glDepthMask (cvtBool dm) 127 glDepthMask (cvtBool dm)
128 cvtC 0 xs 128 cvtC 0 xs
129 cvt xs = do 129 cvt xs = do
130 glDisable GL_DEPTH_TEST 130 glDisable GL_DEPTH_TEST
131 glDisable GL_STENCIL_TEST 131 glDisable GL_STENCIL_TEST
132 cvtC 0 xs 132 cvtC 0 xs
@@ -169,8 +169,8 @@ setupAccumulationContext (AccumulationContext n ops) = cvt ops
169 cvtBool True = 1 169 cvtBool True = 1
170 cvtBool False = 0 170 cvtBool False = 0
171 171
172clearRenderTarget :: [ClearImage] -> IO () 172clearRenderTarget :: GLRenderTarget -> [ClearImage] -> IO ()
173clearRenderTarget values = do 173clearRenderTarget GLRenderTarget{..} values = do
174 let setClearValue (m,i) value = case value of 174 let setClearValue (m,i) value = case value of
175 ClearImage Depth (VFloat v) -> do 175 ClearImage Depth (VFloat v) -> do
176 glDepthMask 1 176 glDepthMask 1
@@ -180,20 +180,46 @@ clearRenderTarget values = do
180 glClearStencil $ fromIntegral v 180 glClearStencil $ fromIntegral v
181 return (m .|. GL_STENCIL_BUFFER_BIT, i) 181 return (m .|. GL_STENCIL_BUFFER_BIT, i)
182 ClearImage Color c -> do 182 ClearImage Color c -> do
183 let (r,g,b,a) = case c of
184 VFloat r -> (realToFrac r, 0, 0, 1)
185 VV2F (V2 r g) -> (realToFrac r, realToFrac g, 0, 1)
186 VV3F (V3 r g b) -> (realToFrac r, realToFrac g, realToFrac b, 1)
187 VV4F (V4 r g b a) -> (realToFrac r, realToFrac g, realToFrac b, realToFrac a)
188 _ -> (0,0,0,1)
189 glColorMask 1 1 1 1 183 glColorMask 1 1 1 1
190 glClearColor r g b a 184 if framebufferObject == 0
191 return (m .|. GL_COLOR_BUFFER_BIT, i+1) 185 then
186 clearDefaultFB >>
187 pure (m .|. GL_COLOR_BUFFER_BIT, i+1)
188 else
189 clearFBColorAttachment >>
190 pure (m, i+1)
191 where
192 clearDefaultFB = do
193 let (r,g,b,a) = case c of
194 VFloat r -> (realToFrac r, 0, 0, 1)
195 VV2F (V2 r g) -> (realToFrac r, realToFrac g, 0, 1)
196 VV3F (V3 r g b) -> (realToFrac r, realToFrac g, realToFrac b, 1)
197 VV4F (V4 r g b a) -> (realToFrac r, realToFrac g, realToFrac b, realToFrac a)
198 _ -> (0,0,0,1)
199 glClearColor r g b a
200 clearFBColorAttachment = do
201 let buf = GL_COLOR
202 case c of -- there must be some clever way to extract the generality here, I'm sure..
203 VFloat r -> with (V4 r 0 0 1) $ glClearBufferfv buf i . castPtr
204 VV2F (V2 r g) -> with (V4 r g 0 1) $ glClearBufferfv buf i . castPtr
205 VV3F (V3 r g b) -> with (V4 r g b 1) $ glClearBufferfv buf i . castPtr
206 VV4F (V4 r g b a) -> with (V4 r g b a) $ glClearBufferfv buf i . castPtr
207
208 VInt r -> with (V4 r 0 0 1) $ glClearBufferiv buf i . castPtr
209 VV2I (V2 r g) -> with (V4 r g 0 1) $ glClearBufferiv buf i . castPtr
210 VV3I (V3 r g b) -> with (V4 r g b 1) $ glClearBufferiv buf i . castPtr
211 VV4I (V4 r g b a) -> with (V4 r g b a) $ glClearBufferiv buf i . castPtr
212
213 VWord r -> with (V4 r 0 0 1) $ glClearBufferiv buf i . castPtr
214 VV2U (V2 r g) -> with (V4 r g 0 1) $ glClearBufferiv buf i . castPtr
215 VV3U (V3 r g b) -> with (V4 r g b 1) $ glClearBufferiv buf i . castPtr
216 VV4U (V4 r g b a) -> with (V4 r g b a) $ glClearBufferiv buf i . castPtr
217 _ -> error $ "internal error: unsupported color attachment format: " <> show c
218
192 _ -> error "internal error (clearRenderTarget)" 219 _ -> error "internal error (clearRenderTarget)"
193 (mask,_) <- foldM setClearValue (0,0) values 220 (mask,_) <- foldM setClearValue (0,0) values
194 glClear $ fromIntegral mask 221 glClear $ fromIntegral mask
195 222
196
197printGLStatus = checkGL >>= print 223printGLStatus = checkGL >>= print
198printFBOStatus = checkFBO >>= print 224printFBOStatus = checkFBO >>= print
199 225
@@ -283,6 +309,15 @@ compileProgram p = do
283 , inputStreams = Map.fromList [(n,(idx, attrName)) | (n,idx) <- Map.toList $ attributes, let attrName = fromMaybe (error $ "missing attribute: " ++ n) $ Map.lookup n lcStreamName] 309 , inputStreams = Map.fromList [(n,(idx, attrName)) | (n,idx) <- Map.toList $ attributes, let attrName = fromMaybe (error $ "missing attribute: " ++ n) $ Map.lookup n lcStreamName]
284 } 310 }
285 311
312renderTargetOutputs :: Vector GLTexture -> RenderTarget -> GLRenderTarget -> [GLOutput]
313renderTargetOutputs glTexs (RenderTarget targetItems) (GLRenderTarget fbo bufs) =
314 let isFB (Framebuffer _) = True
315 isFB _ = False
316 images = [img | TargetItem _ (Just img) <- V.toList targetItems]
317 in case all isFB images of
318 True -> fromMaybe [] $ (GLOutputDrawBuffer fbo <$>) <$> bufs
319 False -> (\(TextureImage texIdx _ _)-> GLOutputRenderTexture fbo $ glTexs ! texIdx) <$> images
320
286compileRenderTarget :: Vector TextureDescriptor -> Vector GLTexture -> RenderTarget -> IO GLRenderTarget 321compileRenderTarget :: Vector TextureDescriptor -> Vector GLTexture -> RenderTarget -> IO GLRenderTarget
287compileRenderTarget texs glTexs (RenderTarget targets) = do 322compileRenderTarget texs glTexs (RenderTarget targets) = do
288 let isFB (Framebuffer _) = True 323 let isFB (Framebuffer _) = True
@@ -344,7 +379,7 @@ compileRenderTarget texs glTexs (RenderTarget targets) = do
344 | n > 1 -> attachArray 379 | n > 1 -> attachArray
345 | otherwise -> attach2D 380 | otherwise -> attach2D
346 TextureBuffer _ -> fail "internalError (compileRenderTarget/TextureBuffer)!" 381 TextureBuffer _ -> fail "internalError (compileRenderTarget/TextureBuffer)!"
347 382
348 go a (TargetItem Stencil (Just img)) = do 383 go a (TargetItem Stencil (Just img)) = do
349 fail "Stencil support is not implemented yet!" 384 fail "Stencil support is not implemented yet!"
350 return a 385 return a
@@ -453,7 +488,7 @@ createStreamCommands texUnitMap topUnis attrs primitive prg = streamUniCmds ++ s
453 488
454 -- object attribute stream commands 489 -- object attribute stream commands
455 streamCmds = [attrCmd i s | (i,name) <- Map.elems attrMap, let s = fromMaybe (error $ "missing attribute: " ++ name) $ Map.lookup name attrs] 490 streamCmds = [attrCmd i s | (i,name) <- Map.elems attrMap, let s = fromMaybe (error $ "missing attribute: " ++ name) $ Map.lookup name attrs]
456 where 491 where
457 attrMap = inputStreams prg 492 attrMap = inputStreams prg
458 attrCmd i s = case s of 493 attrCmd i s = case s of
459 Stream ty (Buffer arrs bo) arrIdx start len -> case ty of 494 Stream ty (Buffer arrs bo) arrIdx start len -> case ty of
@@ -488,16 +523,25 @@ createStreamCommands texUnitMap topUnis attrs primitive prg = streamUniCmds ++ s
488 -- constant generic attribute 523 -- constant generic attribute
489 constAttr -> GLSetVertexAttrib i constAttr 524 constAttr -> GLSetVertexAttrib i constAttr
490 525
526outputIsRenderTexture :: GLOutput -> Bool
527outputIsRenderTexture GLOutputRenderTexture{..} = True
528outputIsRenderTexture _ = False
529
491allocRenderer :: Pipeline -> IO GLRenderer 530allocRenderer :: Pipeline -> IO GLRenderer
492allocRenderer p = do 531allocRenderer p = do
493 smps <- V.mapM compileSampler $ samplers p 532 smps <- V.mapM compileSampler $ samplers p
494 texs <- V.mapM compileTexture $ textures p 533 texs <- V.mapM compileTexture $ textures p
495 trgs <- V.mapM (compileRenderTarget (textures p) texs) $ targets p 534 let cmds = V.toList $ commands p
535 finalRenderTargetIdx = head [i | SetRenderTarget i <- reverse $ cmds]
536 trgs <- traverse (compileRenderTarget (textures p) texs) $ targets p
537 let finalRenderTarget = targets p ! finalRenderTargetIdx
538 finalGLRenderTarget = trgs ! finalRenderTargetIdx
539 outs = renderTargetOutputs texs finalRenderTarget finalGLRenderTarget
496 prgs <- V.mapM compileProgram $ programs p 540 prgs <- V.mapM compileProgram $ programs p
497 -- texture unit mapping ioref trie 541 -- texture unit mapping ioref trie
498 -- texUnitMapRefs :: Map UniformName (IORef TextureUnit) 542 -- texUnitMapRefs :: Map UniformName (IORef TextureUnit)
499 texUnitMapRefs <- Map.fromList <$> mapM (\k -> (k,) <$> newIORef 0) (Set.toList $ Set.fromList $ concat $ V.toList $ V.map (Map.keys . programInTextures) $ programs p) 543 texUnitMapRefs <- Map.fromList <$> mapM (\k -> (k,) <$> newIORef 0) (Set.toList $ Set.fromList $ concat $ V.toList $ V.map (Map.keys . programInTextures) $ programs p)
500 let st = execState (mapM_ (compileCommand texUnitMapRefs smps texs trgs prgs) (V.toList $ commands p)) initCGState 544 let st = execState (mapM_ (compileCommand texUnitMapRefs smps texs trgs prgs) cmds) initCGState
501 input <- newIORef Nothing 545 input <- newIORef Nothing
502 -- default Vertex Array Object 546 -- default Vertex Array Object
503 vao <- alloca $! \pvao -> glGenVertexArrays 1 pvao >> peek pvao 547 vao <- alloca $! \pvao -> glGenVertexArrays 1 pvao >> peek pvao
@@ -515,6 +559,7 @@ allocRenderer p = do
515 , glCommands = reverse $ drawCommands st 559 , glCommands = reverse $ drawCommands st
516 , glSlotPrograms = V.map (V.toList . slotPrograms) $ IR.slots p 560 , glSlotPrograms = V.map (V.toList . slotPrograms) $ IR.slots p
517 , glInput = input 561 , glInput = input
562 , glOutputs = outs
518 , glSlotNames = V.map slotName $ IR.slots p 563 , glSlotNames = V.map slotName $ IR.slots p
519 , glVAO = vao 564 , glVAO = vao
520 , glTexUnitMapping = texUnitMapRefs 565 , glTexUnitMapping = texUnitMapRefs
@@ -573,7 +618,7 @@ isSubTrie eqFun universe subset = and [isMember a (Map.lookup n universe) | (n,a
573 when (sPrim /= (primitiveToFetchPrimitive prim)) $ throw $ userError $ 618 when (sPrim /= (primitiveToFetchPrimitive prim)) $ throw $ userError $
574 "Primitive mismatch for slot (" ++ show slotName ++ ") expected " ++ show sPrim ++ " but got " ++ show prim 619 "Primitive mismatch for slot (" ++ show slotName ++ ") expected " ++ show sPrim ++ " but got " ++ show prim
575 let sType = fmap streamToStreamType attribs 620 let sType = fmap streamToStreamType attribs
576 when (sType /= sAttrs) $ throw $ userError $ unlines $ 621 when (sType /= sAttrs) $ throw $ userError $ unlines $
577 [ "Attribute stream mismatch for slot (" ++ show slotName ++ ") expected " 622 [ "Attribute stream mismatch for slot (" ++ show slotName ++ ") expected "
578 , show sAttrs 623 , show sAttrs
579 , " but got " 624 , " but got "
@@ -790,7 +835,7 @@ renderFrame GLRenderer{..} = do
790 case cmd of 835 case cmd of
791 GLClearRenderTarget rt vals -> do 836 GLClearRenderTarget rt vals -> do
792 setupRenderTarget glInput rt 837 setupRenderTarget glInput rt
793 clearRenderTarget vals 838 clearRenderTarget rt vals
794 modifyIORef glDrawContextRef $ \ctx -> ctx {glRenderTarget = rt} 839 modifyIORef glDrawContextRef $ \ctx -> ctx {glRenderTarget = rt}
795 840
796 GLRenderStream ctx streamIdx progIdx -> do 841 GLRenderStream ctx streamIdx progIdx -> do
@@ -895,4 +940,4 @@ compileCommand texUnitMap samplers textures targets programs cmd = case cmd of
895 case IM.lookup tu tb of 940 case IM.lookup tu tb of
896 Nothing -> fail "internal error (GenerateMipMap)!" 941 Nothing -> fail "internal error (GenerateMipMap)!"
897 Just tex -> return $ GLGenerateMipMap (GL_TEXTURE0 + fromIntegral tu) (glTextureTarget tex) 942 Just tex -> return $ GLGenerateMipMap (GL_TEXTURE0 + fromIntegral tu) (glTextureTarget tex)
898-} \ No newline at end of file 943-}