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 }