constexpr unsigned Height = Width / Aspect;
#include "color.h"
+#include "object.h"
#include "ray.h"
#include "renderer.h"
-#include "sphere.h"
#include "vec3.h"
#include "view.h"
#include "world.h"
static color ray_color(const ray& r, int depth = 50);
static void initiateRender(SDL_Surface *canvas);
-static void showObjectControls(int index, Sphere& o);
+static void showObjectControls(int index, std::unique_ptr<Object>& o);
static void addRandomObject();
static void preview(SDL_Surface *canvas);
ImGui_ImplSDL2_InitForSDLRenderer(window, painter);
ImGui_ImplSDLRenderer2_Init(painter);
- world.add(point3(0.00, -100.50, -1.0), 100.0,
+ world.add<Sphere>(point3(0.00, -100.50, -1.0), 100.0,
Material::Lambertian, color(0.5, 1.0, 0.5));
for (auto i : std::views::iota(0, 10))
addRandomObject();
return {};
if (auto hit = world.hit(r); hit) {
- const auto& [closest, sphere] = *hit;
- const auto [atten, scat] = sphere.scatter(r, closest);
+ const auto& [closest, object] = *hit;
+ const auto [atten, scat] = object->scatter(r, closest);
return atten * ray_color(scat, depth - 1);
} else {
const auto unitDir = r.direction().normalize();
(uint32_t *)canvas->pixels));
}
-void showObjectControls(int index, Sphere& o)
+void showObjectControls(int index, std::unique_ptr<Object>& o)
{
const auto idx = std::to_string(index);
ImGui::SetNextItemWidth(200);
- ImGui::Combo((std::string("mat") + idx).c_str(), reinterpret_cast<int *>(&o.M),
- "Lambertian\0Metal\0Dielectric\0");
- ImGui::SameLine(); ImGui::SetNextItemWidth(100);
- ImGui::InputDouble((std::string("radius") + idx).c_str(),
- &o.radius, 0.1, 0.05, "%.2lf");
+ ImGui::Combo((std::string("mat") + idx).c_str(),
+ reinterpret_cast<int *>(&o->M), "Lambertian\0Metal\0Dielectric\0");
+ //ImGui::SameLine(); ImGui::SetNextItemWidth(100);
+ //ImGui::InputDouble((std::string("radius") + idx).c_str(),
+ // &o->radius, 0.1, 0.05, "%.2lf");
ImGui::SetNextItemWidth(100);
ImGui::InputDouble((std::string("x") + idx).c_str(),
- &o.center.x(), 0.05, 0.05, "%.2lf");
+ &o->center.x(), 0.05, 0.05, "%.2lf");
ImGui::SameLine(); ImGui::SetNextItemWidth(100);
ImGui::InputDouble((std::string("y") + idx).c_str(),
- &o.center.y(), 0.1, 0.05, "%.2lf");
+ &o->center.y(), 0.1, 0.05, "%.2lf");
ImGui::SameLine(); ImGui::SetNextItemWidth(100);
ImGui::InputDouble((std::string("z") + idx).c_str(),
- &o.center.z(), 0.1, 0.05, "%.2lf");
+ &o->center.z(), 0.1, 0.05, "%.2lf");
}
void addRandomObject()
const point3 pos = vec3::random() * vec3(6, 0.8, 3) - vec3(3, 0, 3.8);
const color col = vec3::random();
const auto mat = (int)(randomN() * (int)Material::Undefined);
- world.add(pos, randomN() * 0.3 + 0.05, (Material)mat, col);
+ world.add<Sphere>(pos, randomN() * 0.3 + 0.05, (Material)mat, col);
}
void preview(SDL_Surface *canvas)
#define SPHERE_H
#include "color.h"
+#include "object.h"
#include "ray.h"
#include "vec3.h"
#include <optional>
#include <tuple>
-enum class Material : int {
- Lambertian = 0,
- Metal,
- Dielectric,
- Undefined
-};
-
-struct Sphere
+struct Sphere : public Object
{
- point3 center;
double radius;
- Material M;
- color tint;
- std::pair<color, ray> scatter(const ray& r, double root) const {
+ Sphere(point3 center_, double radius_, Material M_, color tint_):
+ Object(center_, M_, tint_), radius(radius_) {}
+
+ std::pair<color, ray> scatter(const ray& r, double root) const override {
const auto p = r.at(root);
auto normal = (p - center) / radius;
}
}
- std::optional<double> hit(const ray& r, double tmin, double tmax) const {
+ std::optional<double> hit(const ray& r, double tmin, double tmax) const override {
const vec3 oc = center - r.origin();
const auto a = r.direction().length_squared();
const auto h = r.direction().dot(oc);