]> Git Repo - raytracer.git/blob - main.cpp
stl files now
[raytracer.git] / main.cpp
1 #include <iostream>
2 #include "common.h"
3 #include "geometry.h"
4 #include "constants.h"
5 #include "sdl_funcs.h"
6 #include "objects.h"
7 #include "raytrace.h"
8 #include "vector.h"
9 #include "stl.h"
10 SDL_Event event;
11 struct rgb {
12     char r;
13     char g;
14     char b;
15 };
16 rgb colorC(const color c) {
17     rgb colors;
18     char * arr = (char*)&colors;
19     c.rgb(arr);
20     return colors;
21 }
22 class frame{
23     public:
24     size_t height;
25     size_t width;
26     rgb *framebuffer;
27     frame(size_t height_, size_t width_){
28         framebuffer = (rgb*)sdl_pixels_lock();
29         height = height_;
30         width = width_;
31     }
32     ~frame(){
33         sdl_pixels_unlock();
34     }
35     rgb* operator[](const size_t h) {return framebuffer+h*width; }
36     const rgb* operator[](const size_t h) const {return framebuffer+h*width; }
37 };
38
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));
43 }
44 vec3 rotate(vec3 v, const vec3 k)
45 {
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);
49
50
51     cos_theta = cos(k.y);
52     sin_theta = sin(k.y);
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);
54     
55     cos_theta = cos(k.z);
56     sin_theta = sin(k.z);
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);
58
59     return v;
60 }
61
62 void render(const Objects &spheres, const Lights &lights,const Cam &cam) {
63     const float fov  = cam.fov;
64     #if ANTIALIAS 
65     rgb frame1[SCREEN_HEIGHT+2][SCREEN_WIDTH+2];
66     #endif
67     frame framebuffer(SCREEN_HEIGHT,SCREEN_WIDTH);
68
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));
76             
77             #if ANTIALIAS 
78             frame1[j][i] = framebuffer[j][i];
79             #endif
80         }
81     }
82     #if ANTIALIAS 
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);
98                 color newC(0,0,0);
99                 // corners
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];
104                 // sides
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);
111             }
112         }
113     }
114     #endif
115 }
116
117
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
121    sdl_pixels_unlock();
122    sdl_close(0);
123 }
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.};
130
131     objects ={{
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}*/
137     },{
138         //Triangle{vec3{-3,    0,   -16},vec3{-3,    10,   -17},vec3{ 7,    5,   -18},red_rubber}
139     }
140     };
141
142     lights = {{
143         {{-20, 20,  20}, {1.5,1,1}},
144         {{ 30, 50, -25}, {1,1.8,1}},
145         {{ 30, 20,  30}, {1,1,1.7}}
146     }
147     };
148
149 }
150
151 int main(int argc, char*argv[]) {
152     signal(SIGINT, signal_hand);
153         if( !sdl_init() )
154         {
155                 printf( "Failed to initialize!\n" );
156         exit(-1);
157         }
158
159     Cam cam = {
160         {-1.8,12.2,16.8},
161         {-0.52,-0.30,0.},
162         M_PI_2
163     };
164     std::vector<STL_Triangle> triangles;
165     if(argc == 2)
166         triangles = parsestl(std::string(argv[1]));
167     int winsizeX, winsizeY;
168     Objects objects;
169     Lights lights;
170     create_objects(objects,lights);
171     int xM = 0,yM = 0;
172
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});
176     }
177     while(1){
178
179         SDL_PumpEvents();
180         const Uint8 *keystates = SDL_GetKeyboardState(NULL);
181         while( SDL_PollEvent( &event ) )
182         {      
183             if( event.type == SDL_QUIT )
184                 sdl_close(0);
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};
191             }
192         }
193         if(keystates[SDL_SCANCODE_ESCAPE])
194             signal_hand(0);
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);
209         sdl_frame();
210     }
211     sdl_free();
212     return -2; // We shouldn't get here
213 }
This page took 0.03441 seconds and 4 git commands to generate.