137 lines
3.1 KiB
C++
137 lines
3.1 KiB
C++
|
|
/*
|
|
put your name here, just in case ****
|
|
Project 1: Ray Tracing
|
|
CS4451A, Spring 2005
|
|
*/
|
|
|
|
#include <math.h>
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
|
|
#include <vector>
|
|
|
|
#include "defs.h"
|
|
#include "functions.h"
|
|
|
|
#include <thread>
|
|
#include <mutex>
|
|
#include <chrono>
|
|
|
|
/* ------------- 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<std::thread> 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<double> diff = end - start;
|
|
cerr << "Time to generate image: " << diff.count() * 1000 << " ms." << std::endl;
|
|
|
|
/* dump the image to standard output */
|
|
cout << img;
|
|
return 0;
|
|
|
|
}
|