module Mischief.Render.Plugin where
import Control.Monad
import Control.Monad.IO.Class
import Data.Data (Proxy (..))
import Data.Default
import Data.Foldable (for_)
import Data.Text qualified as T
import Data.Traversable
import Foreign (Storable (peek), free, malloc, nullPtr, with)
import Foreign.C.ConstPtr (ConstPtr (..))
import GHC.Generics
import Linear (V3 (..))
import Mischief.Assets.Asset (store)
import Mischief.ECS hiding (get, set)
import Mischief.ECS.Relationships.Order (Before (..))
import Mischief.ECS.Systems qualified as Systems
import Mischief.ECS.World.Query (queryOne)
import Mischief.Materials qualified as Mat
import Mischief.Materials.Sprite (SpriteMaterial)
import Mischief.Math (TransformPlugin)
import Mischief.Render.Bind
import Mischief.Render.Buffer
import Mischief.Render.Camera
import Mischief.Render.Core
import Mischief.Render.Material qualified as Material
import Mischief.Render.Material.Definition
import Mischief.Render.Material.Pipeline (qgetPipeline)
import Mischief.Render.Sprite (SpritePlugin (..), fetchSpriteBindings)
import Mischief.Render.Texture
import Mischief.Render.Texture qualified as Texture
import Mischief.Render.Time (TimeMaterialPlugin)
import Mischief.SDL (SDLPlugin (..))
import Mischief.SDL.Window
import Mischief.Shader (Bindable, Binding, BuiltIn, GPU, Location, Shader, ShaderParam, sample, var)
import Mischief.Shader.Internal.Bindings hiding (Bindings)
import Mischief.Shader.Types qualified as ST
import Mischief.WGPU
import Mischief.WGPU.Types.Enums
import Mischief.WGPU.Types.General
data RenderPlugin = RenderPlugin deriving (RenderPlugin -> RenderPlugin -> Bool
(RenderPlugin -> RenderPlugin -> Bool)
-> (RenderPlugin -> RenderPlugin -> Bool) -> Eq RenderPlugin
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RenderPlugin -> RenderPlugin -> Bool
== :: RenderPlugin -> RenderPlugin -> Bool
$c/= :: RenderPlugin -> RenderPlugin -> Bool
/= :: RenderPlugin -> RenderPlugin -> Bool
Eq)
instance Plugin RenderPlugin where
init :: System ()
init = do
first <- forall sch. Schedule sch => System Entity
forall {k} (sch :: k). Schedule sch => System Entity
scheduleEntity @RenderFirst
prepare <- scheduleEntity @RenderPrepare
update <- scheduleEntity @RenderUpdate
transparent <- scheduleEntity @RenderTransparent
postprocess <- scheduleEntity @RenderPostprocess
last <- scheduleEntity @RenderLast
update' <- scheduleEntity @PostUpdate
insert (Rel Before first) update'
insert (Rel Before prepare) first
insert (Rel Before update) prepare
insert (Rel Before transparent) update
insert (Rel Before postprocess) transparent
insert (Rel Before last) postprocess
for_ [first, update, prepare, transparent, postprocess, last] $ insert UpdateSchedule
insertRes =<< liftIO (RenderInstance <$> wgpuCreateInstance)
void $ spawn $ Observer onAddWindow
void $ spawn $ Observer onSetWindowSize
systems renderCameras
& schedule @RenderLast
systems clearCameras
& schedule @RenderFirst
deps :: [Dependency]
deps = [forall p. Plugin p => Dependency
dep @SDLPlugin, forall p. Plugin p => Dependency
dep @SpritePlugin, forall p. Plugin p => Dependency
dep @CameraPlugin, forall p. Plugin p => Dependency
dep @TimeMaterialPlugin, forall p. Plugin p => Dependency
dep @TransformPlugin]
renderCameras :: System ()
renderCameras :: System ()
renderCameras = do
resources <- System (Maybe (RenderAdapter, RenderDevice, RenderQueue))
getRenderingResources
case resources of
Maybe (RenderAdapter, RenderDevice, RenderQueue)
Nothing -> () -> System ()
forall a. a -> System a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just (RenderAdapter
adapter, RenderDevice
device, RenderQueue
queue) -> do
cameras <- Query System (CameraTexture, From RenderSurface)
-> System [(CameraTexture, From RenderSurface)]
forall w (m :: * -> *) out.
MonadSystem w m =>
Query m out -> m [out]
query [q|CameraTexture, OutputTo -> (RenderSurface)|]
for_ cameras $ \(CameraTexture SwappableTexture {currentTexture :: SwappableTexture -> Ptr WGPUTexture
currentTexture = Ptr WGPUTexture
texture}, From Entity
_ RenderSurface
surface) -> do
format <- RenderSurface -> RenderAdapter -> System TextureFormat
getFormat RenderSurface
surface RenderAdapter
adapter
withSurfaceTexture surface (def {Texture.format}) $ \Texture
output -> do
sampler <- RenderDevice -> System Sampler
newSampler RenderDevice
device
tex <- liftIO $ wgpuTextureCreateView texture (ConstPtr nullPtr)
let command = [ErasedBindingValue] -> Nat -> DrawCommand Bindings
forall {k} (bindings :: k).
[ErasedBindingValue] -> Nat -> DrawCommand bindings
Draw [Bindings CPU -> ErasedBindingValue
forall (b :: * -> *).
(Bindable b, Typeable b) =>
b CPU -> ErasedBindingValue
ErasedBindingValue Bindings {tex :: Binding CPU Texture
tex = Ptr WGPUTextureView -> TextureView
TextureView Ptr WGPUTextureView
tex, Sampler
Binding CPU Sampler
sampler :: Sampler
sampler :: Binding CPU Sampler
sampler}] Nat
3
Just pipeline <- queryOne $ qgetPipeline @DummyFullscreenMaterial format
render @DummyFullscreenMaterial device queue pipeline def output [command]
presentSurface surface
clearCameras :: System ()
clearCameras :: System ()
clearCameras = Query System () -> System ()
forall w (m :: * -> *) out. MonadSystem w m => Query m out -> m ()
query_ (Query System () -> System ()) -> Query System () -> System ()
forall a b. (a -> b) -> a -> b
$ do
device <- Query System RenderDevice
forall c (m :: * -> *) w.
(MonadSystem w m, Component c) =>
Query m c
qres
queue <- qres
(CameraTexture SwappableTexture {currentTexture = texture, desc}) <- [q|CameraTexture|]
pipeline <- qgetPipeline @DummyFullscreenMaterial desc.format
qlift $ render @ClearMaterial device queue pipeline def {clear = Clear $ V3 0.184313725 0.211764706 0.250980392} (Texture texture desc) []
withSurfaceTexture :: RenderSurface -> TextureDescriptor -> (Texture -> System a) -> System ()
withSurfaceTexture :: forall a.
RenderSurface
-> TextureDescriptor -> (Texture -> System a) -> System ()
withSurfaceTexture (RenderSurface Ptr WGPUSurface
surface) TextureDescriptor
desc Texture -> System a
f = do
surfaceTextureBox <- IO (Ptr WGPUSurfaceTexture) -> System (Ptr WGPUSurfaceTexture)
forall a. IO a -> System a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (Ptr WGPUSurfaceTexture)
forall a. Storable a => IO (Ptr a)
malloc
liftIO $ wgpuSurfaceGetCurrentTexture surface surfaceTextureBox
surfaceTexture <- liftIO $ peek surfaceTextureBox
unless (surfaceTexture.texture == nullPtr) $ void $ f (Texture {texture = surfaceTexture.texture, desc})
liftIO $ free surfaceTextureBox
presentSurface :: RenderSurface -> System ()
presentSurface :: RenderSurface -> System ()
presentSurface (RenderSurface Ptr WGPUSurface
surface) = IO () -> System ()
forall a. IO a -> System a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> System ()) -> IO () -> System ()
forall a b. (a -> b) -> a -> b
$ Ptr WGPUSurface -> IO ()
wgpuSurfacePresent Ptr WGPUSurface
surface
data Bindings f = Bindings
{ forall f. Bindings f -> Binding f Texture
tex :: Binding f Texture,
forall f. Bindings f -> Binding f Sampler
sampler :: Binding f Sampler
}
deriving ((forall x. Bindings f -> Rep (Bindings f) x)
-> (forall x. Rep (Bindings f) x -> Bindings f)
-> Generic (Bindings f)
forall x. Rep (Bindings f) x -> Bindings f
forall x. Bindings f -> Rep (Bindings f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (Bindings f) x -> Bindings f
forall f x. Bindings f -> Rep (Bindings f) x
$cfrom :: forall f x. Bindings f -> Rep (Bindings f) x
from :: forall x. Bindings f -> Rep (Bindings f) x
$cto :: forall f x. Rep (Bindings f) x -> Bindings f
to :: forall x. Rep (Bindings f) x -> Bindings f
Generic, Typeable Bindings
Typeable Bindings =>
(Nat -> Proxy (Bindings Internal) -> (Bindings, Nat))
-> (Nat
-> Proxy (Bindings Internal) -> ([WGPUBindGroupLayoutEntry], Nat))
-> (Nat -> Bindings CPU -> ([WGPUBindGroupEntry], Nat))
-> (Nat -> (Bindings GPU, Nat))
-> Bindable Bindings
Nat -> (Bindings GPU, Nat)
Nat
-> Proxy (Bindings Internal) -> ([WGPUBindGroupLayoutEntry], Nat)
Nat -> Proxy (Bindings Internal) -> (Bindings, Nat)
Nat -> Bindings CPU -> ([WGPUBindGroupEntry], Nat)
forall (a :: * -> *).
Typeable a =>
(Nat -> Proxy (a Internal) -> (Bindings, Nat))
-> (Nat -> Proxy (a Internal) -> ([WGPUBindGroupLayoutEntry], Nat))
-> (Nat -> a CPU -> ([WGPUBindGroupEntry], Nat))
-> (Nat -> (a GPU, Nat))
-> Bindable a
$ccollectBindings :: Nat -> Proxy (Bindings Internal) -> (Bindings, Nat)
collectBindings :: Nat -> Proxy (Bindings Internal) -> (Bindings, Nat)
$ccollectLayouts :: Nat
-> Proxy (Bindings Internal) -> ([WGPUBindGroupLayoutEntry], Nat)
collectLayouts :: Nat
-> Proxy (Bindings Internal) -> ([WGPUBindGroupLayoutEntry], Nat)
$ccollectEntries :: Nat -> Bindings CPU -> ([WGPUBindGroupEntry], Nat)
collectEntries :: Nat -> Bindings CPU -> ([WGPUBindGroupEntry], Nat)
$cdummyBinding :: Nat -> (Bindings GPU, Nat)
dummyBinding :: Nat -> (Bindings GPU, Nat)
Bindable)
newtype VertexInput f = VertexInput (BuiltIn f "vertex_index" Mat.Uint)
deriving stock ((forall x. VertexInput f -> Rep (VertexInput f) x)
-> (forall x. Rep (VertexInput f) x -> VertexInput f)
-> Generic (VertexInput f)
forall x. Rep (VertexInput f) x -> VertexInput f
forall x. VertexInput f -> Rep (VertexInput f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (VertexInput f) x -> VertexInput f
forall f x. VertexInput f -> Rep (VertexInput f) x
$cfrom :: forall f x. VertexInput f -> Rep (VertexInput f) x
from :: forall x. VertexInput f -> Rep (VertexInput f) x
$cto :: forall f x. Rep (VertexInput f) x -> VertexInput f
to :: forall x. Rep (VertexInput f) x -> VertexInput f
Generic)
deriving anyclass (Typeable (VertexInput GPU)
Params
ParamDefinition
VertexInput GPU
Typeable (VertexInput GPU) =>
Params
-> ParamDefinition
-> VertexInput GPU
-> (VertexInput GPU -> Values)
-> ShaderParam VertexInput
VertexInput GPU -> Values
forall (a :: * -> *).
Typeable (a GPU) =>
Params
-> ParamDefinition -> a GPU -> (a GPU -> Values) -> ShaderParam a
$ccollectParams :: Params
collectParams :: Params
$cparamDefinition :: ParamDefinition
paramDefinition :: ParamDefinition
$cdummyParam :: VertexInput GPU
dummyParam :: VertexInput GPU
$ccollectValues :: VertexInput GPU -> Values
collectValues :: VertexInput GPU -> Values
Mat.ShaderParam)
data VertexOutput f = VertexOutput
{ forall f. VertexOutput f -> BuiltIn f "position" (Vec 4 Float)
pos :: Mat.BuiltIn f "position" (Mat.Vec 4 Mat.Float),
forall f. VertexOutput f -> Location f 0 (Vec 2 Float)
uv :: Mat.Location f 0 (Mat.Vec 2 Mat.Float)
}
deriving ((forall x. VertexOutput f -> Rep (VertexOutput f) x)
-> (forall x. Rep (VertexOutput f) x -> VertexOutput f)
-> Generic (VertexOutput f)
forall x. Rep (VertexOutput f) x -> VertexOutput f
forall x. VertexOutput f -> Rep (VertexOutput f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (VertexOutput f) x -> VertexOutput f
forall f x. VertexOutput f -> Rep (VertexOutput f) x
$cfrom :: forall f x. VertexOutput f -> Rep (VertexOutput f) x
from :: forall x. VertexOutput f -> Rep (VertexOutput f) x
$cto :: forall f x. Rep (VertexOutput f) x -> VertexOutput f
to :: forall x. Rep (VertexOutput f) x -> VertexOutput f
Generic, Typeable (VertexOutput GPU)
Params
ParamDefinition
VertexOutput GPU
Typeable (VertexOutput GPU) =>
Params
-> ParamDefinition
-> VertexOutput GPU
-> (VertexOutput GPU -> Values)
-> ShaderParam VertexOutput
VertexOutput GPU -> Values
forall (a :: * -> *).
Typeable (a GPU) =>
Params
-> ParamDefinition -> a GPU -> (a GPU -> Values) -> ShaderParam a
$ccollectParams :: Params
collectParams :: Params
$cparamDefinition :: ParamDefinition
paramDefinition :: ParamDefinition
$cdummyParam :: VertexOutput GPU
dummyParam :: VertexOutput GPU
$ccollectValues :: VertexOutput GPU -> Values
collectValues :: VertexOutput GPU -> Values
Mat.ShaderParam)
data DummyFullscreenMaterial
instance Material DummyFullscreenMaterial where
type VI DummyFullscreenMaterial = VertexInput
type VO DummyFullscreenMaterial = VertexOutput
type B DummyFullscreenMaterial = Bindings
vertex :: VertexInput GPU -> Shader DummyFullscreenMaterial (VertexOutput GPU)
vertex :: VertexInput GPU
-> Shader DummyFullscreenMaterial (VertexOutput GPU)
vertex = Shader NoMaterial (VertexOutput GPU)
-> Shader DummyFullscreenMaterial (VertexOutput GPU)
forall a b c. ExtensionOf b a => Shader a c -> Shader b c
liftExt (Shader NoMaterial (VertexOutput GPU)
-> Shader DummyFullscreenMaterial (VertexOutput GPU))
-> (VertexInput GPU -> Shader NoMaterial (VertexOutput GPU))
-> VertexInput GPU
-> Shader DummyFullscreenMaterial (VertexOutput GPU)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VertexInput GPU -> Shader NoMaterial (VertexOutput GPU)
vertexShader
fragment :: VertexOutput GPU -> Shader DummyFullscreenMaterial (Mat.Vec 4 Mat.Float)
fragment :: VertexOutput GPU -> Shader DummyFullscreenMaterial (Vec 4 Float)
fragment VertexOutput GPU
input = do
b <- Shader DummyFullscreenMaterial (B DummyFullscreenMaterial GPU)
Shader DummyFullscreenMaterial (Bindings GPU)
forall a. Material a => Shader a (B a GPU)
Mat.bindings
pure $ Mat.sample b.tex b.sampler input.uv
data ClearMaterial
data NoBindings f = NoBindings deriving ((forall x. NoBindings f -> Rep (NoBindings f) x)
-> (forall x. Rep (NoBindings f) x -> NoBindings f)
-> Generic (NoBindings f)
forall x. Rep (NoBindings f) x -> NoBindings f
forall x. NoBindings f -> Rep (NoBindings f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall k (f :: k) x. Rep (NoBindings f) x -> NoBindings f
forall k (f :: k) x. NoBindings f -> Rep (NoBindings f) x
$cfrom :: forall k (f :: k) x. NoBindings f -> Rep (NoBindings f) x
from :: forall x. NoBindings f -> Rep (NoBindings f) x
$cto :: forall k (f :: k) x. Rep (NoBindings f) x -> NoBindings f
to :: forall x. Rep (NoBindings f) x -> NoBindings f
Generic, Typeable NoBindings
Typeable NoBindings =>
(Nat -> Proxy (NoBindings Internal) -> (Bindings, Nat))
-> (Nat
-> Proxy (NoBindings Internal)
-> ([WGPUBindGroupLayoutEntry], Nat))
-> (Nat -> NoBindings CPU -> ([WGPUBindGroupEntry], Nat))
-> (Nat -> (NoBindings GPU, Nat))
-> Bindable NoBindings
Nat -> (NoBindings GPU, Nat)
Nat
-> Proxy (NoBindings Internal) -> ([WGPUBindGroupLayoutEntry], Nat)
Nat -> Proxy (NoBindings Internal) -> (Bindings, Nat)
Nat -> NoBindings CPU -> ([WGPUBindGroupEntry], Nat)
forall (a :: * -> *).
Typeable a =>
(Nat -> Proxy (a Internal) -> (Bindings, Nat))
-> (Nat -> Proxy (a Internal) -> ([WGPUBindGroupLayoutEntry], Nat))
-> (Nat -> a CPU -> ([WGPUBindGroupEntry], Nat))
-> (Nat -> (a GPU, Nat))
-> Bindable a
$ccollectBindings :: Nat -> Proxy (NoBindings Internal) -> (Bindings, Nat)
collectBindings :: Nat -> Proxy (NoBindings Internal) -> (Bindings, Nat)
$ccollectLayouts :: Nat
-> Proxy (NoBindings Internal) -> ([WGPUBindGroupLayoutEntry], Nat)
collectLayouts :: Nat
-> Proxy (NoBindings Internal) -> ([WGPUBindGroupLayoutEntry], Nat)
$ccollectEntries :: Nat -> NoBindings CPU -> ([WGPUBindGroupEntry], Nat)
collectEntries :: Nat -> NoBindings CPU -> ([WGPUBindGroupEntry], Nat)
$cdummyBinding :: Nat -> (NoBindings GPU, Nat)
dummyBinding :: Nat -> (NoBindings GPU, Nat)
Bindable)
instance Material ClearMaterial where
type VI ClearMaterial = VertexInput
type VO ClearMaterial = VertexOutput
type B ClearMaterial = NoBindings
vertex :: VI ClearMaterial GPU -> Shader ClearMaterial (VO ClearMaterial GPU)
vertex = Shader NoMaterial (VertexOutput GPU)
-> Shader ClearMaterial (VertexOutput GPU)
forall a b c. ExtensionOf b a => Shader a c -> Shader b c
liftExt (Shader NoMaterial (VertexOutput GPU)
-> Shader ClearMaterial (VertexOutput GPU))
-> (VertexInput GPU -> Shader NoMaterial (VertexOutput GPU))
-> VertexInput GPU
-> Shader ClearMaterial (VertexOutput GPU)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VertexInput GPU -> Shader NoMaterial (VertexOutput GPU)
vertexShader
fragment :: VO ClearMaterial GPU -> Shader ClearMaterial (Vec 4 Float)
fragment VO ClearMaterial GPU
_ = Vec 4 Float -> Shader ClearMaterial (Vec 4 Float)
forall a. a -> Shader ClearMaterial a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Vec 4 Float -> Shader ClearMaterial (Vec 4 Float))
-> Vec 4 Float -> Shader ClearMaterial (Vec 4 Float)
forall a b. (a -> b) -> a -> b
$ Expr ('Primitive (DesugarPrimitiveExpr Float))
-> Expr ('Primitive (DesugarPrimitiveExpr Float))
-> Expr ('Primitive (DesugarPrimitiveExpr Float))
-> Expr ('Primitive (DesugarPrimitiveExpr Float))
-> Vec 4 Float
forall a.
(Expr ('Primitive (DesugarPrimitiveExpr a)) ~ a,
SingI (DesugarPrimitiveExpr a),
PrintVecElements 4 (DesugarPrimitiveExpr a)) =>
Expr ('Primitive (DesugarPrimitiveExpr a))
-> Expr ('Primitive (DesugarPrimitiveExpr a))
-> Expr ('Primitive (DesugarPrimitiveExpr a))
-> Expr ('Primitive (DesugarPrimitiveExpr a))
-> Vec 4 a
Mat.vec4 Float
Expr ('Primitive (DesugarPrimitiveExpr Float))
0 Float
Expr ('Primitive (DesugarPrimitiveExpr Float))
0 Float
Expr ('Primitive (DesugarPrimitiveExpr Float))
0 Float
Expr ('Primitive (DesugarPrimitiveExpr Float))
0
vertexShader :: VertexInput GPU -> Shader NoMaterial (VertexOutput GPU)
vertexShader :: VertexInput GPU -> Shader NoMaterial (VertexOutput GPU)
vertexShader (VertexInput BuiltIn GPU "vertex_index" (Expr ('Primitive 'TUInt))
index) = do
positions <- Expr ('ArrayType (DesugarExpr (Vec 2 Float)))
-> Shader
NoMaterial (Expr ('ArrayType (DesugarExpr (Vec 2 Float))))
forall {k} (a :: Types) (m :: k).
SingI a =>
Expr a -> Shader m (Expr a)
Mat.var (Expr ('ArrayType (DesugarExpr (Vec 2 Float)))
-> Shader
NoMaterial (Expr ('ArrayType (DesugarExpr (Vec 2 Float)))))
-> Expr ('ArrayType (DesugarExpr (Vec 2 Float)))
-> Shader
NoMaterial (Expr ('ArrayType (DesugarExpr (Vec 2 Float))))
forall a b. (a -> b) -> a -> b
$ forall a.
SingI (DesugarExpr a) =>
[Expr (DesugarExpr a)] -> Array a
Mat.array @(Mat.Vec 2 Mat.Float) [Expr ('Primitive (DesugarPrimitiveExpr Float))
-> Expr ('Primitive (DesugarPrimitiveExpr Float)) -> Vec 2 Float
forall a.
(Expr ('Primitive (DesugarPrimitiveExpr a)) ~ a,
SingI (DesugarPrimitiveExpr a),
PrintVecElements 2 (DesugarPrimitiveExpr a)) =>
Expr ('Primitive (DesugarPrimitiveExpr a))
-> Expr ('Primitive (DesugarPrimitiveExpr a)) -> Vec 2 a
Mat.vec2 (-Float
1) (-Float
1), Expr ('Primitive (DesugarPrimitiveExpr Float))
-> Expr ('Primitive (DesugarPrimitiveExpr Float)) -> Vec 2 Float
forall a.
(Expr ('Primitive (DesugarPrimitiveExpr a)) ~ a,
SingI (DesugarPrimitiveExpr a),
PrintVecElements 2 (DesugarPrimitiveExpr a)) =>
Expr ('Primitive (DesugarPrimitiveExpr a))
-> Expr ('Primitive (DesugarPrimitiveExpr a)) -> Vec 2 a
Mat.vec2 Float
Expr ('Primitive (DesugarPrimitiveExpr Float))
3 (-Float
1), Expr ('Primitive (DesugarPrimitiveExpr Float))
-> Expr ('Primitive (DesugarPrimitiveExpr Float)) -> Vec 2 Float
forall a.
(Expr ('Primitive (DesugarPrimitiveExpr a)) ~ a,
SingI (DesugarPrimitiveExpr a),
PrintVecElements 2 (DesugarPrimitiveExpr a)) =>
Expr ('Primitive (DesugarPrimitiveExpr a))
-> Expr ('Primitive (DesugarPrimitiveExpr a)) -> Vec 2 a
Mat.vec2 (-Float
1) Float
Expr ('Primitive (DesugarPrimitiveExpr Float))
3]
let pos = Expr ('ArrayType (DesugarExpr (Expr ('VectorType 2 'TFloat))))
Expr ('ArrayType (DesugarExpr (Vec 2 Float)))
positions Expr ('ArrayType (DesugarExpr (Expr ('VectorType 2 'TFloat))))
-> Expr ('Primitive 'TUInt) -> Expr ('VectorType 2 'TFloat)
forall (a :: Types).
SingI a =>
Array (Expr a) -> Expr ('Primitive 'TUInt) -> Expr a
Mat.!! Expr ('Primitive 'TUInt)
BuiltIn GPU "vertex_index" (Expr ('Primitive 'TUInt))
index
pure $
VertexOutput
{ pos = Mat.vec4 pos.x pos.y 0 1,
uv = Mat.vec2 (pos.x Mat.* 0.5 + 0.5) (1.0 Mat.- (pos.y Mat.* 0.5 Mat.+ 0.5))
}