diff options
Diffstat (limited to 'src/LambdaCube')
-rw-r--r-- | src/LambdaCube/GL/Backend.hs | 254 | ||||
-rw-r--r-- | src/LambdaCube/GL/Type.hs | 50 |
2 files changed, 202 insertions, 102 deletions
diff --git a/src/LambdaCube/GL/Backend.hs b/src/LambdaCube/GL/Backend.hs index c682723..712f357 100644 --- a/src/LambdaCube/GL/Backend.hs +++ b/src/LambdaCube/GL/Backend.hs | |||
@@ -1,9 +1,9 @@ | |||
1 | {-# LANGUAGE TupleSections, MonadComprehensions, RecordWildCards, LambdaCase #-} | 1 | {-# LANGUAGE TupleSections, MonadComprehensions, RecordWildCards, LambdaCase, FlexibleContexts #-} |
2 | module LambdaCube.GL.Backend where | 2 | module LambdaCube.GL.Backend where |
3 | 3 | ||
4 | import Control.Applicative | 4 | import Control.Applicative |
5 | import Control.Monad | 5 | import Control.Monad |
6 | import Control.Monad.State | 6 | import Control.Monad.State.Strict |
7 | import Data.Maybe | 7 | import Data.Maybe |
8 | import Data.Bits | 8 | import Data.Bits |
9 | import Data.IORef | 9 | import Data.IORef |
@@ -497,23 +497,31 @@ allocRenderer p = do | |||
497 | -- texture unit mapping ioref trie | 497 | -- texture unit mapping ioref trie |
498 | -- texUnitMapRefs :: Map UniformName (IORef TextureUnit) | 498 | -- texUnitMapRefs :: Map UniformName (IORef TextureUnit) |
499 | texUnitMapRefs <- Map.fromList <$> mapM (\k -> (k,) <$> newIORef 0) (S.toList $ S.fromList $ concat $ V.toList $ V.map (Map.keys . programInTextures) $ programs p) | 499 | texUnitMapRefs <- Map.fromList <$> mapM (\k -> (k,) <$> newIORef 0) (S.toList $ S.fromList $ concat $ V.toList $ V.map (Map.keys . programInTextures) $ programs p) |
500 | let (cmds,st) = runState (mapM (compileCommand texUnitMapRefs smps texs trgs prgs) $ V.toList $ commands p) initCGState | 500 | let st = execState (mapM_ (compileCommand texUnitMapRefs smps texs trgs prgs) (V.toList $ commands p)) initCGState |
501 | input <- newIORef Nothing | 501 | input <- newIORef Nothing |
502 | -- default Vertex Array Object | 502 | -- default Vertex Array Object |
503 | vao <- alloca $! \pvao -> glGenVertexArrays 1 pvao >> peek pvao | 503 | vao <- alloca $! \pvao -> glGenVertexArrays 1 pvao >> peek pvao |
504 | strs <- V.mapM compileStreamData $ streams p | 504 | strs <- V.mapM compileStreamData $ streams p |
505 | drawContextRef <- newIORef $ error "missing DrawContext" | ||
506 | forceSetup <- newIORef True | ||
507 | vertexBufferRef <- newIORef 0 | ||
508 | indexBufferRef <- newIORef 0 | ||
505 | return $ GLRenderer | 509 | return $ GLRenderer |
506 | { glPrograms = prgs | 510 | { glPrograms = prgs |
507 | , glTextures = texs | 511 | , glTextures = texs |
508 | , glSamplers = smps | 512 | , glSamplers = smps |
509 | , glTargets = trgs | 513 | , glTargets = trgs |
510 | , glCommands = cmds | 514 | , glCommands = reverse $ drawCommands st |
511 | , glSlotPrograms = V.map (V.toList . slotPrograms) $ IR.slots p | 515 | , glSlotPrograms = V.map (V.toList . slotPrograms) $ IR.slots p |
512 | , glInput = input | 516 | , glInput = input |
513 | , glSlotNames = V.map slotName $ IR.slots p | 517 | , glSlotNames = V.map slotName $ IR.slots p |
514 | , glVAO = vao | 518 | , glVAO = vao |
515 | , glTexUnitMapping = texUnitMapRefs | 519 | , glTexUnitMapping = texUnitMapRefs |
516 | , glStreams = strs | 520 | , glStreams = strs |
521 | , glDrawContextRef = drawContextRef | ||
522 | , glForceSetup = forceSetup | ||
523 | , glVertexBufferRef = vertexBufferRef | ||
524 | , glIndexBufferRef = indexBufferRef | ||
517 | } | 525 | } |
518 | 526 | ||
519 | disposeRenderer :: GLRenderer -> IO () | 527 | disposeRenderer :: GLRenderer -> IO () |
@@ -684,20 +692,26 @@ setStorage' p@GLRenderer{..} input' = do | |||
684 | buffer binding on various targets: GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER | 692 | buffer binding on various targets: GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER |
685 | glEnable/DisableVertexAttribArray | 693 | glEnable/DisableVertexAttribArray |
686 | -} | 694 | -} |
687 | renderSlot :: [GLObjectCommand] -> IO () | 695 | renderSlot :: IORef GLuint -> IORef GLuint -> [GLObjectCommand] -> IO () |
688 | renderSlot cmds = forM_ cmds $ \cmd -> do | 696 | renderSlot glVertexBufferRef glIndexBufferRef cmds = forM_ cmds $ \cmd -> do |
697 | let setup ref v m = do | ||
698 | old <- readIORef ref | ||
699 | unless (old == v) $ do | ||
700 | writeIORef ref v | ||
701 | m | ||
702 | |||
689 | case cmd of | 703 | case cmd of |
690 | GLSetVertexAttribArray idx buf size typ ptr -> do | 704 | GLSetVertexAttribArray idx buf size typ ptr -> do |
691 | glBindBuffer GL_ARRAY_BUFFER buf | 705 | setup glVertexBufferRef buf $ glBindBuffer GL_ARRAY_BUFFER buf |
692 | glEnableVertexAttribArray idx | 706 | glEnableVertexAttribArray idx |
693 | glVertexAttribPointer idx size typ (fromIntegral GL_FALSE) 0 ptr | 707 | glVertexAttribPointer idx size typ (fromIntegral GL_FALSE) 0 ptr |
694 | GLSetVertexAttribIArray idx buf size typ ptr -> do | 708 | GLSetVertexAttribIArray idx buf size typ ptr -> do |
695 | glBindBuffer GL_ARRAY_BUFFER buf | 709 | setup glVertexBufferRef buf $ glBindBuffer GL_ARRAY_BUFFER buf |
696 | glEnableVertexAttribArray idx | 710 | glEnableVertexAttribArray idx |
697 | glVertexAttribIPointer idx size typ 0 ptr | 711 | glVertexAttribIPointer idx size typ 0 ptr |
698 | GLDrawArrays mode first count -> glDrawArrays mode first count | 712 | GLDrawArrays mode first count -> glDrawArrays mode first count |
699 | GLDrawElements mode count typ buf indicesPtr -> do | 713 | GLDrawElements mode count typ buf indicesPtr -> do |
700 | glBindBuffer GL_ELEMENT_ARRAY_BUFFER buf | 714 | setup glIndexBufferRef buf $ glBindBuffer GL_ELEMENT_ARRAY_BUFFER buf |
701 | glDrawElements mode count typ indicesPtr | 715 | glDrawElements mode count typ indicesPtr |
702 | GLSetUniform idx (GLUniform ty ref) -> setUniform idx ty ref | 716 | GLSetUniform idx (GLUniform ty ref) -> setUniform idx ty ref |
703 | GLBindTexture txTarget tuRef (GLUniform _ ref) -> do | 717 | GLBindTexture txTarget tuRef (GLUniform _ ref) -> do |
@@ -715,105 +729,175 @@ renderSlot cmds = forM_ cmds $ \cmd -> do | |||
715 | --isOk <- checkGL | 729 | --isOk <- checkGL |
716 | --putStrLn $ isOk ++ " - " ++ show cmd | 730 | --putStrLn $ isOk ++ " - " ++ show cmd |
717 | 731 | ||
732 | setupRenderTarget glInput GLRenderTarget{..} = do | ||
733 | -- set target viewport | ||
734 | ic' <- readIORef glInput | ||
735 | case ic' of | ||
736 | Nothing -> return () | ||
737 | Just ic -> do | ||
738 | let input = icInput ic | ||
739 | (w,h) <- readIORef $ screenSize input | ||
740 | glViewport 0 0 (fromIntegral w) (fromIntegral h) | ||
741 | -- TODO: set FBO target viewport | ||
742 | glBindFramebuffer GL_DRAW_FRAMEBUFFER framebufferObject | ||
743 | case framebufferDrawbuffers of | ||
744 | Nothing -> return () | ||
745 | Just bl -> withArray bl $ glDrawBuffers (fromIntegral $ length bl) | ||
746 | |||
747 | setupDrawContext glForceSetup glDrawContextRef glInput new = do | ||
748 | old <- readIORef glDrawContextRef | ||
749 | writeIORef glDrawContextRef new | ||
750 | force <- readIORef glForceSetup | ||
751 | writeIORef glForceSetup False | ||
752 | |||
753 | let setup :: Eq a => (GLDrawContext -> a) -> (a -> IO ()) -> IO () | ||
754 | setup f m = case force of | ||
755 | True -> m $ f new | ||
756 | False -> do | ||
757 | let a = f new | ||
758 | unless (a == f old) $ m a | ||
759 | |||
760 | setup glRenderTarget $ setupRenderTarget glInput | ||
761 | setup glRasterContext $ setupRasterContext | ||
762 | setup glAccumulationContext setupAccumulationContext | ||
763 | setup glProgram glUseProgram | ||
764 | |||
765 | -- setup texture mapping | ||
766 | setup glTextureMapping $ mapM_ $ \(textureUnit,GLTexture{..}) -> do | ||
767 | glActiveTexture (GL_TEXTURE0 + fromIntegral textureUnit) | ||
768 | glBindTexture glTextureTarget glTextureObject | ||
769 | |||
770 | -- setup sampler mapping | ||
771 | setup glSamplerMapping $ mapM_ $ \(textureUnit,GLSampler{..}) -> do | ||
772 | glBindSampler (GL_TEXTURE0 + fromIntegral textureUnit) glSamplerObject | ||
773 | |||
774 | -- setup sampler uniform mapping | ||
775 | setup glSamplerUniformMapping $ mapM_ $ \(textureUnit,GLSamplerUniform{..}) -> do | ||
776 | glUniform1i glUniformBinding (fromIntegral textureUnit) | ||
777 | writeIORef glUniformBindingRef (fromIntegral textureUnit) | ||
778 | |||
718 | renderFrame :: GLRenderer -> IO () | 779 | renderFrame :: GLRenderer -> IO () |
719 | renderFrame glp = do | 780 | renderFrame GLRenderer{..} = do |
720 | glBindVertexArray (glVAO glp) | 781 | writeIORef glForceSetup True |
721 | forM_ (glCommands glp) $ \cmd -> do | 782 | writeIORef glVertexBufferRef 0 |
783 | writeIORef glIndexBufferRef 0 | ||
784 | glBindVertexArray glVAO | ||
785 | forM_ glCommands $ \cmd -> do | ||
722 | case cmd of | 786 | case cmd of |
723 | GLSetRasterContext rCtx -> setupRasterContext rCtx | 787 | GLClearRenderTarget rt vals -> do |
724 | GLSetAccumulationContext aCtx -> setupAccumulationContext aCtx | 788 | setupRenderTarget glInput rt |
725 | GLSetRenderTarget rt bufs -> do | 789 | clearRenderTarget vals |
726 | -- set target viewport | 790 | modifyIORef glDrawContextRef $ \ctx -> ctx {glRenderTarget = rt} |
727 | --when (rt == 0) $ do -- screen out | 791 | |
728 | ic' <- readIORef $ glInput glp | 792 | GLRenderStream ctx streamIdx progIdx -> do |
729 | case ic' of | 793 | setupDrawContext glForceSetup glDrawContextRef glInput ctx |
730 | Nothing -> return () | 794 | drawcmd <- readIORef (glStreamCommands $ glStreams ! streamIdx) |
731 | Just ic -> do | 795 | renderSlot glVertexBufferRef glIndexBufferRef drawcmd |
732 | let input = icInput ic | 796 | |
733 | (w,h) <- readIORef $ screenSize input | 797 | GLRenderSlot ctx slotIdx progIdx -> do |
734 | glViewport 0 0 (fromIntegral w) (fromIntegral h) | 798 | input <- readIORef glInput |
735 | -- TODO: set FBO target viewport | 799 | case input of |
736 | glBindFramebuffer GL_DRAW_FRAMEBUFFER rt | 800 | Nothing -> putStrLn "Warning: No pipeline input!" >> return () |
737 | case bufs of | 801 | Just ic -> do |
738 | Nothing -> return () | 802 | let draw setupDone obj = readIORef (objEnabled obj) >>= \case |
739 | Just bl -> withArray bl $ glDrawBuffers (fromIntegral $ length bl) | 803 | False -> return setupDone |
740 | GLSetProgram p -> glUseProgram p | 804 | True -> do |
741 | GLSetSamplerUniform i tu ref -> glUniform1i i tu >> writeIORef ref tu | 805 | unless setupDone $ setupDrawContext glForceSetup glDrawContextRef glInput ctx |
742 | GLSetTexture tu target tx -> glActiveTexture tu >> glBindTexture target tx | 806 | drawcmd <- readIORef $ objCommands obj |
743 | GLSetSampler tu s -> glBindSampler tu s | 807 | --putStrLn "Render object" |
744 | GLClearRenderTarget vals -> clearRenderTarget vals | 808 | renderSlot glVertexBufferRef glIndexBufferRef ((drawcmd ! icId ic) ! progIdx) |
745 | GLGenerateMipMap tu target -> glActiveTexture tu >> glGenerateMipmap target | 809 | return True |
746 | GLRenderStream streamIdx progIdx -> do | 810 | --putStrLn $ "Rendering " ++ show (V.length objs) ++ " objects" |
747 | renderSlot =<< readIORef (glStreamCommands $ glStreams glp ! streamIdx) | 811 | readIORef (slotVector (icInput ic) ! (icSlotMapPipelineToInput ic ! slotIdx)) >>= \case |
748 | GLRenderSlot slotIdx progIdx -> do | 812 | GLSlot _ objs Ordered -> foldM_ (\a -> draw a . snd) False objs |
749 | input <- readIORef (glInput glp) | 813 | GLSlot objMap _ _ -> foldM_ draw False objMap |
750 | case input of | 814 | |
751 | Nothing -> putStrLn "Warning: No pipeline input!" >> return () | ||
752 | Just ic -> do | ||
753 | let draw obj = do | ||
754 | enabled <- readIORef $ objEnabled obj | ||
755 | when enabled $ do | ||
756 | cmd <- readIORef $ objCommands obj | ||
757 | --putStrLn "Render object" | ||
758 | renderSlot ((cmd ! icId ic) ! progIdx) | ||
759 | --putStrLn $ "Rendering " ++ show (V.length objs) ++ " objects" | ||
760 | readIORef (slotVector (icInput ic) ! (icSlotMapPipelineToInput ic ! slotIdx)) >>= \case | ||
761 | GLSlot _ objs Ordered -> forM_ objs $ draw . snd | ||
762 | GLSlot objMap _ _ -> forM_ objMap draw | ||
763 | {- | ||
764 | GLSetSampler | ||
765 | GLSaveImage | ||
766 | GLLoadImage | ||
767 | -} | ||
768 | --isOk <- checkGL | 815 | --isOk <- checkGL |
769 | --putStrLn $ isOk ++ " - " ++ show cmd | 816 | --putStrLn $ isOk ++ " - " ++ show cmd |
770 | 817 | ||
771 | data CGState | 818 | data CGState |
772 | = CGState | 819 | = CGState |
773 | { currentProgram :: ProgramName | 820 | { textureBinding :: IntMap GLTexture |
774 | , textureBinding :: IntMap GLTexture | 821 | , drawCommands :: [GLCommand] |
775 | } | 822 | -- draw context data |
823 | , rasterContext :: RasterContext | ||
824 | , accumulationContext :: AccumulationContext | ||
825 | , renderTarget :: GLRenderTarget | ||
826 | , currentProgram :: ProgramName | ||
827 | , samplerUniformMapping :: [(GLTextureUnit,GLSamplerUniform)] | ||
828 | , textureMapping :: [(GLTextureUnit,GLTexture)] | ||
829 | , samplerMapping :: [(GLTextureUnit,GLSampler)] | ||
830 | } | ||
776 | 831 | ||
777 | initCGState = CGState | 832 | initCGState = CGState |
778 | { currentProgram = error "CGState: empty currentProgram" | 833 | { textureBinding = mempty |
779 | , textureBinding = IM.empty | 834 | , drawCommands = mempty |
780 | } | 835 | -- draw context data |
836 | , rasterContext = error "compileCommand: missing RasterContext" | ||
837 | , accumulationContext = error "compileCommand: missing AccumulationContext" | ||
838 | , renderTarget = error "compileCommand: missing RenderTarget" | ||
839 | , currentProgram = error "compileCommand: missing Program" | ||
840 | , samplerUniformMapping = mempty | ||
841 | , textureMapping = mempty | ||
842 | , samplerMapping = mempty | ||
843 | } | ||
781 | 844 | ||
782 | type CG a = State CGState a | 845 | type CG a = State CGState a |
783 | 846 | ||
784 | compileCommand :: Map String (IORef GLint) -> Vector GLSampler -> Vector GLTexture -> Vector GLRenderTarget -> Vector GLProgram -> Command -> CG GLCommand | 847 | emit :: GLCommand -> CG () |
848 | emit cmd = modify $ \s -> s {drawCommands = cmd : drawCommands s} | ||
849 | |||
850 | drawContext programs = | ||
851 | GLDrawContext <$> gets rasterContext | ||
852 | <*> gets accumulationContext | ||
853 | <*> gets renderTarget | ||
854 | <*> gets (programObject . (programs !) . currentProgram) | ||
855 | <*> gets textureMapping | ||
856 | <*> gets samplerMapping | ||
857 | <*> gets samplerUniformMapping | ||
858 | |||
859 | compileCommand :: Map String (IORef GLint) -> Vector GLSampler -> Vector GLTexture -> Vector GLRenderTarget -> Vector GLProgram -> Command -> CG () | ||
785 | compileCommand texUnitMap samplers textures targets programs cmd = case cmd of | 860 | compileCommand texUnitMap samplers textures targets programs cmd = case cmd of |
786 | SetRasterContext rCtx -> return $ GLSetRasterContext rCtx | 861 | SetRasterContext rCtx -> modify $ \s -> s {rasterContext = rCtx} |
787 | SetAccumulationContext aCtx -> return $ GLSetAccumulationContext aCtx | 862 | SetAccumulationContext aCtx -> modify $ \s -> s {accumulationContext = aCtx} |
788 | SetRenderTarget rt -> let GLRenderTarget fbo bufs = targets ! rt in return $ GLSetRenderTarget fbo bufs | 863 | SetRenderTarget rt -> modify $ \s -> s {renderTarget = targets ! rt} |
789 | SetProgram p -> do | 864 | SetProgram p -> modify $ \s -> s |
790 | modify (\s -> s {currentProgram = p}) | 865 | { currentProgram = p |
791 | return $ GLSetProgram $ programObject $ programs ! p | 866 | , samplerUniformMapping = mempty |
867 | , textureMapping = mempty | ||
868 | , samplerMapping = mempty | ||
869 | } | ||
792 | SetSamplerUniform n tu -> do | 870 | SetSamplerUniform n tu -> do |
793 | p <- currentProgram <$> get | 871 | p <- currentProgram <$> get |
794 | case Map.lookup n (inputTextures $ programs ! p) of | 872 | case Map.lookup n (inputTextures $ programs ! p) of |
795 | Nothing -> return (GLSetProgram (programObject $ programs ! p) {-HACK!!! we have to emit something-}) -- TODO: some drivers does heavy cross stage (vertex/fragment) dead code elimination; fail $ "internal error (SetSamplerUniform)! - " ++ show cmd | 873 | Nothing -> return () -- TODO: some drivers does heavy cross stage (vertex/fragment) dead code elimination; fail $ "internal error (SetSamplerUniform)! - " ++ show cmd |
796 | Just i -> case Map.lookup n texUnitMap of | 874 | Just i -> case Map.lookup n texUnitMap of |
797 | Nothing -> fail $ "internal error (SetSamplerUniform - IORef)! - " ++ show cmd | 875 | Nothing -> fail $ "internal error (SetSamplerUniform - IORef)! - " ++ show cmd |
798 | Just r -> return $ GLSetSamplerUniform i (fromIntegral tu) r | 876 | Just r -> modify $ \s -> s {samplerUniformMapping = (tu, GLSamplerUniform i r) : samplerUniformMapping s} |
799 | SetTexture tu t -> do | 877 | SetTexture tu t -> do |
800 | let tex = textures ! t | 878 | let tex = textures ! t |
801 | modify (\s -> s {textureBinding = IM.insert tu tex $ textureBinding s}) | 879 | modify $ \s -> s |
802 | return $ GLSetTexture (GL_TEXTURE0 + fromIntegral tu) (glTextureTarget tex) (glTextureObject tex) | 880 | { textureBinding = IM.insert tu tex $ textureBinding s |
803 | SetSampler tu s -> return $ GLSetSampler (GL_TEXTURE0 + fromIntegral tu) (maybe 0 (glSamplerObject . (samplers !)) s) | 881 | , textureMapping = (tu, tex) : textureMapping s |
882 | } | ||
883 | SetSampler tu i -> modify $ \s -> s {samplerMapping = (tu, maybe (GLSampler 0) (samplers !) i) : samplerMapping s} | ||
884 | |||
885 | -- draw commands | ||
804 | RenderSlot slot -> do | 886 | RenderSlot slot -> do |
805 | p <- currentProgram <$> get | 887 | p <- gets currentProgram |
806 | return $ GLRenderSlot slot p | 888 | ctx <- drawContext programs |
889 | emit $ GLRenderSlot ctx slot p | ||
807 | RenderStream stream -> do | 890 | RenderStream stream -> do |
808 | p <- currentProgram <$> get | 891 | p <- gets currentProgram |
809 | return $ GLRenderStream stream p | 892 | ctx <- drawContext programs |
810 | ClearRenderTarget vals -> return $ GLClearRenderTarget $ V.toList vals | 893 | emit $ GLRenderStream ctx stream p |
894 | ClearRenderTarget vals -> do | ||
895 | rt <- gets renderTarget | ||
896 | emit $ GLClearRenderTarget rt $ V.toList vals | ||
897 | {- | ||
811 | GenerateMipMap tu -> do | 898 | GenerateMipMap tu -> do |
812 | tb <- textureBinding <$> get | 899 | tb <- textureBinding <$> get |
813 | case IM.lookup tu tb of | 900 | case IM.lookup tu tb of |
814 | Nothing -> fail "internal error (GenerateMipMap)!" | 901 | Nothing -> fail "internal error (GenerateMipMap)!" |
815 | Just tex -> return $ GLGenerateMipMap (GL_TEXTURE0 + fromIntegral tu) (glTextureTarget tex) | 902 | Just tex -> return $ GLGenerateMipMap (GL_TEXTURE0 + fromIntegral tu) (glTextureTarget tex) |
816 | {- | 903 | -} \ No newline at end of file |
817 | SaveImage _ _ -> undefined | ||
818 | LoadImage _ _ -> undefined | ||
819 | -} | ||
diff --git a/src/LambdaCube/GL/Type.hs b/src/LambdaCube/GL/Type.hs index 5a9117d..776a425 100644 --- a/src/LambdaCube/GL/Type.hs +++ b/src/LambdaCube/GL/Type.hs | |||
@@ -128,7 +128,7 @@ data GLTexture | |||
128 | = GLTexture | 128 | = GLTexture |
129 | { glTextureObject :: GLuint | 129 | { glTextureObject :: GLuint |
130 | , glTextureTarget :: GLenum | 130 | , glTextureTarget :: GLenum |
131 | } | 131 | } deriving Eq |
132 | 132 | ||
133 | data InputConnection | 133 | data InputConnection |
134 | = InputConnection | 134 | = InputConnection |
@@ -159,34 +159,50 @@ data GLRenderer | |||
159 | , glVAO :: GLuint | 159 | , glVAO :: GLuint |
160 | , glTexUnitMapping :: Map String (IORef GLint) -- maps texture uniforms to texture units | 160 | , glTexUnitMapping :: Map String (IORef GLint) -- maps texture uniforms to texture units |
161 | , glStreams :: Vector GLStream | 161 | , glStreams :: Vector GLStream |
162 | , glDrawContextRef :: IORef GLDrawContext | ||
163 | , glForceSetup :: IORef Bool | ||
164 | , glVertexBufferRef :: IORef GLuint | ||
165 | , glIndexBufferRef :: IORef GLuint | ||
162 | } | 166 | } |
163 | 167 | ||
164 | data GLSampler | 168 | data GLSampler |
165 | = GLSampler | 169 | = GLSampler |
166 | { glSamplerObject :: GLuint | 170 | { glSamplerObject :: GLuint |
167 | } | 171 | } deriving Eq |
168 | 172 | ||
169 | data GLRenderTarget | 173 | data GLRenderTarget |
170 | = GLRenderTarget | 174 | = GLRenderTarget |
171 | { framebufferObject :: GLuint | 175 | { framebufferObject :: GLuint |
172 | , framebufferDrawbuffers :: Maybe [GLenum] | 176 | , framebufferDrawbuffers :: Maybe [GLenum] |
173 | } | 177 | } deriving Eq |
178 | |||
179 | type GLTextureUnit = Int | ||
180 | type GLUniformBinding = GLint | ||
181 | |||
182 | data GLSamplerUniform | ||
183 | = GLSamplerUniform | ||
184 | { glUniformBinding :: GLUniformBinding | ||
185 | , glUniformBindingRef :: IORef GLUniformBinding | ||
186 | } | ||
187 | |||
188 | instance Eq GLSamplerUniform where | ||
189 | a == b = glUniformBinding a == glUniformBinding b | ||
190 | |||
191 | data GLDrawContext | ||
192 | = GLDrawContext | ||
193 | { glRasterContext :: RasterContext | ||
194 | , glAccumulationContext :: AccumulationContext | ||
195 | , glRenderTarget :: GLRenderTarget | ||
196 | , glProgram :: GLuint | ||
197 | , glTextureMapping :: [(GLTextureUnit,GLTexture)] | ||
198 | , glSamplerMapping :: [(GLTextureUnit,GLSampler)] | ||
199 | , glSamplerUniformMapping :: [(GLTextureUnit,GLSamplerUniform)] | ||
200 | } | ||
174 | 201 | ||
175 | data GLCommand | 202 | data GLCommand |
176 | = GLSetRasterContext !RasterContext | 203 | = GLRenderSlot GLDrawContext SlotName ProgramName |
177 | | GLSetAccumulationContext !AccumulationContext | 204 | | GLRenderStream GLDrawContext StreamName ProgramName |
178 | | GLSetRenderTarget !GLuint !(Maybe [GLenum]) | 205 | | GLClearRenderTarget GLRenderTarget [ClearImage] |
179 | | GLSetProgram !GLuint | ||
180 | | GLSetSamplerUniform !GLint !GLint (IORef GLint) -- sampler index, texture unit, IORef stores the actual texture unit mapping | ||
181 | | GLSetTexture !GLenum !GLuint !GLuint | ||
182 | | GLSetSampler !GLuint !GLuint | ||
183 | | GLRenderSlot !SlotName !ProgramName | ||
184 | | GLRenderStream !StreamName !ProgramName | ||
185 | | GLClearRenderTarget [ClearImage] | ||
186 | | GLGenerateMipMap !GLenum !GLenum | ||
187 | | GLSaveImage FrameBufferComponent ImageRef -- from framebuffer component to texture (image) | ||
188 | | GLLoadImage ImageRef FrameBufferComponent -- from texture (image) to framebuffer component | ||
189 | deriving Show | ||
190 | 206 | ||
191 | instance Show (IORef GLint) where | 207 | instance Show (IORef GLint) where |
192 | show _ = "(IORef GLint)" | 208 | show _ = "(IORef GLint)" |