diff --git a/CMakeLists.txt b/CMakeLists.txt index 84d028a..b3a5d0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,4 +16,6 @@ add_executable(Raytracer main.c raytrace.c raytrace.h vectorOp.c - vectorOp.h) + vectorOp.h + interface.c + interface.h) diff --git a/examples.c b/examples.c index f14c2a3..e972ec1 100644 --- a/examples.c +++ b/examples.c @@ -7,22 +7,23 @@ #include "vectorOp.h" #include "raytrace.h" #include +#include "interface.h" -void example_color(int width, int height, int channels, unsigned char *image) { +void example_color(int width, int height, int channels, unsigned char **image) { for (int i = 0; i < height * width; i++) { int step = i *channels; int x = i % width; int y = i / width; - image[step] = 0 + (int)((((double)x)/width) * 255); - image[step+1] = 0 + (int)((((double)y)/width) * 255); - image[step+2] = 0; + (*image)[step] = 0 + (int)((((double)x)/width) * 255); + (*image)[step+1] = 0 + (int)((((double)y)/width) * 255); + (*image)[step+2] = 0; if (channels == 4) { - image[step+3] = 255; + (*image)[step+3] = 255; } } } -void exampleSphere( int width, int height, int channels, unsigned char *image) { +void exampleSphere( int width, int height, int channels, unsigned char **image) { camera cam1; cam1.origin.x = 0; cam1.origin.y = 0; @@ -37,58 +38,21 @@ void exampleSphere( int width, int height, int channels, unsigned char *image) { cam1.height = 1.080; vec3 sphereOrigin = (vec3){0,0,5}; double sphereRadius = 1.0; - sphere obj1 = (sphere){sphereOrigin, sphereRadius}; - sphere **objectList = (sphere **) calloc(4+1, sizeof(sphere*));; + sphere obj1 = (sphere){sphereOrigin, sphereRadius,(RGBA){1,0.5,1,1},0}; + sphere **objectList = (sphere **) calloc(5+1, sizeof(sphere*));; objectList[0] = &obj1; - sphere obj2 = (sphere){vec3Add(sphereOrigin, (vec3){3,0,0}), sphereRadius}; + sphere obj2 = (sphere){vec3Add(sphereOrigin, (vec3){3,0,0}), sphereRadius, (RGBA){1,1,0.5,1},0}; objectList[1] = &obj2; - sphere obj3 = (sphere){vec3Add(sphereOrigin, (vec3){-3,0,0}), sphereRadius}; + sphere obj3 = (sphere){vec3Add(sphereOrigin, (vec3){-2,1,0}), sphereRadius, (RGBA){1,1,1,1},0}; objectList[2] = &obj3; - sphere obj4 = (sphere){vec3Add(sphereOrigin, (vec3){1,1,3}), sphereRadius}; + sphere obj4 = (sphere){vec3Add(sphereOrigin, (vec3){1,1,3}), sphereRadius, (RGBA){0.5,1,1,1},0}; objectList[3] = &obj4; + sphere light1 = (sphere){(vec3){2,1,0}, sphereRadius, (RGBA){1,1,1,1},1}; + objectList[4] = &light1; + int objectCount = 5; - vec3 worldUp = (vec3){0, 1, 0}; - vec3 screenX = vec3Cross(worldUp, cam1.direction); - vec3 screenY = vec3Cross(screenX, cam1.direction); - vec3 screenMiddlePoint = vec3Add(cam1.origin, vec3Scale(cam1.direction, cam1.screenDistance)); - vec3 screenTopLeft = vec3Add( - vec3Add(screenMiddlePoint, - vec3Scale(screenY, -cam1.height/2.0)),///////////////////////////////////////////////////////////////////////////////////////////////////////////////aendern minus weg - vec3Scale(screenX, -cam1.width/2.0) - ); - double pixelStepX = cam1.width / cam1.resolutionX; - 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) - ) - ); + displaySzene(objectList, objectCount, cam1, width, height, channels, image); - ray *lightRay = (ray *)malloc(sizeof(ray));; - lightRay->origin = cam1.origin; - - lightRay->direction = vec3Normalize(vec3Subtract(*pixelOrigin, cam1.origin)); - - pixelColor = raytraceSphere(objectList, 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; - } - } free(objectList); } diff --git a/examples.h b/examples.h index 7fc85b1..ed08ff6 100644 --- a/examples.h +++ b/examples.h @@ -1,2 +1,2 @@ -void example_color(int, int, int, unsigned char *); -void exampleSphere(int, int, int, unsigned char *); \ No newline at end of file +void example_color(int, int, int, unsigned char **); +void exampleSphere(int, int, int, unsigned char **); \ No newline at end of file diff --git a/interface.c b/interface.c new file mode 100644 index 0000000..77106e1 --- /dev/null +++ b/interface.c @@ -0,0 +1,56 @@ +// +// Created by ary on 29.07.2026. +// + +#include "interface.h" +#include "examples.h" +#include "structs.h" +#include "vectorOp.h" +#include "raytrace.h" +#include + +void displaySzene(sphere **objectList, int objectCount, camera cam1, int width, int height, int channels, unsigned char **image) { + const vec3 worldUp = (vec3){0, 1, 0}; + vec3 screenX = vec3Cross(worldUp, cam1.direction); + vec3 screenY = vec3Cross(screenX, cam1.direction); + vec3 screenMiddlePoint = vec3Add(cam1.origin, vec3Scale(cam1.direction, cam1.screenDistance)); + vec3 screenTopLeft = vec3Add( + vec3Add(screenMiddlePoint, + vec3Scale(screenY, -cam1.height/2.0)),///////////////////////////////////////////////////////////////////////////////////////////////////////////////aendern minus weg + vec3Scale(screenX, -cam1.width/2.0) + ); + double pixelStepX = cam1.width / cam1.resolutionX; + 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) + ) + ); + + ray *lightRay = (ray *)malloc(sizeof(ray));; + lightRay->origin = cam1.origin; + + lightRay->direction = vec3Normalize(vec3Subtract(*pixelOrigin, cam1.origin)); + + pixelColor = raytraceSphere(objectList, 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; + } + } +} \ No newline at end of file diff --git a/interface.h b/interface.h new file mode 100644 index 0000000..e55b2c3 --- /dev/null +++ b/interface.h @@ -0,0 +1,4 @@ +#pragma once +#include "structs.h" + +void displaySzene(sphere **objectList, int objectCount, camera cam1, int width, int height, int channels, unsigned char **image); diff --git a/main.c b/main.c index ce5d86d..c74759c 100644 --- a/main.c +++ b/main.c @@ -28,7 +28,7 @@ int main() { //example_color(width, height, channels, image); - exampleSphere(width, height, channels, image); + exampleSphere(width, height, channels, &image); stbi_write_png("C:/Users/ary/CLionProjects/Raytracer/test.png", width, height, channels, image, width * channels); diff --git a/structs.h b/structs.h index d5e515a..6840d4b 100644 --- a/structs.h +++ b/structs.h @@ -14,12 +14,6 @@ struct ray { vec3 direction; }; typedef struct ray ray; -struct sphere { - vec3 origin; - double radius; - double luminance; -}; typedef struct sphere sphere; - struct camera { vec3 origin; vec3 direction; @@ -32,4 +26,11 @@ struct camera { struct rgba { double r, g, b, a; -}; typedef struct rgba RGBA; \ No newline at end of file +}; typedef struct rgba RGBA; + +struct sphere { + vec3 origin; + double radius; + RGBA color; + int isLight; +}; typedef struct sphere sphere; \ No newline at end of file diff --git a/test.png b/test.png index 99add92..10e6154 100644 Binary files a/test.png and b/test.png differ