chapter 2 wip
This commit is contained in:
parent
e5b29bdc81
commit
062cc66885
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
*.o
|
||||
*.gch
|
||||
test/test_tuples
|
||||
test/test_canvas
|
32
canvas.h
Normal file
32
canvas.h
Normal file
@ -0,0 +1,32 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tuples.h"
|
||||
|
||||
struct canvas {
|
||||
int width;
|
||||
int height;
|
||||
struct tuple * pixels;
|
||||
};
|
||||
|
||||
struct canvas canvas(int width, int height)
|
||||
{
|
||||
return (struct canvas){
|
||||
width,
|
||||
height,
|
||||
calloc(width * height, (sizeof (struct tuple)))
|
||||
};
|
||||
}
|
||||
|
||||
void canvas_write_pixel(struct canvas canvas, int x, int y, struct tuple color)
|
||||
{
|
||||
struct tuple * pixel = &canvas.pixels[y * canvas.width + x];
|
||||
pixel->r = color.r;
|
||||
pixel->g = color.g;
|
||||
pixel->b = color.b;
|
||||
pixel->a = color.a;
|
||||
}
|
||||
|
||||
struct tuple canvas_pixel_at(struct canvas canvas, int x, int y)
|
||||
{
|
||||
return canvas.pixels[y * canvas.width + x];
|
||||
}
|
11
test/run.sh
Normal file
11
test/run.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!bin/bash
|
||||
|
||||
set -eux
|
||||
|
||||
for name in tuples canvas; do
|
||||
gcc -g -gdwarf-5 \
|
||||
-Wall -Werror -Wfatal-errors \
|
||||
-I. \
|
||||
test/test_${name}.c -o test/test_${name} -O0 -lm
|
||||
./test/test_${name}
|
||||
done
|
35
test/test_canvas.c
Normal file
35
test/test_canvas.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "runner.h"
|
||||
|
||||
static bool canvas_test_0(const char ** scenario)
|
||||
{
|
||||
*scenario = "Creating a canvas";
|
||||
struct canvas c = canvas(10, 20);
|
||||
bool zeroized = true;
|
||||
for (int i = 0; i < c.width * c.height; i++) {
|
||||
zeroized &= tuple_equal(c.pixels[i], color(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
return
|
||||
c.width == 10 &&
|
||||
c.height == 20 &&
|
||||
zeroized;
|
||||
}
|
||||
|
||||
static bool canvas_test_1(const char ** scenario)
|
||||
{
|
||||
*scenario = "Writing pixels to the screen";
|
||||
struct canvas c = canvas(10, 20);
|
||||
struct tuple red = color(1.0f, 0.0f, 0.0f);
|
||||
canvas_write_pixel(c, 2, 3, red);
|
||||
return tuple_equal(canvas_pixel_at(c, 2, 3), red);
|
||||
}
|
||||
|
||||
test_t canvas_tests[] = {
|
||||
canvas_test_0,
|
||||
canvas_test_1,
|
||||
};
|
||||
|
||||
RUNNER(canvas_tests)
|
@ -194,6 +194,47 @@ static bool tuple_test_22(const char ** scenario)
|
||||
;
|
||||
}
|
||||
|
||||
static bool tuple_test_23(const char ** scenario)
|
||||
{
|
||||
*scenario = "Colors are (red, green, blue) tuples";
|
||||
struct tuple c = color(-0.5, 0.4, 1.7);
|
||||
return
|
||||
float_equal(c.r, -0.5) &&
|
||||
float_equal(c.g, 0.4) &&
|
||||
float_equal(c.b, 1.7);
|
||||
}
|
||||
|
||||
static bool tuple_test_24(const char ** scenario)
|
||||
{
|
||||
*scenario = "Adding colors";
|
||||
struct tuple c1 = color(0.9f, 0.6f, 0.75f);
|
||||
struct tuple c2 = color(0.7f, 0.1f, 0.25f);
|
||||
return tuple_equal(tuple_add(c1, c2), color(1.6f, 0.7f, 1.0f));
|
||||
}
|
||||
|
||||
static bool tuple_test_25(const char ** scenario)
|
||||
{
|
||||
*scenario = "Subtracting colors";
|
||||
struct tuple c1 = color(0.9f, 0.6f, 0.75f);
|
||||
struct tuple c2 = color(0.7f, 0.1f, 0.25f);
|
||||
return tuple_equal(tuple_sub(c1, c2), color(0.2f, 0.5f, 0.5f));
|
||||
}
|
||||
|
||||
static bool tuple_test_26(const char ** scenario)
|
||||
{
|
||||
*scenario = "Multiplying a color by a scalar";
|
||||
struct tuple c = color(0.2f, 0.3f, 0.4f);
|
||||
return tuple_equal(tuple_mul(c, 2.0f), color(0.4f, 0.6f, 0.8f));
|
||||
}
|
||||
|
||||
static bool tuple_test_27(const char ** scenario)
|
||||
{
|
||||
*scenario = "Multiplying colors";
|
||||
struct tuple c1 = color(1.0f, 0.2f, 0.4f);
|
||||
struct tuple c2 = color(0.9f, 1.0f, 0.1f);
|
||||
return tuple_equal(hadmard_product(c1, c2), color(0.9f, 0.2f, 0.04f));
|
||||
}
|
||||
|
||||
test_t tuple_tests[] = {
|
||||
tuple_test_0,
|
||||
tuple_test_1,
|
||||
@ -217,7 +258,12 @@ test_t tuple_tests[] = {
|
||||
tuple_test_19,
|
||||
tuple_test_20,
|
||||
tuple_test_21,
|
||||
tuple_test_22
|
||||
tuple_test_22,
|
||||
tuple_test_23,
|
||||
tuple_test_24,
|
||||
tuple_test_25,
|
||||
tuple_test_26,
|
||||
tuple_test_27,
|
||||
};
|
||||
|
||||
RUNNER(tuple_tests)
|
||||
|
55
tuples.h
55
tuples.h
@ -1,10 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
struct tuple {
|
||||
union {
|
||||
struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
struct {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
inline static bool float_equal(float a, float b)
|
||||
@ -15,7 +25,7 @@ inline static bool float_equal(float a, float b)
|
||||
|
||||
inline static struct tuple tuple(float x, float y, float z, float w)
|
||||
{
|
||||
return (struct tuple){ x, y, z, w };
|
||||
return (struct tuple){{{ x, y, z, w }}};
|
||||
}
|
||||
|
||||
inline static bool tuple_is_point(struct tuple t)
|
||||
@ -39,62 +49,67 @@ inline static bool tuple_equal(struct tuple a, struct tuple b)
|
||||
|
||||
inline static struct tuple point(float x, float y, float z)
|
||||
{
|
||||
return (struct tuple){x, y, z, 1.0f};
|
||||
return tuple(x, y, z, 1.0f);
|
||||
}
|
||||
|
||||
inline static struct tuple vector(float x, float y, float z)
|
||||
{
|
||||
return (struct tuple){x, y, z, 0.0f};
|
||||
return tuple(x, y, z, 0.0f);
|
||||
}
|
||||
|
||||
inline static struct tuple color(float r, float g, float b)
|
||||
{
|
||||
return tuple(r, g, b, 0.0f);
|
||||
}
|
||||
|
||||
inline static struct tuple tuple_add(struct tuple a, struct tuple b)
|
||||
{
|
||||
return (struct tuple){
|
||||
return tuple(
|
||||
a.x + b.x,
|
||||
a.y + b.y,
|
||||
a.z + b.z,
|
||||
a.w + b.w
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
inline static struct tuple tuple_sub(struct tuple a, struct tuple b)
|
||||
{
|
||||
return (struct tuple){
|
||||
return tuple(
|
||||
a.x - b.x,
|
||||
a.y - b.y,
|
||||
a.z - b.z,
|
||||
a.w - b.w
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
inline static struct tuple tuple_neg(struct tuple a)
|
||||
{
|
||||
return (struct tuple){
|
||||
return tuple(
|
||||
-a.x,
|
||||
-a.y,
|
||||
-a.z,
|
||||
-a.w
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
inline static struct tuple tuple_mul(struct tuple a, float s)
|
||||
{
|
||||
return (struct tuple){
|
||||
return tuple(
|
||||
a.x * s,
|
||||
a.y * s,
|
||||
a.z * s,
|
||||
a.w * s
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
inline static struct tuple tuple_div(struct tuple a, float s)
|
||||
{
|
||||
return (struct tuple){
|
||||
return tuple(
|
||||
a.x / s,
|
||||
a.y / s,
|
||||
a.z / s,
|
||||
a.w / s
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
inline static float tuple_magnitude(struct tuple a)
|
||||
@ -121,10 +136,20 @@ inline static float tuple_dot(struct tuple a, struct tuple b)
|
||||
|
||||
inline static struct tuple tuple_cross(struct tuple a, struct tuple b)
|
||||
{
|
||||
return (struct tuple){
|
||||
return tuple(
|
||||
a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x,
|
||||
0.0f
|
||||
};
|
||||
);
|
||||
}
|
||||
|
||||
inline static struct tuple hadmard_product(struct tuple c1, struct tuple c2)
|
||||
{
|
||||
return tuple(
|
||||
c1.r * c2.r,
|
||||
c1.g * c2.g,
|
||||
c1.b * c2.b,
|
||||
0.0f
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user