PageRenderTime 63ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/main.cpp

https://github.com/Lykathia/raytracer
C++ | 186 lines | 144 code | 16 blank | 26 comment | 37 complexity | 2c676cd437d11d8b51186091b830ede6 MD5 | raw file
  1. #include <cstdlib>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cassert>
  5. #include <cmath>
  6. #include <vector>
  7. #include <cfloat> // FLT_MAX
  8. #include <iostream>
  9. #include <malloc.h>
  10. #include <stdint.h>
  11. #include <png.h> //libpng
  12. using namespace std;
  13. #include "image_png.h"
  14. #include "raytracer.h"
  15. #include "light.h"
  16. #include "scene_parser.h"
  17. #include "image.h"
  18. #include "vectors.h"
  19. #include "camera.h"
  20. #include "ray.h"
  21. #include "hit.h"
  22. #include "group.h"
  23. #include "material.h"
  24. float clamp(float a)
  25. {
  26. if(a > 1.0f)
  27. return 1.0f;
  28. else if(a < 0.0f)
  29. return 0.0f;
  30. else
  31. return a;
  32. }
  33. /*void run(const size_t threads, vector<std::function<void()> > &tasks)
  34. {
  35. boost::thread_group group;
  36. const size_t taskCount = (tasks.size() / threads) + 1;
  37. for(size_t i = 0; i < tasks.size(); i+=taskCount)
  38. {
  39. group.create_thread([&tasks, i, taskCount]()
  40. {
  41. const size_t end = min(tasks.size(), i+taskCount);
  42. for(size_t j = i; j<end; ++j)
  43. tasks[j]();
  44. });
  45. }
  46. group.join_all();
  47. }*/
  48. int main(int argc, char * argv[])
  49. {
  50. char *input_file = NULL;
  51. int width = 100;
  52. int height = 100;
  53. char *output_file = NULL;
  54. float depth_min = 0;
  55. float depth_max = 1;
  56. char *depth_file = NULL;
  57. char *normal_file = NULL;
  58. bool shade_back = false;
  59. bool shadows = true;
  60. float weight = 1;
  61. int bounces = 0;
  62. for (int i = 1; i < argc; i++)
  63. {
  64. if (!strcmp(argv[i],"-input")) {
  65. i++; assert (i < argc);
  66. input_file = argv[i];
  67. }
  68. else if (!strcmp(argv[i],"-size")) {
  69. i++; assert (i < argc);
  70. width = atoi(argv[i]);
  71. i++; assert (i < argc);
  72. height = atoi(argv[i]);
  73. }
  74. else if (!strcmp(argv[i],"-output")) {
  75. i++; assert (i < argc);
  76. output_file = argv[i];
  77. }
  78. else if (!strcmp(argv[i],"-depth")) {
  79. i++; assert (i < argc);
  80. depth_min = atof(argv[i]);
  81. i++; assert (i < argc);
  82. depth_max = atof(argv[i]);
  83. i++; assert (i < argc);
  84. depth_file = argv[i];
  85. }
  86. else if(!strcmp(argv[i],"-normals")){
  87. i++; assert(i<argc);
  88. normal_file = argv[i];
  89. }
  90. else if(!strcmp(argv[i],"-shade_back")){
  91. shade_back = true;
  92. }
  93. else if(!strcmp(argv[i],"-bounces")){
  94. i++; assert(i<argc);
  95. bounces = atoi(argv[i]);
  96. }
  97. else if(!strcmp(argv[i],"-weight")){
  98. i++; assert(i<argc);
  99. weight = atof(argv[i]);
  100. }
  101. else if(!strcmp(argv[i],"-noshadow")){
  102. shadows=false;
  103. }
  104. else {
  105. printf ("whoops error with command line argument %d: '%s'\n",i,argv[i]);
  106. assert(0);
  107. }
  108. }
  109. // Define Image Files
  110. png img(width, height);
  111. png img_depth(width, height);
  112. png img_normal(width, height);
  113. // Read input file
  114. SceneParser *s = new SceneParser(input_file);
  115. Camera *c = s->getCamera();
  116. Group *g = s->getGroup();
  117. // Set output files
  118. bool out=false, depthout=false, normout=false;
  119. if(output_file != NULL)
  120. out = true;
  121. if(depth_file != NULL)
  122. depthout = true;
  123. if(normal_file != NULL)
  124. normout = true;
  125. /*vector<std::function<void()> > tasks(height);*/
  126. // Main loop
  127. for(int i=0;i<width;i++) {
  128. for(int j=0;j<height;j++)
  129. {
  130. float xi = (float)i / width;
  131. float yj = (float)j / height;
  132. Vec2f p(xi,yj); //0,0 to 1,1
  133. Ray r = c->generateRay(p);
  134. Hit h(FLT_MAX, NULL, Vec3f(0,0,0)); // The object hit
  135. float tmin = c->getTMin();
  136. RayTracer t(s, bounces, shadows, shade_back);
  137. /*tasks.push_back([&img,t,i,j,p,width,height]()
  138. {*/
  139. //Vec3f cc = t.castRay(r,h,tmin,0,1); // comment out for anti-aliasing
  140. Vec3f cc = t.antiAlias(p, float(width), float(height)); // comment out for no AA
  141. img.setPixel(i,j,cc);
  142. /*});*/
  143. //if(debugg)
  144. {
  145. Hit hh(FLT_MAX, NULL, Vec3f(0,0,0)); // The object hit
  146. g->intersect(r,hh,tmin);
  147. if(hh.getMaterial() != NULL)
  148. {
  149. Vec3f n = hh.getNormal();
  150. if(depthout) {
  151. float dc = clamp((depth_max-hh.getT()) / (depth_max-depth_min)); // depth colour
  152. img_depth.setPixel(i,j,Vec3f(dc,dc,dc));
  153. }
  154. if(normout) {
  155. n.Set(abs(n.x()), abs(n.y()), abs(n.z())); //positive or negative
  156. img_normal.setPixel(i,j,n);
  157. }
  158. }
  159. }
  160. }
  161. }
  162. // Save the image
  163. if(out)
  164. img.render(output_file);
  165. if(depthout)
  166. img_depth.render(depth_file);
  167. if(normout)
  168. img_normal.render(normal_file);
  169. return 0;
  170. }