Files
GTSchoolShit/CS4451/proj1/proj1.cpp
2025-06-07 01:59:34 -04:00

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;
}