ixshader-0.0.1.0: README.md
# ixshader
`ixshader` is a shallow embedding of the OpenGL Shading Language in Haskell. It
aims to look as close to actual glsl shader code as possible, while providing
better compile-time safety. Currently writing shader code in `ixshader`'s
`IxShader` monad will catch variable assignment mismatches, multiplication
mismatches and some other common errors. It also builds a description of your
shader at the type level to use downstream during buffering and uniform updates.
Lastly, it abstracts over shader code written for opengl and webgl.
Since this is a work in progress the entire language is not yet supported,
though you can easy use the `nxt` and `acc` functions to push your own glsl into
the pipeline, typechecking only what you want.
The resulting source is pretty and human readable, even debuggable without
sourcemapping.
You should create a separate file for your shaders as `ixshader` relies on
the `RebindableSyntax` language extension and re-defines key functions such as
`>>=`, `>>`, `return`, `fail`, `void`, `fromInteger` and `fromRational`.
## example
```haskell
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module MyShaders where
import Graphics.IxShader
myvertex
:: forall (ctx :: GLContext). HasContext ctx
=> IxShader ctx '[] '[ In Xvec2 "position"
, In Xvec4 "color"
, Uniform Xmat4 "projection"
, Uniform Xmat4 "modelview"
, Out Xvec4 "fcolor"
, Out Xvec4 "gl_Position"
, Main
] ()
myvertex = do
pos <- in_
color <- in_
proj <- uniform_
modl <- uniform_
fcolor <- out_
glPos <- gl_Position
main_ $ do
fcolor .= color
glPos .= proj .* modl .* (pos .: 0.0 .: 1.0)
myfragment
:: forall (ctx :: GLContext). IsGLContext ctx
=> IxShader ctx '[] '[ In Xvec4 "fcolor"
, Out Xvec4 (GLFragName ctx)
, Main
] ()
myfragment = do
fcolor <- in_
glFrag <- gl_FragColor
main_ $ glFrag .= fcolor
main = do
putStrLn "First OpenGL:"
putSrcLn $ vertex @'OpenGLContext
putStrLn "\nThen WebGL:"
putSrcLn $ vertex @'WebGLContext
{-
First OpenGL:
in vec2 position;
in vec4 color;
uniform mat4 projection;
uniform mat4 modelview;
out vec4 fcolor;
void main ()
{ fcolor = color;
gl_Position = projection * modelview * vec4 (position.x, position.y, 0.0, 1.0);
}
Then WebGL:
attribute vec2 position;
attribute vec4 color;
uniform mat4 projection;
uniform mat4 modelview;
varying vec4 fcolor;
void main ()
{ fcolor = color;
gl_Position = projection * modelview * vec4 (position.x, position.y, 0.0, 1.0);
}
-}
```