ray-tracer

default description
git clone _git@git.tontus.eu/ray-tracer.git
Log | Files | Refs

image_gen.c (3246B)


      1 
      2 #include <stdlib.h>
      3 #include <stdio.h>
      4 #include <float.h>
      5 #include <math.h>
      6 
      7 #include "../include/color.h"
      8 #include "../include/ray.h"
      9 #include "../include/vec3.h"
     10 
     11 /* macros */
     12 #define PI 3.14
     13 
     14 typedef struct {
     15 	float aspect_ratio;
     16 	int image_width;
     17 	float fov;
     18 	vec3 lookfrom, lookat, vup;
     19 	float derfocusangle, focusdist;
     20 
     21 	int image_height;
     22 	vec3 center, pixel_delta_u, pixel_delta_v, pixel00_loc, u, v, w;
     23 	vec3 *output;
     24 } camera;
     25 
     26 #define CAMERADEFAULT {16.0f / 9.0f, 256, 90, {0, 0, -1}, {0, 0, 0}, {0, 1, 0}, 0, 10}
     27 
     28 /* function declarations */
     29 static void print_image(void);
     30 static color ray_color(ray);
     31 static int hit_sphere(point3, double, ray);
     32 static void camera_init(camera *);
     33 static float degtorad(float);
     34 
     35 /* function implementations */
     36 static float
     37 degtorad(float deg)
     38 {
     39 	return (PI * deg / 180.0);
     40 }
     41 
     42 static void
     43 print_image(void)
     44 {
     45 	
     46 }
     47 
     48 static color
     49 ray_color(ray r)
     50 {
     51 	color sphere = {1, 0, 0};
     52 	point3 c = {0, 0, -3};
     53 
     54 	if (hit_sphere(c, 0.5, r)) {
     55 		return sphere;
     56 	}
     57 
     58 	vec3 unit_direction = vec3_unit_vector(r.direction);
     59 	double a = 0.5*(unit_direction.y + 1.0);
     60 
     61 	color col1 = {1, 1, 1};
     62 	color col2 = {0.5, 0.7, 1.0};
     63 
     64 	return vec3_add(vec3_mul(1.0 - a, col1), vec3_mul(a, col2));
     65 }
     66 
     67 static int
     68 hit_sphere(point3 center, double radius, ray r)
     69 {
     70 	vec3 oc = vec3_sub(center, r.origin);
     71 	double a = vec3_dot(r.direction, r.direction);
     72 	double b = -2.0 * vec3_dot(r.direction, oc);
     73 	double c = vec3_dot(oc, oc) - radius*radius;
     74 	double discriminant = b*b - 4*a*c;
     75 
     76 	return (discriminant >= 0);
     77 }
     78 
     79 static void
     80 camera_init(camera *c)
     81 {
     82 	float viewport_height, viewport_width, h;
     83 	vec3 viewport_u, viewport_v, viewport_upper_left;
     84 
     85 	c->image_height = c->image_width / c->aspect_ratio;
     86 	if (c->image_height < 1)
     87 		c->image_height = 1;
     88 
     89 	c->center = c->lookfrom;
     90 
     91 	h = tan(degtorad(c->fov) / 2);
     92 	viewport_height = 2 * h * c->focusdist;
     93 	viewport_width = viewport_height * ((float)c->image_width / c->image_height);
     94 
     95 	c->w = vec3_unit_vector(vec3_sub(c->lookfrom, c->lookat));
     96 	c->u = vec3_unit_vector(vec3_cross(c->vup, c->w));
     97 	c->v = vec3_cross(c->w, c->u);
     98 
     99 	viewport_u = vec3_mul(viewport_width, c->u);
    100 	viewport_v = vec3_mul(viewport_height, vec3_neg(c->v));
    101 	c->pixel_delta_u = vec3_mul(1.0 / c->image_width, viewport_u);
    102 	c->pixel_delta_v = vec3_mul(1.0 / c->image_height, viewport_v);
    103 
    104 	viewport_upper_left = vec3_sub(vec3_sub(vec3_sub(c->center, vec3_mul(c->focusdist, c->w)),
    105 				vec3_mul(0.5, viewport_u)),
    106 			vec3_mul(0.5, viewport_v));
    107 
    108 	c->pixel00_loc =
    109 		vec3_add(viewport_upper_left, vec3_mul(0.5, vec3_add(c->pixel_delta_u, c->pixel_delta_v)));
    110 
    111 }
    112 int
    113 main(int argc, char *argv[])
    114 {
    115 	camera c = CAMERADEFAULT;
    116 	camera_init(&c);
    117 
    118 
    119 	/* render */
    120 	printf("P3\n %i %i \n255\n", c.image_width, c.image_height);
    121 
    122 	for (int j = 0; j < c.image_height; j++) {
    123 		for (int i = 0; i < c.image_width; i++) {
    124 			vec3 pixel_center = vec3_add(
    125 					c.pixel00_loc,
    126 					vec3_add(vec3_mul(i, c.pixel_delta_u), vec3_mul(j, c.pixel_delta_v)));
    127 			vec3 ray_direction = vec3_sub(pixel_center, c.center);
    128 			ray r = {c.center, ray_direction};
    129 
    130 			color pixel_color = ray_color(r); 
    131 			write_color(stdout, pixel_color);
    132 		}
    133 	}
    134 	// vec3_print(stdout, viewport_upper_left);
    135 	// vec3_print(stdout, pixel00_loc);
    136 	return EXIT_SUCCESS;
    137 }