Normalise indentation (spaces vs tabs)
This commit is contained in:
parent
c02be0fa2f
commit
e00649fc05
1 changed files with 253 additions and 253 deletions
506
tinyray.c
506
tinyray.c
|
@ -18,61 +18,61 @@ typedef unsigned char byte;
|
|||
|
||||
/* Minimal Floating Point Vector Maths - Author: Matthew Jakeman */
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} Vec3;
|
||||
|
||||
Vec3 vec3_new(float x, float y, float z) {
|
||||
Vec3 vec;
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
return vec;
|
||||
Vec3 vec;
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
Vec3 vec3_add(Vec3 a, Vec3 b) {
|
||||
return vec3_new(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
return vec3_new(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
}
|
||||
|
||||
Vec3 vec3_subtract(Vec3 a, Vec3 b) {
|
||||
return vec3_new(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
return vec3_new(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
}
|
||||
|
||||
Vec3 vec3_subtract_scalar(Vec3 a, float b) {
|
||||
return vec3_new(a.x - b, a.y - b, a.z - b);
|
||||
return vec3_new(a.x - b, a.y - b, a.z - b);
|
||||
}
|
||||
|
||||
Vec3 vec3_divide_scalar(Vec3 a, float b) {
|
||||
return vec3_new(a.x/b, a.y/b, a.z/b);
|
||||
return vec3_new(a.x/b, a.y/b, a.z/b);
|
||||
}
|
||||
|
||||
Vec3 vec3_multiply(Vec3 a, Vec3 b) {
|
||||
return vec3_new(a.x*b.x, a.y*b.y, a.z*b.z);
|
||||
return vec3_new(a.x*b.x, a.y*b.y, a.z*b.z);
|
||||
}
|
||||
|
||||
Vec3 vec3_multiply_scalar(Vec3 a, float b) {
|
||||
return vec3_new(a.x*b, a.y*b, a.z*b);
|
||||
return vec3_new(a.x*b, a.y*b, a.z*b);
|
||||
}
|
||||
|
||||
float vec3_dot(Vec3 a, Vec3 b) {
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
float vec3_len(Vec3 v) {
|
||||
return (float)sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
|
||||
return (float)sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
|
||||
}
|
||||
|
||||
Vec3 vec3_normalise(Vec3 v) {
|
||||
return vec3_divide_scalar(v, vec3_len(v)); // Calculate unit vector
|
||||
return vec3_divide_scalar(v, vec3_len(v)); // Calculate unit vector
|
||||
}
|
||||
|
||||
Vec3 vec3_clamp(Vec3 v, float min_value, float max_value) {
|
||||
return vec3_new(
|
||||
fmin(fmax(v.x, min_value), max_value),
|
||||
fmin(fmax(v.y, min_value), max_value),
|
||||
fmin(fmax(v.z, min_value), max_value)
|
||||
);
|
||||
return vec3_new(
|
||||
fmin(fmax(v.x, min_value), max_value),
|
||||
fmin(fmax(v.y, min_value), max_value),
|
||||
fmin(fmax(v.z, min_value), max_value)
|
||||
);
|
||||
}
|
||||
// END - vectors
|
||||
|
||||
|
@ -80,32 +80,32 @@ Vec3 vec3_clamp(Vec3 v, float min_value, float max_value) {
|
|||
typedef Vec3 RgbColour;
|
||||
|
||||
typedef struct {
|
||||
RgbColour diffuse;
|
||||
float specular;
|
||||
RgbColour diffuse;
|
||||
float specular;
|
||||
} Material;
|
||||
|
||||
typedef struct {
|
||||
Vec3 centre;
|
||||
float radius;
|
||||
Material material;
|
||||
Vec3 centre;
|
||||
float radius;
|
||||
Material material;
|
||||
} Sphere;
|
||||
|
||||
typedef struct {
|
||||
Vec3 origin;
|
||||
Vec3 direction;
|
||||
Vec3 origin;
|
||||
Vec3 direction;
|
||||
} Ray;
|
||||
|
||||
typedef enum {
|
||||
PointLight,
|
||||
DirectionalLight,
|
||||
AmbientLight
|
||||
PointLight,
|
||||
DirectionalLight,
|
||||
AmbientLight
|
||||
} LightType;
|
||||
|
||||
typedef struct {
|
||||
LightType type;
|
||||
Vec3 position; // point only
|
||||
Vec3 direction; // directional only
|
||||
float intensity;
|
||||
LightType type;
|
||||
Vec3 position; // point only
|
||||
Vec3 direction; // directional only
|
||||
float intensity;
|
||||
} Light;
|
||||
|
||||
/* Globals */
|
||||
|
@ -118,48 +118,48 @@ const static unsigned int HEIGHT = 600;
|
|||
|
||||
/* Constructors */
|
||||
Sphere sphere_new(Vec3 centre, float radius, Material material) {
|
||||
Sphere sphere = {0};
|
||||
sphere.centre = centre;
|
||||
sphere.radius = radius;
|
||||
sphere.material = material;
|
||||
return sphere;
|
||||
Sphere sphere = {0};
|
||||
sphere.centre = centre;
|
||||
sphere.radius = radius;
|
||||
sphere.material = material;
|
||||
return sphere;
|
||||
}
|
||||
|
||||
Light light_point_new(float intensity, Vec3 position) {
|
||||
Light light = {0};
|
||||
light.type = PointLight;
|
||||
light.position = position;
|
||||
light.intensity = intensity;
|
||||
return light;
|
||||
Light light = {0};
|
||||
light.type = PointLight;
|
||||
light.position = position;
|
||||
light.intensity = intensity;
|
||||
return light;
|
||||
}
|
||||
|
||||
Light light_ambient_new(float intensity) {
|
||||
Light light = {0};
|
||||
light.type = AmbientLight;
|
||||
light.intensity = intensity;
|
||||
return light;
|
||||
Light light = {0};
|
||||
light.type = AmbientLight;
|
||||
light.intensity = intensity;
|
||||
return light;
|
||||
}
|
||||
|
||||
Light light_directional_new(float intensity, Vec3 direction) {
|
||||
Light light = {0};
|
||||
light.type = DirectionalLight;
|
||||
light.direction = direction;
|
||||
light.intensity = intensity;
|
||||
return light;
|
||||
Light light = {0};
|
||||
light.type = DirectionalLight;
|
||||
light.direction = direction;
|
||||
light.intensity = intensity;
|
||||
return light;
|
||||
}
|
||||
|
||||
Material material_new(Vec3 diffuse, float specular) {
|
||||
Material material = {0};
|
||||
material.diffuse = diffuse;
|
||||
material.specular = specular;
|
||||
return material;
|
||||
Material material = {0};
|
||||
material.diffuse = diffuse;
|
||||
material.specular = specular;
|
||||
return material;
|
||||
}
|
||||
|
||||
Ray ray_new(Vec3 origin, Vec3 direction) {
|
||||
Ray ray;
|
||||
ray.origin = origin;
|
||||
ray.direction = direction;
|
||||
return ray;
|
||||
Ray ray;
|
||||
ray.origin = origin;
|
||||
ray.direction = direction;
|
||||
return ray;
|
||||
}
|
||||
|
||||
// Lighting Compute Algorithm
|
||||
|
@ -171,50 +171,50 @@ Ray ray_new(Vec3 origin, Vec3 direction) {
|
|||
// RETURNS:
|
||||
// - intensity of light
|
||||
float lighting_compute(Vec3 point, Vec3 normal,
|
||||
Vec3 view, float specular,
|
||||
Light *lights, int num_lights) {
|
||||
|
||||
// Intensity of light for the given pixel
|
||||
float intensity = 0.0f;
|
||||
Vec3 view, float specular,
|
||||
Light *lights, int num_lights) {
|
||||
|
||||
// Intensity of light for the given pixel
|
||||
float intensity = 0.0f;
|
||||
|
||||
// Iterate over lights
|
||||
for (int i = 0; i < num_lights; i++)
|
||||
{
|
||||
Light *light = &lights[i];
|
||||
if (light->type == AmbientLight)
|
||||
{
|
||||
// Simply add ambient light to total
|
||||
intensity += light->intensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3 light_ray;
|
||||
if (light->type == PointLight)
|
||||
// Point Light: Direction of ray from light to point
|
||||
light_ray = vec3_subtract(light->position, point);
|
||||
else
|
||||
// Directional Light: Direction
|
||||
light_ray = light->direction;
|
||||
// Iterate over lights
|
||||
for (int i = 0; i < num_lights; i++)
|
||||
{
|
||||
Light *light = &lights[i];
|
||||
if (light->type == AmbientLight)
|
||||
{
|
||||
// Simply add ambient light to total
|
||||
intensity += light->intensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3 light_ray;
|
||||
if (light->type == PointLight)
|
||||
// Point Light: Direction of ray from light to point
|
||||
light_ray = vec3_subtract(light->position, point);
|
||||
else
|
||||
// Directional Light: Direction
|
||||
light_ray = light->direction;
|
||||
|
||||
// Diffuse
|
||||
float reflect = vec3_dot(normal, light_ray);
|
||||
intensity += (light->intensity * reflect)/(vec3_len(normal) * vec3_len(light_ray));
|
||||
// Diffuse
|
||||
float reflect = vec3_dot(normal, light_ray);
|
||||
intensity += (light->intensity * reflect)/(vec3_len(normal) * vec3_len(light_ray));
|
||||
|
||||
// Specular
|
||||
if (specular != -1)
|
||||
{
|
||||
Vec3 r = vec3_subtract(vec3_multiply_scalar(normal, 2 * vec3_dot(normal, light_ray)), light_ray);
|
||||
float reflect_view_proj = vec3_dot(r, view);
|
||||
if (reflect_view_proj > 0)
|
||||
{
|
||||
float cosine = reflect_view_proj/(vec3_len(r) * vec3_len(view));
|
||||
intensity += light->intensity * powf(cosine, specular);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Specular
|
||||
if (specular != -1)
|
||||
{
|
||||
Vec3 r = vec3_subtract(vec3_multiply_scalar(normal, 2 * vec3_dot(normal, light_ray)), light_ray);
|
||||
float reflect_view_proj = vec3_dot(r, view);
|
||||
if (reflect_view_proj > 0)
|
||||
{
|
||||
float cosine = reflect_view_proj/(vec3_len(r) * vec3_len(view));
|
||||
intensity += light->intensity * powf(cosine, specular);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return intensity;
|
||||
return intensity;
|
||||
}
|
||||
|
||||
// Sphere-Ray Intersection
|
||||
|
@ -227,40 +227,40 @@ float lighting_compute(Vec3 point, Vec3 normal,
|
|||
// - boolean of whether ray intersected a sphere
|
||||
// - [out] dist0, dist 1 = perpendicular distances to points of intersection
|
||||
int do_sphere_raycast(Sphere sphere, Ray ray, float *dist0, float *dist1) {
|
||||
|
||||
// Please see sphere_ray_intersection.bmp
|
||||
*dist0 = 0;
|
||||
*dist1 = 0;
|
||||
|
||||
// Please see sphere_ray_intersection.bmp
|
||||
*dist0 = 0;
|
||||
*dist1 = 0;
|
||||
|
||||
// Find L and tca
|
||||
Vec3 L = vec3_subtract(sphere.centre, ray.origin);
|
||||
float tca = vec3_dot(L, ray.direction);
|
||||
// Find L and tca
|
||||
Vec3 L = vec3_subtract(sphere.centre, ray.origin);
|
||||
float tca = vec3_dot(L, ray.direction);
|
||||
|
||||
// Discard if intersection is behind origin
|
||||
if (tca < 0)
|
||||
return 0;
|
||||
// Discard if intersection is behind origin
|
||||
if (tca < 0)
|
||||
return 0;
|
||||
|
||||
// Find d
|
||||
float d = sqrtf(vec3_dot(L, L) - tca * tca);
|
||||
if (d > sphere.radius)
|
||||
return 0;
|
||||
// Find d
|
||||
float d = sqrtf(vec3_dot(L, L) - tca * tca);
|
||||
if (d > sphere.radius)
|
||||
return 0;
|
||||
|
||||
// Calculate thc using pythagoras
|
||||
float thc = sqrtf(sphere.radius * sphere.radius - d * d);
|
||||
// Calculate thc using pythagoras
|
||||
float thc = sqrtf(sphere.radius * sphere.radius - d * d);
|
||||
|
||||
// Calculate t0 and t1 (perpendicular distance to
|
||||
// the 0th and 1st intersection)
|
||||
float t0 = tca - thc;
|
||||
float t1 = tca + thc;
|
||||
// Calculate t0 and t1 (perpendicular distance to
|
||||
// the 0th and 1st intersection)
|
||||
float t0 = tca - thc;
|
||||
float t1 = tca + thc;
|
||||
|
||||
// Ensure at least one of t0 and t1 is greater than zero
|
||||
if (t0 < 0 && t1 < 0)
|
||||
return 0;
|
||||
// Ensure at least one of t0 and t1 is greater than zero
|
||||
if (t0 < 0 && t1 < 0)
|
||||
return 0;
|
||||
|
||||
*dist0 = t0;
|
||||
*dist1 = t1;
|
||||
|
||||
return 1; // Intersection found
|
||||
*dist0 = t0;
|
||||
*dist1 = t1;
|
||||
|
||||
return 1; // Intersection found
|
||||
}
|
||||
|
||||
// Raytrace Scene at Point
|
||||
|
@ -274,64 +274,64 @@ int do_sphere_raycast(Sphere sphere, Ray ray, float *dist0, float *dist1) {
|
|||
// RETURNS:
|
||||
// - rgb colour of pixel being raytraced
|
||||
RgbColour raytrace(Vec3 origin, Vec3 dir, float min_t, float max_t,
|
||||
Sphere *spheres, int num_spheres,
|
||||
Light *lights, int num_lights) {
|
||||
Sphere *spheres, int num_spheres,
|
||||
Light *lights, int num_lights) {
|
||||
|
||||
// Closest sphere to screen (for depth-testing)
|
||||
Sphere *closest = 0;
|
||||
|
||||
// We use t_comp to store the t-depth of the closest
|
||||
// sphere and compare it with other spheres to perform
|
||||
// primitive depth testing (where 't' is perpendicular
|
||||
// distance to the point of intersection)
|
||||
float t_comp = (float)MAX_DIST;
|
||||
// Closest sphere to screen (for depth-testing)
|
||||
Sphere *closest = 0;
|
||||
|
||||
// We use t_comp to store the t-depth of the closest
|
||||
// sphere and compare it with other spheres to perform
|
||||
// primitive depth testing (where 't' is perpendicular
|
||||
// distance to the point of intersection)
|
||||
float t_comp = (float)MAX_DIST;
|
||||
|
||||
// Ray to test
|
||||
Ray ray = ray_new(origin, dir);
|
||||
// Ray to test
|
||||
Ray ray = ray_new(origin, dir);
|
||||
|
||||
// Cycle through all spheres and depth-test
|
||||
for (int i = 0; i < num_spheres; i++)
|
||||
{
|
||||
float dist0, dist1;
|
||||
if (do_sphere_raycast(spheres[i], ray, &dist0, &dist1))
|
||||
{
|
||||
// Check dist0
|
||||
if ((min_t < dist0 && dist0 < max_t) &&
|
||||
dist0 < t_comp)
|
||||
{
|
||||
t_comp = dist0;
|
||||
closest = &spheres[i];
|
||||
}
|
||||
// Cycle through all spheres and depth-test
|
||||
for (int i = 0; i < num_spheres; i++)
|
||||
{
|
||||
float dist0, dist1;
|
||||
if (do_sphere_raycast(spheres[i], ray, &dist0, &dist1))
|
||||
{
|
||||
// Check dist0
|
||||
if ((min_t < dist0 && dist0 < max_t) &&
|
||||
dist0 < t_comp)
|
||||
{
|
||||
t_comp = dist0;
|
||||
closest = &spheres[i];
|
||||
}
|
||||
|
||||
// Now check dist1
|
||||
if ((min_t < dist1 && dist1 < max_t) &&
|
||||
dist1 < t_comp)
|
||||
{
|
||||
t_comp = dist1;
|
||||
closest = &spheres[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now check dist1
|
||||
if ((min_t < dist1 && dist1 < max_t) &&
|
||||
dist1 < t_comp)
|
||||
{
|
||||
t_comp = dist1;
|
||||
closest = &spheres[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!closest)
|
||||
return Invalid;
|
||||
if (!closest)
|
||||
return Invalid;
|
||||
|
||||
Vec3 point = vec3_add(origin, vec3_multiply_scalar(dir, t_comp));
|
||||
Vec3 normal = vec3_normalise(vec3_subtract(point, closest->centre));
|
||||
Material material = closest->material;
|
||||
Vec3 point = vec3_add(origin, vec3_multiply_scalar(dir, t_comp));
|
||||
Vec3 normal = vec3_normalise(vec3_subtract(point, closest->centre));
|
||||
Material material = closest->material;
|
||||
|
||||
return vec3_clamp(
|
||||
vec3_multiply_scalar(
|
||||
material.diffuse,
|
||||
lighting_compute(
|
||||
point, normal,
|
||||
vec3_multiply_scalar(dir, -1),
|
||||
material.specular,
|
||||
lights, num_lights
|
||||
)
|
||||
),
|
||||
0.0f, 255.0f // Clamp between 0 and 255
|
||||
);
|
||||
return vec3_clamp(
|
||||
vec3_multiply_scalar(
|
||||
material.diffuse,
|
||||
lighting_compute(
|
||||
point, normal,
|
||||
vec3_multiply_scalar(dir, -1),
|
||||
material.specular,
|
||||
lights, num_lights
|
||||
)
|
||||
),
|
||||
0.0f, 255.0f // Clamp between 0 and 255
|
||||
);
|
||||
}
|
||||
|
||||
// Watermark: Says "MATT J"
|
||||
|
@ -339,12 +339,12 @@ RgbColour raytrace(Vec3 origin, Vec3 dir, float min_t, float max_t,
|
|||
#define MARK_ROWS 7
|
||||
int mark[MARK_ROWS][MARK_COLS] = {
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0},
|
||||
{0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0},
|
||||
{0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
|
||||
{0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
|
||||
{0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
|
||||
{0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
// Draws a watermark on the screen using the above array
|
||||
|
@ -357,94 +357,94 @@ void DrawWatermark(byte *data) {
|
|||
|
||||
for (int i = 0; i < MARK_COLS; i++) {
|
||||
for (int j = 0; j < MARK_ROWS; j++) {
|
||||
int y_corner = start_y + j*(size*2 + stride);
|
||||
int x_corner = start_x + i*(size*2 + stride);
|
||||
int y_corner = start_y + j*(size*2 + stride);
|
||||
int x_corner = start_x + i*(size*2 + stride);
|
||||
|
||||
// Draw Square
|
||||
for (int x = x_corner; x < (x_corner + size); x++) {
|
||||
for (int y = y_corner; y < (y_corner + size); y++) {
|
||||
if (mark[j][i] == 0) {
|
||||
data[(y*WIDTH + x) * 3 + 0] = (byte)(i/(float)MARK_COLS * 255) % 180;
|
||||
data[(y*WIDTH + x) * 3 + 1] = (byte)(j/(float)MARK_ROWS * 255) % 180;
|
||||
data[(y*WIDTH + x) * 3 + 2] = (byte)240;
|
||||
}
|
||||
else {
|
||||
data[(y*WIDTH + x) * 3 + 0] = (byte)255;
|
||||
data[(y*WIDTH + x) * 3 + 1] = (byte)255;
|
||||
data[(y*WIDTH + x) * 3 + 2] = (byte)255;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Draw Square
|
||||
for (int x = x_corner; x < (x_corner + size); x++) {
|
||||
for (int y = y_corner; y < (y_corner + size); y++) {
|
||||
if (mark[j][i] == 0) {
|
||||
data[(y*WIDTH + x) * 3 + 0] = (byte)(i/(float)MARK_COLS * 255) % 180;
|
||||
data[(y*WIDTH + x) * 3 + 1] = (byte)(j/(float)MARK_ROWS * 255) % 180;
|
||||
data[(y*WIDTH + x) * 3 + 2] = (byte)240;
|
||||
}
|
||||
else {
|
||||
data[(y*WIDTH + x) * 3 + 0] = (byte)255;
|
||||
data[(y*WIDTH + x) * 3 + 1] = (byte)255;
|
||||
data[(y*WIDTH + x) * 3 + 2] = (byte)255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
byte *data = malloc(sizeof(byte) * 3 * WIDTH * HEIGHT);
|
||||
byte *data = malloc(sizeof(byte) * 3 * WIDTH * HEIGHT);
|
||||
|
||||
// Materials
|
||||
Material blue = material_new(vec3_new(69, 161, 255), 500);
|
||||
Material white = material_new(vec3_new(240, 240, 240), 180);
|
||||
Material red = material_new(vec3_new(255, 0, 57), 10);
|
||||
Material ground = material_new(vec3_new(0, 57, 89), 1000);
|
||||
// Materials
|
||||
Material blue = material_new(vec3_new(69, 161, 255), 500);
|
||||
Material white = material_new(vec3_new(240, 240, 240), 180);
|
||||
Material red = material_new(vec3_new(255, 0, 57), 10);
|
||||
Material ground = material_new(vec3_new(0, 57, 89), 1000);
|
||||
|
||||
// Scene
|
||||
#define NUM_SPHERES 4
|
||||
Sphere spheres[NUM_SPHERES];
|
||||
spheres[0] = sphere_new(vec3_new(-0.75f, -0.2f, 6.5f), 1.5f, red);
|
||||
spheres[1] = sphere_new(vec3_new(0, -1, 5), 1.0f, blue);
|
||||
spheres[2] = sphere_new(vec3_new(2, -0.5, 8), 3.0f, white);
|
||||
spheres[3] = sphere_new(vec3_new(0, -4001, 0), 4000, ground);
|
||||
// Scene
|
||||
#define NUM_SPHERES 4
|
||||
Sphere spheres[NUM_SPHERES];
|
||||
spheres[0] = sphere_new(vec3_new(-0.75f, -0.2f, 6.5f), 1.5f, red);
|
||||
spheres[1] = sphere_new(vec3_new(0, -1, 5), 1.0f, blue);
|
||||
spheres[2] = sphere_new(vec3_new(2, -0.5, 8), 3.0f, white);
|
||||
spheres[3] = sphere_new(vec3_new(0, -4001, 0), 4000, ground);
|
||||
|
||||
// Lights
|
||||
#define NUM_LIGHTS 3
|
||||
Light lights[NUM_LIGHTS];
|
||||
lights[0] = light_ambient_new(0.2f);
|
||||
lights[1] = light_point_new(0.6f, vec3_new(-8, 1, 0));
|
||||
lights[2] = light_directional_new(0.2f, vec3_new(1, 4, -8));
|
||||
// Lights
|
||||
#define NUM_LIGHTS 3
|
||||
Light lights[NUM_LIGHTS];
|
||||
lights[0] = light_ambient_new(0.2f);
|
||||
lights[1] = light_point_new(0.6f, vec3_new(-8, 1, 0));
|
||||
lights[2] = light_directional_new(0.2f, vec3_new(1, 4, -8));
|
||||
|
||||
// For non-square images (future-proofing?)
|
||||
float aspect_ratio = (float)WIDTH/(float)HEIGHT;
|
||||
float screen_dim = tanf(FOV / (float)2);
|
||||
// For non-square images (future-proofing?)
|
||||
float aspect_ratio = (float)WIDTH/(float)HEIGHT;
|
||||
float screen_dim = tanf(FOV / (float)2);
|
||||
|
||||
Vec3 origin = Zero;
|
||||
Vec3 origin = Zero;
|
||||
|
||||
// Render
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
// Render
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
|
||||
// Background
|
||||
data[(y*WIDTH + x) * 3 + 0] = (byte)(y/(float)WIDTH * 255);
|
||||
data[(y*WIDTH + x) * 3 + 1] = (byte)(x/(float)HEIGHT * 255);
|
||||
data[(y*WIDTH + x) * 3 + 2] = (byte)160;
|
||||
|
||||
// Get Pixel in World Coords
|
||||
float x_world_coord = (2*(x + 0.5f)/(float)HEIGHT - 1) * screen_dim * aspect_ratio;
|
||||
float y_world_coord = -(2*(y + 0.5f)/(float)WIDTH - 1) * screen_dim;
|
||||
Vec3 dir = vec3_normalise(vec3_new(x_world_coord, y_world_coord, 1));
|
||||
// Background
|
||||
data[(y*WIDTH + x) * 3 + 0] = (byte)(y/(float)WIDTH * 255);
|
||||
data[(y*WIDTH + x) * 3 + 1] = (byte)(x/(float)HEIGHT * 255);
|
||||
data[(y*WIDTH + x) * 3 + 2] = (byte)160;
|
||||
|
||||
// Get Pixel in World Coords
|
||||
float x_world_coord = (2*(x + 0.5f)/(float)HEIGHT - 1) * screen_dim * aspect_ratio;
|
||||
float y_world_coord = -(2*(y + 0.5f)/(float)WIDTH - 1) * screen_dim;
|
||||
Vec3 dir = vec3_normalise(vec3_new(x_world_coord, y_world_coord, 1));
|
||||
|
||||
// Raytrace Pixel
|
||||
RgbColour colour = raytrace(origin, dir, 1.0f, (float)MAX_DIST,
|
||||
spheres, NUM_SPHERES,
|
||||
lights, NUM_LIGHTS);
|
||||
// Raytrace Pixel
|
||||
RgbColour colour = raytrace(origin, dir, 1.0f, (float)MAX_DIST,
|
||||
spheres, NUM_SPHERES,
|
||||
lights, NUM_LIGHTS);
|
||||
|
||||
// Draw Geometry
|
||||
if (colour.x != -1) {
|
||||
data[(y*WIDTH + x) * 3 + 0] = (byte)colour.x;
|
||||
data[(y*WIDTH + x) * 3 + 1] = (byte)colour.y;
|
||||
data[(y*WIDTH + x) * 3 + 2] = (byte)colour.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Draw Geometry
|
||||
if (colour.x != -1) {
|
||||
data[(y*WIDTH + x) * 3 + 0] = (byte)colour.x;
|
||||
data[(y*WIDTH + x) * 3 + 1] = (byte)colour.y;
|
||||
data[(y*WIDTH + x) * 3 + 2] = (byte)colour.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output
|
||||
// Output
|
||||
DrawWatermark(data);
|
||||
|
||||
// Write to file
|
||||
printf("tinyray: writing to file!");
|
||||
if (!stbi_write_bmp("output.bmp", WIDTH, HEIGHT, 3, data))
|
||||
printf("tinyray: failed to write image!");
|
||||
// Write to file
|
||||
printf("tinyray: writing to file!");
|
||||
if (!stbi_write_bmp("output.bmp", WIDTH, HEIGHT, 3, data))
|
||||
printf("tinyray: failed to write image!");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue