packages feed

keid-render-basic 0.1.6.0 → 0.1.6.1

raw patch · 10 files changed

+351/−33 lines, 10 filesdep −adjunctionsdep −distributivedep ~keid-corePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: adjunctions, distributive

Dependency ranges changed: keid-core

API changes (from Hackage documentation)

- Global.Resource.CubeMap.Base: instance Data.Distributive.Distributive Global.Resource.CubeMap.Base.Collection
- Global.Resource.CubeMap.Base: instance Data.Functor.Rep.Representable Global.Resource.CubeMap.Base.Collection
- Global.Resource.CubeMap.Base: instance GHC.Generics.Generic (Global.Resource.CubeMap.Base.Collection a)
- Global.Resource.Texture.Base: instance Data.Distributive.Distributive Global.Resource.Texture.Base.Collection
- Global.Resource.Texture.Base: instance Data.Functor.Rep.Representable Global.Resource.Texture.Base.Collection
- Global.Resource.Texture.Base: instance GHC.Generics.Generic (Global.Resource.Texture.Base.Collection a)
+ Render.Basic: [$sel:pSprite:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pSpriteOutline:Pipelines] :: Pipelines -> Pipeline
+ Render.Unlit.Colored.Model: black :: VertexAttrs
+ Render.Unlit.Colored.Model: rgbF :: Float -> Float -> Float -> VertexAttrs
+ Render.Unlit.Colored.Model: white :: VertexAttrs
+ Render.Unlit.Sprite.Model: InstanceAttrs :: Vec4 -> Vec4 -> Vec4 -> Vec4 -> Int32 -> Int32 -> UVec2 -> InstanceAttrs
+ Render.Unlit.Sprite.Model: [$sel:fragRect:InstanceAttrs] :: InstanceAttrs -> Vec4
+ Render.Unlit.Sprite.Model: [$sel:outline:InstanceAttrs] :: InstanceAttrs -> Vec4
+ Render.Unlit.Sprite.Model: [$sel:samplerId:InstanceAttrs] :: InstanceAttrs -> Int32
+ Render.Unlit.Sprite.Model: [$sel:textureId:InstanceAttrs] :: InstanceAttrs -> Int32
+ Render.Unlit.Sprite.Model: [$sel:textureSize:InstanceAttrs] :: InstanceAttrs -> UVec2
+ Render.Unlit.Sprite.Model: [$sel:tint:InstanceAttrs] :: InstanceAttrs -> Vec4
+ Render.Unlit.Sprite.Model: [$sel:vertRect:InstanceAttrs] :: InstanceAttrs -> Vec4
+ Render.Unlit.Sprite.Model: data InstanceAttrs
+ Render.Unlit.Sprite.Model: fromAtlas :: Int32 -> Atlas -> Vec2 -> Vec2 -> Vec2 -> InstanceAttrs
+ Render.Unlit.Sprite.Model: fromTexture :: Int32 -> Int32 -> Vec2 -> Vec2 -> InstanceAttrs
+ Render.Unlit.Sprite.Model: instance Foreign.Storable.Generic.Internal.GStorable Render.Unlit.Sprite.Model.InstanceAttrs
+ Render.Unlit.Sprite.Model: instance GHC.Generics.Generic Render.Unlit.Sprite.Model.InstanceAttrs
+ Render.Unlit.Sprite.Model: instance GHC.Show.Show Render.Unlit.Sprite.Model.InstanceAttrs
+ Render.Unlit.Sprite.Model: instance Vulkan.Zero.Zero Render.Unlit.Sprite.Model.InstanceAttrs
+ Render.Unlit.Sprite.Model: type InstanceBuffer stage = Allocated stage InstanceAttrs
+ Render.Unlit.Sprite.Model: type StorableAttrs = Vector InstanceAttrs
+ Render.Unlit.Sprite.Model: vkInstanceAttrs :: [Format]
+ Render.Unlit.Sprite.Pipeline: allocate :: (HasVulkan env, HasRenderPass renderpass) => SampleCountFlagBits -> Maybe Float -> Bool -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline
+ Render.Unlit.Sprite.Pipeline: type Pipeline = Pipeline '[Scene] () InstanceAttrs
- Render.Basic: Pipelines :: SampleCountFlagBits -> Tagged Scene DsBindings -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipelines
+ Render.Basic: Pipelines :: SampleCountFlagBits -> Tagged Scene DsBindings -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipelines

