00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <iostream>
00014 #include <string>
00015 #include <sstream>
00016
00017 #include <sys/time.h>
00018 #include <unistd.h>
00019
00020 #ifndef _GNU_SOURCE
00021 #define _GNU_SOURCE
00022 #endif
00023
00024 #include <getopt.h>
00025
00026 #include "General/Debug.hh"
00027 #include "General/Types.hh"
00028
00029 #include "Math/Matrix.hh"
00030 #include "Math/Vector.hh"
00031 #include "Math/Transform.hh"
00032 #include "Render/Raytracer.hh"
00033
00034 #include "General/Testcases.hh"
00035
00054 static void Render1(Graphics::Screen &Scr, Bool Antialiasing)
00055 {
00056 using namespace World;
00057 const Math::Vector V1(0.0, 0.0, 0.0);
00058 const Math::Vector V2(0.0, 0.0, 1.0);
00059
00060 Scene::Scene S(Camera(V1, V2), ColLib::Black());
00061
00062 const Texture &Plain = TexLib::Plain(
00063 Color(0.2, 0.2, 0.2));
00064
00065 TexLib::Checked Checked = TexLib::Checked();
00066
00067 Material SphereMat(
00068 TexLib::Red(),
00069 TexLib::White(),
00070 TexLib::Black(),
00071 Plain);
00072
00073 Material PlaneMat(
00074 Checked,
00075 TexLib::Black(),
00076 TexLib::Black(),
00077 TexLib::White()
00078 );
00079
00080 S.AddObject(new Sphere(
00081 Math::Vector(0.0, 0.0, 10.0),
00082 1.0,
00083 SphereMat));
00084
00085 S.AddObject(new Plane(
00086 Math::Vector(0.0, 1.0, 0.0),
00087 -1.0,
00088 PlaneMat));
00089
00090 S.AddLight(new PointLight(Math::Vector(3.0, 10.0, 7.0)));
00091 S.AddLight(new AmbientLight(Color(0.05, 0.05, 0.05)));
00092
00093 Render::Raytracer R(S, Antialiasing);
00094
00095 std::cout << "Raytracing with " << S.GetCamera();
00096
00097 R.Render(Scr);
00098 }
00099
00101 static void Render2(Graphics::Screen &Scr, Bool Antialiasing)
00102 {
00103 using namespace World;
00104
00105 const Math::Vector Pos(-2.0, 3.0, -2.0);
00106 const Math::Vector Dir(0.2, -0.3, 1.0);
00107 Scene::Scene S(Camera(Pos, Dir), ColLib::Black());
00108
00109 TexLib::Checked Checked = TexLib::Checked(
00110 ColLib::Black(),
00111 Color(0.8, 0.8, 0.8));
00112
00113 TexLib::Checked Checked2 = TexLib::Checked(
00114 ColLib::Blue(),
00115 ColLib::Red(),
00116 0.2, 0.2);
00117
00118 Material SphereMat = MatLib::Glass();
00119 Material SphereMat2(
00120 Checked2,
00121 TexLib::Black(), TexLib::Black(),
00122 TexLib::Black());
00123
00124 Material PlaneMat(
00125 Checked,
00126 TexLib::Black(),
00127 TexLib::Black(),
00128 TexLib::Black()
00129 );
00130
00131 S.AddObject(new Sphere(
00132 Math::Vector(1.0, 0.0, 8.0),
00133 1.0, SphereMat));
00134
00135 S.AddObject(new Sphere(
00136 Math::Vector(0.0, 0.0, 10.0),
00137 1.0, SphereMat2));
00138
00139 S.AddObject(new Sphere(
00140 Math::Vector(-1.5, 0.0, 8.0),
00141 1.0, SphereMat));
00142
00143 S.AddObject(new Plane(
00144 Math::Vector(0.0, 1.0, 0.0),
00145 -1.0,
00146 PlaneMat));
00147
00148 S.AddLight(new PointLight(Math::Vector(3.0, 10.0, 7.0)));
00149 S.AddLight(new AmbientLight(Color(0.05, 0.05, 0.05)));
00150
00151 Render::Raytracer R(S, Antialiasing);
00152
00153 std::cout << "Raytracing with " << S.GetCamera();
00154
00155 R.Render(Scr);
00156 }
00157
00159 static void RenderFile(Int Width, Int Height,
00160 Bool Antialiasing,
00161 const std::string &SceneFile,
00162 const std::string &OutputFile)
00163 {
00164 using namespace World;
00165 struct timeval A, B;
00166 Scene S;
00167 if (S.ParseFile(SceneFile) == false) {
00168 std::cout
00169 << "Error while parsing file, finishing"
00170 << std::endl;
00171 return;
00172 }
00173
00174 Graphics::Screen Scr(Width, Height);
00175 Render::Raytracer R(S, Antialiasing);
00176
00177 gettimeofday(&A, NULL);
00178 R.Render(Scr);
00179 gettimeofday(&B, NULL);
00180
00181 Double ATime = A.tv_sec + 0.000001 * A.tv_usec;
00182 Double BTime = B.tv_sec + 0.000001 * B.tv_usec;
00183
00184 std::cout << "*** Rendering took "
00185 << BTime - ATime
00186 << " seconds" << std::endl;
00187
00188 Scr.Refresh();
00189 if (OutputFile != "")
00190 Scr.Save(OutputFile);
00191 Scr.EventWait();
00192
00193 }
00194
00196 static void Demo(Int Width, Int Height,
00197 Bool Antialiasing, Int Which, const std::string &Output)
00198 {
00199 std::cout << "*** Rendering demo " << Which << std::endl;
00200
00201 Graphics::Screen Scr(Width, Height);
00202
00203 struct timeval A, B;
00204 gettimeofday(&A, NULL);
00205 switch ((const int)Which) {
00206 case 1: Render1(Scr, Antialiasing);
00207 break;
00208 case 2: Render2(Scr, Antialiasing);
00209 break;
00210 default:
00211 std::cout << "Wrong demo specified. "
00212 << "Possible values: 1, 2" << std::endl;
00213 return;
00214 }
00215 gettimeofday(&B, NULL);
00216
00217 Double ATime = A.tv_sec + 0.000001 * A.tv_usec;
00218 Double BTime = B.tv_sec + 0.000001 * B.tv_usec;
00219
00220 std::cout << "*** Rendering took "
00221 << BTime - ATime
00222 << " seconds" << std::endl;
00223
00224 Scr.Refresh();
00225 if (Output != "")
00226 Scr.Save(Output);
00227 Scr.EventWait();
00228 }
00229
00231 static void Help()
00232 {
00233 using namespace std;
00234 cout
00235 << "Usage: ./blaRAY [-x width] [-y height] [-a] --demo 1|2" << endl
00236 << " ./blaRAY [-x width] [-y height] [-a]"
00237 << " --file <path> --output <path>" << endl
00238 << "List of options:" << endl
00239 << " --scene|-s <filename> - Scene description to render" << endl
00240 << " --demo|-d <num> - Render demo 1 or 2 instead of a file" << endl
00241 << " --output|-o <filename> - Output rendered scene to filename (BMP)" << endl
00242 << " --width|-x <arg> - sets screen width (default:640)" << endl
00243 << " --height|-y <arg> - sets screen height (default:480)" << endl
00244 << " --antialiasing|-a - Turn antialiasing on" << endl
00245 << " --help|-h - Show this help" << endl
00246 << endl
00247 << "blaRAY (C) 2008 by Tomasz bla Fortuna <bla@thera.be>" << endl
00248 << "License: GPLv3 See Docs/LICENSE" << endl;
00249 }
00250
00251 int main(int argc, char **argv)
00252 {
00253 using namespace std;
00254 enum { WIDTH=0, HEIGHT, SCENE, OUTPUT, ANTIALIASING, DEMO, HELP };
00255 static struct {
00256 Int Width;
00257 Int Height;
00258 std::string SceneFile;
00259 std::string OutputFile;
00260 Bool Antialiasing;
00261 Int Demo;
00262 } Configuration = {
00263 640, 480, "", "", false, 0
00264 };
00265
00266 static struct option long_options[] = {
00267 {"width", 1, 0, 0},
00268 {"height", 1, 0, 0},
00269 {"scene", 1, 0, 0},
00270 {"output", 1, 0, 0},
00271 {"antialiasing", 0, 0, 0},
00272 {"demo", 1, 0, 0},
00273 {"help", 0, 0, 0},
00274 {NULL, 0, 0, 0}
00275 };
00276
00277 for (;;) {
00278 int c, index;
00279 c = getopt_long(argc, argv, "x:y:s:o:ad:h",
00280 long_options, &index);
00281 if (c == -1)
00282 break;
00283
00284 switch (c) {
00285 case 0: break;
00286 case 'x': index = WIDTH; break;
00287 case 'y': index = HEIGHT; break;
00288 case 's': index = SCENE; break;
00289 case 'o': index = OUTPUT; break;
00290 case 'a': index = ANTIALIASING; break;
00291 case 'd': index = DEMO; break;
00292 case 'h': index = HELP; break;
00293 }
00294
00295 std::string opt("");
00296 if (optarg) opt = optarg;
00297 stringstream s(opt);
00298
00299 switch (index) {
00300 case WIDTH:
00301 s >> Configuration.Width;
00302 break;
00303 case HEIGHT:
00304 s >> Configuration.Height;
00305 break;
00306 case SCENE:
00307 s >> Configuration.SceneFile;
00308 break;
00309 case OUTPUT:
00310 s >> Configuration.OutputFile;
00311 break;
00312
00313 case ANTIALIASING:
00314 Configuration.Antialiasing = true;
00315 break;
00316
00317 case DEMO:
00318 s >> Configuration.Demo;
00319 break;
00320
00321 case HELP:
00322 Help();
00323 return -1;
00324 }
00325 }
00326
00327 if (Configuration.Demo != 0) {
00328 Demo(Configuration.Width,
00329 Configuration.Height,
00330 Configuration.Antialiasing,
00331 Configuration.Demo,
00332 Configuration.OutputFile);
00333 return 0;
00334 }
00335
00336 if (Configuration.SceneFile == "") {
00337 cout << "ERROR: You must specify scene file to render (or --demo)"
00338 << endl << endl;
00339 Help();
00340 return -1;
00341 }
00342
00343 if (DEBUG)
00344 Testcases::All();
00345
00346
00347 RenderFile(Configuration.Width,
00348 Configuration.Height,
00349 Configuration.Antialiasing,
00350 Configuration.SceneFile,
00351 Configuration.OutputFile);
00352 return 0;
00353 }