/*=
Introduction to Raydium
100
**/

// About
/**
Well, first of all, let me talk about [[Raydium]] goals: this project
aims to be simple, easy to use, portable, and quite fast.

[[Raydium]] is a C written abstract layer, on top of OpenGL,
and [[GLU]]: this means you can write an entire 3D
application without calling any OpenGL function.
Want to draw an object ? call the suitable [[Raydium]] function,
and all textures and vertices will be loaded, and your object drawn.
Want to make an explosion ? Same thing: call the right function.
Note that you can call OpenGL functions anyway, if necessary.

About portability, I can say a few things: [[Raydium]] was initially
planned for Linux only, but with a "clean" (nearly [[ANSI]]) code,
and, in facts, we have been able to compile Raydium under Visual Studio (Windows)
and mingw with a very few modifications.
So you can expect a correct result on any system providing
OpenGL (at least 1.2), [[GLU]] and a C compiler. Using Raydium as a shared
library (.so or DLL), you can also use C++ language for you own applications

As we ([[CQFD Corp]].) needed a library for our own games, demos,
and... and things like that, and as I was interested by OpenGL,
I starts to write [[Raydium]].

Raydium is perfect for outdoors spaces, integrating a landscape engine,
with suitable physic, supports dynamic lighting, fog, blending, water
and waves, reflections, and more, but also provides everything for indoor,
with radiosity lightmaps for example.

Some other advanced features are available : physics, scripting,
live video, transparent networking, GUI, shaders, ...

This features list will probably grow up during Raydium developpement, see
Raydium website: http://raydium.org/

You'll find, in this document, a list of many functions and possibilities
of [[Raydium]], but if it's your first view of Raydium, you should
start with tutorials ( http://wiki.raydium.org/wiki/RaydiumTutorials ) and
packaged demo programs.

After this short introduction, let's talk about the [[API]] itself,
starting with the main file (from the programmer's point of vue)
of [[Raydium]]: common.c
**/


