packages feed

luminance 0.10.0.2 → 0.11

raw patch · 10 files changed

+133/−198 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Graphics.Luminance.Region: data Region r m a
- Graphics.Luminance.Region: drawGeometry :: (MonadIO m) => RenderCmd rw c d Geometry -> Region Program m ()
- Graphics.Luminance.Region: gpuRegion :: Region () m a -> m a
- Graphics.Luminance.Region: newFrame :: (MonadIO m) => Framebuffer rw c d -> Region Framebuffer m a -> Region () m a
- Graphics.Luminance.Region: newShading :: (MonadIO m) => Some Program -> Region Program m a -> Region Framebuffer m a
+ Graphics.Luminance: DrawCmd :: (a -> (U', RenderCmd rw c d Geometry)) -> DrawCmd rw c d a
+ Graphics.Luminance: FrameCmd :: Framebuffer rw c d -> [ShadingCmd rw c d a] -> FrameCmd rw c d a
+ Graphics.Luminance: ShadingCmd :: Program a -> (a -> U') -> [DrawCmd rw c d a] -> ShadingCmd rw c d a
+ Graphics.Luminance: [drawCmd] :: DrawCmd rw c d a -> a -> (U', RenderCmd rw c d Geometry)
+ Graphics.Luminance: [frameCmdFramebuffer] :: FrameCmd rw c d a -> Framebuffer rw c d
+ Graphics.Luminance: [frameCmdShadingCmds] :: FrameCmd rw c d a -> [ShadingCmd rw c d a]
+ Graphics.Luminance: [shadingCmdDrawCmds] :: ShadingCmd rw c d a -> [DrawCmd rw c d a]
+ Graphics.Luminance: [shadingCmdProgram] :: ShadingCmd rw c d a -> Program a
+ Graphics.Luminance: [shadingCmdUniforms] :: ShadingCmd rw c d a -> a -> U'
+ Graphics.Luminance: data FrameCmd rw c d a
+ Graphics.Luminance: data ShadingCmd rw c d a
+ Graphics.Luminance: defaultFrameCmd :: [ShadingCmd RW () () a] -> FrameCmd RW () () a
+ Graphics.Luminance: draw :: (MonadIO m, Writable w) => FrameCmd w c d a -> m (Output c d)
+ Graphics.Luminance: newtype DrawCmd rw c d a
+ Graphics.Luminance: pureDraw :: RenderCmd rw c d Geometry -> DrawCmd rw c d a
+ Graphics.Luminance: render :: (MonadIO m) => U' -> RenderCmd rw c d Geometry -> m ()
+ Graphics.Luminance: shade :: (MonadIO m) => ShadingCmd rw c d a -> m ()
+ Graphics.Luminance: updateAndDraw :: (a -> U') -> RenderCmd rw c d Geometry -> DrawCmd rw c d a

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+# 0.11++- Removed `Region`s. Now using commands (`FrameCmd`, `ShadingCmd`, `DrawCmd` and `RenderCmd`). Safer+  interface.+ ### 0.10.0.2  - Fixed `Buffer` documentation.
luminance.cabal view
@@ -1,5 +1,5 @@ name:                luminance-version:             0.10.0.2+version:             0.11 synopsis:            Type-safe, type-level and stateless graphics framework description:         This package exposes several modules to work with /GPUs/ in a stateless and                      type-safe way. Currently, it uses OpenGL as backend hardware technology but@@ -76,13 +76,11 @@                      , Graphics.Luminance                      , Graphics.Luminance.Blending                      , Graphics.Luminance.Buffer-                     , Graphics.Luminance.Cmd                      , Graphics.Luminance.Core.Tuple                      , Graphics.Luminance.Framebuffer                      , Graphics.Luminance.Geometry                      , Graphics.Luminance.Pixel                      , Graphics.Luminance.Query-                     , Graphics.Luminance.Region                      , Graphics.Luminance.RenderCmd                      , Graphics.Luminance.RW                      , Graphics.Luminance.Shader@@ -93,15 +91,14 @@    other-modules:       Graphics.Luminance.Core.Blending                      , Graphics.Luminance.Core.Buffer-                     , Graphics.Luminance.Core.Cmd                      , Graphics.Luminance.Core.Cubemap                      , Graphics.Luminance.Core.CubemapArray                      , Graphics.Luminance.Core.Debug+                     , Graphics.Luminance.Core.Draw                      , Graphics.Luminance.Core.Framebuffer                      , Graphics.Luminance.Core.Geometry                      , Graphics.Luminance.Core.Pixel                      , Graphics.Luminance.Core.Query-                     , Graphics.Luminance.Core.Region                      , Graphics.Luminance.Core.RenderCmd                      , Graphics.Luminance.Core.Renderbuffer                      , Graphics.Luminance.Core.RW
src/Graphics/Luminance.hs view
@@ -16,16 +16,16 @@ -- This library doesn’t expose any architectural patterns or designs. It’s up to you to design your -- program as you want and following your own plans. Because it’s a graphics and rendering API, you -- won’t find several common things you find in animations, games or simulations. If you need those--- you’ll have to look for dedicated libraries instead.+-- you’ll have to look for dedicated libraries instead or write your own. -- -- One of the most important thing you have to keep in mind is the fact that luminance won’t -- provide you with anything else than working with the /GPU/. That is, it won’t even provide -- functions to open windows. That’s actually a good thing, because then you’ll be able to use it--- with /any kind of windowing and system library you want to/!+-- with /any kind of windowing and system library you want/! -- -- The drawback is about safety. If you screw up setting up the OpenGL context, there’s no way--- luminance will work. If users feel the need, a few dedicated packages will be uploaded, like--- __luminance-glfw__ to add "GLFW-b" support for instance.+-- luminance will work. A few dedicated packages will be uploaded, like __luminance-glfw__ to add+-- "GLFW-b" support for instance. -- -- = Getting started --@@ -51,9 +51,11 @@ -- @ -- -- That part just setup the window’s OpenGL hints so that we create a compatible context for--- luminance. luminance will work with __OpenGL 4.5__ only, don’t even try to make it work with a+-- luminance. That part is important as you need to select which OpenGL versions you want to use.+-- luminance will work with __OpenGL 3.3__ and upper only, don’t even try to make it work with a -- lower implementation. We also disable the /forward compatibility/ because we don’t need it and--- ask to stick to a /core/ profile.+-- ask to stick to a /core/ profile. You’ll need to compile with the proper flags depending on what+-- context you’d have choosen. -- -- @ --     case window of@@ -102,9 +104,9 @@ -- -- luminance generalizes OpenGL concepts so that they’re made safer. In order to render something -- onto the screen, you have to understand what the screen truly is. It’s actually… a back buffer –--- assuming we have double buffering enabled, which the case with "GLFW-b" by default. So rendering--- to the screen is the same thing than rendering to the back buffer and ask "GLFW-b" to swap the--- back buffer with the front buffer.+-- assuming we have double buffering enabled, which is the case with "GLFW-b" by default. So+-- rendering to the screen is the same thing than rendering to the back buffer and ask "GLFW-b" to+-- swap the back buffer with the front buffer. -- -- And guess what. luminance wraps the back buffer into a 'Framebuffer' object. You can access it -- through 'defaultFramebuffer'. That value will always represent the back buffer.@@ -114,25 +116,21 @@ -- In most graphics frameworks, rendering is the act of taking an object and getting it rendered. -- luminance follows a different path. Because of real world needs and, well, real applications, you -- cannot do that in luminance. Because, what serious application will render only __one__ object?--- None. If so, then it’s an exception. We shouldn’t design our libraries and interface for the+-- None. If so, then it’s an exception. We shouldn’t design our libraries and interfaces for the -- exceptions. We should build them for the most used case, which is, having a lot of objects in a -- scene. -- -- That’s why luminance exposes the concept of /batched rendering/. The idea is that you have to--- gather you objects in /batches/ and render them all at once. That enables a correct sharing of--- resources – for instance, framebuffers or textures – and is very straight-forward to reason+-- gather your objects in /batches/ and render them all at once. That enables a correct sharing of+-- resources – for instance, framebuffers or shaders – and is very straight-forward to reason -- about. ----- luminance has several types of batches, each for the type of shared information. You can – up to--- now – shared two information between the rendered objects:------ * /framebuffer/: that means you can create a 'FBBatch' that will gather several values under the---   same 'Framebuffer';--- * or /shaders/: that means you can create a 'SPBatch' that will gather several values under the---   same shader 'Program'.+-- Render batches are not directly exposed through the interface. Another concept is used instead:+-- regions. Regions are used to bind resources and share them in a safe way. You can find two types+-- of regions right now: ----- The idea is that the 'SPBatch'es are stored in 'FBBatch'es. That creates a structure similar to--- an AST luminance knows how to dispatch to the GPU.+-- * /framebuffer/ regions ;+-- * /shaders/ regions. -- -- == About shader stages --@@ -144,13 +142,13 @@ -- * /geometry shader/ -- * /fragment shader/ ----- Additionnaly, you can create /compute shaders/ but they’re not usable up to now.--- -- When creating a new shader, you have to pass a 'String' representing the source code. This will -- change in the end. An EDSL is planned to make things easier and safer, but in the waiting, you -- are stuck with 'String', I’m sorry. ----- You have to write /GLSL450/-conformant code.+-- You have to write either /GLSL330/ or /GLSL450/ conformant code. If you compile with the+-- __gl45-bindless-textures__ flag, samplers will have an automatic qualifier to make them+-- bindless. -- -- == About uniforms --@@ -302,13 +300,12 @@     module Control.Some   , module Graphics.Luminance.Blending   , module Graphics.Luminance.Buffer-  , module Graphics.Luminance.Cmd   , module Graphics.Luminance.Core.Tuple+  , module Graphics.Luminance.Core.Draw   , module Graphics.Luminance.Framebuffer   , module Graphics.Luminance.Geometry   , module Graphics.Luminance.Pixel   , module Graphics.Luminance.Query-  , module Graphics.Luminance.Region   , module Graphics.Luminance.RenderCmd   , module Graphics.Luminance.RW   , module Graphics.Luminance.Shader@@ -319,13 +316,12 @@ import Control.Some import Graphics.Luminance.Blending import Graphics.Luminance.Buffer-import Graphics.Luminance.Cmd import Graphics.Luminance.Core.Tuple+import Graphics.Luminance.Core.Draw import Graphics.Luminance.Framebuffer import Graphics.Luminance.Geometry import Graphics.Luminance.Pixel import Graphics.Luminance.Query-import Graphics.Luminance.Region import Graphics.Luminance.RenderCmd import Graphics.Luminance.RW import Graphics.Luminance.Shader
− src/Graphics/Luminance/Cmd.hs
@@ -1,22 +0,0 @@--------------------------------------------------------------------------------- |--- Copyright   : (C) 2015, 2016 Dimitri Sabadie--- License     : BSD3------ Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>--- Stability   : experimental--- Portability : portable--------------------------------------------------------------------------------module Graphics.Luminance.Cmd (-  {--    -- * Command type-    Cmd-  , runCmd-    -- * Available commands-  , draw-  , blit-  -}-  ) where--import Graphics.Luminance.Core.Cmd
− src/Graphics/Luminance/Core/Cmd.hs
@@ -1,55 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}---------------------------------------------------------------------------------- |--- Copyright   : (C) 2015, 2016 Dimitri Sabadie--- License     : BSD3------ Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>--- Stability   : experimental--- Portability : portable--------------------------------------------------------------------------------module Graphics.Luminance.Core.Cmd where--import Control.Monad.IO.Class ( MonadIO(..) )-import Graphics.Luminance.Core.Framebuffer-import Graphics.Luminance.Core.RW ( Readable, Writable )-import Graphics.Luminance.Core.Texture ( Filter )-import Numeric.Natural ( Natural )--{---- |Command type. Used to accumulate GPU commands. Use 'runCmd' to execute--- the whole chain of commands.-newtype Cmd a = Cmd (IO a) deriving (Applicative,Functor,Monad)--runCmd :: (MonadIO m) => Cmd a -> m a-runCmd (Cmd a) = liftIO a---- |Draw a framebuffer batch and return the framebuffer’s output.-draw :: FBBatch rw c d -> Cmd (Output c d)-draw fbb = Cmd $ do-  runFBBatch fbb-  pure . framebufferOutput $ fbBatchFramebuffer fbb---- |Blit a framebuffer batch onto a framebuffer and return the framebuffer’s output of the write--- framebuffer.-blit :: (Readable r,Writable w)-     => Framebuffer r c0 d0-     -> Framebuffer w c1 d1-     -> Int-     -> Int-     -> Natural-     -> Natural-     -> Int-     -> Int-     -> Natural-     -> Natural-     -> FramebufferBlitMask-     -> Filter-     -> Cmd (Output c1 d1)-blit r w rx ry rwidth rheight wx wy wwidth wheight mask flt = Cmd $ do-  framebufferBlit r w rx ry rwidth rheight wx wy wwidth wheight mask flt-  pure (framebufferOutput w)---}
+ src/Graphics/Luminance/Core/Draw.hs view
@@ -0,0 +1,100 @@+-----------------------------------------------------------------------------+-- |+-- Copyright   : (C) 2015, 2016 Dimitri Sabadie+-- License     : BSD3+--+-- Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>+-- Stability   : experimental+-- Portability : portable+-----------------------------------------------------------------------------++module Graphics.Luminance.Core.Draw where++import Control.Monad.IO.Class ( MonadIO(..) )+import Data.Bits ( (.|.) )+import Data.Foldable ( traverse_ )+import Foreign.Ptr ( nullPtr )+import Graphics.GL+import Graphics.Luminance.Core.Blending ( setBlending )+import Graphics.Luminance.Core.Debug ( debugGL )+import Graphics.Luminance.Core.Framebuffer ( Framebuffer(..), Output, defaultFramebuffer )+import Graphics.Luminance.Core.Geometry ( Geometry(..), VertexArray(..) )+import Graphics.Luminance.Core.RW ( RW, Writable )+import Graphics.Luminance.Core.RenderCmd ( RenderCmd(..) )+import Graphics.Luminance.Core.Shader.Program ( Program(..), U'(..) )++-- |Frame command.+data FrameCmd rw c d a = FrameCmd {+    frameCmdFramebuffer :: Framebuffer rw c d+  , frameCmdShadingCmds :: [ShadingCmd rw c d a]+  }++-- |Build a 'FrameCmd' for the default framebuffer.+defaultFrameCmd :: [ShadingCmd RW () () a] -> FrameCmd RW () () a+defaultFrameCmd = FrameCmd defaultFramebuffer++-- |Shading command.+data ShadingCmd rw c d a = ShadingCmd {+    shadingCmdProgram :: Program a+  , shadingCmdUniforms :: a -> U'+  , shadingCmdDrawCmds :: [DrawCmd rw c d a]+  }++-- |Draw command.+newtype DrawCmd rw c d a = DrawCmd { drawCmd :: a -> (U',RenderCmd rw c d Geometry) }++-- |Build a 'DrawCmd', updating the program’s interface.+updateAndDraw :: (a -> U') -> RenderCmd rw c d Geometry -> DrawCmd rw c d a+updateAndDraw update rdrCmd = DrawCmd $ \a -> (update a,rdrCmd)++-- |Build a 'DrawCmd' without updating the program’s interface.+pureDraw :: RenderCmd rw c d Geometry -> DrawCmd rw c d a+pureDraw rdrCmd = DrawCmd $ const (mempty,rdrCmd)++-- |Issue a draw to the GPU. Don’t be afraid of the type signature. Let’s explain it.+--+-- The first parameter is the framebuffer you want to perform the rendering in. It must be+-- writable.+--+-- The second parameter is a list of /shading commands/. A shading command is composed of three+-- parts:+--+-- * a 'Program' used for shading;+-- * a @(a -> 'U'')@ uniform sink used to update uniforms in the program passed as first value;+--   this is useful if you want to update uniforms only once per draw or for all render+--   commands, like time, user event, etc.;+-- * a list of /render commands/ function; that function enables you to update uniforms via the+--   @(a -> 'U'')@ uniform sink for each render command that follows.+--+-- This function yields a value of type @'Output' m c d'@, which represents the output of the render+-- – typically, textures or '()'.+draw :: (MonadIO m,Writable w)+     => FrameCmd w c d a+     -> m (Output c d)+draw fc = do+  debugGL $ glBindFramebuffer GL_DRAW_FRAMEBUFFER (fromIntegral . framebufferID $ frameCmdFramebuffer fc)+  debugGL $ glClear $ GL_DEPTH_BUFFER_BIT .|. GL_COLOR_BUFFER_BIT+  traverse_ shade (frameCmdShadingCmds fc)+  pure (framebufferOutput . frameCmdFramebuffer $ fc)++shade :: (MonadIO m) => ShadingCmd rw c d a -> m ()+shade shd = do+    debugGL $ glUseProgram (programID prog)+    liftIO . runU' $ (shadingCmdUniforms shd) iface+    traverse_ (\drw -> uncurry render $ drawCmd drw iface) (shadingCmdDrawCmds shd)+  where+    prog = shadingCmdProgram shd+    iface = programInterface prog++render :: (MonadIO m) => U' -> RenderCmd rw c d Geometry -> m ()+render u (RenderCmd blending depthTest geometry) = do+  liftIO (runU' u)+  setBlending blending+  (if depthTest then glEnable else glDisable) GL_DEPTH_TEST+  case geometry of+    DirectGeometry (VertexArray vid mode vbNb) -> do+      debugGL $ glBindVertexArray vid+      debugGL $ glDrawArrays mode 0 vbNb+    IndexedGeometry (VertexArray vid mode ixNb) -> do+      debugGL $ glBindVertexArray vid+      debugGL $ glDrawElements mode ixNb GL_UNSIGNED_INT nullPtr
src/Graphics/Luminance/Core/Geometry.hs view
@@ -88,7 +88,7 @@     -- vertex buffer     vreg :: Buffer W v <- createBuffer $ newRegion (fromIntegral vertNb)     writeWhole vreg vertices-    liftIO $ glVertexArrayVertexBuffer vid vertexBindingIndex (bufferID reg) 0 (fromIntegral $ sizeOf (undefined :: v))+    liftIO $ glVertexArrayVertexBuffer vid vertexBindingIndex (bufferID vreg) 0 (fromIntegral $ sizeOf (undefined :: v))     _ <- setFormatV vid 0 0 (Proxy :: Proxy v)     -- element buffer, if required     case indices of
− src/Graphics/Luminance/Core/Region.hs
@@ -1,65 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE PolyKinds #-}---------------------------------------------------------------------------------- |--- Copyright   : (C) 2015, 2016 Dimitri Sabadie--- License     : BSD3------ Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>--- Stability   : experimental--- Portability : portable--------------------------------------------------------------------------------module Graphics.Luminance.Core.Region where--import Control.Monad.IO.Class ( MonadIO(..) )-import Control.Monad.Trans ( MonadTrans(..) )-import Control.Some ( Some(..) )-import Data.Bits-import Foreign.Ptr ( nullPtr )-import Graphics.GL-import Graphics.Luminance.Core.Blending ( setBlending )-import Graphics.Luminance.Core.Debug-import Graphics.Luminance.Core.Framebuffer ( Framebuffer(..) )-import Graphics.Luminance.Core.Geometry ( Geometry(..), VertexArray(..) )-import Graphics.Luminance.Core.Shader.Program ( Program(..), )-import Graphics.Luminance.Core.RenderCmd ( RenderCmd(..) )---- |A 'Region' is a monad transformer used to create relationships between two monadic layers--- and ensure GPU safety.-newtype Region r m a = Region { runRegion :: m a } deriving (Applicative,Functor,Monad,MonadIO)--instance MonadTrans (Region r) where-  lift = Region---- |The /GPU/ main 'Region'. This 'Region' is the highest and more general you can find. You’ll need--- to enter it if you want to enter any /GPU/ specific regions.-gpuRegion :: Region () m a -> m a-gpuRegion = runRegion---- |The 'Framebuffer' 'Region'. This 'Region' binds a 'Framebuffer' for all children regions.-newFrame :: (MonadIO m) => Framebuffer rw c d -> Region Framebuffer m a -> Region () m a-newFrame fb fbRegion = do-  liftIO . debugGL $ glBindFramebuffer GL_DRAW_FRAMEBUFFER (fromIntegral $ framebufferID fb)-  liftIO . debugGL $ glClear $ GL_DEPTH_BUFFER_BIT .|. GL_COLOR_BUFFER_BIT-  lift (runRegion fbRegion)---- |The 'Program' 'Region'. This 'Region' binds a 'Program' for all children regions.-newShading :: (MonadIO m) => Some Program -> Region Program m a -> Region Framebuffer m a-newShading (Some prog) progRegion = do-  liftIO . debugGL $ glUseProgram (programID prog)-  lift (runRegion progRegion)---- |Draw the 'Geometry' held by a 'RenderCmd'.-drawGeometry :: (MonadIO m) => RenderCmd rw c d Geometry -> Region Program m ()-drawGeometry (RenderCmd blending depthTest geometry) = do-  setBlending blending-  (if depthTest then glEnable else glDisable) GL_DEPTH_TEST-  case geometry of-    DirectGeometry (VertexArray vid mode vbNb) -> do-      debugGL $ glBindVertexArray vid-      debugGL $ glDrawArrays mode 0 vbNb-    IndexedGeometry (VertexArray vid mode ixNb) -> do-      debugGL $ glBindVertexArray vid-      debugGL $ glDrawElements mode ixNb GL_UNSIGNED_INT nullPtr
− src/Graphics/Luminance/Region.hs
@@ -1,21 +0,0 @@--------------------------------------------------------------------------------- |--- Copyright   : (C) 2015, 2016 Dimitri Sabadie--- License     : BSD3------ Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>--- Stability   : experimental--- Portability : portable--------------------------------------------------------------------------------module Graphics.Luminance.Region (-    -- * Regions-    Region-  , gpuRegion-  , newFrame-  , newShading-    -- * Drawing-  , drawGeometry-  ) where--import Graphics.Luminance.Core.Region
src/Graphics/Luminance/Shader/Program.hs view
@@ -19,10 +19,10 @@   , U   , U'   , (.=)+  , updateUniforms   , UniformInterface   , UniformName(..)   , SomeUniformName(..)-  , updateUniforms     -- * Uniform block   , UniformBlock   , UB(..)