16 rgb colorC(const color c) {
18 char * arr = (char*)&colors;
27 frame(size_t height_, size_t width_){
28 framebuffer = (rgb*)sdl_pixels_lock();
35 rgb* operator[](const size_t h) {return framebuffer+h*width; }
36 const rgb* operator[](const size_t h) const {return framebuffer+h*width; }
39 double alias[2] = {.25,.5};
40 int threshold[2] = {30,10}; // corners sides
41 inline bool checkT(rgb ca, rgb cb,int t){
42 return ((abs(((int)ca.r)-((int)cb.r)) +abs(((int)ca.g)-((int)cb.g)) + abs(((int)ca.b)-((int)cb.b)) > t*3));
44 vec3 rotate(vec3 v, const vec3 k)
46 double cos_theta = cos(k.x);
47 double sin_theta = sin(k.x);
48 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);
53 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);
57 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);
62 void render(const Objects &spheres, const Lights &lights,const Cam &cam) {
63 const float fov = cam.fov;
65 rgb frame1[SCREEN_HEIGHT+2][SCREEN_WIDTH+2];
67 frame framebuffer(SCREEN_HEIGHT,SCREEN_WIDTH);
69 #pragma omp parallel for
70 for (size_t j = 0; j<SCREEN_HEIGHT; j++) { // actual rendering loop
71 for (size_t i = 0; i<SCREEN_WIDTH; i++) {
72 double dir_x = (i + 0.5) - SCREEN_WIDTH/2.;
73 double dir_y = -(j + 0.5) + SCREEN_HEIGHT/2.; // this flips the image at the same time
74 double dir_z = -SCREEN_HEIGHT/(2.*tan(fov/2.));
75 framebuffer[j][i] = colorC(cast_ray(cam.pos, rotate(vec3{dir_x, dir_y, dir_z},cam.dir).normalize(), spheres, lights));
78 frame1[j][i] = framebuffer[j][i];
83 #pragma omp parallel for
84 for (size_t j = 0; j<SCREEN_HEIGHT; j++) { // actual rendering loop
85 for (size_t i = 0; i<SCREEN_WIDTH; i++) {
86 double dir_x = (i + 0.5) - SCREEN_WIDTH/2.;
87 double dir_y = -(j + 0.5) + SCREEN_HEIGHT/2.; // this flips the image at the same time
88 double dir_z = -SCREEN_HEIGHT/(2.*tan(fov/2.));
89 if(checkT(frame1[j][i],frame1[j+1][i+1],threshold[0])|| \
90 checkT(frame1[j][i],frame1[j-1][i+1],threshold[0])|| \
91 checkT(frame1[j][i],frame1[j-1][i-1],threshold[0])|| \
92 checkT(frame1[j][i],frame1[j+1][i-1],threshold[0])|| \
93 checkT(frame1[j][i],frame1[j][i+1],threshold[1])|| \
94 checkT(frame1[j][i],frame1[j][i-1],threshold[1])|| \
95 checkT(frame1[j][i],frame1[j-1][i],threshold[1])|| \
96 checkT(frame1[j][i],frame1[j+1][i],threshold[1])){
97 //color newC(framebuffer [j][i].r/512.0,framebuffer [j][i].g/512.0,framebuffer [j][i].b/512.0);
100 newC += cast_ray(cam.pos, rotate(vec3{dir_x+0.25, dir_y+0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[0];
101 newC += cast_ray(cam.pos, rotate(vec3{dir_x-0.25, dir_y+0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[0];
102 newC += cast_ray(cam.pos, rotate(vec3{dir_x-0.25, dir_y-0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[0];
103 newC += cast_ray(cam.pos, rotate(vec3{dir_x+0.25, dir_y-0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[0];
105 newC += cast_ray(cam.pos, rotate(vec3{dir_x, dir_y+0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[1];
106 newC += cast_ray(cam.pos, rotate(vec3{dir_x, dir_y-0.25, dir_z},cam.dir).normalize(), spheres, lights)*alias[1];
107 newC += cast_ray(cam.pos, rotate(vec3{dir_x-0.25, dir_y, dir_z},cam.dir).normalize(), spheres, lights)*alias[1];
108 newC += cast_ray(cam.pos, rotate(vec3{dir_x+0.25, dir_y, dir_z},cam.dir).normalize(), spheres, lights)*alias[1];
109 newC /= 3; // .25*4 + .5*4 + .5
110 framebuffer[j][i] = colorC(newC);
118 void signal_hand(int signum) {
119 std::cout << "Caught signal " << signum << std::endl;
120 #pragma omp flush // fix seg fault from open mp accesing sdl doesnt work though
124 void create_objects(Objects& objects ,Lights& lights){
125 const Material ivory = {1.0, {0.6, 0.3, 0.1, 0.0}, {0.4, 0.4, 0.3}, 50.};
126 const Material glass = {1.5, {0.0, 0.5, 0.1, 0.8}, {0.6, 0.7, 0.8}, 125.};
127 const Material red_rubber = {1.0, {0.9, 0.1, 0.0, 0.0}, {0.3, 0.1, 0.1}, 10.};
128 const Material mirror = {1.0, {0.0, 10.0, 0.8, 0.0}, {5.0, 1.0, 1.0}, 1425.};
129 const Material wood = {1.0, {1.2, 0.1, 0.0, 0.0}, {0.2, 0.1, 0.02}, 1.};
132 /*Sphere{vec3{-3, 0, -16}, 2, ivory},
133 Sphere{vec3{-1.0, -1.5, -12}, 2, glass},
134 Sphere{vec3{ 1.5, -0.5, -18}, 3, red_rubber},
135 Sphere{vec3{ 7, 5, -18}, 4, mirror},
136 Sphere{vec3{-3, 10, -17}, 2, wood}*/
138 //Triangle{vec3{-3, 0, -16},vec3{-3, 10, -17},vec3{ 7, 5, -18},red_rubber}
143 {{-20, 20, 20}, {1.5,1,1}},
144 {{ 30, 50, -25}, {1,1.8,1}},
145 {{ 30, 20, 30}, {1,1,1.7}}
151 int main(int argc, char*argv[]) {
152 signal(SIGINT, signal_hand);
155 printf( "Failed to initialize!\n" );
164 std::vector<STL_Triangle> triangles;
166 triangles = parsestl(std::string(argv[1]));
167 int winsizeX, winsizeY;
170 create_objects(objects,lights);
173 const Material default_mat = {1.0, {0.9, 0.1, 0.0, 0.0}, {0.3, 0.1, 0.1}, 10.};
174 for(STL_Triangle t: triangles){
175 objects.triangle.push_back(Triangle{vec3{t.a[0],t.a[2],t.a[1]},vec3{t.c[0],t.c[2],t.c[1]},vec3{t.b[0],t.b[2],t.b[1]},default_mat});
180 const Uint8 *keystates = SDL_GetKeyboardState(NULL);
181 while( SDL_PollEvent( &event ) )
183 if( event.type == SDL_QUIT )
185 if(event.type == SDL_MOUSEMOTION){
186 //SDL_GetMouseState(&,&yM);
187 xM += event.motion.xrel*MOUSE_SENSITIVITY;
188 yM += event.motion.yrel*MOUSE_SENSITIVITY;
189 SDL_GetWindowSize(sdl_getwindow(), &winsizeX,&winsizeY);
190 cam.dir = vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1,0};
193 if(keystates[SDL_SCANCODE_ESCAPE])
195 if(keystates[SDL_SCANCODE_W])
196 cam.pos -= rotate(vec3{0,0,MOVEMENT_SPEED},vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1.,0});
197 if(keystates[SDL_SCANCODE_S])
198 cam.pos += rotate(vec3{0,0,MOVEMENT_SPEED},vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1.,0});
199 if(keystates[SDL_SCANCODE_A])
200 cam.pos -= rotate(vec3{MOVEMENT_SPEED,0,0},vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1.,0});
201 if(keystates[SDL_SCANCODE_D])
202 cam.pos += rotate(vec3{MOVEMENT_SPEED,0,0},vec3{-(yM*M_PI/winsizeX)*1.,-(xM*M_PI/winsizeY)*1.,0});
203 if(keystates[SDL_SCANCODE_SPACE])
204 cam.pos.y += MOVEMENT_SPEED;
205 if(keystates[SDL_SCANCODE_LSHIFT])
206 cam.pos.y -= MOVEMENT_SPEED;
207 render(objects, lights,cam);
208 //SDL_Log("{%lf,%lf,%lf},{%lf,%lf,%lf}",cam.pos.x,cam.pos.y,cam.pos.z,cam.dir.x,cam.dir.y,cam.dir.z);
212 return -2; // We shouldn't get here