]> git.tdb.fi Git - libs/math.git/commitdiff
Add a raytracer example program
authorMikko Rasa <tdb@tdb.fi>
Sat, 22 Nov 2014 09:18:34 +0000 (11:18 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 22 Nov 2014 10:37:55 +0000 (12:37 +0200)
.gitignore
Build
examples/raytrace.cpp [new file with mode: 0644]

index 8354f320ca11844fbb4c4849a5d385fee750164d..c773a80a5f65f35bcd83d63165ccab63773acc86 100644 (file)
@@ -3,4 +3,5 @@ temp
 /libmspmath.a
 /libmspmath.so
 /mspmath.pc
+/raytrace
 /tests/test
diff --git a/Build b/Build
index 5e5297d3712333bb0e0338e0b12db659961af620..20875c46e442db491f61bd0ad9b7456041d5603a 100644 (file)
--- a/Build
+++ b/Build
@@ -12,4 +12,11 @@ package "mspmath"
                        map "source" "include/msp";
                };
        };
+
+       program "raytrace"
+       {
+               source "examples/raytrace.cpp";
+               require "mspcore";
+               use "mspmath";
+       };
 };
diff --git a/examples/raytrace.cpp b/examples/raytrace.cpp
new file mode 100644 (file)
index 0000000..2af8653
--- /dev/null
@@ -0,0 +1,92 @@
+#include <msp/core/application.h>
+#include <msp/core/getopt.h>
+#include <msp/core/inttypes.h>
+#include <msp/geometry/loader.h>
+#include <msp/io/buffered.h>
+#include <msp/io/print.h>
+
+using namespace std;
+using namespace Msp;
+
+class RayTracer: public RegisteredApplication<RayTracer>
+{
+private:
+       Geometry::Shape<double, 3> *shape;
+       unsigned width;
+       unsigned height;
+       string filename;
+       UInt8 *pixels;
+
+public:
+       RayTracer(int, char **);
+       virtual ~RayTracer();
+
+       virtual int main();
+private:
+       void load_shape();
+};
+
+
+RayTracer::RayTracer(int argc, char **argv):
+       shape(0),
+       width(500),
+       height(500),
+       pixels(new UInt8[width*height])
+{
+       GetOpt getopt;
+       getopt.add_option('w', "width", width, GetOpt::REQUIRED_ARG);
+       getopt.add_option('h', "height", height, GetOpt::REQUIRED_ARG);
+       getopt.add_argument("filename", filename, GetOpt::REQUIRED_ARG);
+       getopt(argc, argv);
+}
+
+RayTracer::~RayTracer()
+{
+       delete shape;
+       delete[] pixels;
+}
+
+int RayTracer::main()
+{
+       load_shape();
+
+       for(unsigned y=0; y<height; ++y)
+       {
+               double yf = 1.0-y*2.0/height;
+               for(unsigned x=0; x<width; ++x)
+               {
+                       double xf = x*2.0/width-1.0;
+                       Geometry::Ray<double, 3> ray(LinAl::Vector<double, 3>(0, 0, 5), LinAl::Vector<double, 3>(xf, yf, -2));
+                       Geometry::SurfacePoint<double, 3> points[4];
+                       unsigned count = shape->get_intersections(ray, points, 4);
+                       UInt8 *pixel = pixels+y*width+x;
+                       if(count)
+                               *pixel = 255*(0.2+max(dot(points[0].normal, LinAl::Vector<double, 3>(0, 0, 1)), 0.0)*0.8);
+                       else
+                               *pixel = 0;
+               }
+       }
+
+       IO::Buffered cout_buf(IO::cout);
+       IO::print(cout_buf, "P2\n");
+       IO::print(cout_buf, "%d %d\n", width, height);
+       IO::print(cout_buf, "255\n");
+
+       for(unsigned y=0; y<height; ++y)
+       {
+               for(unsigned x=0; x<width; ++x)
+                       IO::print(cout_buf, "%d ", pixels[y*width+x]);
+               IO::print(cout_buf, "\n");
+       }
+
+       return 0;
+}
+
+void RayTracer::load_shape()
+{
+       IO::BufferedFile in(filename);
+       DataFile::Parser parser(in, filename);
+       Geometry::Loader<double, 3> loader;
+       loader.load(parser);
+       shape = loader.get_shape().clone();
+}