/* put your name here, just in case **** Project 1: Ray Tracing CS4451A, Spring 2005 */ #include #include #include #include #include "defs.h" #include "functions.h" #include #include #include /* ------------- Main ------------ */ static void DoRayTraceST(RayTracer &tracer, image &img) { //RayTracer tracer; for (int x = 0; x < tracer.m; x++) { for (int y = 0; y < tracer.n; y++) { RGB& pix = img.pixel(x, y); tracer.getPixelAt(x, y, pix); } } } static void DoRayTraceMT(RayTracer& tracer, image& img) { static mutex lock; static int currentColumn; currentColumn = 0; auto threadFunc = [&]() { int x = 0; while (true) { lock.lock(); x = currentColumn; currentColumn++; lock.unlock(); if (!(x < tracer.m)) break; for (int y = 0; y < tracer.n; y++) { RGB& pix = img.pixel(x, y); tracer.getPixelAt(x, y, pix); } } ; }; const auto threadCount = std::thread::hardware_concurrency(); std::vector threads; threads.reserve(threadCount); for (unsigned int i = 0; i < threadCount; i++) { threads.push_back(std::thread(threadFunc)); } for (auto& t : threads) { t.join(); } } int main (int argc, char **argv ) { using namespace std; /* First, get the necessary data */ RayTracer tracer; /* Begin scanning the input assuming 80 column lines */ char* input = (char*)malloc(sizeof(char) * 81); char* pEnd; //Get m and n cin.getline(input, 81); tracer.m = strtol(input, &pEnd, 10); tracer.n = strtol(pEnd,NULL,10); //Get e scanInput(tracer.e,input); //Get l scanInput(tracer.l,input); //Get h scanInput(tracer.h,input); //Get v scanInput(tracer.v,input); //Get Light scanInput(tracer.light,input); //Get ambient light level cin.getline(input,81); tracer.ambience = strtod(input, NULL); //Get Primitives cin.getline(input,81); tracer.numPrimitives = strtol(input,NULL,10); scanInput(tracer.primitives,tracer.numPrimitives, input); /* ------------ Do the actual raytracing ---------------- */ image img(tracer.m,tracer.n); auto start = std::chrono::high_resolution_clock::now(); if (true || argc > 1) { cerr << "Starting MT ray trace." << std::endl; DoRayTraceMT(tracer, img); } else { cerr << "Starting ST ray trace." << std::endl; DoRayTraceST(tracer, img); } auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration diff = end - start; cerr << "Time to generate image: " << diff.count() * 1000 << " ms." << std::endl; /* dump the image to standard output */ cout << img; return 0; }