Files

ChangeLog.md view
@@ -1,5 +1,12 @@ # Changelog for keid-render-basic +## 0.1.6.1++- `withFrozenCallStack` fixes for GHC-9.0.+- Added color helpers to `Render.Unlit.Colored`.+- Added `Render.Unlit.Sprite` pipeline.+  * Available as `pSprite` and `pSpriteOutline`.+ ## 0.1.6.0  - Updated `Loader` stage to camera changes in core.
keid-render-basic.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           keid-render-basic-version:        0.1.6.0+version:        0.1.6.1 synopsis:       Basic rendering programs for Keid engine. category:       Game Engine homepage:       https://keid.haskell-game.dev@@ -59,6 +59,8 @@       Render.Skybox.Pipeline       Render.Unlit.Colored.Model       Render.Unlit.Colored.Pipeline+      Render.Unlit.Sprite.Model+      Render.Unlit.Sprite.Pipeline       Render.Unlit.Textured.Model       Render.Unlit.Textured.Pipeline       Render.Unlit.TileMap.Model@@ -134,16 +136,14 @@       ViewPatterns   ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints   build-depends:-      adjunctions-    , aeson+      aeson     , base >=4.7 && <5     , bytestring     , derive-storable     , derive-storable-plugin-    , distributive     , file-embed >=0.0.10     , geomancy-    , keid-core >=0.1.6.0+    , keid-core >=0.1.6.1     , keid-geometry     , neat-interpolation     , resourcet
src/Global/Resource/CubeMap/Base.hs view
@@ -9,24 +9,18 @@  import RIO -import Data.Distributive (Distributive(..))-import Data.Distributive.Generic (genericCollect)-import Data.Functor.Rep (Co(..), Representable) import GHC.Generics (Generic1) import Resource.Source (Source) import Resource.Source qualified as Source+import Resource.Collection (Generically1(..))  import Global.Resource.CubeMap.Base.Paths qualified as Paths  data Collection a = Collection   { black        :: a   }-  deriving stock (Show, Functor, Foldable, Traversable, Generic, Generic1)-  deriving Applicative via (Co Collection)-  deriving anyclass (Representable)--instance Distributive Collection where-  collect = genericCollect+  deriving stock (Show, Functor, Foldable, Traversable, Generic1)+  deriving Applicative via Generically1 Collection  sources :: Collection Source sources = Collection
src/Global/Resource/Texture/Base.hs view
@@ -9,10 +9,8 @@  import RIO -import Data.Distributive (Distributive(..))-import Data.Distributive.Generic (genericCollect)-import Data.Functor.Rep (Co(..), Representable) import GHC.Generics (Generic1)+import Resource.Collection (Generically1(..)) import Resource.Source (Source) import Resource.Source qualified as Source @@ -23,12 +21,8 @@   , flat         :: a   , ibl_brdf_lut :: a   }-  deriving stock (Show, Functor, Foldable, Traversable, Generic, Generic1)-  deriving Applicative via (Co Collection)-  deriving anyclass (Representable)--instance Distributive Collection where-  collect = genericCollect+  deriving stock (Show, Functor, Foldable, Traversable, Generic1)+  deriving Applicative via Generically1 Collection  sources :: Collection Source sources = Collection
src/Render/Basic.hs view
@@ -40,6 +40,7 @@ import Render.ShadowMap.RenderPass qualified as ShadowPass import Render.Skybox.Pipeline qualified as Skybox import Render.Unlit.Colored.Pipeline qualified as UnlitColored+import Render.Unlit.Sprite.Pipeline qualified as UnlitSprite import Render.Unlit.Textured.Pipeline qualified as UnlitTextured import Render.Unlit.TileMap.Pipeline qualified as UnlitTileMap @@ -125,6 +126,9 @@   , pUnlitColoredNoDepth :: UnlitColored.Pipeline   , pUnlitTextured       :: UnlitTextured.Pipeline   , pUnlitTexturedBlend  :: UnlitTextured.Pipeline++  , pSprite              :: UnlitSprite.Pipeline+  , pSpriteOutline       :: UnlitSprite.Pipeline   , pTileMap             :: UnlitTileMap.Pipeline   , pTileMapBlend        :: UnlitTileMap.Pipeline   , pWireframe           :: UnlitColored.Pipeline@@ -169,12 +173,14 @@   pLitTextured      <- LitTextured.allocate pMSAA pSceneBinds rpForwardMsaa   pLitTexturedBlend <- LitTextured.allocateBlend pMSAA pSceneBinds rpForwardMsaa +  pSprite              <- UnlitSprite.allocate pMSAA Nothing False pSceneBinds rpForwardMsaa+  pSpriteOutline       <- UnlitSprite.allocate pMSAA Nothing True pSceneBinds rpForwardMsaa+  pTileMap             <- UnlitTileMap.allocate pMSAA pSceneBinds rpForwardMsaa+  pTileMapBlend        <- UnlitTileMap.allocateBlend pMSAA pSceneBinds rpForwardMsaa   pUnlitColored        <- UnlitColored.allocate True pMSAA pSceneBinds rpForwardMsaa   pUnlitColoredNoDepth <- UnlitColored.allocate False pMSAA pSceneBinds rpForwardMsaa   pUnlitTextured       <- UnlitTextured.allocate pMSAA pSceneBinds rpForwardMsaa   pUnlitTexturedBlend  <- UnlitTextured.allocateBlend pMSAA pSceneBinds rpForwardMsaa-  pTileMap             <- UnlitTileMap.allocate pMSAA pSceneBinds rpForwardMsaa-  pTileMapBlend        <- UnlitTileMap.allocateBlend pMSAA pSceneBinds rpForwardMsaa   pWireframe           <- UnlitColored.allocateWireframe True pMSAA pSceneBinds rpForwardMsaa   pWireframeNoDepth    <- UnlitColored.allocateWireframe False pMSAA pSceneBinds rpForwardMsaa 
src/Render/Unlit/Colored/Model.hs view
@@ -4,10 +4,16 @@   , VertexAttrs   , vkVertexAttrs +  , rgbF+  , black+  , white+   , InstanceAttrs   ) where -import Geomancy (Transform, Vec4)+import RIO++import Geomancy (Transform, Vec4, vec4) import Geomancy.Vec3 qualified as Vec3 import Resource.Model qualified as Model import Vulkan.Core10 qualified as Vk@@ -23,3 +29,15 @@ vkVertexAttrs =   [ Vk.FORMAT_R32G32B32A32_SFLOAT -- vColor :: vec4   ]++{-# INLINE rgbF #-}+rgbF :: Float -> Float -> Float -> VertexAttrs+rgbF r g b = vec4 r g b 1++{-# INLINE black #-}+black :: VertexAttrs+black = rgbF 0 0 0++{-# INLINE white #-}+white :: VertexAttrs+white = rgbF 1 1 1
+ src/Render/Unlit/Sprite/Model.hs view
@@ -0,0 +1,113 @@+{-# OPTIONS_GHC -fplugin Foreign.Storable.Generic.Plugin #-}++module Render.Unlit.Sprite.Model+  ( InstanceAttrs(..)+  , StorableAttrs+  , InstanceBuffer+  , fromTexture+  , fromAtlas++  , vkInstanceAttrs+  ) where++import RIO++import Foreign.Storable.Generic (GStorable)+import Geomancy (Vec2, Vec4, UVec2, withUVec2, vec2)+import Geomancy.Vec4 qualified as Vec4+import Render.Samplers qualified as Samplers+import Resource.Buffer qualified as Buffer+import Resource.Image.Atlas (Atlas)+import Resource.Image.Atlas qualified as Atlas+import RIO.Vector.Storable qualified as Storable+import Vulkan.Core10 qualified as Vk+import Vulkan.Zero (Zero(..))++type StorableAttrs = Storable.Vector InstanceAttrs++data InstanceAttrs = InstanceAttrs+  { vertRect :: Vec4+  , fragRect :: Vec4++  , tint    :: Vec4+  , outline :: Vec4++  , samplerId :: Int32+  , textureId :: Int32+  , textureSize :: UVec2+  }+  deriving (Show, Generic)++instance GStorable InstanceAttrs++instance Zero InstanceAttrs where+  zero = InstanceAttrs+    { vertRect = 0+    , fragRect = 0++    , tint    = 0+    , outline = 0++    , samplerId = 0+    , textureId = 0+    , textureSize = 0+    }++vkInstanceAttrs :: [Vk.Format]+vkInstanceAttrs =+  [ Vk.FORMAT_R32G32B32A32_SFLOAT -- Quad scale+offset+  , Vk.FORMAT_R32G32B32A32_SFLOAT -- UV scale+offset+  , Vk.FORMAT_R32G32B32A32_SFLOAT -- Tint+  , Vk.FORMAT_R32G32B32A32_SFLOAT -- Outline (when enabled)++  , Vk.FORMAT_R32G32_SINT -- Sampler + texture IDs+  , Vk.FORMAT_R32G32_UINT -- Texture size+  ]++type InstanceBuffer stage = Buffer.Allocated stage InstanceAttrs++fromTexture+  :: Int32 -- ^ Sampler index.+  -> Int32 -- ^ Texture index.+  -> Vec2  -- ^ Sprite size.+  -> Vec2  -- ^ Sprite position.+  -> InstanceAttrs+fromTexture sampler texture wh pos =+  InstanceAttrs+    { vertRect = Vec4.fromVec22 pos wh+    , fragRect = Vec4.fromVec22 0 1++    , tint    = 1+    , outline = 0++    , samplerId = sampler+    , textureId = texture+    , textureSize = 0+    }++fromAtlas+  :: Int32 -- ^ Texture ID.+  -> Atlas+  -> Vec2 -- ^ Sprite scale, wrt. to native tile size+  -> Vec2 -- ^ Tile position in atlas tiles. Can be fractional when using subgrids.+  -> Vec2 -- ^ Sprite position.+  -> InstanceAttrs+fromAtlas texture atlas scale atlasPos worldPos =+  InstanceAttrs+    { vertRect = Vec4.fromVec22 worldPos (tileSize * scale)+    , fragRect = Vec4.fromVec22 (atlasPos * uvScale) uvScale++    , tint    = 1+    , outline = 0++    , samplerId = Samplers.nearest Samplers.indices+    , textureId = texture+    , textureSize = Atlas.sizePx atlas+    }++  where+    uvScale = Atlas.uvScale atlas++    tileSize =+      withUVec2 (Atlas.tileSizePx atlas) \tw th ->+        vec2 (fromIntegral tw) (fromIntegral th)
+ src/Render/Unlit/Sprite/Pipeline.hs view
@@ -0,0 +1,184 @@+{-# LANGUAGE OverloadedLists #-}++module Render.Unlit.Sprite.Pipeline+  ( Pipeline+  , allocate+  -- , allocateOutline+  ) where++import RIO++import Control.Monad.Trans.Resource (ResourceT)+import Data.Tagged (Tagged(..))+import Vulkan.Core10 qualified as Vk++import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)+import Render.Code (compileVert, compileFrag, glsl)+import Render.DescSets.Set0 (Scene)+import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2)+import Render.Unlit.Sprite.Model qualified as Model++type Config = Pipeline.Configure Pipeline (Float, Bool)+type Pipeline = Pipeline.Pipeline '[Scene] () Model.InstanceAttrs++allocate+  :: ( HasVulkan env+     , HasRenderPass renderpass+     )+  => Vk.SampleCountFlagBits+  -> Maybe Float+  -> Bool+  -> Tagged Scene DsBindings+  -> renderpass+  -> ResourceT (RIO env) Pipeline+allocate multisample discardAlpha outline set0 = do+  fmap snd . Pipeline.allocate+    Nothing+    multisample+    (config discardAlpha outline set0)++config+  :: Maybe Float+  -> Bool+  -> Tagged Scene DsBindings+  -> Config+config discardAlpha outline (Tagged set0) =+  Pipeline.baseConfig+    { Pipeline.cVertexCode     = Just vertCode+    , Pipeline.cFragmentCode   = Just fragCode+    , Pipeline.cDescLayouts    = Tagged @'[Scene] [set0]+    , Pipeline.cVertexInput    = vertexInput+    , Pipeline.cDepthTest      = False+    , Pipeline.cDepthWrite     = False+    , Pipeline.cBlend          = True+    , Pipeline.cCull           = Vk.CULL_MODE_NONE+    , Pipeline.cSpecialization = specs+    }+  where+    vertexInput = Pipeline.vertexInput+      [ (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceAttrs)+      ]++    specs =+      ( fromMaybe 0.0 discardAlpha+      , outline+      )++vertCode :: ByteString+vertCode =+  $(compileVert [glsl|+    #version 450+    #extension GL_ARB_separate_shader_objects : enable++    ${set0binding0}++    layout(location = 0) in  vec4 iVert;+    layout(location = 1) in  vec4 iFrag;+    layout(location = 2) in  vec4 iTint;+    layout(location = 3) in  vec4 iOutline;+    layout(location = 4) in ivec2 iTextureIds;+    layout(location = 5) in uvec2 iTextureSize;++    layout(location = 0)      out  vec2 fTexCoord;+    layout(location = 1) flat out  vec4 fTint;+    layout(location = 2) flat out  vec4 fOutline;+    layout(location = 3) flat out ivec2 fTextureIds;+    layout(location = 4) flat out uvec2 fTextureSize;++    vec2 positions[6] = vec2[](+      vec2(-0.5, -0.5),+      vec2(0.5, -0.5),+      vec2(-0.5, 0.5),++      vec2(0.5, 0.5),+      vec2(-0.5, 0.5),+      vec2(0.5, -0.5)+    );++    vec2 texCoords[6] = vec2[](+      vec2(0.0, 0.0),+      vec2(1.0, 0.0),+      vec2(0.0, 1.0),++      vec2(1.0, 1.0),+      vec2(0.0, 1.0),+      vec2(1.0, 0.0)+    );++    void main() {+      vec2 pos = positions[gl_VertexIndex];++      gl_Position+        = scene.projection+        * scene.view+        * vec4(iVert.xy + pos * iVert.zw, 0, 1.0);++      vec2 uv = texCoords[gl_VertexIndex];+      fTexCoord = iFrag.xy + uv * iFrag.zw;++      fTint = iTint;+      fOutline = iOutline;+      fTextureIds = iTextureIds;+      fTextureSize = iTextureSize;+    }+  |])++fragCode :: ByteString+fragCode =+  $(compileFrag [glsl|+    #version 450+    #extension GL_ARB_separate_shader_objects : enable+    #extension GL_EXT_nonuniform_qualifier : enable++    ${set0binding1}+    ${set0binding2}++    layout(location = 0)      in  vec2 fTexCoord;+    layout(location = 1) flat in  vec4 fTint;+    layout(location = 2) flat in  vec4 fOutline;+    layout(location = 3) flat in ivec2 fTextureIds;+    layout(location = 4) flat in uvec2 fTextureSize;++    layout(location = 0) out vec4 outColor;++    layout(constant_id=0) const float discardAlpha = 0.0;+    layout(constant_id=1) const bool  doOutline = false;++    vec4 tap(vec2 uv) {+      return texture(+        sampler2D(+          textures[nonuniformEXT(fTextureIds.t)],+          samplers[nonuniformEXT(fTextureIds.s)]+        ),+        fTexCoord + uv+      );+    }++    vec2 step_size = 1.0 / vec2(fTextureSize);++    void main() {+      vec4 texel = tap(vec2(0));++      if (discardAlpha != 0.0) {+        if (texel.a < discardAlpha) {+          discard;+        }+      }++      outColor = texel * fTint * texel.a;++      if (doOutline) {+        if (fOutline.a > 0.0 && texel.a < 1.0) {+          float alpha = 0.0;++          alpha += tap(vec2(step_size.x,  0.0)         ).a / 4.0;+          alpha += tap(vec2(-step_size.x, 0.0)         ).a / 4.0;+          alpha += tap(vec2(0.0,          step_size.y) ).a / 4.0;+          alpha += tap(vec2(0.0,          -step_size.y)).a / 4.0;++          outColor += fOutline * alpha;+        }+      }+    }+  |])
src/Resource/Font.hs view
@@ -73,7 +73,7 @@   container <- withFrozenCallStack $     EvanW.load configContainer -  createTexture <- toIO . withFrozenCallStack $+  createTexture <- toIO $ withFrozenCallStack $     Ktx1.load pools configTexture    (textureKey, texture) <- Resource.allocate
src/Resource/Font/EvanW.hs view
@@ -68,12 +68,14 @@      , HasCallStack      )   => Source -> m Container-load = withFrozenCallStack . Source.load \bytes ->-  case eitherDecodeStrict' bytes of-    Left err ->-      liftIO . throwIO . FontError $ Text.pack err-    Right res ->-      pure res+load =+  withFrozenCallStack $+    Source.load \bytes ->+      case eitherDecodeStrict' bytes of+        Left err ->+          liftIO . throwIO . FontError $ Text.pack err+        Right res ->+          pure res  -- * Typesetting