rewritten threads with heavy debug information
disabling pthreads library will not be possible any more
#include "raytracer.h"
#include "octree.h"
#include "image.h"
#include "common_sdl.h"
Camera cam;
Light light(Vector3(-2.0, 10.0, -2.0), Colour(0.9, 0.9, 0.9));
Float lx, ly, lz, cf;
/*class CloudTexture: public Texture
{
Vector3 centre;
public:
Colour evaluate(Vector3 point)
{
Float sum = 0.0;
for (int i = 1; i < 5; i++)
sum += fabsf(perlin(point.x*i, point.y*i, point.z*i))/i;
Float value = sinf(point.x + sum)/2 + 0.5;
return Colour(value, value*0.5, value*0.5);
};
};*/
void texture2D(Float u, Float v, Float &r, Float &g, Float &b)
{
// checkers
r = fabs((int)(u*4.2)%2 + (int)(v*4.2)%2 - 1);
g=r; b=r;
}
class PlanarMapTexture: public Texture
{
Vector3 centre;
public:
PlanarMapTexture(Vector3 acentre): centre(acentre) {};
Colour evaluate(Vector3 point)
{
point = point - centre;
Float u = 1000+point.x;
Float v = 1000+point.y;
Float r,g,b;
texture2D(u,v, r,g,b);
return Colour(r, g, b);
};
};
class CubicMapTexture: public Texture
{
Vector3 centre;
public:
CubicMapTexture(Vector3 acentre): centre(acentre) {};
Colour evaluate(Vector3 point)
{
point = point - centre;
Float u,v;
if (fabs(point.x) > fabs(point.y))
{
if (fabs(point.x) > fabs(point.z))
{
if (point.x < 0)
u = -point.y;
else
u = point.y;
v = point.z;
}
else
{
if (point.z < 0)
u = -point.x;
else
u = point.x;
v = point.y;
}
}
else
{
if (fabs(point.y) > fabs(point.z))
{
if (point.y < 0)
u = -point.x;
else
u = point.x;
v = point.z;
}
else
{
if (point.z < 0)
u = -point.x;
else
u = point.x;
v = point.y;
}
}
u += 1000;
v += 1000;
Float r,g,b;
texture2D(u,v, r,g,b);
return Colour(r, g, b);
};
};
class CylinderMapTexture: public Texture
{
Vector3 centre;
public:
CylinderMapTexture(Vector3 acentre): centre(acentre) {};
Colour evaluate(Vector3 point)
{
point = point - centre;
Float u,v;
v = 1000+point.y;
u = M_PI + atan2(point.z, point.x);
Float r,g,b;
texture2D(u,v, r,g,b);
return Colour(r, g, b);
};
};
class SphereMapTexture: public Texture
{
Vector3 centre;
public:
SphereMapTexture(Vector3 acentre): centre(acentre) {};
Colour evaluate(Vector3 point)
{
point = point - centre;
Float u,v;
v = acos(point.y / point.mag());
u = M_PI + atan2(point.z, point.x);
Float r,g,b;
texture2D(u,v, r,g,b);
return Colour(r, g, b);
};
};
void update_callback()
{
if (lx != 0.0)
light.pos.x += lx;
if (ly != 0.0)
light.pos.y += ly;
if (lz != 0.0)
light.pos.z += lz;
if (cf != 0.0)
cam.f += cf;
}
void key_callback(int key, int down)
{
switch (key)
{
case SDLK_r:
lx = -0.1 * down;
break;
case SDLK_t:
lx = +0.1 * down;
break;
case SDLK_f:
ly = -0.1 * down;
break;
case SDLK_g:
ly = +0.1 * down;
break;
case SDLK_v:
lz = -0.1 * down;
break;
case SDLK_b:
lz = +0.1 * down;
break;
case SDLK_z:
cf = -0.02 * down;
break;
case SDLK_x:
cf = +0.02 * down;
break;
}
}
int main(int argc, char **argv)
{
Raytracer rt;
Octree top;
rt.setTop(&top);
rt.addlight(&light);
light.castShadows(false);
Material mat0a(Colour(0.7, 0.7, 0.7));
mat0a. setReflectivity(0.0);
Box box(Vector3(-12.0, -1.2, -20.0), Vector3(12.0, -1.0, 0.0), &mat0a);
rt.addshape(&box);
Material mat0b(Colour(0.1, 0.7, 0.8));
mat0b.setReflectivity(0.7);
Box box2(Vector3(-12.0, -1.2, -10.0), Vector3(12.0, 10.0, -10.2), &mat0b);
rt.addshape(&box2);
// spheres
Material mat1(Colour(1.0, 1.0, 1.0));
mat1.texture = new PlanarMapTexture(Vector3(4.0, 2.0, -7.0));
Sphere sphere1(Vector3(4.0, 2.0, -7.0), 1.0, &mat1);
rt.addshape(&sphere1);
Material mat2(Colour(1.0, 1.0, 1.0));
mat2.texture = new CubicMapTexture(Vector3(1.0, 2.0, -7.0));
Sphere sphere2(Vector3(1.0, 2.0, -7.0), 1.0, &mat2);
rt.addshape(&sphere2);
Material mat3(Colour(1.0, 1.0, 1.0));
mat3.texture = new CylinderMapTexture(Vector3(-2.0, 2.0, -7.0));
Sphere sphere3(Vector3(-2.0, 2.0, -7.0), 1.0, &mat3);
rt.addshape(&sphere3);
Material mat4(Colour(1.0, 1.0, 1.0));
mat4.texture = new SphereMapTexture(Vector3(-5.0, 2.0, -7.0));
Sphere sphere4(Vector3(-5.0, 2.0, -7.0), 1.0, &mat4);
rt.addshape(&sphere4);
// cubes
Material mat5(Colour(1.0, 1.0, 1.0));
mat5.texture = new PlanarMapTexture(Vector3(4.0, 0.0, -7.0));
Box cube1(Vector3(4.0, 0.0, -7.0)-1.0, Vector3(4.0, 0.0, -7.0)+1.0, &mat5);
rt.addshape(&cube1);
Material mat6(Colour(1.0, 1.0, 1.0));
mat6.texture = new CubicMapTexture(Vector3(1.0, 0.0, -7.0));
Box cube2(Vector3(1.0, 0.0, -7.0)-1.0, Vector3(1.0, 0.0, -7.0)+1.0, &mat6);
rt.addshape(&cube2);
Material mat7(Colour(1.0, 1.0, 1.0));
mat7.texture = new CylinderMapTexture(Vector3(-2.0, 0.0, -7.0));
Box cube3(Vector3(-2.0, 0.0, -7.0)-1.0, Vector3(-2.0, 0.0, -7.0)+1.0, &mat7);
rt.addshape(&cube3);
Material mat8(Colour(1.0, 1.0, 1.0));
mat8.texture = new SphereMapTexture(Vector3(-5.0, 0.0, -7.0));
Box cube4(Vector3(-5.0, 0.0, -7.0)-1.0, Vector3(-5.0, 0.0, -7.0)+1.0, &mat8);
rt.addshape(&cube4);
mat1.setReflectivity(0);
mat2.setReflectivity(0);
mat3.setReflectivity(0);
mat4.setReflectivity(0);
mat5.setReflectivity(0);
mat6.setReflectivity(0);
mat7.setReflectivity(0);
mat8.setReflectivity(0);
top.optimize();
cam.setEye(Vector3(-0.530505, 11.0964, 11.2208));
cam.p = Vector3(-4.18144e-08, -0.461779, -0.886995);
cam.u = Vector3(-1, 0, 6.3393e-11);
cam.v = Vector3(3.19387e-08, 0.886995, -0.461779);
rt.setCamera(&cam);
w = 1024;
h = 600;
/* run interactive mode */
loop_sdl(rt, cam, update_callback, key_callback);
/* render image */
if (argc == 2 && !strcmp(argv[1], "-r"))
{
pyrit_verbosity = 2;
Float *fdata = (Float *) malloc(w*h*3*sizeof(Float));
rt.ambientocclusion(300, 5.0, 0.5);
DefaultSampler sampler(fdata, w, h);
sampler.setOversample(2);
sampler.setSubsample(1);
rt.setSampler(&sampler);
rt.render();
struct image *img;
new_image(&img, w, h, 3);
Float *fd = fdata;
for (char *cd = img->data; cd != img->data + w*h*3; cd++, fd++) {
if (*fd > 1.0)
*cd = 255;
else
*cd = (unsigned char)(*fd * 255.0);
}
free(fdata);
save_png("textures.png", img);
destroy_image(&img);
}
}