Basic stuff
===========

GTKstereograph is a user friendly GTK frontend to Stereograph, a stereogram
generator -- also known as a SIS generator (SIS = Single Image Stereogram).
In a few words, a SIS generator produces plane images which can be interpreted
and look like 3D images.

The core program has been written by Fabian Januszewski (the C script
editor/compiler has been contributed by Jean-Pierre Demailly). 

How does Stereograph operates? Well, as follows. Starting from two images,

* a base image, providing information on the shape and distance of the 
  "magic object" to be displayed,
* a texture, giving the output its superficial appearance,

Stereograph combines them into a single output image (performing clever 
anti-aliasing and anti-artefact procedures along the way). These images 
must be in .jpg, .png, .ppm or .tga format. They can be produced by graphic 
tools such as gimp, povray (or with the builtinC script compiler). The base 
image should only use gray scale colors.

As a result of the combination of the base and texture, a 3D stereogram 
is generated. In such a stereogram, the "magic" object is somehow hidden,
although you can see it with bare eyes, after your eyes reach a suitable
position and focus.

The "Load" buttons are used to select the base image and texture, 
respectively. The "Random" buttons provide random selection of images from 
the distributed  SHAREDIR/base and SHAREDIR/textures  subdirectories.

It is also possible to produce stereograms from a user built base and
texture images, rather than from the distributed demo files. This can be 
done e.g. with the builtin editor (accessible via the "Edit" buttons), 
which provides a powerful machinery for writing C scripts and compiling them 
on the fly. A standard C compiler such as gcc is needed for that purpose.


Builtin editor/compiler
=======================

The builtin editor can be used to produce C scripts which are compiled at 
run time to build a base or texture image. This is done by assigning to each
point of coordinates (x,y) in a rectangle x1 <= x <= x2, y1 <= y <= y2, a 
grey-level luminosity value in the rangle 0..765 (765=3*255), in the case 
of base images, or a (red,green,blue) pixel value in the case of textures, 
where 0 <= red, green, blue <= 255 as usual.
  
In the case of base images, the luminosity is calculated mathematically as a
result of the position of all objects present in the scene, and depends
linearly on the value of the third coordinate z, which is viewed as
perpendicular to the Oxy screen plane. The user should thus also specify the
lower and upper values of z. If several objects have parts sharing the same
values of (x,y), only those parts corresponding to the upper layer 
(z maximal) are represented. 
  

Here is a typical C script:

{
   init_graphic_window(720, 600, DIRECT);   /* initialize width, size */
   set_range('x', -2.0, 2.0);               /* set range of variable x */
   set_range('y', -2.0, 2.0);               /* set range of variable y */
   set_range('z', -1.5, 1.5);               /* set range of variable z */

   rotation_angles(34,22,45);               /* rotate object by some angles */
   scale(1.5);                              /* rescale by 1.5 */
   build(octahedron);                       /* call subprogram and build */

   set_grey_levels();                       /* compute grey levels */
}   

(The above script assumes of course that a suitable subprogram
 octahedron(...) has been defined prior to the main program).
In the case of a texture, the last line should normally be replaced by
   set_color_levels();
if one wishes to get colors.


Several position and drawing primitives can be used, in any combination
position primitives -- drawing primitives, 
position primitives -- drawing primitives,
position primitives -- drawing primitives...


Position primitives:
--------------------

1. rotation_angles(double a, double b, double c);

Rotates an object by an angle a with respect to 0xy, b with respect to
0xz and c with respect to 0yz. All angles in degrees.
Default values: a=0, b=0, c=0.

2. scale(double h);
Sets an homothety factor equal to h. All three coordinates x,y,z are 
multiplied by h.
Default value: h=1.

3. translation(double a, double b, double c);

Translates coordinates (x,y,z) by (a,b,c).
Default values: (a,b,c)=(0,0,0).


Drawing primitives:
-------------------

0. max(double x, double y);  min(double x, double y);

standard max and min functions.

1. mesh(point *p, int i, int j, int k);

Here "point" is the predefined type  double[3], and p is an
array of points, e.g.  point p[15], representing 15 points
as triples of coordinates (x,y,z). The above mesh primitive 
draws the 3D-triangle whose vertices are p[i], p[j], p[k].

2. build(BFunction bfunct);

where BFunction is the predefined void function type
typedef void (*BFunction)();

bfunct() is used to define the object, e.g. as a collection of 
triangular meshes, and build(bfunct) makes the actual drawing.

3. graph(PFunction pfunct, double u1, double u2, int nu,
                           double v1, double v2, int nv);

where PFunction is the predefined function type
typedef void  (*PFunction)(point p, double u, double v);

pfunct(p,u,v) assigns to parameters (u,v) a point
       p={x(u,v),y(u,v),z(u,v)}. 
The procedure  graph(pfunct, u1,u2,nu, v1,v2,nv); draws the graph for 
u1 <= u <= u2, v1 <= v <= v2, by using a subdvision in nu subintervals 
for u and nv subintervals for v.

4. light(ZFunction zfunct);

with predefined function type
typedef double (*ZFunction)(double x, double y);

The function zfunct prescribes the depth as  z=zfunct(x,y), and
light(zfunct) assigns the luminosity accordingly. 
NOTE: The position primitives have no effect on the light procedure.

5. put_pixel(x, y, r, g, b);

This puts a pixel value red=r green=g blue=b  at position (x,y) with respect
to the chosen system of coordinates.


Check examples in the SHAREDIR/base/C_scripts and SHAREDIR/textures/C_scripts
subdirectories to see how all this works.

