Multi-threading

} m = exp(m3()'0)

map

} String(m)

exp( ( m3() ' 0 ) )

} String(m)()

map

To improve readability, there is a mode xyzuvt which, when set, replaces the domain components by , surprise, x, y, z, u, v, and t.

} xyzuvt(T)

T

} String(m)

exp( x )

} String(m)()

error 127: identifier unknown x

Of course when calling this string as a function, x has to be defined. Initially doing read( "xyz" )takes care of all of this:

} read("xyz")

xyz = m3();

x = xyz'0;

y = xyz'1;

z = xyz'2;

uv = m2();

u = uv'0;

v = uv'1;

t = m1();

xyzuvt( T );

To have even more fun with this, I introduced differential operators. Each domain has it's own, and they are generated by functions: D1, D2, D3. They are applied by multiplication.

For maps representing a scalar function (Real valued), they can be regarded as gradient. For a vector field (for instance Real3 valued), they are the divergence. http://en.wikipedia.org/wiki/Del

To apply them as curl, use cross product notation: **.

} ma = exp(x) / log(y*z)

map

} dma = D3()*ma

map

} String(dma)

real3( ( ( exp( x ) * log( ( y * z ) ) ) / sqr( log( ( y * z ) ) ) ), ( exp( x ) / sqr( log( ( y * z ) ) ) ), ( exp( x ) / sqr( log( ( y * z ) ) ) ) )

} mb = real3( x^2, sin(y), tan(z) )

map

} dmb = D3()*mb

map

} String(dmb)

( ( 2 * x ) + ( cos( y ) + ( 1 + sqr( tan( z ) ) ) ) )

} mc = real3( log( y * sin(z) ) , exp(z) / cos( x), tan( x*y ) )

map

} String( D3()**mc )

real3( ( ( x * ( 1 + sqr( tan( ( x * y ) ) ) ) ) - ( ( exp( z ) * cos( x ) ) / sqr( cos( x ) ) ) ), ( ( ( y * cos( z ) ) / ( y * sin( z ) ) ) - ( y * ( 1 + sqr( tan( ( x * y ) ) ) ) ) ), ( ( exp( z ) / sqr( cos( x ) ) ) - ( sin( z ) / ( y * sin( z ) ) ) ) )

- a shader program to use, followed by a list of uniform definition pairs.
- a drawable followed by its model transform
- a framebuffer to render to, which will be used as a texture when switching back to normal window rendering (by a list with a single 0)

Look at glalphatest.il for instance.

glrendertotex.il is a framebuffer example. Also notice here how easy it is to do a simple animation by just using a m1 (time) based map in a transform expression.

Other files you can try are: glalphatestI.il for simple mouse interaction, glcubmap(I).il, glcubemap_refract(I).il, gldiscardI.il and gledge.il.

All these examples are based on the book "OpenGL 4.0 Shading Language Cookbook" by David Wolff.

} f = "( log( %1 ) + sin( %1 ) ) / tan( %1 )"

( log( %1 ) + sin( %1 ) ) / tan( %1 )

} f( 5 )

-0.19243

} f(dual(5,1))

-0.19243 - 0.85051 e

} m = f( t )

map

} setmapdom(5.0)

5.0

} evalmap( D1() * m )

-0.85051

}

vr = "real3( normrand(), normrand(), normrand() )";

zr := "cmplx( normrand(), normrand() )";

nzr := "norm( zr() )";

dr = "dual( normrand(), normrand() )";

qr := "quat( normrand(), normrand(), normrand(), normrand() )";

nqr := "norm( qr() )";

nor := "norm( or() )";

dqr = "dualquat( qr(), qr() )";

ndqr = "norm( dqr() )";

} dq = ndqr()

0.52269 0.04899

0.81424-0.009

-0.13412 0.19706

0.21407 0.0381

} conj(dq)

0.52269 0.04899

-0.81424 0.009

0.13412-0.19706

-0.21407-0.0381

} dconj(dq)

0.52269-0.04899

0.81424 0.009

-0.13412-0.19706

0.21407-0.0381

}

A dual quaternion is equivalent to a rigid transformation:

} Transform(dq)

0.87237 -0.4422 0.20841 -0.18378

0.00538 -0.41762 -0.9086 0.15325

0.48882 0.79376 -0.36194 0.33735

0.0 0.0 0.0 1.0

} tt = rotate( 0.5*pi, lx ) * translate( 1,2,3 )

1.0 0.0 0.0 1.0

0.0 0.0 -1.0 -3.0

0.0 1.0 0.0 2.0

0.0 0.0 0.0 1.0

} DualQuat( tt )

0.70711-0.35355

0.70711 0.35355

0.0 -0.35355

0.0 1.7678

}

In il.il a function is defined how to transform with a dual quaternion:

dqtrf = "im( Qe( %1 * DualQuat( %2 ) * conj( dconj( %1 ) ) ) )";

} dq = ndqr()

0.52269 0.04899

0.81424-0.009

-0.13412 0.19706

0.21407 0.0381

} w = vr()

-0.40635

1.7416

-1.1295

} Transform(dq) * w

-1.5438

0.44997

1.93

} dqtrf(dq,w)

-1.5438

0.44997

1.93

}