hylogen 0.1.0.12 → 0.1.1.0
raw patch · 13 files changed
+641/−893 lines, 13 filesdep +data-reifydep −containersdep −hashabledep −mtlnew-component:exe:hyde
Dependencies added: data-reify
Dependencies removed: containers, hashable, mtl
Files
- README.md +35/−14
- app/Main.hs +1/−3
- hylogen.cabal +10/−6
- src/Hylogen.hs +4/−44
- src/Hylogen/Booly.hs +22/−0
- src/Hylogen/CSE.hs +0/−153
- src/Hylogen/Expr.hs +231/−0
- src/Hylogen/Globals.hs +39/−60
- src/Hylogen/Program.hs +40/−0
- src/Hylogen/Texture.hs +14/−0
- src/Hylogen/Types.hs +7/−613
- src/Hylogen/Vec.hs +190/−0
- src/Hylogen/WithHyde.hs +48/−0
README.md view
@@ -1,43 +1,64 @@ # [*H Y L O G E N*](https://hylogen.com) -Hylogen is a purely functional language [embedded in Haskell](https://wiki.haskell.org/Embedded_domain_specific_language) for live-coding fragment shaders.+Hylogen is a purely functional language [embedded in Haskell](https://wiki.haskell.org/Embedded_domain_specific_language) for live-coding fragment shaders, featuring: -## Setup+- a simple and pure syntax+- standard operators (`+`, `*`, [`*^`, `<.>`](https://hackage.haskell.org/package/vector-space))+- compat. w/ your fav haskell goodies (higher-order functions, ADTS, swanky polymorphism).++<br/>++It comes with `hyde`, an accompanying rendering environment featuring:+- *hot-reloading*+- audio-reactive primitives+- texture backbuffering++<br/>+++## Install ``` cabal update cabal install hylogen ``` +This will install the hylogen package and `hyde`, the rendering environment.++<br/>+ ## Usage ```haskell -- ./Main.hs module Main where-import Hylogen+import Hylogen.WithHyde color = vec4 (a, a, a, 1) where a = cos(X uvN * sin(time/ 10) * 10 + X mouse) + sin(Y uvN * sin(time / 10) * 10 + Y mouse) -main = putStrLn $ toGLSL $ color+main = putStrLn . toGLSL $ color ``` -#### 1. run hylogen server+#### 1. run hyde... ```-hylogen Main.hs+hyde Main.hs ``` -#### 2. play!-Visit [localhost:5678](http://localhost:5678) in your browser.+#### 2. ... live-code!+Go to [localhost:5678](http://localhost:5678) in your browser. -Changes in `Main.hs` will now be propagated in realtime to your WebGL rendering context!+You will now see your changes to `Main.hs` propagate to your WebGL rendering environment! -## inspiration-- [The_Force](https://github.com/shawnlawson/The_Force)+<br/> -## resources-[hackage](https://hackage.haskell.org/package/hylogen)+## References+- [The_Force](https://github.com/shawnlawson/The_Force) by Shawn Lawson. Live-coding audio-reactive shaders!+- [Type-Safe Observable Sharing](https://pdfs.semanticscholar.org/4838/bd0a91b3058b467fa31ad9e0810121b46388.pdf) by Andy Gill. [`data-reify`](https://hackage.haskell.org/package/data-reify) made compile times combinatorially faster! -[examples](https://github.com/sleexyz/hylogen-yay)+## Resources+- [hackage](https://hackage.haskell.org/package/hylogen)++- [examples](https://github.com/sleexyz/hylogen-yay)
app/Main.hs view
@@ -18,12 +18,10 @@ import Network.Wai.Handler.Warp import Network.HTTP.Types (status200, status404) --- import System.Random- main :: IO () main = getArgs >>= \case [pathToWatch] -> main' pathToWatch- _ -> error "Name a file to watch!"+ _ -> error "Error: Name a file to watch!" main' :: FilePath -> IO () main' pathToWatch = do
hylogen.cabal view
@@ -1,5 +1,5 @@ name: hylogen-version: 0.1.0.12+version: 0.1.1.0 synopsis: an EDSL for live-coding fragment shaders description: an EDSL for live-coding fragment shaders homepage: https://hylogen.com@@ -18,19 +18,23 @@ library exposed-modules: Hylogen , Hylogen.Types+ , Hylogen.Vec+ , Hylogen.Expr+ , Hylogen.Booly+ , Hylogen.Texture , Hylogen.Globals- , Hylogen.CSE+ , Hylogen.Program+ , Hylogen.WithHyde build-depends: base >=4.8 && <4.9 , vector-space- , containers- , hashable- , mtl+ , data-reify hs-source-dirs: src default-language: Haskell2010 -executable hylogen+executable hyde main-is: Main.hs other-extensions: OverloadedStrings+ other-modules: Paths_hylogen build-depends: base , bytestring , filepath
src/Hylogen.hs view
@@ -1,47 +1,7 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ExplicitForAll #-}-{-# LANGUAGE ExtendedDefaultRules #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoMonoLocalBinds #-}-{-# LANGUAGE NoMonomorphismRestriction #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE Rank2Types #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}--module Hylogen- ( module Hylogen- , module Hylogen.Types- , module Hylogen.Globals- )- where+module Hylogen ( module Hylogen.Types+ , module Hylogen.Globals+ ) where -import Data.Monoid-import Data.List-import Hylogen.CSE (contextToAssignments, getTopLevel, genContext) import Hylogen.Globals-import Hylogen.Types (Vec (fromVec1, select, toList),- Vec1 (W, X, Y, Z), Vec2, Vec3, Vec4)--toGLSL' :: Vec4 -> String-toGLSL' v = unlines [ "void main() {"- , " gl_FragColor = " <> show v<> ";"- , "}"- ]---toGLSL :: Vec4 -> String-toGLSL v = unlines [ "void main() {"- , assignments- , ""- , " gl_FragColor = " <> show topLevel <> ";"- , "}"- ]- where- assignments = mconcat . fmap ("\n "<>) $ contextToAssignments glsl- glsl = genContext v- topLevel = getTopLevel glsl+import Hylogen.Types
+ src/Hylogen/Booly.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}+module Hylogen.Booly where++import Hylogen.Expr++data BoolyType = BoolyType+instance ToGLSLType BoolyType where+ toGLSLType _ = GLSLBool+ tag = BoolyType++type Booly = Expr BoolyType++instance Num Booly where+ (+) = op2 "||"+ (*) = op2 "&&"+ negate = op1 "!"+ abs = id+ signum = id+ fromInteger x+ | x > 0 = uniform "true"+ | otherwise = uniform "false"
− src/Hylogen/CSE.hs
@@ -1,153 +0,0 @@-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE NoMonomorphismRestriction #-}-{-# LANGUAGE LambdaCase#-}-{-# LANGUAGE DeriveFoldable #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE TupleSections #-}--module Hylogen.CSE where--import Data.IntMap.Lazy (IntMap)-import qualified Data.IntMap as IntMap-import Data.Monoid-import Data.Hashable-import GHC.Generics--import Hylogen.Types-import Control.Arrow--type Hash = Int---- data HashTree a = Leaf Hash a | Branch Hash a [HashTree a]--- deriving (Generic, Hashable, Show, Eq, Ord, Foldable)--type Tags = (ExprForm, GLSLType, String, Hash, [Either Expr Hash])--type HashTree = Tree (ExprForm, GLSLType, String, Hash, [Either Expr Hash])--getHash :: HashTree -> Hash-getHash (Tree (_, _, _, h, _) _) = h--getExprForm :: HashTree -> ExprForm-getExprForm (Tree (ef, _, _, _, _) _) = ef---toHashTree :: Tree (ExprForm, GLSLType, String) -> Tree (ExprForm, GLSLType, String, Hash, [Either Expr Hash])-toHashTree (Tree (ef, ty, str) subtrees) = let- subHashTrees :: [Tree (ExprForm, GLSLType, String, Hash, [Either Expr Hash])]- subHashTrees = toHashTree <$> subtrees-- subHashes :: [Hash]- subHashes = getHash <$> subHashTrees-- parentHash :: Hash- parentHash = hash (ef, ty, str, subHashes)-- subHashes' :: [Either Expr Hash]- subHashes' = zipWith fn subHashes subtrees- where- fn :: Hash -> Expr -> Either Expr Hash- fn h expr@(Tree (ef, _, _) _) = case ef of- Uniform -> Left expr- _ -> Right h- - in Tree (ef, ty, str, parentHash, subHashes') subHashTrees---- variablize :: [Hash] -> HashTree -> [Hash] -> HashTree--- variablize subHashes tree@(Tree (ef, ty, str, h) _) = case ef of--- Uniform -> tree--- _ -> tree------type Id = Int--- | Add if in first, variabalize!-type GLSL = ( IntMap (ExprForm, GLSLType, String, [Either Expr Hash])- , [(ExprForm, GLSLType, String, Hash, [Either Expr Hash])]- )---- TODO:--- newtype GLSL = GLSL ([(Id, (Expr, [Hash]))], IntMap.Map Hash Id)--- deriving (Show)---initialGLSL :: GLSL-initialGLSL = (IntMap.empty, [])------ genContext :: HashTree -> GLSL--- genContext = foldr fn initialGLSL--- where--- fn :: (Hash, Expr, [Hash]) -> GLSL -> GLSL--- fn (h, e, children) glsl =--- case e of--- Uniform _ _ -> glsl--- _ -> snd $ addNode' h e children glsl----- TODO: slow---- HashTree = Tree (ExprForm, GLSLType, String, Hash, [Hash])-toContext :: HashTree -> GLSL-toContext ht = genContext' ht initialGLSL- where- genContext' :: HashTree -> GLSL -> GLSL- genContext' (Tree foo subTrees) glsl = fn foo (foldr genContext' glsl subTrees)- where- fn :: (ExprForm, GLSLType, String, Hash, [Either Expr Hash]) -> GLSL -> GLSL- fn orig@(ef, ty, str, h, hs) (hashmap, output)- = if IntMap.member h hashmap- then ( hashmap- , output- )- else ( IntMap.insert h (ef, ty, str, hs) hashmap- , orig:output- )--genContext :: (Expressible a) => a -> GLSL-genContext = toExpr- >>> toHashTree- >>> toContext--hash2Name :: Hash -> String-hash2Name h- | h < 0 = "_n" <> tail shown- | otherwise = "_" <> shown- where- shown = show h-----getTopLevel :: GLSL -> Expr-getTopLevel (_, output) = tagsToExpr $ head output--contextToAssignments :: GLSL -> [String]-contextToAssignments (_, output) = foldl fn [] output- where- fn bs tags@(ef, _, _, _, _) = case ef of- Uniform -> bs- _ -> assign tags : bs--- contextToAssignments :: GLSL -> [String]--- contextToAssignments (_, output) = assign <$> reverse output--assign :: (ExprForm, GLSLType, String, Hash, [Either Expr Hash]) -> String-assign tags@(ef, ty, str, h, hs)- = show ty <> " "- <> hash2Name h <> " = "- <> show expr <> ";"- where- expr = tagsToExpr tags---- type Tags = (ExprForm, GLSLType, String, Hash, [Hash])-tagsToExpr :: Tags -> Expr-tagsToExpr (ef, ty, str, h, hs) = case ef of- _ -> Tree (ef, ty, str) $ fn <$> hs- where- fn :: Either Expr Hash -> Expr- fn (Left e) = e- fn (Right h) = Tree (Variable, GLSLFloat, hash2Name h) []-
+ src/Hylogen/Expr.hs view
@@ -0,0 +1,231 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE DeriveFunctor #-}+++module Hylogen.Expr where++import Data.Reify++data GLSLType = GLSLFloat+ | GLSLVec2+ | GLSLVec3+ | GLSLVec4+ | GLSLBool+ | GLSLTexture+ deriving (Eq, Ord)++instance Show GLSLType where+ show x = case x of+ GLSLFloat -> "float"+ GLSLVec2 -> "vec2"+ GLSLVec3 -> "vec3"+ GLSLVec4 -> "vec4"+ GLSLBool -> "bool"+ GLSLTexture -> "sampler2D"++data ExprForm = Uniform+ | Variable+ | Op1+ | Op1Pre+ | Op2+ | Op2Pre+ | Op3Pre+ | Op4Pre+ | Select+ | Access+ deriving (Show)++data Tree a = Tree { getElem :: a+ , getChildren :: [Tree a]+ }+++type ExprMono = Tree (ExprForm, GLSLType, String)++instance Show ExprMono where+ show (Tree (form, _, str) xs) = case form of+ Uniform -> str+ Variable -> str+ Op1 -> mconcat ["(", str, show (xs!!0), ")"]+ Op1Pre -> mconcat [ str, "(", show (xs!!0), ")"]+ Op2 -> mconcat ["(", show (xs !! 0), " ", str, " ", show (xs !! 1), ")"]+ Op2Pre -> mconcat [str, "(", show (xs!!0), ", ", show (xs!!1), ")"]+ Op3Pre -> mconcat [str, "(", show (xs!!0), ", ", show (xs!!1), ", ", show (xs!!2), ")"]+ Op4Pre -> mconcat [str, "(", show (xs!!0), ", ", show (xs!!1), ", ", show (xs!!2), ", ", show (xs!!3), ")"]+ Select -> mconcat ["( ", show (xs!!0), " ? ", show (xs!!1), " : ", show (xs!!2), ")"]+ Access -> mconcat [show (xs!!0), ".", str]++-- The GLSLType needs to be manually dependent++-- light typed wrapper+data Expr ty = Expr { getTypeTag :: ty+ , toMono :: Tree (ExprForm, GLSLType, String)+ }++instance ToGLSLType ty => Show (Expr ty) where+ show = show . toMono++class ToGLSLType ty where+ toGLSLType :: ty -> GLSLType+ tag :: ty -- TODO: fill in!++uniform :: forall a+ . ToGLSLType a+ => String -> Expr a+uniform str = Expr t (Tree (Uniform, toGLSLType t, str) [])+ where t = tag :: a++op1 :: forall a b+ . (ToGLSLType a, ToGLSLType b)+ => String -> Expr a -> Expr b+op1 str a = Expr t (Tree (Op1, toGLSLType t, str) [toMono a])+ where t = tag :: b++op1'' :: forall a+ . (ToGLSLType a)+ => String -> Expr a -> Expr a+op1'' str a = Expr t (Tree (Op1, toGLSLType t, str) [toMono a])+ where t = tag :: a++op1pre :: forall a b+ . (ToGLSLType a, ToGLSLType b)+ => String -> Expr a -> Expr b+op1pre str a = Expr t (Tree (Op1Pre, toGLSLType t, str) [toMono a])+ where t = tag :: b++op1pre'' :: forall a+ . (ToGLSLType a)+ => String -> Expr a -> Expr a+op1pre'' str a = Expr t (Tree (Op1Pre, toGLSLType t, str) [toMono a])+ where t = tag :: a++op2 :: forall a b c+ . (ToGLSLType a, ToGLSLType b, ToGLSLType c)+ => String -> Expr a -> Expr b -> Expr c+op2 str a b = Expr t (Tree (Op2, toGLSLType t, str) [toMono a, toMono b])+ where t = tag :: c++op2' :: forall a c+ . (ToGLSLType a, ToGLSLType c)+ => String -> Expr a -> Expr a -> Expr c+op2' str a b = Expr t (Tree (Op2, toGLSLType t, str) (fmap toMono [a, b]))+ where t = tag :: c++op2'' :: forall a+ . (ToGLSLType a)+ => String -> Expr a -> Expr a -> Expr a+op2'' str a b = Expr t (Tree (Op2, toGLSLType t, str) (fmap toMono [a, b]))+ where t = tag :: a+++op2pre :: forall a b c+ . (ToGLSLType a, ToGLSLType b, ToGLSLType c)+ => String -> Expr a -> Expr b -> Expr c+op2pre str a b = Expr t (Tree (Op2Pre, toGLSLType t, str) [toMono a, toMono b])+ where t = tag :: c++op2pre' :: forall a c+ . (ToGLSLType a, ToGLSLType c)+ => String -> Expr a -> Expr a -> Expr c+op2pre' str a b = Expr t (Tree (Op2Pre, toGLSLType t, str) (fmap toMono [a, b]))+ where t = tag :: c++op2pre'' :: forall a+ . (ToGLSLType a)+ => String -> Expr a -> Expr a -> Expr a+op2pre'' str a b = Expr t (Tree (Op2Pre, toGLSLType t, str) (fmap toMono [a, b]))+ where t = tag :: a++op3pre :: forall a b c d+ . (ToGLSLType a, ToGLSLType b, ToGLSLType c, ToGLSLType d)+ => String -> Expr a -> Expr b -> Expr c -> Expr d+op3pre str a b c = Expr t (Tree (Op3Pre, toGLSLType t, str) [toMono a, toMono b, toMono c])+ where t = tag :: d++op3pre' :: forall a d+ . (ToGLSLType a, ToGLSLType d)+ => String -> Expr a -> Expr a -> Expr a -> Expr d+op3pre' str a b c = Expr t (Tree (Op3Pre, toGLSLType t, str) (fmap toMono [a, b, c]))+ where t = tag :: d++op3pre'' :: forall a+ . (ToGLSLType a)+ => String -> Expr a -> Expr a -> Expr a -> Expr a+op3pre'' str a b c = Expr t (Tree (Op3Pre, toGLSLType t, str) (fmap toMono [a, b, c]))+ where t = tag :: a+++op4pre :: forall a b c d e+ . (ToGLSLType a, ToGLSLType b, ToGLSLType c, ToGLSLType d, ToGLSLType e)+ => String -> Expr a -> Expr b -> Expr c -> Expr d -> Expr e+op4pre str a b c d = Expr t (Tree (Op4Pre, toGLSLType t, str) [toMono a, toMono b, toMono c, toMono d])+ where t = tag :: e++op4pre' :: forall a e+ . (ToGLSLType a, ToGLSLType e)+ => String -> Expr a -> Expr a -> Expr a -> Expr a -> Expr e+op4pre' str a b c d = Expr t (Tree (Op4Pre, toGLSLType t, str) (fmap toMono [a, b, c, d]))+ where t = tag :: e++op4pre'' :: forall a e+ . (ToGLSLType a, ToGLSLType e)+ => String -> Expr a -> Expr a -> Expr a -> Expr a -> Expr e+op4pre'' str a b c d = Expr t (Tree (Op4Pre, toGLSLType t, str) (fmap toMono [a, b, c, d]))+ where t = tag :: e+++++data TreeF a b = TreeF { getElemF :: a+ , getChildrenF :: [Maybe b]+ }+ deriving (Functor)++type ExprMonoF = TreeF (ExprForm, GLSLType, String, [ExprMono])++emfStringAt :: (Show a) => ExprMonoF a -> Int -> String+emfStringAt (TreeF (_, _, _, xs) ys) i = zipWith fn xs ys !! i+ where+ fn x Nothing = show x+ fn _ (Just y)= show y++instance (Show a) => Show (ExprMonoF a) where+ show expr@(TreeF (form, _, str, _) _) = case form of+ Uniform -> str+ Variable -> str+ Op1 -> mconcat ["(", str, strAt 0, ")"]+ Op1Pre -> mconcat [ str, "(", strAt 0, ")"]+ Op2 -> mconcat ["(", strAt 0, " ", str, " ", strAt 1, ")"]+ Op2Pre -> mconcat [str, "(", strAt 0, ", ", strAt 1, ")"]+ Op3Pre -> mconcat [str, "(", strAt 0, ", ", strAt 1, ", ", strAt 2, ")"]+ Op4Pre -> mconcat [str, "(", strAt 0, ", ", strAt 1, ", ", strAt 2, ", ", strAt 3, ")"]+ Select -> mconcat ["( ", strAt 0, " ? ", strAt 1, " : ", strAt 2, ")"]+ Access -> mconcat [strAt 0, ".", str]+ where+ strAt = emfStringAt expr++-- instance MuRef ExprMono where+-- type DeRef ExprMono = ExprMonoF+-- mapDeRef f (Tree tup xs) = TreeF tup <$> traverse f xs++instance MuRef ExprMono where+ type DeRef ExprMono = ExprMonoF+ mapDeRef func (Tree (form, ty, str) xs) = TreeF (form, ty, str, xs) <$> g xs+ where+ g (x:xs) = (:) <$> (traverse func $ shouldShare x) <*> (g $ xs)+ g [] = pure []++ shouldShare :: ExprMono -> Maybe ExprMono+ shouldShare (Tree (Uniform, _, _) _) = Nothing+ shouldShare expr = Just expr
src/Hylogen/Globals.hs view
@@ -1,39 +1,36 @@ {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE DataKinds #-} module Hylogen.Globals where import Hylogen.Types+import Hylogen.Expr import Data.VectorSpace -vec2 :: (ConstructFrom tc Vec2) => tc -> Vec2-vec2 = Vec2 -vec3 :: (ConstructFrom tc Vec3) => tc -> Vec3-vec3 = Vec3 -vec4 :: (ConstructFrom tc Vec4) => tc -> Vec4-vec4 = Vec4 -inverseSqrt :: (Vec a) => a -> a-inverseSqrt = vuop "inversesqrt"+inverseSqrt :: forall n. (Veccable n) => Vec n -> Vec n+inverseSqrt = op1pre'' "inversesqrt" -fract :: (Vec a) => a -> a-fract = vuop "fract"+fract :: forall n. (Veccable n) => Vec n -> Vec n+fract = op1pre'' "fract" -floor_ :: (Vec a) => a -> a-floor_ = vuop "floor"+floor_:: forall n. (Veccable n) => Vec n -> Vec n+floor_ = op1pre'' "floor" -ceil_ :: (Vec a) => a -> a-ceil_ = vuop "ceil"+ceil_ :: forall n. (Veccable n) => Vec n -> Vec n+ceil_ = op1pre'' "ceil" -min_ :: (Vec a) => a -> a -> a-min_ = vboppre "min"+min_ :: forall n. (Veccable n) => Vec n -> Vec n -> Vec n+min_ = op2pre'' "min" -max_:: (Vec a) => a -> a -> a-max_ = vboppre "max"+max_ :: forall n. (Veccable n) => Vec n -> Vec n -> Vec n+max_ = op2pre'' "max" -clamp :: (Vec a) => a -> a -> a -> a+clamp :: forall n. (Veccable n) => Vec n -> Vec n -> Vec n -> Vec n clamp x y z = (z `min_` y) `max_` x @@ -44,60 +41,42 @@ linlin (a, b, c, d) x = c + (d - c) * ((x - a) / (b - a)) -time :: Vec1-time = V1u "time" -uv :: Vec2-uv = V2u "uv()"--uvN :: Vec2-uvN = V2u "uvN"--resolution :: Vec2-resolution = V2u "resolution"--mouse :: Vec2-mouse = V2u "mouse"---audio :: Vec4-audio = V4u "audio"--backBuffer :: Texture-backBuffer = Tu "backBuffer"--channel1 :: Texture-channel1 = Tu "channel1"- mix :: Vec1 -> Vec4 -> Vec4 -> Vec4 mix p a b = p *^ a + (1 - p) *^ b --- | Booly's- true :: Booly-true = Bu "true"+true = uniform "true" false :: Booly-false = Bu "false"+false = uniform "false" -eq :: (Vec v) => v -> v -> Booly-eq = Bcomp "=="+bcomp :: (Veccable v) => String -> Vec v -> Vec v -> Booly+bcomp str x y = product $ zipWith (op2' str) (toList x) (toList y) -neq :: (Vec v) => v -> v -> Booly-neq = Bcomp "!="+eq :: (Veccable v) => Vec v -> Vec v -> Booly+eq = bcomp "==" -lt :: (Vec v) => v -> v -> Booly-lt = Bcomp "<"+neq :: (Veccable v) => Vec v -> Vec v -> Booly+neq = bcomp "!=" -gt :: (Vec v) => v -> v -> Booly-gt = Bcomp ">"+lt :: (Veccable v) => Vec v -> Vec v -> Booly+lt = bcomp "<" -leq :: (Vec v) => v -> v -> Booly-leq = Bcomp "<="+gt :: (Veccable v) => Vec v -> Vec v -> Booly+gt = bcomp ">" -geq :: (Vec v) => v -> v -> Booly-geq = Bcomp ">="+leq :: (Veccable v) => Vec v -> Vec v -> Booly+leq = bcomp "<=" +geq :: (Veccable v) => Vec v -> Vec v -> Booly+geq = bcomp ">=" texture2D :: Texture -> Vec2 -> Vec4-texture2D = Texture2D+texture2D = op2pre "texture2D"++select :: forall a+ . (ToGLSLType a)+ => Booly -> Expr a -> Expr a -> Expr a+select a b c = Expr t (Tree (Select, toGLSLType t, "") ([toMono a, toMono b, toMono c]))+ where t = tag :: a
+ src/Hylogen/Program.hs view
@@ -0,0 +1,40 @@+module Hylogen.Program where++import Data.Reify+import Data.Monoid+import System.IO.Unsafe++import Hylogen.Expr++-- Just for printing!+newtype Id = Id Int+instance Show Id where+ show (Id h) = "_" <> show h++data Statement = NewAssign (Unique, ExprMonoF Unique)+ -- | MutAssign (Unique, ExprMonoF Unique)++getExpr :: Statement -> ExprMonoF Unique+getExpr (NewAssign (_, expr)) = expr++++instance Show Statement where+ show (NewAssign (i, expr@(TreeF (_, ty, _, _) _)))+ = mconcat [ show ty, " ", show . Id $ i, " = ", show . (Id<$>) $ expr, ";"]++newtype Function = Function [Statement]+instance Show Function where+ show (Function xs) = unlines [ "void main() {"+ , assignments+ , " gl_FragColor = _1;"+ , "}"+ ]+ where+ assignments = mconcat $ (<> "\n") . (" "<>) . show <$> reverse xs+++toProgram :: ExprMono -> Function+toProgram v = unsafePerformIO $ do+ Graph nodes _ <- reifyGraph v+ return . Function $ NewAssign <$> nodes
+ src/Hylogen/Texture.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}++module Hylogen.Texture where++import Hylogen.Expr++data TextureType = TextureType+instance ToGLSLType TextureType where+ toGLSLType _ = GLSLTexture+ tag = TextureType++type Texture = Expr TextureType
src/Hylogen/Types.hs view
@@ -1,615 +1,9 @@-{-# LANGUAGE GADTs #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ExtendedDefaultRules #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE LambdaCase #-}--module Hylogen.Types where---import Data.Monoid-import Data.VectorSpace-import GHC.Exts (Constraint)-import Data.Hashable-import GHC.Generics--class (ConstructFrom' tuple hprim, Show tuple, Vec hprim) => ConstructFrom tuple hprim where- exprFormFromTuple :: tuple -> hprim -> Expr--instance ConstructFrom Float Vec1 where- exprFormFromTuple x _ = Tree (Uniform, GLSLFloat, (show x)) [] -- TODO: this is a hack!-instance ConstructFrom (Vec1, Vec1) Vec2 where- exprFormFromTuple (x, y) _ = Tree (BinaryOpPre, GLSLVec2, "vec2") [toExpr x, toExpr y]-instance ConstructFrom (Vec1, Vec1, Vec1) Vec3 where- exprFormFromTuple (x, y, z) _ = Tree (TernaryOpPre, GLSLVec3, "vec3") [toExpr x, toExpr y, toExpr z]-instance ConstructFrom (Vec2, Vec1) Vec3 where- exprFormFromTuple (x, y) _ = Tree (BinaryOpPre, GLSLVec3, "vec3") [toExpr x, toExpr y]-instance ConstructFrom (Vec1, Vec2) Vec3 where- exprFormFromTuple (x, y) _ = Tree (BinaryOpPre, GLSLVec3, "vec3") [toExpr x, toExpr y]-instance ConstructFrom (Vec1, Vec1, Vec1, Vec1) Vec4 where- exprFormFromTuple (x, y, z, w) _ = Tree (QuaternaryOpPre, GLSLVec4, "vec4") [toExpr x, toExpr y, toExpr z, toExpr w]-instance ConstructFrom (Vec2, Vec1, Vec1) Vec4 where- exprFormFromTuple (x, y, z) _ = Tree (TernaryOpPre, GLSLVec4, "vec4") [toExpr x, toExpr y, toExpr z]-instance ConstructFrom (Vec1, Vec2, Vec1) Vec4 where- exprFormFromTuple (x, y, z) _ = Tree (TernaryOpPre, GLSLVec4, "vec4") [toExpr x, toExpr y, toExpr z]-instance (a ~ Vec1, b ~ Vec1) => ConstructFrom (a, b, Vec2) Vec4 where- exprFormFromTuple (x, y, z) _ = Tree (TernaryOpPre, GLSLVec4, "vec4") [toExpr x, toExpr y, toExpr z]-instance ConstructFrom (Vec3, Vec1) Vec4 where- exprFormFromTuple (x, y) _ = Tree (BinaryOpPre, GLSLVec4, "vec4") [toExpr x, toExpr y]-instance (a ~ Vec1) => ConstructFrom (a, Vec3) Vec4 where- exprFormFromTuple (x, y) _ = Tree (BinaryOpPre, GLSLVec4, "vec4") [toExpr x, toExpr y]-instance (a ~ Vec2) => ConstructFrom (a, Vec2) Vec4 where- exprFormFromTuple (x, y) _ = Tree (BinaryOpPre, GLSLVec4, "vec4") [toExpr x, toExpr y]--type family (ConstructFrom' tuple hprim) :: Constraint where- ConstructFrom' a Vec1 = a ~ Float- ConstructFrom' (a, b) Vec2 = (a ~ Vec1, b ~ Vec1)-- ConstructFrom' (a, b, c) Vec3 = (a ~ Vec1, b ~ Vec1, c ~ Vec1)- ConstructFrom' (Vec2, b) Vec3 = (b ~ Vec1)- ConstructFrom' (a, Vec2) Vec3 = (a ~ Vec1)-- ConstructFrom' (a, b, c, d) Vec4 = (a ~ Vec1, b ~ Vec1, c ~ Vec1, d ~ Vec1)- ConstructFrom' (Vec3, b) Vec4 = (b ~ Vec1)- ConstructFrom' (Vec2, b) Vec4 = (b ~ Vec2)- ConstructFrom' (a, Vec3) Vec4 = (a ~ Vec1)--- -- ConstructFrom' (Vec1, Vec1, Vec2) Vec4 = ()- -- ConstructFrom' (Vec1, Vec2, Vec1) Vec4 = ()- -- ConstructFrom' (Vec2, Vec1, Vec1) Vec4 = ()-- ConstructFrom' (Vec2, b, c) Vec4 = (b ~ Vec1, c ~ Vec1)- ConstructFrom' (a, Vec2, c) Vec4 = (a ~ Vec1, c ~ Vec1) -- works- ConstructFrom' (a, b, Vec2) Vec4 = (a ~ Vec1, b ~ Vec1)------class (Expressible v, Show v) => Vec v where- vec :: (ConstructFrom tuple v) => tuple -> v- vu :: String -> v- vuop :: String -> v -> v- vuoppre :: String -> v -> v- vbop :: String -> v -> v -> v- vboppre :: String -> v -> v -> v- select :: Booly -> v -> v -> v- fromVec1 :: Vec1 -> v- toList :: v -> [Vec1]----class (Expressible a, Show a) => HasX a-class HasX a => HasY a-class HasY a => HasZ a-class HasZ a => HasW a---data Vec1 where- Vec1 :: Float -> Vec1- V1u :: String -> Vec1- V1uop :: String -> Vec1 -> Vec1- V1uoppre :: String -> Vec1 -> Vec1- V1bop :: String -> Vec1 -> Vec1 -> Vec1- V1boppre :: String -> Vec1 -> Vec1 -> Vec1- V1select :: Booly -> Vec1 -> Vec1 -> Vec1- Dot :: (Vec a) => a -> a -> Vec1- X :: (HasX a) => a -> Vec1- Y :: (HasY a) => a -> Vec1- Z :: (HasZ a) => a -> Vec1- W :: (HasW a) => a -> Vec1----instance Show Vec1 where- show expr = case expr of- Vec1 x -> show x- V1u x -> x- V1uop u x -> u <> "(" <> show x <> ")"- V1uoppre u x -> "(" <> u <> show x <> ")"- V1bop b x y -> "(" <> show x <> " " <> b <> " " <> show y <> ")"- V1boppre b x y -> b <> "(" <> show x <> ", " <> show y <> ")"- V1select b x y -> "( " <> show b <> " ? " <> show x <> " : " <> show y <> ")"- Dot x y -> "dot(" <> show x <> ", " <> show y <> ")"- X x -> show x <> ".x"- Y x -> show x <> ".y"- Z x -> show x <> ".z"- W x -> show x <> ".w"---instance Vec Vec1 where- vec = Vec1- vu = V1u- vuop = V1uop- vuoppre = V1uoppre- vbop = V1bop- vboppre = V1boppre- select = V1select- fromVec1 = id- toList x = [x]--instance Num Vec1 where- (+) = vbop "+"- (*) = vbop "*"- negate = vuoppre "-"- abs = vuop "abs"- signum = vuop "sign"- fromInteger = Vec1 . fromInteger--instance Fractional Vec1 where- (/) = vbop "/"- recip = vbop "/" 1- fromRational = Vec1 . fromRational---instance Floating Vec1 where- pi = vu "pi"- exp = vuop "exp"- log = vuop "log"- sqrt = vuop "sqrt"- (**) = vboppre "pow"- sin = vuop "sin"- cos = vuop "cos"- tan = vuop "tan"- asin = vuop "asin"- acos = vuop "acos"- atan = vuop "atan"- sinh x = (exp x - exp (negate x))/2- cosh x = (exp x + exp (negate x))/2- tanh x = sinh x / cosh x- asinh x = log $ x + sqrt(x**2 + 1)- acosh x = log $ x + sqrt(x**2 - 1)- atanh x = 0.5 * log ((1 + x)/(1 - x))--instance AdditiveGroup Vec1 where- zeroV = 0- (^+^) = (+)- negateV = negate- (^-^) = (-)--instance VectorSpace Vec1 where- type Scalar Vec1 = Vec1- a *^ b = a * b--instance InnerSpace Vec1 where- (<.>) = Dot---- | Vec2:--data Vec2 where- Vec2 :: (ConstructFrom tuple Vec2) => tuple -> Vec2- V2u :: String -> Vec2- V2uop :: String -> Vec2 -> Vec2- V2uoppre :: String -> Vec2 -> Vec2- V2bop :: String -> Vec2 -> Vec2 -> Vec2- V2boppre :: String -> Vec2 -> Vec2 -> Vec2- V2bops :: String -> Vec1 -> Vec2 -> Vec2- V2select :: Booly -> Vec2 -> Vec2 -> Vec2---instance Vec Vec2 where- vec = Vec2- vu = V2u- vuop = V2uop- vuoppre = V2uoppre- vbop = V2bop- vboppre = V2boppre- select = V2select- fromVec1 x = Vec2 (x, x)- toList x = [X x, Y x]---instance Show Vec2 where- show expr = case expr of- Vec2 tuple -> "vec2" <> show tuple- V2u x -> x- V2uop u x -> u <> "(" <> show x <> ")"- V2uoppre u x -> "(" <> u <> show x <> ")"- V2bop b x y -> "(" <> show x <> " " <> b <> " " <> show y <> ")"- V2boppre b x y -> b <> "(" <> show x <> ", " <> show y <> ")"- V2bops b x y -> "(" <> show x <> " " <> b <> " " <> show y <> ")"- V2select b x y -> "( " <> show b <> " ? " <> show x <> " : " <> show y <> ")"--instance Num Vec2 where- (+) = vbop "+"- (*) = vbop "*"- negate = vuoppre "-"- abs = vuop "abs"- signum = vuop "sign"- fromInteger = fromVec1 . fromInteger--instance Fractional Vec2 where- (/) = vbop "/"- recip = vbop "/" 1- fromRational = fromVec1 . fromRational---instance Floating Vec2 where- pi = vu "pi"- exp = vuop "exp"- log = vuop "log"- sqrt = vuop "sqrt"- (**) = vboppre "pow"- sin = vuop "sin"- cos = vuop "cos"- tan = vuop "tan"- asin = vuop "asin"- acos = vuop "acos"- atan = vuop "atan"- sinh x = (exp x - exp (negate x))/2- cosh x = (exp x + exp (negate x))/2- tanh x = sinh x / cosh x- asinh x = log $ x + sqrt(x**2 + 1)- acosh x = log $ x + sqrt(x**2 - 1)- atanh x = 0.5 * log ((1 + x)/(1 - x))--instance AdditiveGroup Vec2 where- zeroV = 0- (^+^) = (+)- negateV = negate- (^-^) = (-)--instance VectorSpace Vec2 where- type Scalar Vec2 = Vec1- a *^ b = V2bops "*" a b--instance InnerSpace Vec2 where- (<.>) = Dot--instance HasX Vec2-instance HasY Vec2----- | Vec3:--data Vec3 where- Vec3 :: (ConstructFrom tuple Vec3) => tuple -> Vec3- V3u :: String -> Vec3- V3uop :: String -> Vec3 -> Vec3- V3uoppre :: String -> Vec3 -> Vec3- V3bop :: String -> Vec3 -> Vec3 -> Vec3- V3boppre :: String -> Vec3 -> Vec3 -> Vec3- V3bops :: String -> Vec1 -> Vec3 -> Vec3- V3select :: Booly -> Vec3 -> Vec3 -> Vec3--instance Vec Vec3 where- vec = Vec3- vu = V3u- vuop = V3uop- vuoppre = V3uoppre- vbop = V3bop- vboppre = V3boppre- select = V3select- fromVec1 x = Vec3 (x, x, x)- toList x = [X x, Y x, Z x]--instance Show Vec3 where- show expr = case expr of- Vec3 tuple -> "vec3" <> show tuple- V3u x -> x- V3uop u x -> u <> "(" <> show x <> ")"- V3uoppre u x -> "(" <> u <> show x <> ")"- V3bop b x y -> "(" <> show x <> " " <> b <> " " <> show y <> ")"- V3boppre b x y -> b <> "(" <> show x <> ", " <> show y <> ")"- V3bops b x y -> "(" <> show x <> " " <> b <> " " <> show y <> ")"- V3select b x y -> "( " <> show b <> " ? " <> show x <> " : " <> show y <> ")"--instance Num Vec3 where- (+) = vbop "+"- (*) = vbop "*"- negate = vuoppre "-"- abs = vuop "abs"- signum = vuop "sign"- fromInteger = fromVec1 . fromInteger--instance Fractional Vec3 where- (/) = vbop "/"- recip = vbop "/" 1- fromRational = fromVec1 . fromRational---instance Floating Vec3 where- pi = vu "pi"- exp = vuop "exp"- log = vuop "log"- sqrt = vuop "sqrt"- (**) = vboppre "pow"- sin = vuop "sin"- cos = vuop "cos"- tan = vuop "tan"- asin = vuop "asin"- acos = vuop "acos"- atan = vuop "atan"- sinh x = (exp x - exp (negate x))/2- cosh x = (exp x + exp (negate x))/2- tanh x = sinh x / cosh x- asinh x = log $ x + sqrt(x**2 + 1)- acosh x = log $ x + sqrt(x**2 - 1)- atanh x = 0.5 * log ((1 + x)/(1 - x))--instance AdditiveGroup Vec3 where- zeroV = 0- (^+^) = (+)- negateV = negate- (^-^) = (-)--instance VectorSpace Vec3 where- type Scalar Vec3 = Vec1- a *^ b = V3bops "*" a b--instance InnerSpace Vec3 where- (<.>) = Dot--instance HasX Vec3-instance HasY Vec3-instance HasZ Vec3------ | Vec4:--data Vec4 where- Vec4 :: (ConstructFrom tuple Vec4) => tuple -> Vec4- V4u :: String -> Vec4- V4uop :: String -> Vec4 -> Vec4- V4uoppre :: String -> Vec4 -> Vec4- V4bop :: String -> Vec4 -> Vec4 -> Vec4- V4boppre :: String -> Vec4 -> Vec4 -> Vec4- V4bops :: String -> Vec1 -> Vec4 -> Vec4- V4select :: Booly -> Vec4 -> Vec4 -> Vec4- Texture2D :: Texture -> Vec2 -> Vec4---instance Vec Vec4 where- vec = Vec4- vu = V4u- vuop = V4uop- vuoppre = V4uoppre- vbop = V4bop- vboppre = V4boppre- select = V4select- fromVec1 x = Vec4 (x, x, x, x)- toList x = [X x, Y x, Z x, W x]--instance Show Vec4 where- show expr = case expr of- Vec4 tuple -> "vec4" <> show tuple- V4u x -> x- V4uop u x -> u <> "(" <> show x <> ")"- V4uoppre u x -> "(" <> u <> show x <> ")"- V4bop b x y -> "(" <> show x <> " " <> b <> " " <> show y <> ")"- V4boppre b x y -> b <> "(" <> show x <> ", " <> show y <> ")"- V4bops b x y -> "(" <> show x <> " " <> b <> " " <> show y <> ")"- V4select b x y -> "( " <> show b <> " ? " <> show x <> " : " <> show y <> ")"- Texture2D t v -> "texture2D(" <> show t <> ", " <> show v <> ")"--instance Num Vec4 where- (+) = vbop "+"- (*) = vbop "*"- negate = vuoppre "-"- abs = vuop "abs"- signum = vuop "sign"- fromInteger = fromVec1 . fromInteger--instance Fractional Vec4 where- (/) = vbop "/"- recip = vbop "/" 1- fromRational = fromVec1 . fromRational---instance Floating Vec4 where- pi = vu "pi"- exp = vuop "exp"- log = vuop "log"- sqrt = vuop "sqrt"- (**) = vboppre "pow"- sin = vuop "sin"- cos = vuop "cos"- tan = vuop "tan"- asin = vuop "asin"- acos = vuop "acos"- atan = vuop "atan"- sinh x = (exp x - exp (negate x))/2- cosh x = (exp x + exp (negate x))/2- tanh x = sinh x / cosh x- asinh x = log $ x + sqrt(x**2 + 1)- acosh x = log $ x + sqrt(x**2 - 1)- atanh x = 0.5 * log ((1 + x)/(1 - x))--instance AdditiveGroup Vec4 where- zeroV = 0- (^+^) = (+)- negateV = negate- (^-^) = (-)--instance VectorSpace Vec4 where- type Scalar Vec4 = Vec1- a *^ b = V4bops "*" a b--instance InnerSpace Vec4 where- (<.>) = Dot--instance HasX Vec4-instance HasY Vec4-instance HasZ Vec4-instance HasW Vec4---data Texture where- Tu :: String -> Texture--instance Show Texture where- show (Tu xs) = xs---- | We implement Bool as a Num--data Booly where- Bu:: String -> Booly- Buop :: String -> Booly -> Booly- Buoppre :: String -> Booly -> Booly- Bbop :: String -> Booly -> Booly -> Booly- Bcomp :: (Vec a) => String -> a -> a -> Booly- Bcomp_ :: String -> Vec1 -> Vec1 -> Booly--instance Show Booly where- show expr = case expr of- Bu x -> x- Buop u x -> u <> "(" <> show x <> ")"- Buoppre u x -> "(" <> u <> show x <> ")"- Bbop u x y -> "(" <> show x <> " " <> u <> " " <> show y <> ")"- Bcomp u x y -> show . product $ zipWith (Bcomp_ u) (toList x) (toList y)- Bcomp_ u x y -> "(" <> show x <> " " <> u <> " " <> show y <> ")"--instance Num Booly where- (+) = Bbop "||"- (*) = Bbop "&&"- negate = Buoppre "!"- abs = id- signum = id- fromInteger x- | x > 0 = Bu "true"- | otherwise = Bu "false"----data GLSLType = GLSLFloat- | GLSLVec2- | GLSLVec3- | GLSLVec4- | GLSLBool- | GLSLTexture- deriving (Generic, Hashable, Eq, Ord)--instance Show GLSLType where- show x = case x of- GLSLFloat -> "float"- GLSLVec2 -> "vec2"- GLSLVec3 -> "vec3"- GLSLVec4 -> "vec4"- GLSLBool -> "bool"- GLSLTexture -> "(texture)" -- this should never be variablized---class (Show a) => Expressible a where- toExpr :: a -> Expr------ TODO: get rid of Vec?, replace with Expr? at least get rid of all the duplicate show statements in my primitives!--data ExprForm = Uniform- | Variable- | UnaryOp- | UnaryOpPre- | BinaryOp- | BinaryOpPre- | TernaryOpPre- | QuaternaryOpPre- | Select- | Access- deriving (Show, Generic, Hashable)---data Tree a = Tree { getElem :: a- , getChildren :: [Tree a]- }- deriving (Functor)--type Expr = Tree (ExprForm, GLSLType, String)--instance Show Expr where- show (Tree (form, _, str) xs) = case form of- Uniform -> str- Variable -> str- UnaryOp -> str <> "(" <> show (xs!!0) <> ")"- UnaryOpPre -> "(" <> str <> show (xs!!0) <> ")"- BinaryOp -> "(" <> show (xs !! 0) <> " " <> str <> " " <> show (xs !! 1) <> ")"- BinaryOpPre -> str <> "(" <> show (xs!!0) <> ", " <> show (xs!!1) <> ")"- TernaryOpPre -> str <> "(" <> show (xs!!0) <> ", " <> show (xs!!1) <> ", " <> show (xs!!2) <> ")"- QuaternaryOpPre -> str <> "(" <> show (xs!!0) <> ", " <> show (xs!!1) <> ", " <> show (xs!!2) <> ", " <> show (xs!!3) <> ")"- Select -> "( " <> show (xs!!0) <> " ? " <> show (xs!!1) <> " : " <> show (xs!!2) <> ")"- Access -> show (xs!!0) <> "." <> str--instance Expressible Vec1 where- toExpr foo = case foo of- Vec1 x -> exprFormFromTuple x foo- V1u str -> Tree (Uniform, ty, str) []- V1uop str x -> Tree (UnaryOp, ty, str) [toExpr x]- V1uoppre str x -> Tree (UnaryOpPre, ty, str) [toExpr x]- V1bop str x y -> Tree (BinaryOp, ty, str) [toExpr x, toExpr y]- V1boppre str x y -> Tree (BinaryOpPre, ty, str) [toExpr x, toExpr y]- V1select b x y -> Tree (Select, ty, "?:") [toExpr b, toExpr x, toExpr y]- Dot x y -> Tree (BinaryOpPre, ty, "dot") [toExpr x, toExpr y]- X x -> Tree (Access, ty, "x") [toExpr x]- Y x -> Tree (Access, ty, "y") [toExpr x]- Z x -> Tree (Access, ty, "z") [toExpr x]- W x -> Tree (Access, ty, "w") [toExpr x]- where- ty = GLSLFloat--instance Expressible Vec2 where- toExpr foo = case foo of- Vec2 x -> exprFormFromTuple x foo- V2u str -> Tree (Uniform, ty, str) []- V2uop str x -> Tree (UnaryOp, ty, str) [toExpr x]- V2uoppre str x -> Tree (UnaryOpPre, ty, str) [toExpr x]- V2bop str x y -> Tree (BinaryOp, ty, str) [toExpr x, toExpr y]- V2boppre str x y -> Tree (BinaryOpPre, ty, str) [toExpr x, toExpr y]- V2bops str x y -> Tree (BinaryOp , ty, str) [toExpr x, toExpr y]- V2select b x y -> Tree (Select, ty, "?:") [toExpr b, toExpr x, toExpr y]- where- ty = GLSLVec2--instance Expressible Vec3 where- toExpr foo = case foo of- Vec3 x -> exprFormFromTuple x foo- V3u str -> Tree (Uniform, ty, str) []- V3uop str x -> Tree (UnaryOp, ty, str) [toExpr x]- V3uoppre str x -> Tree (UnaryOpPre, ty, str) [toExpr x]- V3bop str x y -> Tree (BinaryOp, ty, str) [toExpr x, toExpr y]- V3boppre str x y -> Tree (BinaryOpPre, ty, str) [toExpr x, toExpr y]- V3bops str x y -> Tree (BinaryOp , ty, str) [toExpr x, toExpr y]- V3select b x y -> Tree (Select, ty, "?:") [toExpr b, toExpr x, toExpr y]- where- ty = GLSLVec3--instance Expressible Vec4 where- toExpr foo = case foo of- Vec4 x -> exprFormFromTuple x foo- V4u str -> Tree (Uniform, ty, str) []- V4uop str x -> Tree (UnaryOp, ty, str) [toExpr x]- V4uoppre str x -> Tree (UnaryOpPre, ty, str) [toExpr x]- V4bop str x y -> Tree (BinaryOp, ty, str) [toExpr x, toExpr y]- V4boppre str x y -> Tree (BinaryOpPre, ty, str) [toExpr x, toExpr y]- V4bops str x y -> Tree (BinaryOp , ty, str) [toExpr x, toExpr y]- V4select b x y -> Tree (Select, ty, "?:") [toExpr b, toExpr x, toExpr y]- Texture2D t x -> Tree (BinaryOpPre, ty, "texture2D") [toExpr t, toExpr x]- where- ty = GLSLVec4+module Hylogen.Types ( module Hylogen.Vec+ , module Hylogen.Booly+ , module Hylogen.Texture+ ) where -instance Expressible Booly where- toExpr foo = case foo of- Bu str -> Tree (Uniform, ty, str) []- Buop str x -> Tree (UnaryOp, ty, str) [toExpr x]- Buoppre str x -> Tree (UnaryOpPre, ty, str) [toExpr x]- Bbop str x y -> Tree (BinaryOp, ty, str) [toExpr x, toExpr y]- Bcomp_ str x y -> Tree (BinaryOp, ty, str) [toExpr x, toExpr y]- Bcomp str x y -> toExpr . product $ zipWith (Bcomp_ str) (toList x) (toList y)- where- ty = GLSLBool+import Hylogen.Vec hiding (FloatVec, swizzShow)+import Hylogen.Booly hiding (BoolyType)+import Hylogen.Texture hiding (TextureType) -instance Expressible Texture where- toExpr (Tu str) = Tree (Uniform, ty, str) []- where- ty = GLSLTexture
+ src/Hylogen/Vec.hs view
@@ -0,0 +1,190 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE InstanceSigs #-}+++module Hylogen.Vec where++import GHC.TypeLits+import Data.VectorSpace++import Hylogen.Expr+++data FloatVec (n :: Nat) = FloatVec++type Vec n = Expr (FloatVec n)+type Vec1 = Vec 1+type Vec2 = Vec 2+type Vec3 = Vec 3+type Vec4 = Vec 4++instance ToGLSLType (FloatVec 1) where+ toGLSLType _ = GLSLFloat+ tag = FloatVec+instance ToGLSLType (FloatVec 2) where+ toGLSLType _ = GLSLVec2+ tag = FloatVec+instance ToGLSLType (FloatVec 3) where+ toGLSLType _ = GLSLVec3+ tag = FloatVec+instance ToGLSLType (FloatVec 4) where+ toGLSLType _ = GLSLVec4+ tag = FloatVec++++class (ToGLSLType (FloatVec n), KnownNat n) => Veccable n where+ copy :: Vec1 -> Vec n+ toList :: Vec n -> [Vec1]+++instance Veccable 1 where+ copy = id+ toList x = [x]+instance Veccable 2 where+ copy x = op2pre' "vec2" x x+ toList x = [x ! X, x ! Y]+instance Veccable 3 where+ copy x = op3pre' "vec3" x x x+ toList x = [x ! X, x ! Y, x ! Z]+instance Veccable 4 where+ copy x = op4pre' "vec4" x x x x+ toList x = [x ! X, x ! Y, x ! Z, x ! W]++++instance (Veccable n) => Num (Vec n) where+ (+) = op2' "+"+ (-) = op2' "-"+ (*) = op2' "*"+ abs = op1pre "abs"+ signum = op1pre "sign"+ negate = op1 "-"+ fromInteger x = copy . uniform . show $ (fromInteger x :: Float)+++instance (Veccable n) => Fractional (Vec n) where+ (/) = op2' "/"+ fromRational x = copy . uniform . show $ (fromRational x :: Float)++instance (Veccable n) => Floating (Vec n) where+ -- pi = copy $ uniform "pi"+ pi = copy $ uniform "3.141592653589793238462643383"+ exp = op1pre "exp"+ log = op1pre "log"+ sqrt = op1pre "sqrt"+ (**) = op2pre' "pow"+ sin = op1pre "sin"+ cos = op1pre "cos"+ tan = op1pre "tan"+ asin = op1pre "asin"+ acos = op1pre "acos"+ atan = op1pre "atan"+ sinh x = (exp x - exp (negate x)) / 2+ cosh x = (exp x + exp (negate x))/2+ tanh x = sinh x / cosh x+ asinh x = log $ x + sqrt(x**2 + 1)+ acosh x = log $ x + sqrt(x**2 - 1)+ atanh x = 0.5 * log ((1 + x)/(1 - x))++instance Veccable n => AdditiveGroup (Vec n) where+ zeroV = 0+ (^+^) = (+)+ negateV = negate+ (^-^) = (-)++instance Veccable n => VectorSpace (Vec n) where+ type Scalar (Vec n) = Vec 1+ a *^ b = copy a * b++instance Veccable n => InnerSpace (Vec n) where+ a <.> b = Expr fv (Tree (Op2Pre, GLSLFloat, "dot") (fmap toMono [a, b]))+ where fv = FloatVec :: FloatVec 1+++ +type (>=) x y = (x + 1 <=? y) ~ 'False++class Swizzle a where+ type InputMin a :: Nat+ type OutputDim a :: Nat+ swizzShow :: a -> String++ (!) :: forall n. (Veccable (OutputDim a), n >= InputMin a) => Vec n -> a -> Vec (OutputDim a)+ x ! sw = Expr fv (Tree (Access, toGLSLType fv, swizzShow sw) (fmap toMono [x]))+ where fv = FloatVec :: FloatVec (OutputDim a)++data X = X+instance Swizzle X where+ type InputMin X = 2+ type OutputDim X = 1+ swizzShow _ = "x"++data Y = Y+instance Swizzle Y where+ type InputMin Y = 2+ type OutputDim Y = 1+ swizzShow _ = "y"++data Z = Z+instance Swizzle Z where+ type InputMin Z = 3+ type OutputDim Z = 1+ swizzShow _ = "z"++data W = W+instance Swizzle W where+ type InputMin W = 4+ type OutputDim W = 1+ swizzShow _ = "w"++-- TODO: finish swizzling!+++vec2 :: (Vec1, Vec1) -> Vec2+vec2 (x, y) = op2pre' "vec2" x y+++class ToVec3 tuple where vec3 :: tuple -> Vec3++instance (a ~ Vec m, b ~ Vec (3 - m)) => ToVec3 (a, b) where+ vec3 (x, y) = Expr fv (Tree (Op2Pre, toGLSLType fv, "vec3") [toMono x, toMono y])+ where fv = FloatVec :: FloatVec 3++instance (a ~ Vec1, b ~ Vec1, c ~ Vec1) => ToVec3 (a, b, c) where+ vec3 (x, y, z) = Expr fv (Tree (Op3Pre, toGLSLType fv, "vec3") (fmap toMono [x, y, z]))+ where fv = FloatVec :: FloatVec 3+++class ToVec4 tuple where vec4 :: tuple -> Vec4++instance (a ~ Vec m, b ~ Vec (4 - m)) => ToVec4 (a, b) where+ vec4 (x, y) = Expr fv (Tree (Op2Pre, toGLSLType fv, "vec4") [toMono x,toMono y])+ where fv = FloatVec :: FloatVec 4++instance {-#INCOHERENT#-} (b ~ Vec1, c ~ Vec1) => ToVec4 (Vec2, b, c) where+ vec4 (x, y, z) = Expr fv (Tree (Op3Pre, toGLSLType fv, "vec4") [toMono x,toMono y,toMono z])+ where fv = FloatVec :: FloatVec 4++instance {-#INCOHERENT#-} (a ~ Vec1, c ~ Vec1) => ToVec4 (a, Vec2, c) where+ vec4 (x, y, z) = Expr fv (Tree (Op3Pre, toGLSLType fv, "vec4") [toMono x,toMono y,toMono z])+ where fv = FloatVec :: FloatVec 4++instance {-#INCOHERENT#-} (a ~ Vec1, b ~ Vec1) => ToVec4 (a, b, Vec2) where+ vec4 (x, y, z) = Expr fv (Tree (Op3Pre, toGLSLType fv, "vec4") [toMono x,toMono y,toMono z])+ where fv = FloatVec :: FloatVec 4+++instance (a ~ Vec1, b ~ Vec1, c ~ Vec1, d ~ Vec1) => ToVec4 (a, b, c, d) where+ vec4 (x, y, z, w) = Expr fv (Tree (Op4Pre, toGLSLType fv, "vec4") (fmap toMono [x, y, z, w]))+ where fv = FloatVec :: FloatVec 4
+ src/Hylogen/WithHyde.hs view
@@ -0,0 +1,48 @@+module Hylogen.WithHyde ( module Hylogen.WithHyde+ , module Hylogen+ ) where++import Data.Monoid+import Hylogen+import Hylogen.Expr+import Hylogen.Program (toProgram)++-- TODO: flip these definitions! Normalized means ??+uv :: Vec2+uv = uniform "uv()"++uvN :: Vec2+uvN = uniform "uvN"++time :: Vec1+time = uniform "time"+++resolution :: Vec2+resolution = uniform "resolution"++mouse :: Vec2+mouse = uniform "mouse"+++audio :: Vec4+audio = uniform "audio"++backBuffer :: Texture+backBuffer = uniform "backBuffer"++channel1 :: Texture+channel1 = uniform "channel1"+++-- | No sharing+toGLSL' :: Vec4 -> String+toGLSL' v = unlines [ "void main() {"+ , " gl_FragColor = " <> show v <> ";"+ , "}"+ ]+++-- | sharing via Data.reify+toGLSL :: Vec4 -> String+toGLSL = show . toProgram . toMono