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 +5/−0
- luminance.cabal +2/−5
- src/Graphics/Luminance.hs +24/−28
- src/Graphics/Luminance/Cmd.hs +0/−22
- src/Graphics/Luminance/Core/Cmd.hs +0/−55
- src/Graphics/Luminance/Core/Draw.hs +100/−0
- src/Graphics/Luminance/Core/Geometry.hs +1/−1
- src/Graphics/Luminance/Core/Region.hs +0/−65
- src/Graphics/Luminance/Region.hs +0/−21
- src/Graphics/Luminance/Shader/Program.hs +1/−1
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(..)