

#ifndef __RT_H__
#define __RT_H__


/*

Lewpen's Realtime Raytracing library


Changelog
-

2003-08-24
  2151 - Added xc, xs, yc, ys to RT_SCENE to hold per-rotation constants

2003-08-25
  2015 - Added size, w2,w3,w4,wm4 to RT_VIEW

*/




#define RT_DEBUG_RENDER_BAR_GRAPHS



#define RT_SCENE_MAXSPHERES 10000
#define RT_SCENE_MAXLIGHTS  10
#define RT_LIGHT_MAP_RES    16

#define RT_OBJ_NONE   0
#define RT_OBJ_SPHERE 1
#define RT_OBJ_PLANE  2
#define RT_OBJ_MESH   3



#define RT_NEAR_PLANE 0.0001f
#define RT_FAR_PLANE  999999.f


#define RT_SUPERPIXEL_SIZE   4




//---- RT_SHERE

typedef struct
{
  float ax, ay, az;  //  Actual position
  float rad;         //  Radius
  int col;

  //  Data for render calculations

  float  x,  y,  z;  //  Transformed position

  float r2, c;       //  Per-frame constants

  int x1, y1, x2, y2;  //  Screen bounding box

  //  As we loop over each pixel in the screen we use these vars to keep a list of the currently available spheres
  // ie the ones which are in both the current horiz list and the current vert list
  // effectively a nice quick bounding box test

  int in_xy;
  int in_prev, in_next;
}
RT_SPHERE;



//---- RT_LIGHT

typedef struct
{
  float ax, ay, az;  //  Actual position
  int col;

  //  Data for render calculations

  float  x,  y,  z;  //  Transformed position

  //  Light maps

  unsigned int map[ 6 ][ RT_LIGHT_MAP_RES * RT_LIGHT_MAP_RES ];
}
RT_LIGHT;



//---- RT_RAY

typedef struct
{
  float ox, oy, oz;
  float dx, dy, dz;

  //- Precalculated values for rendering

  float dx2, dy2, dz2;  //  Squared values of ray direction
  float len2, leno22, len42;  //  Various lengths

  //  Values inserted into ray during intersection test

  float ix, iy, iz, id;  //  Intersection point & distance (in ray units)
  float inx, iny, inz;   //  Intersection normal (unit for spheres)

  unsigned int isphere;  //  Intersected sphere
}
RT_RAY;



//---- RT_SCENE

typedef struct
{
  float rx, ry;          //  Current rotation
  float xc, xs, yc, ys;  //  Per-rotation constants

  //  Spheres in scene

  int numSpheres;
  RT_SPHERE sphere[ RT_SCENE_MAXSPHERES ];

  //  Light sources

  RT_LIGHT light;
}
RT_SCENE;



//---- RT_VIEW

typedef struct
{
  int w, h, size;

  //- The render buffer

  int *buf;

  //- Object, shadow, reflection buffer

  unsigned int *obj;  //  First hit objects
  unsigned int *sob;  //  Shadow objects
  unsigned int *ref;  //  Reflection objects

  //- View box (for calculating rays)

  float bx1, by1, bx2, by2;
  float bdx, bdy;

  //- Various precalculated values

  int w2;   //  Width times 2
  int w3;   //  Width times 3
  int w4;   //  Width times 4
  int wm4;  //  Width minus 4
}
RT_VIEW;



//---- FUNCTIONS -------------------------------------------------------------//



RT_VIEW*  rt_view_create( int w, int h );
void      rt_view_destroy( RT_VIEW *view );

RT_SCENE* rt_scene_create( );
void      rt_scene_destroy( RT_SCENE *scene );

int       rt_scene_sphere( RT_SCENE *scene, float x, float y, float z, float r, int col );
int       rt_scene_light ( RT_SCENE *scene, float x, float y, float z, int col );

void      rt_scene_setRotation( RT_SCENE *scene, float rx, float ry );

bool      rt_sphere_boundingRect( float x, float y, float z, float r, float *bounds );

void      rt_render_area( RT_SCENE *scene, int x1, int y1, int x2, int y2, RT_VIEW *view );
void      rt_render_area_4x4( RT_SCENE *scene, int x1, int y1, int x2, int y2, RT_VIEW *view );

void      rt_render( RT_SCENE *scene, RT_VIEW *view );


void      rt_setPixel( RT_VIEW *view, float x, float y, int col );
void      rt_setPixelAbs( RT_VIEW *view, int x, int y, int col );

void      rt_drawHUD( RT_SCENE *scene, RT_VIEW *view );

void      rt_drawFrameRate( RT_VIEW *view );






#endif
