add horse
This commit is contained in:
parent
9809dfccd0
commit
f47a2df75b
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
build
|
build
|
||||||
|
progress
|
||||||
|
|
100000
resources/horse.pts.txt
Normal file
100000
resources/horse.pts.txt
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,32 +1,34 @@
|
||||||
// Alexander Bass
|
// Alexander Bass
|
||||||
// Created 4/16/24
|
// Created 4/16/24
|
||||||
|
// Modified 4/17/24
|
||||||
|
|
||||||
#include "donut.h"
|
#include "donut.h"
|
||||||
#include "point.h"
|
#include "point.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "rgb.h"
|
#include "vec3.h"
|
||||||
|
|
||||||
rgb sample_rgb(u8 *texture, usize index) {
|
vec3 sample_rgb(u8 *texture, usize index) {
|
||||||
u8 d_red = texture[index * 3];
|
u8 red = texture[index];
|
||||||
u8 d_green = texture[index * 3 + 1];
|
u8 green = texture[index + 1];
|
||||||
u8 d_blue = texture[index * 3 + 2];
|
u8 blue = texture[index + 2];
|
||||||
f64 d_r = (f64)d_red / 255.0;
|
vec3 color = vec3((f64)red, (f64)green, (f64)blue);
|
||||||
f64 d_g = (f64)d_green / 255.0;
|
color *= vec3(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
|
||||||
f64 d_b = (f64)d_blue / 255.0;
|
return color;
|
||||||
return rgb(d_r, d_g, d_b);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline rgb mix_transparency(rgb transparent, rgb solid) {
|
inline vec3 mix_transparency(vec3 transparent, vec3 solid) {
|
||||||
if (transparent.r == 0.0 && transparent.g == 0.0 && transparent.b == 0.0) {
|
if (transparent.i == 0.0 && transparent.j == 0.0 && transparent.k == 0.0) {
|
||||||
return solid;
|
return solid;
|
||||||
|
} else {
|
||||||
|
return transparent;
|
||||||
}
|
}
|
||||||
return transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Point> generate_cube(u8 *bottom_texture, u8 *top_texture, u8 *side_texture, i32 face_x, i32 face_y) {
|
std::vector<Point> generate_cube(u8 *bottom_texture, u8 *top_texture, u8 *side_texture, i32 face_x, i32 face_y) {
|
||||||
std::vector<Point> out = {};
|
std::vector<Point> out = {};
|
||||||
|
const vec3 grass_color_scale = vec3(0.4, 1.0, 0.4);
|
||||||
const usize image_size = 16;
|
const usize image_size = 16;
|
||||||
const usize point_count = 22;
|
const usize point_count = 22;
|
||||||
const usize world_width = 16;
|
const usize world_width = 16;
|
||||||
|
@ -35,46 +37,45 @@ std::vector<Point> generate_cube(u8 *bottom_texture, u8 *top_texture, u8 *side_t
|
||||||
|
|
||||||
f64 sx = (f64)l_x / (f64)point_count;
|
f64 sx = (f64)l_x / (f64)point_count;
|
||||||
f64 sy = (f64)l_y / (f64)point_count;
|
f64 sy = (f64)l_y / (f64)point_count;
|
||||||
usize index = (usize)(sx * (f64)(image_size)) + usize(sy * (f64)(image_size)) * image_size;
|
usize index = 3 * ((usize)(sx * (f64)(image_size)) + usize(sy * (f64)(image_size)) * image_size);
|
||||||
rgb dirt = sample_rgb(bottom_texture, index);
|
vec3 dirt = sample_rgb(bottom_texture, index);
|
||||||
rgb grass = sample_rgb(top_texture, index);
|
vec3 grass = sample_rgb(top_texture, index);
|
||||||
rgb sides = sample_rgb(side_texture, index);
|
vec3 side = sample_rgb(side_texture, index);
|
||||||
grass.mix(rgb(0.4, 1.0, 0.4));
|
grass *= grass_color_scale;
|
||||||
sides.mix(rgb(0.4, 1.0, 0.4));
|
side *= grass_color_scale;
|
||||||
|
|
||||||
sides = mix_transparency(sides, dirt);
|
side = mix_transparency(side, dirt);
|
||||||
|
|
||||||
f64 x_w = sx * (f64)world_width;
|
f64 x_w = sx * (f64)world_width;
|
||||||
f64 y_w = sy * (f64)world_width;
|
f64 y_w = sy * (f64)world_width;
|
||||||
f64 w_w = (f64)world_width;
|
f64 w_w = (f64)world_width;
|
||||||
|
|
||||||
if (face_y == -1 || (face_y == 1 && face_x == 0)) {
|
if (face_y == -1 || (face_y == 1 && face_x == 0)) {
|
||||||
out.push_back(*Point(x_w, 0, y_w).set_rgb(sides));
|
out.push_back(*Point(x_w, 0, y_w).set_rgb(side));
|
||||||
}
|
}
|
||||||
if (face_x == -1 || (face_x == 1 && face_y == 0)) {
|
if (face_x == -1 || (face_x == 1 && face_y == 0)) {
|
||||||
out.push_back(*Point(0, x_w, y_w).set_rgb(sides));
|
out.push_back(*Point(0, x_w, y_w).set_rgb(side));
|
||||||
}
|
}
|
||||||
if (face_x == 1 || (face_x == -1 && face_y == 0)) {
|
if (face_x == 1 || (face_x == -1 && face_y == 0)) {
|
||||||
out.push_back(*Point(w_w, x_w, y_w).set_rgb(sides));
|
out.push_back(*Point(w_w, x_w, y_w).set_rgb(side));
|
||||||
}
|
}
|
||||||
if (face_y == 1 || (face_y == -1 && face_x == 0)) {
|
if (face_y == 1 || (face_y == -1 && face_x == 0)) {
|
||||||
out.push_back(*Point(x_w, w_w, y_w).set_rgb(sides));
|
out.push_back(*Point(x_w, w_w, y_w).set_rgb(side));
|
||||||
}
|
}
|
||||||
|
|
||||||
out.push_back(*Point(x_w, y_w, w_w).set_rgb(dirt));
|
out.push_back(*Point(x_w, y_w, w_w).set_rgb(dirt));
|
||||||
out.push_back(*Point(x_w, y_w, 0.0).set_rgb(grass));
|
out.push_back(*Point(x_w, y_w, 0.0).set_rgb(grass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (usize i = 0; i < out.size(); i++) {
|
for (auto &p : out) {
|
||||||
Point *p = &out[i];
|
p.translate_x((f64)face_x * (f64)world_width - (f64)world_width / 2.0);
|
||||||
p->translate_x((f64)face_x * (f64)world_width - (f64)world_width / 2.0);
|
p.translate_y((f64)face_y * (f64)world_width - (f64)world_width / 2.0);
|
||||||
p->translate_y((f64)face_y * (f64)world_width - (f64)world_width / 2.0);
|
p.translate_z(-(f64)world_width / 2.0);
|
||||||
p->translate_z(-(f64)world_width / 2.0);
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Point> generate_donut(u8 *bottom_texture, u8 *top_texture, u8 *side_texture, f64 offset) {
|
std::vector<Point> generate_donut(u8 *bottom_texture, u8 *top_texture, u8 *side_texture) {
|
||||||
std::vector<Point> points = {};
|
std::vector<Point> points = {};
|
||||||
for (i32 x = -1; x <= 1; x++) {
|
for (i32 x = -1; x <= 1; x++) {
|
||||||
for (i32 y = -1; y <= 1; y++) {
|
for (i32 y = -1; y <= 1; y++) {
|
||||||
|
@ -85,10 +86,6 @@ std::vector<Point> generate_donut(u8 *bottom_texture, u8 *top_texture, u8 *side_
|
||||||
points.insert(points.end(), pt.begin(), pt.end());
|
points.insert(points.end(), pt.begin(), pt.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (usize i = 0; i < points.size(); i++) {
|
|
||||||
Point *point = &points[i];
|
|
||||||
point->translate_z(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
// Alexander Bass
|
// Alexander Bass
|
||||||
// Created 4/16/24
|
// Created 4/16/24
|
||||||
|
// Modified 4/17/24
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "point.h"
|
#include "point.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
std::vector<Point> generate_donut(u8 *bottom_texture, u8 *top_texture, u8 *side_texture, f64);
|
std::vector<Point> generate_donut(u8 *bottom_texture, u8 *top_texture, u8 *side_texture);
|
||||||
|
|
77
src/main.cpp
77
src/main.cpp
|
@ -1,18 +1,21 @@
|
||||||
// Alexander Bass
|
// Alexander Bass
|
||||||
// Created 4/16/24
|
// Created 4/16/24
|
||||||
|
// Modified 4/17/24
|
||||||
|
|
||||||
#include "donut.h"
|
#include "donut.h"
|
||||||
#include "point.h"
|
#include "point.h"
|
||||||
#include "ppm/ppm.h"
|
#include "ppm/ppm.h"
|
||||||
|
#include "pts.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
const i32 WIDTH = 120;
|
const i32 WIDTH = 120;
|
||||||
const i32 HEIGHT = 100;
|
const i32 HEIGHT = 100;
|
||||||
const i32 DEPTH = WIDTH;
|
const i32 DEPTH = WIDTH;
|
||||||
|
@ -25,25 +28,24 @@ void update(vector<Point> &points);
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
ifstream dirt_file("dirt.ppm");
|
u8 *dirt = ppm::from_file("dirt.ppm");
|
||||||
u8 *dirt = ppm::load_ppm(dirt_file);
|
u8 *grass = ppm::from_file("grass_top.ppm");
|
||||||
dirt_file.close();
|
u8 *grass_side = ppm::from_file("grass_side.ppm");
|
||||||
ifstream grass_file("grass_top.ppm");
|
|
||||||
u8 *grass = ppm::load_ppm(grass_file);
|
|
||||||
grass_file.close();
|
|
||||||
ifstream grass_side_file("grass_side.ppm");
|
|
||||||
u8 *grass_side = ppm::load_ppm(grass_side_file);
|
|
||||||
grass_side_file.close();
|
|
||||||
|
|
||||||
std::vector<Point> points = {};
|
std::vector<Point> points = {};
|
||||||
points.push_back(*Point(0, 0, 0).set_rgb(1.0, 0, 0));
|
points.push_back(*Point().set_rgb(1.0, 0, 0));
|
||||||
|
|
||||||
|
std::vector<Point> horse = pts::load_pts_from_path("horse.pts.txt");
|
||||||
|
for (auto &p : horse) {
|
||||||
|
vec3 a = p.get_xyz();
|
||||||
|
a *= 300.0;
|
||||||
|
p.set_xyz(a);
|
||||||
|
}
|
||||||
|
points.insert(points.end(), horse.begin(), horse.end());
|
||||||
|
|
||||||
|
// std::vector<Point> donut = generate_donut(dirt, grass, grass_side);
|
||||||
|
// points.insert(points.end(), donut.begin(), donut.end());
|
||||||
|
|
||||||
std::vector<Point> donut = generate_donut(dirt, grass, grass_side, 0.0);
|
|
||||||
points.insert(points.end(), donut.begin(), donut.end());
|
|
||||||
donut = generate_donut(dirt, grass, grass_side, 32.0);
|
|
||||||
points.insert(points.end(), donut.begin(), donut.end());
|
|
||||||
donut = generate_donut(dirt, grass, grass_side, -32.0);
|
|
||||||
points.insert(points.end(), donut.begin(), donut.end());
|
|
||||||
delete[] dirt;
|
delete[] dirt;
|
||||||
delete[] grass;
|
delete[] grass;
|
||||||
delete[] grass_side;
|
delete[] grass_side;
|
||||||
|
@ -51,20 +53,25 @@ int main() {
|
||||||
auto grid = new size_t[WIDTH * HEIGHT];
|
auto grid = new size_t[WIDTH * HEIGHT];
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
std::cout << "\033c";
|
// Move cursor to top left
|
||||||
|
std::cout << "\033[0;0H";
|
||||||
|
// Draw points
|
||||||
draw(grid, points);
|
draw(grid, points);
|
||||||
|
// Rotate points
|
||||||
update(points);
|
update(points);
|
||||||
|
// Wait
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 60));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 60));
|
||||||
|
// Repeat
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 w_x_to_screen(f64 w_x) {
|
i32 w_x_to_screen(f64 w_x) {
|
||||||
return static_cast<i32>(std::round(w_x + static_cast<f64>(WIDTH) / 2.0));
|
return static_cast<i32>(std::round(w_x + static_cast<f64>(WIDTH) / 2.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 w_y_to_screen(f64 w_y) {
|
i32 w_y_to_screen(f64 w_y) {
|
||||||
return static_cast<i32>(std::round(w_y + static_cast<f64>(HEIGHT) / 2.0));
|
return static_cast<i32>(std::round(w_y + static_cast<f64>(HEIGHT) / 2.0 + 10.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 w_z_to_screen(f64 w_z) {
|
f64 w_z_to_screen(f64 w_z) {
|
||||||
|
@ -72,30 +79,37 @@ f64 w_z_to_screen(f64 w_z) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(size_t *grid, vector<Point> &points) {
|
void draw(size_t *grid, vector<Point> &points) {
|
||||||
|
// grid is a list of handles to points in the points vector.
|
||||||
|
// these handles can be 0 to indicate that there is no representative point
|
||||||
|
// and therefor no pixel for that position.
|
||||||
|
// the values of grid can also be the index to points to represent a point
|
||||||
|
// being mapped to a pixel. This system also handles depth buffering.
|
||||||
for (u32 i = 0; i < static_cast<u32>(WIDTH * HEIGHT); i++) {
|
for (u32 i = 0; i < static_cast<u32>(WIDTH * HEIGHT); i++) {
|
||||||
grid[i] = 0;
|
grid[i] = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Pseudo-rasterization
|
||||||
for (size_t i = 0; i < points.size(); i++) {
|
for (size_t i = 0; i < points.size(); i++) {
|
||||||
Point p = points[i];
|
Point &p = points[i];
|
||||||
f64 p_x = p.get_x();
|
f64 p_x = p.get_x();
|
||||||
f64 p_y = p.get_y();
|
f64 p_y = p.get_y();
|
||||||
f64 p_z = p.get_z();
|
f64 p_z = p.get_z();
|
||||||
|
|
||||||
i32 s_x = w_x_to_screen(p_x);
|
i32 s_x = w_x_to_screen(p_x);
|
||||||
i32 s_y = w_y_to_screen(p_y);
|
i32 s_y = w_y_to_screen(p_y);
|
||||||
f64 s_z = w_z_to_screen(p_z);
|
|
||||||
if (0 <= s_x && s_x < HEIGHT && 0 <= s_y && s_y < HEIGHT) {
|
if (0 <= s_x && s_x < HEIGHT && 0 <= s_y && s_y < HEIGHT) {
|
||||||
size_t index = static_cast<size_t>(s_x + s_y * HEIGHT);
|
size_t index = static_cast<size_t>(s_x + s_y * HEIGHT);
|
||||||
size_t existing_pixel_handle = grid[index];
|
size_t existing_pixel_handle = grid[index];
|
||||||
if (existing_pixel_handle == 0) {
|
if (existing_pixel_handle == 0) {
|
||||||
grid[index] = i + 1;
|
grid[index] = i + 1;
|
||||||
} else if (points[existing_pixel_handle - 1].get_z() < p_z) {
|
} else if (points[existing_pixel_handle - 1].get_z() < p_z) {
|
||||||
|
// Pixel already exists at point on screen. Check its depth.
|
||||||
grid[index] = i + 1;
|
grid[index] = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Printing
|
||||||
std::string line = "";
|
std::string line = "";
|
||||||
for (size_t y = 0; y < static_cast<size_t>(WIDTH); y++) {
|
for (size_t y = 0; y < static_cast<size_t>(WIDTH); y++) {
|
||||||
for (size_t x = 0; x < static_cast<size_t>(HEIGHT); x++) {
|
for (size_t x = 0; x < static_cast<size_t>(HEIGHT); x++) {
|
||||||
|
@ -109,12 +123,10 @@ void draw(size_t *grid, vector<Point> &points) {
|
||||||
f64 depth = w_z_to_screen(p.get_z());
|
f64 depth = w_z_to_screen(p.get_z());
|
||||||
assert(depth >= 0.0);
|
assert(depth >= 0.0);
|
||||||
assert(depth <= 1.0);
|
assert(depth <= 1.0);
|
||||||
f64 red = p.get_r() * depth;
|
vec3 rgb = p.get_rgb() * depth * 255.0;
|
||||||
f64 green = p.get_g() * depth;
|
u8 r8 = (u8)(round(rgb.i));
|
||||||
f64 blue = p.get_b() * depth;
|
u8 g8 = (u8)(round(rgb.j));
|
||||||
u8 r8 = static_cast<u8>(round(red * 255.0));
|
u8 b8 = (u8)(round(rgb.k));
|
||||||
u8 g8 = static_cast<u8>(round(green * 255.0));
|
|
||||||
u8 b8 = static_cast<u8>(round(blue * 255.0));
|
|
||||||
line += format("\033[38;2;{};{};{}m██", r8, g8, b8);
|
line += format("\033[38;2;{};{};{}m██", r8, g8, b8);
|
||||||
}
|
}
|
||||||
line += '\n';
|
line += '\n';
|
||||||
|
@ -123,10 +135,9 @@ void draw(size_t *grid, vector<Point> &points) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(vector<Point> &points) {
|
void update(vector<Point> &points) {
|
||||||
for (size_t i = 0; i < points.size(); i++) {
|
for (auto &p : points) {
|
||||||
Point *p = &points[i];
|
p.rotate_x(0.02);
|
||||||
p->rotate_x(0.02);
|
p.rotate_y(-0.04);
|
||||||
p->rotate_y(-0.04);
|
p.rotate_z(0.03);
|
||||||
p->rotate_z(0.03);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
src/point.h
32
src/point.h
|
@ -1,8 +1,9 @@
|
||||||
// Alexander Bass
|
// Alexander Bass
|
||||||
// Created 4/16/24
|
// Created 4/16/24
|
||||||
|
// Modified 4/17/24
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "rgb.h"
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "vec3.h"
|
||||||
class Point {
|
class Point {
|
||||||
private:
|
private:
|
||||||
f64 x;
|
f64 x;
|
||||||
|
@ -21,11 +22,24 @@ class Point {
|
||||||
g = 1.0;
|
g = 1.0;
|
||||||
b = 1.0;
|
b = 1.0;
|
||||||
}
|
}
|
||||||
|
Point() {
|
||||||
|
x = 0.0;
|
||||||
|
y = 0.0;
|
||||||
|
z = 0.0;
|
||||||
|
r = 0.0;
|
||||||
|
g = 0.0;
|
||||||
|
b = 0.0;
|
||||||
|
}
|
||||||
void set_xyz(f64 _x, f64 _y, f64 _z) {
|
void set_xyz(f64 _x, f64 _y, f64 _z) {
|
||||||
x = _x;
|
x = _x;
|
||||||
y = _y;
|
y = _y;
|
||||||
z = _z;
|
z = _z;
|
||||||
};
|
};
|
||||||
|
void set_xyz(vec3 pos) {
|
||||||
|
x = pos.i;
|
||||||
|
y = pos.j;
|
||||||
|
z = pos.k;
|
||||||
|
};
|
||||||
void rotate_x(f64 angle);
|
void rotate_x(f64 angle);
|
||||||
void rotate_y(f64 angle);
|
void rotate_y(f64 angle);
|
||||||
void rotate_z(f64 angle);
|
void rotate_z(f64 angle);
|
||||||
|
@ -46,6 +60,10 @@ class Point {
|
||||||
return z;
|
return z;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vec3 get_xyz() const {
|
||||||
|
return vec3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
f64 get_r() const {
|
f64 get_r() const {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +74,10 @@ class Point {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 get_rgb() const {
|
||||||
|
return vec3(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
void translate_x(f64 dx) {
|
void translate_x(f64 dx) {
|
||||||
x += dx;
|
x += dx;
|
||||||
}
|
}
|
||||||
|
@ -72,10 +94,10 @@ class Point {
|
||||||
b = _b;
|
b = _b;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
Point *set_rgb(rgb col) {
|
Point *set_rgb(vec3 col) {
|
||||||
r = col.r;
|
r = col.i;
|
||||||
g = col.g;
|
g = col.j;
|
||||||
b = col.b;
|
b = col.k;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
};
|
};
|
|
@ -1,8 +1,10 @@
|
||||||
// Alexander Bass
|
// Alexander Bass
|
||||||
// Created 4/16/24
|
// Created 4/16/24
|
||||||
|
// Modified 4/17/24
|
||||||
#include "ppm.h"
|
#include "ppm.h"
|
||||||
using std::string;
|
using std::string;
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
u8 *ppm::load_ppm(std::istream &input) {
|
u8 *ppm::load_ppm(std::istream &input) {
|
||||||
|
@ -19,11 +21,21 @@ u8 *ppm::load_ppm(std::istream &input) {
|
||||||
|
|
||||||
u8 *buffer = new u8[width * height * 3];
|
u8 *buffer = new u8[width * height * 3];
|
||||||
for (size_t i = 0; i < width * height * 3; i++) {
|
for (size_t i = 0; i < width * height * 3; i++) {
|
||||||
u16 val = 0;
|
// The extraction operator assumes a uint8_t type represents an ascii
|
||||||
|
// character and thus grabs the first ascii character of the color value
|
||||||
|
// and places it within the u8.
|
||||||
|
// A u32 is used as the extraction operator understands it to be an integer
|
||||||
|
u32 val = 0;
|
||||||
input >> val;
|
input >> val;
|
||||||
buffer[i] = val;
|
buffer[i] = (u8)(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *ppm::from_file(string path) {
|
||||||
|
std::ifstream in(path);
|
||||||
|
u8 *ppm = ppm::load_ppm(in);
|
||||||
|
in.close();
|
||||||
|
return ppm;
|
||||||
}
|
}
|
|
@ -1,12 +1,14 @@
|
||||||
// Alexander Bass
|
// Alexander Bass
|
||||||
// Created 4/16/24
|
// Created 4/16/24
|
||||||
|
// Modified 4/17/24
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace ppm {
|
namespace ppm {
|
||||||
|
|
||||||
u8 *load_ppm(std::istream &input);
|
u8 *load_ppm(std::istream &input);
|
||||||
|
u8 *from_file(std::string path);
|
||||||
} // namespace ppm
|
} // namespace ppm
|
38
src/pts.cpp
Normal file
38
src/pts.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Alexander Bass
|
||||||
|
// Created 4/19/24
|
||||||
|
// Modified 4/19/24
|
||||||
|
#include "point.h"
|
||||||
|
#include <istream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
using std::string;
|
||||||
|
#include <cassert>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace pts {
|
||||||
|
std::vector<Point> load_pts(std::istream &input) {
|
||||||
|
std::vector<Point> output = {};
|
||||||
|
while (true) {
|
||||||
|
f64 i = 0.0, j = 0.0, k = 0.0;
|
||||||
|
f64 ni = 0.0, nj = 0.0, nk = 0.0;
|
||||||
|
input >> i;
|
||||||
|
input >> j;
|
||||||
|
input >> k;
|
||||||
|
input >> ni;
|
||||||
|
input >> nj;
|
||||||
|
input >> nk;
|
||||||
|
if (input.eof() || input.fail()) {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
output.push_back(Point(i, j, k));
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
std::vector<Point> load_pts_from_path(std::string path) {
|
||||||
|
std::ifstream input(path);
|
||||||
|
return load_pts(input);
|
||||||
|
input.close();
|
||||||
|
}
|
||||||
|
}
|
13
src/pts.h
Normal file
13
src/pts.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
// Alexander Bass
|
||||||
|
// Created 4/19/24
|
||||||
|
// Modified 4/19/24
|
||||||
|
#include "point.h"
|
||||||
|
#include <istream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace pts {
|
||||||
|
std::vector<Point> load_pts(std::istream &);
|
||||||
|
std::vector<Point> load_pts_from_path(std::string);
|
||||||
|
}
|
19
src/rgb.h
19
src/rgb.h
|
@ -1,19 +0,0 @@
|
||||||
// Alexander Bass
|
|
||||||
// Created 4/16/24
|
|
||||||
#pragma once
|
|
||||||
#include "types.h"
|
|
||||||
struct rgb {
|
|
||||||
f64 r;
|
|
||||||
f64 g;
|
|
||||||
f64 b;
|
|
||||||
rgb(f64 _r, f64 _g, f64 _b) {
|
|
||||||
r = _r;
|
|
||||||
g = _g;
|
|
||||||
b = _b;
|
|
||||||
}
|
|
||||||
void mix(rgb rhs) {
|
|
||||||
r *= rhs.r;
|
|
||||||
g *= rhs.g;
|
|
||||||
b *= rhs.b;
|
|
||||||
}
|
|
||||||
};
|
|
16
src/types.h
16
src/types.h
|
@ -1,18 +1,18 @@
|
||||||
// Alexander Bass
|
// Alexander Bass
|
||||||
// Created 4/15/24
|
// Created 4/15/24
|
||||||
// Modified 4/14/24
|
// Modified 4/17/24
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
typedef uint8_t u8;
|
typedef std::uint8_t u8;
|
||||||
typedef uint16_t u16;
|
typedef std::uint16_t u16;
|
||||||
typedef uint32_t u32;
|
typedef std::uint32_t u32;
|
||||||
typedef uint64_t u64;
|
typedef std::uint64_t u64;
|
||||||
|
|
||||||
typedef int8_t i8;
|
typedef std::int8_t i8;
|
||||||
typedef std::int16_t i16;
|
typedef std::int16_t i16;
|
||||||
typedef int32_t i32;
|
typedef std::int32_t i32;
|
||||||
typedef int64_t i64;
|
typedef std::int64_t i64;
|
||||||
|
|
||||||
typedef float f32;
|
typedef float f32;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
|
|
42
src/vec3.h
Normal file
42
src/vec3.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Alexander Bass
|
||||||
|
// Created 4/16/24
|
||||||
|
// Modified 4/17/24
|
||||||
|
#pragma once
|
||||||
|
#include "types.h"
|
||||||
|
struct vec3 {
|
||||||
|
f64 i;
|
||||||
|
f64 j;
|
||||||
|
f64 k;
|
||||||
|
vec3(f64 _i, f64 _j, f64 _k) {
|
||||||
|
i = _i;
|
||||||
|
j = _j;
|
||||||
|
k = _k;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 &operator*=(const vec3 &rhs) {
|
||||||
|
i *= rhs.i;
|
||||||
|
j *= rhs.j;
|
||||||
|
k *= rhs.k;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
vec3 operator*(const vec3 &rhs) {
|
||||||
|
vec3 copy = *this;
|
||||||
|
copy.i *= rhs.i;
|
||||||
|
copy.j *= rhs.j;
|
||||||
|
copy.k *= rhs.k;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
vec3 &operator*=(const f64 &rhs) {
|
||||||
|
i *= rhs;
|
||||||
|
j *= rhs;
|
||||||
|
k *= rhs;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
vec3 operator*(const f64 &rhs) {
|
||||||
|
vec3 copy = *this;
|
||||||
|
copy.i *= rhs;
|
||||||
|
copy.j *= rhs;
|
||||||
|
copy.k *= rhs;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in a new issue