An open API service indexing awesome lists of open source software.

https://github.com/schell/ixshader

A shallow embedding of the OpenGL Shading Language in Haskell
https://github.com/schell/ixshader

Last synced: about 2 months ago
JSON representation

A shallow embedding of the OpenGL Shading Language in Haskell

Awesome Lists containing this project

README

        

# ixshader
If you're interested in this project please see its spiritual successor
[gristle](https://github.com/schell/gristle), which simplifies the types
involved by removing indexed monads.

`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);
}
-}
```