10 rgb colorC(const color c) {
12 char * arr = (char*)&colors;
17 double alias[2] = {.25,.5};
18 int threshold[2] = {30,10}; // corners sides
19 inline bool checkT(rgb ca, rgb cb,int t){
20 return ((abs(((int)ca.r)-((int)cb.r)) +abs(((int)ca.g)-((int)cb.g)) + abs(((int)ca.b)-((int)cb.b)) > t*3));
23 vec3 rotate(vec3 v, const vec3 k)
25 double cos_theta = cos(k.x);
26 double sin_theta = sin(k.x);
27 v = (v * cos_theta) + (vec3(1,0,0).cross(v) * sin_theta) + (vec3(1,0,0) * vec3(1,0,0).dot(v)) * (1 - cos_theta);
32 v = (v * cos_theta) + (vec3(0,1,0).cross(v) * sin_theta) + (vec3(0,1,0) * vec3(0,1,0).dot(v)) * (1 - cos_theta);
36 v = (v * cos_theta) + (vec3(0,0,1).cross(v) * sin_theta) + (vec3(0,0,1) * vec3(0,0,1).dot(v)) * (1 - cos_theta);
41 void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights,const Cam &cam) {
42 const float fov = cam.fov;
43 frame framebuffer(SCREEN_HEIGHT,SCREEN_WIDTH);
45 rgb frame1[SCREEN_HEIGHT+2][SCREEN_WIDTH+2];
48 #pragma omp parallel for
49 for (size_t j = 0; j<SCREEN_HEIGHT; j++) { // actual rendering loop
50 for (size_t i = 0; i<SCREEN_WIDTH; i++) {
51 double dir_x = (i + 0.5) - SCREEN_WIDTH/2.;
52 double dir_y = -(j + 0.5) + SCREEN_HEIGHT/2.; // this flips the image at the same time
53 double dir_z = -SCREEN_HEIGHT/(2.*tan(fov/2.));
54 framebuffer[j][i] = colorC(cast_ray(cam.pos, rotate(vec3{dir_x, dir_y, dir_z},cam.dir).normalize(), spheres, lights));
57 frame1[j][i] = framebuffer[j][i];
62 #pragma omp parallel for
63 for (size_t j = 0; j<SCREEN_HEIGHT; j++) { // actual rendering loop
64 for (size_t i = 0; i<SCREEN_WIDTH; i++) {
65 double dir_x = (i + 0.5) - SCREEN_WIDTH/2.;
66 double dir_y = -(j + 0.5) + SCREEN_HEIGHT/2.; // this flips the image at the same time
67 double dir_z = -SCREEN_HEIGHT/(2.*tan(fov/2.));
68 if(checkT(frame1[j][i],frame1[j+1][i+1],threshold[0])|| \
69 checkT(frame1[j][i],frame1[j-1][i+1],threshold[0])|| \
70 checkT(frame1[j][i],frame1[j-1][i-1],threshold[0])|| \
71 checkT(frame1[j][i],frame1[j+1][i-1],threshold[0])|| \
72 checkT(frame1[j][i],frame1[j][i+1],threshold[1])|| \
73 checkT(frame1[j][i],frame1[j][i-1],threshold[1])|| \
74 checkT(frame1[j][i],frame1[j-1][i],threshold[1])|| \
75 checkT(frame1[j][i],frame1[j+1][i],threshold[1])){
76 //color newC(framebuffer [j][i].r/512.0,framebuffer [j][i].g/512.0,framebuffer [j][i].b/512.0);
79 newC += cast_ray(cam.pos, rotate(vec3{dir_x+0.25, dir_y+0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[0];
80 newC += cast_ray(cam.pos, rotate(vec3{dir_x-0.25, dir_y+0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[0];
81 newC += cast_ray(cam.pos, rotate(vec3{dir_x-0.25, dir_y-0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[0];
82 newC += cast_ray(cam.pos, rotate(vec3{dir_x+0.25, dir_y-0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[0];
84 newC += cast_ray(cam.pos, rotate(vec3{dir_x, dir_y+0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[1];
85 newC += cast_ray(cam.pos, rotate(vec3{dir_x, dir_y-0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[1];
86 newC += cast_ray(cam.pos, rotate(vec3{dir_x-0.25, dir_y, dir_z},cam.dir).normalize(), spheres, lights)*alias[1];
87 newC += cast_ray(cam.pos, rotate(vec3{dir_x+0.25, dir_y, dir_z},cam.dir).normalize(), spheres, lights)*alias[1];
88 newC /= 3; // .25*4 + .5*4 + .5
89 framebuffer[j][i] = colorC(newC);
97 void signal_hand(int signum) {
98 std::cout << "Caught signal " << signum << std::endl;
104 int winsizeX, winsizeY;
105 signal(SIGINT, signal_hand);
108 printf( "Failed to initialize!\n" );
112 const Material ivory = {1.0, {0.6, 0.3, 0.1, 0.0}, {0.4, 0.4, 0.3}, 50.};
113 const Material glass = {1.5, {0.0, 0.5, 0.1, 0.8}, {0.6, 0.7, 0.8}, 125.};
114 const Material red_rubber = {1.0, {0.9, 0.1, 0.0, 0.0}, {0.3, 0.1, 0.1}, 10.};
115 const Material mirror = {1.0, {0.0, 10.0, 0.8, 0.0}, {1.0, 1.0, 1.0}, 1425.};
117 std::vector<Sphere> spheres = {
118 Sphere{vec3{-3, 0, -16}, 2, ivory},
119 Sphere{vec3{-1.0, -1.5, -12}, 2, glass},
120 Sphere{vec3{ 1.5, -0.5, -18}, 3, red_rubber},
121 Sphere{vec3{ 7, 5, -18}, 4, mirror}
124 std::vector<Light> lights = {
125 {{-20, 20, 20}, {1.5,1,1}},
126 {{ 30, 50, -25}, {1,1.8,1}},
127 {{ 30, 20, 30}, {1,1,1.7}}
140 const Uint8 *keystates = SDL_GetKeyboardState(NULL);
141 while( SDL_PollEvent( &event ) )
143 if( event.type == SDL_QUIT )
145 if(event.type == SDL_MOUSEMOTION){
146 //SDL_GetMouseState(&,&yM);
147 xM += event.motion.xrel*MOUSE_SENSITIVITY;
148 yM += event.motion.yrel*MOUSE_SENSITIVITY;
149 SDL_GetWindowSize(sdl_getwindow(), &winsizeX,&winsizeY);
150 cam.dir = vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1,0};
153 if(keystates[SDL_SCANCODE_ESCAPE])
155 if(keystates[SDL_SCANCODE_W])
156 cam.pos -= rotate(vec3{0,0,MOVEMENT_SPEED},vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1.,0});
157 if(keystates[SDL_SCANCODE_S])
158 cam.pos += rotate(vec3{0,0,MOVEMENT_SPEED},vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1.,0});
159 if(keystates[SDL_SCANCODE_A])
160 cam.pos -= rotate(vec3{MOVEMENT_SPEED,0,0},vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1.,0});
161 if(keystates[SDL_SCANCODE_D])
162 cam.pos += rotate(vec3{MOVEMENT_SPEED,0,0},vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1.,0});
163 if(keystates[SDL_SCANCODE_SPACE])
164 cam.pos.y += MOVEMENT_SPEED;
165 if(keystates[SDL_SCANCODE_LSHIFT])
166 cam.pos.y -= MOVEMENT_SPEED;
167 render(spheres, lights,cam);
171 return -2; // We shouldn't get here