diff --git a/examples.c b/examples.c index f86cb1f..3cc3c54 100644 --- a/examples.c +++ b/examples.c @@ -9,6 +9,8 @@ #include #include "interface.h" #include "helper.h" +#include +#include void example_color(int width, int height, int channels, unsigned char **image) { for (int i = 0; i < height * width; i++) { @@ -113,7 +115,11 @@ void exampleCornell( int width, int height, int channels, unsigned char **image) objectList[18] = (object){1, &(makroObj3.quad6), 0}; - + clock_t startTime = clock(); displaySzene(objectList, objectCount, cam1, width, height, channels, image); + clock_t endTime = clock(); + double elapsedTime = (endTime - startTime)/(double)CLOCKS_PER_SEC; + printf("%.3lf\n", elapsedTime); + } diff --git a/interface.c b/interface.c index 8f5850e..80fe812 100644 --- a/interface.c +++ b/interface.c @@ -9,6 +9,57 @@ #include "raytrace.h" #include #include "helper.h" +#include +#define WORKTHREADSIZE 32 + +void* renderPixel(RenderArgs *arg, int pixelId) { + RenderArgs *args = (RenderArgs*)arg; + int step = pixelId * args->channels; + int x = pixelId % args->width; + int y = pixelId / args->width; + RGBA pixelColor; + + vec3 *pixelOrigin = (vec3 *)malloc(sizeof(vec3)); + *pixelOrigin = vec3Add(*args->screenTopLeft, + vec3Add( + vec3Scale(*args->vecPixelStepX, x), + vec3Scale(*args->vecPixelStepY, y) + ) + ); + + ray *lightRay = (ray *)malloc(sizeof(ray));; + lightRay->origin = args->cam1->origin; + + lightRay->direction = vec3Normalize(vec3Subtract(*pixelOrigin, args->cam1->origin)); + + pixelColor = getPixelColor(args->objectList,args->objectCount, lightRay); + free(pixelOrigin); + free(lightRay); + + (*args->image)[step] = (int)(pixelColor.r * 255.0); + (*args->image)[step+1] = (int)(pixelColor.g * 255.0); + (*args->image)[step+2] = (int)(pixelColor.b * 255.0); + if (args->channels == 4) { + (*args->image)[step+3] = 255; + } + return NULL; +} + +void *workerLoop(void *arg) { + RenderArgs *args = (RenderArgs*)arg; + + while (1) { + pthread_mutex_lock(&args->mutexKey); + int pixelId = args->nextPixelId; + args->nextPixelId++; + pthread_mutex_unlock(&args->mutexKey); + + if (pixelId >= args->pixelCount) break; + + renderPixel(args, pixelId); + } + return NULL; +} void displaySzene(object objectList[], int objectCount, camera cam1, int width, int height, int channels, unsigned char **image) { const vec3 worldUp = (vec3){0, 1, 0}; @@ -24,34 +75,26 @@ void displaySzene(object objectList[], int objectCount, camera cam1, int width, double pixelStepY = cam1.height / cam1.resolutionY; vec3 vecPixelStepX = vec3Scale(screenX, pixelStepX); vec3 vecPixelStepY = vec3Scale(screenY, pixelStepY); - for (int i = 0; i < height * width; i++) { - int step = i *channels; - int x = i % width; - int y = i / width; - RGBA pixelColor; - vec3 *pixelOrigin = (vec3 *)malloc(sizeof(vec3)); - *pixelOrigin = vec3Add(screenTopLeft, - vec3Add( - vec3Scale(vecPixelStepX, x), - vec3Scale(vecPixelStepY, y) - ) - ); + pthread_t *threadIdList = (pthread_t *)malloc(sizeof(pthread_t) * WORKTHREADSIZE); - ray *lightRay = (ray *)malloc(sizeof(ray));; - lightRay->origin = cam1.origin; - lightRay->direction = vec3Normalize(vec3Subtract(*pixelOrigin, cam1.origin)); - pixelColor = getPixelColor(objectList,objectCount, lightRay); - free(pixelOrigin); - free(lightRay); - - (*image)[step] = (int)(pixelColor.r * 255.0); - (*image)[step+1] = (int)(pixelColor.g * 255.0); - (*image)[step+2] = (int)(pixelColor.b * 255.0); - if (channels == 4) { - (*image)[step+3] = 255; + RenderArgs *args = (RenderArgs*)malloc(sizeof(RenderArgs)); + *args = (RenderArgs){objectList, objectCount, width, channels, &screenTopLeft, &vecPixelStepX, &vecPixelStepY, &cam1, image, 0, 0,width * height}; + pthread_mutex_init(&args->mutexKey, NULL); + //pthread_t threadId; + for (int i = 0; i < WORKTHREADSIZE; i++) { + pthread_create(&(threadIdList[i]), NULL, workerLoop, args); } + + + //renderPixel(i, objectList, objectCount, width, channels, &screenTopLeft, &vecPixelStepX, &vecPixelStepY, &cam1, image); + + for (int i = 0; i < WORKTHREADSIZE; i++) { + pthread_join(threadIdList[i], NULL); } + pthread_mutex_destroy(&args->mutexKey); + free(threadIdList); + free(args); } \ No newline at end of file diff --git a/raytrace.c b/raytrace.c index 38ac855..c2395c4 100644 --- a/raytrace.c +++ b/raytrace.c @@ -8,7 +8,7 @@ #include #define epsilon 1e-8 #define RAYSPERPIXEL 100 -#define lightBounces 5 +#define lightBounces 6 #define GLOBALILLUMINATION 0.3 enum objectType { SPHERETYPE, diff --git a/structs.h b/structs.h index fb687c1..81d4310 100644 --- a/structs.h +++ b/structs.h @@ -1,4 +1,5 @@ #pragma once +#include struct vec3 { double x, y, z; }; @@ -55,4 +56,20 @@ struct object { struct cube { quad quad1,quad2,quad3,quad4,quad5,quad6; -}; typedef struct cube cube; \ No newline at end of file +}; typedef struct cube cube; + +typedef struct { + //int pixelId; + object *objectList; + int objectCount; + int width; + int channels; + vec3 *screenTopLeft; + vec3 *vecPixelStepX; + vec3 *vecPixelStepY; + camera *cam1; + unsigned char **image; + int nextPixelId; + pthread_mutex_t mutexKey; + int pixelCount; +} RenderArgs; \ No newline at end of file diff --git a/test.png b/test.png new file mode 100644 index 0000000..998e51c Binary files /dev/null and b/test.png differ