// Defines
/**
As mentioned above, the file common.c is quite interesting,
for several reasons: first, as this file includes all others [[Raydium]]'s
files, you can have an overview of the whole project, just by looking at this.

It can also be used as a "quick help", since all variables are declared
here, and not in the corresponding files. I mean, for example,
that "##raydium_light_intensity...##" will be declared in common.c,
not in light.c . There's many reasons for using such "style",
but you must only retain that it is simpler for you :)

Ok, after this little disclaimer, we can have a look to the first part
of our file.

After usual #include (nothing interesting here), we find some #defines.

===generic limits===

The first #define block determine limits of your application,
and here you are the actual values for basic defines:
%%(c)
#define RAYDIUM_MAX_VERTICES 500000
#define RAYDIUM_MAX_TEXTURES 256
#define RAYDIUM_MAX_LIGHTS 8
#define RAYDIUM_MAX_NAME_LEN 255
#define RAYDIUM_MAX_OBJECTS 1024
%%

- As you may expect, ##MAX_VERTICES## defines the amount of memory you'll
waste with vertex tables. These tables will contain all loaded objects,
then remember each time you draw something (object),
[[Raydium]] loads it (if not already done). Currently, there is no "delete"
mechanism implemented (except by deleting all objects).
Let me give you a scale: with an Athlon XP1900+, [[GeForce]] 3,
actual [[Raydium]] devel. version 0.31, with around 100 000 vertices,
losts of options (sky, blending, 2 lights, 15 textures, ...),
Raydium renders ~ 45 FPS. Beyond this, a very correct object uses less
than 10 000 vertices. So 500 000 vertices, the actual default,
is quite large. It's also important to talk about memory: Linux is
very efficient on this point, and allocates only "really used" memory.
Under Linux, with the above scene, Raydium used about 20 MB (data only),
instead of "much more" (~ 5x). I haven't made any test about this under
Wir_variable(&scale,RAYDIUM_REGISTER_FLOAT,"force_scale");
        raydium_register_variable(&verbose,RAYDIUM_REGISTER_INT,"verbose");
        raydium_register_variable(&force_face,RAYDIUM_REGISTER_INT,"force_face");
        raydium_file_basename(triname,kmzname);
        strcpy(strrchr(triname,'.'),".tri");
        raydium_php_exec("kmz_2_tri.php");
        raydium_register_variable_unregister_last();
        raydium_register_variable_unregister_last();
        raydium_register_variable_unregister_last();
        raydium_register_variable_unregister_last();
        if (strlen(kmzname))
            {
            if (raydium_ode_element_find("test")!=-1)
                raydium_ode_element_delete_name("test",1);

            raydium_ode_object_box_add("test",0,1,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STATIC,0,triname);
            mode=follow;
            raydium_gui_hide();
            }
        }
}

void gui_main(){

    raydium_gui_theme_load("theme-raydium2.gui");

    if (raydium_gui_window_isvalid(handle=raydium_gui_window_find("info")))
        raydium_gui_window_delete_name("info");
    if (raydium_gui_window_isvalid(handle=raydium_gui_window_find("Model"))){
        char str[RAYDIUM_MAX_NAME_LEN];
            kmz=raydium_gui_check_read(handle,wkmz,str);
            dae=raydium_gui_check_read(handle,wdae,str);
            raydium_gui_window_delete_name("Model");
    }
    raydium_gui_widget_sizes(0,0,16);
    handle=raydium_gui_window_create("info",15,25,70,40);
    {
    int i=0;
    char * infos[]={"Raydium Sketchup to Raydium Converter",
                    "",
                    "1) Sketchup file->export->3D model .kmz format",
                    "",
                    "2) Select name and click Load",
                    "",
                    "3) Converted .tri file and created tga textures",
                    "Are now in your writable directory",
                    "Note: You can specify an output mesh scale",
                    "",0};
    char tmp[4];
        while(infos[i])
            {
            snprintf(tmp,4,"%2.2d",i);
            raydium_gui_label_create(tmp,handle,50,90-i*10,infos[i],0,0,0);
            i++;
            }

    }
    handle=raydium_gui_window_create("Model",45,75,55,25);

    refresh_list(list);

    raydium_gui_widget_sizes(25,4,18);
    raydium_gui_combo_create("list",handle,47,75,list,0);
    raydium_gui_widget_sizes(0,0,18);
    raydium_gui_label_create("Model Name",handle,25,85,"Model Name :",0,0,0);

    raydium_gui_widget_sizes(4,4,18);
    wkmz=raydium_gui_check_create("edtkmz",handle,55,52,".kmz",kmz);
    wdae=raydium_gui_check_create("edtdae",handle,75,52,".dae",dae);

    raydium_gui_check_create("edtVerbose",handle,65,18," Verbose",0);
    
    raydium_gui_check_create("edtTwoSides",handle,10,34," Force Single Face",force_face);

    raydium_gui_widget_sizes(0,0,18);
    raydium_gui_label_create("Scale",handle,28,25,"Scale :",0,0,0);
    raydium_gui_widget_sizes(8,4,18);
    raydium_gui_edit_create("edtScale",handle,42,17,"1.0");

    raydium_gui_widget_sizes(15,5,18);
    raydium_gui_button_create("btnOk",handle,10,50,"Load",loadclick);

    raydium_gui_show();
}


void display(void)
{

if(raydium_key_last==1027)
    exit(0);

if(raydium_mouse_click==2)
    {
    if (mode==menu)
        {
        raydium_gui_hide();
        mode=follow;
        }
    else
        {
        raydium_init_purgemem();
        gui_main();
        raydium_gui_show();
        mode=menu;
        }
    }
if (kmz!=raydium_gui_check_read(handle,wkmz,NULL)){
    refresh_list(list);
    kmz=raydium_gui_check_read(handle,wkmz,NULL);
    gui_main();
}
if (dae!=raydium_gui_check_read(handle,wdae,NULL)){
    refresh_list(list);
    dae=raydium_gui_check_read(handle,wdae,NULL);
    gui_main();
}

raydium_clear_frame();

if (mode==menu)
    raydium_camera_freemove(RAYDIUM_CAMERA_FREEMOVE_FIXED);
else
    raydium_camera_freemove(RAYDIUM_CAMERA_FREEMOVE_NORMAL);

raydium_ode_draw_all(RAYDIUM_ODE_DRAW_NORMAL);

if(raydium_key[GLUT_KEY_F1])
    raydium_ode_draw_all(RAYDIUM_ODE_DRAW_DEBUG);

//raydium_w many textures are loaded,
wich is the current one.

The next variable, ##raydium_texture_filter##, is very important. You can
assign ##RAYDIUM_TEXTURE_FILTER_NONE## (default), ##RAYDIUM_TEXTURE_FILTER_BILINEAR##
or ##RAYDIUM_TEXTURE_FILTER_TRILINEAR## (recommended).
Raydium now support anisotropic filtering with ##RAYDIUM_TEXTURE_FILTER_ANISO##.
Do not change the variable yourself, use the ##raydium_texture_filter_change()##
function instead, it allows the user to override your setting from the
command line (--filer option).

Using no texture filter can gives you higher framerate on old 3D hardware,
but this is quite ugly.

You can activate bilinear filtering without any framerate impact on
most recent video cards, and get a much more attractive rendering.

Trilinear filtering uses Bilinear filtering and MipMaps. A MipMaped
texture is a duplicated texture (3 times, with Raydium), but at different
sizes. A 512x512 texture will generate, for example, a (smoothed)
256x256 texture, and a (smoothed) 128x128 one. Your video card will
use these textures according to distance from POV (point of vue),
reducing flickering effect.

This is on of the best filtering Raydium can use, for a great rendering 
quality. See also anisotropic filter, in Texture chapter of this document.
Good and recent 3D hardware can do trilinear filtering in a single pass,
so it must be the default setting for your application.

About ##raydium_texture_filter## itself: changing this variable will not modify
the rendering, but the way to load textures. It means you can (for example)
use trilinear only for landscape textures, and bilinear for others.
It also means you must reload (erase) a texture to change it's filter.

See (and prefer)  ##raydium_texture_filter_change()## to change the filter.

Note that Raydium will never use trilinear filter with blended (transparent)
textures, for good reasons :)

Let's talk quickly about next (internal) texture variables:
##raydium_texture_blended[]## is a flag table, where each element is
non zero for a blended (RGBA) texture, and 0 for an RGB one.

For Raydium, when a texture does not contain a "bitmap" (texture file,
for example), it contains a plain color, and this color is stored in
##raydium_texture_rgb[][4]## (4 is for RGBA, values between 0 and 1).
You can load an rgb texture with "rgb" keyword. For example, instead of
loading "red.tga", you can load "rgb(0.8,0.1,0.1)".

##raydium_texture_name[]## table simply contains texture filenames.

Last thing, ##raydium_texture_to_replace##,
can be used to erase an already loaded texture.
Set the variable to n, and load a new texture: texture number "n" will be
replaced in memory.

===Projection===

Raydium supports 2 types of projection: ##RAYDIUM_PROJECTION_ORTHO##
(orthographic) and ##RAYDIUM_PROJECTION_PERSPECTIVE##.

First of all, let us point out what "projection" is. Using a "perspective"
projection, closest objects will looks larger than the orthers. It is
typically used in video games (since human eye runs like that),
by opposition to orthographic projection, wich is mostly used by 3D
modeling tools. The principle is simple, discover it by yourself :)

Raydium reads ##raydium_projection## to determine wich method to use.
Each projection is configured with ##raydium_projection_*## variables.
Some of these variables are used both by "perspective" and "orthographic"
projections.

Here is what common.c says:

%%(c)
GLFLOAT RAYDIUM_PROJECTION_FOV; // PERSPECTIVE ONLY
GLFLOAT RAYDIUM_PROJECTION_NEAR; // PERSPECTIVE & ORTHO
GLFLOAT RAYDIUM_PROJECTION_FAR; // PERSPECTIVE & ORTHO
GLFLOAT RAYDIUM_PROJECTION_LEFT; // ORTHO ONLY
GLFLOAT RAYDIUM_PROJECTION_RIGHT; // ORTHO ONLY
GLFLOAT RAYDIUM_PROJECTION_BOTTOM; // ORTHO ONLY
GLFLOAT RAYDIUM_PROJECTION_TOP; // ORTHO ONLY
%%

You've probably noticed that orthographic projection defines a "box"
with your screen: near, far, left, right, bottom. Everything out ouf
this box will never be displayed.

Perspective projection is based on FOV: Field Of Vision, given in degrees.
"near" and "far" are used for many things: Z-Buffer precision is affected,
and clipping too: as with "orthographic", nothing will be displayed beyond
"far", and fog, if enabled, will hide this "limit". This is right for "near",
too, but without fog, obviously :)

Also remember that decreasing FOV will zoom in.

You must call ##raydium_window_view_update()## after any modification on one
(or more) of these variables (see "Window Managment" section for more
information)

===Frame size and color===

##raydium_window_tx## and ##raydium_window_ty## are read-only variables,
providing you actual frame size.

##raydium_background_color[4]## is a RGBA table, and will be used for
frame clearing, and fog color. You can change this variable, and call
respective update functions (frame and fog), or simply use
##raydium_background_color_change(GLfloat r, GLfloat g, GLfloat b, GLfloat a)##.

More informations in corresponding sections.

===Vertices===

Vertices data structure is distributed in 4 parts:

- ##raydium_vertex_*## : these tables will simply contains vertices coordinates

- ##raydium_vertex_normal_*## : vertices normals. Raydium will maintain
two distinct normal tables, and this one will be used for calculations.

- ##raydium_vertex_normal_visu_*## : the other normal table, used for
lighting. Smoothing "visu" normals will provides a better rendering, and Raydium includes
all necessary functions to automate this task.

- ##raydium_vertex_texture_u##, ##*raydium_vertex_texture_v##,
##*raydium_vertex_texture## contains, for each vertex stored
in the vertices data structure, u and v mapping information,
and associated texture number. U and V are texture mapping coordinates.

Raydium can automatically generates some of these data
(normals and uv coords, that is), Read "Vertices" section above
for more information.

PLEASE, do not write directly in these tables, use dedicated functions.

===Objects===

Objects are loaded in Vertices stream, identified by a "start" and an "end"
(##raydium_object_start[]## and ##raydium_object_end[]##) in this stream.
An index is incremented each time you load an object
(##GLuint raydium_object_index##). Filename is also stored in
##raydium_object_name[][]##. Go to "Objects" section to know more.

===Lights===

First of all, ##raydium_light_enabled_tag## contains 0 when light is
disabled, non-zero otherwise. This is a read-only variable, so use
suitable functions.

Currently, for Raydium, a light can have 3 states: on, off, or blinking.
##raydium_light_internal_state[]## stores this.

Next comes all light's features: position, color, intensity. You can
modify directly these variables, and call update fonctions,
if needed (not recommended).

Next, ##raydium_light_blink_*## are used internaly for blinking lights,
setting lowest, higher light intensity, and blinking speed.
Do noy modify these variables, use suitable functions.

You should read the chapter dedicated to lights for more information.

===Fog===

Only one variable, here: ##raydium_fog_enabled_tag##, switching from zero
to non zero if fog is enabled. Do NOT use this variable to enable or
disable fog, but suitable functions, this variable is just a tag.

===Camera===

Since many calls to camera functions are done during one frame,
Raydium must track if any call to these functions was already done,
using ##raydium_frame_first_camera_pass## boolean.

##raydium_camera_pushed##, also used as a boolean, stores stack state.
When you place your camera in the scene with Raydium, it pushes matrix
on top of the stack, so you can modify it (the matrix), placing an object
for example, an restore it quickly after, by popping matrix off.

**/