diff options
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 95 |
1 files changed, 57 insertions, 38 deletions
@@ -1,7 +1,6 @@ constexpr unsigned Width = 1000; constexpr double Aspect = 16.0 / 9.0; constexpr unsigned Height = Width / Aspect; -constexpr unsigned Threads = 3; #include "color.h" #include "ray.h" @@ -26,14 +25,17 @@ constexpr unsigned Threads = 3; static View Camera; static World world; +static int threads = 4; static int SamplesPerPixel = 20; static float Daylight = 0.5f; -static std::unique_ptr<Renderer<Threads>> renderer; +static std::unique_ptr<Renderer> renderer; static std::chrono::time_point<std::chrono::high_resolution_clock> renderStart; static std::chrono::duration<double> renderTime; 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 addRandomObject(); int main() { @@ -47,10 +49,10 @@ int main() ImGui_ImplSDL2_InitForSDLRenderer(window, painter); ImGui_ImplSDLRenderer2_Init(painter); - world.add(point3( 0.00, -100.50, -1.0), 100.0, Material::Lambertian, color(0.5, 1.0, 0.5)); - world.add(point3(-0.50, 0.00, -1.2), 0.5, Material::Dielectric, color(1.0, 0.8, 0.8)); - world.add(point3( 0.50, 0.00, -1.0), 0.5, Material::Metal, color(0.5, 0.5, 0.5)); - world.add(point3(-0.05, -0.35, -0.7), 0.1, Material::Metal, color(0.8, 0.6, 0.0)); + world.add(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(); std::cout << "Spawning threads..." << std::endl; initiateRender(canvas); @@ -73,11 +75,17 @@ int main() ImGui::Begin("settings", nullptr, ImGuiWindowFlags_AlwaysAutoResize); ImGui::SliderFloat("fov", &Camera.fieldOfView, 10, 160); - ImGui::SetNextItemWidth(100); ImGui::InputDouble("X", &Camera.camera.x(), 0.1, 0.05, "%.2lf"); - ImGui::SameLine(); ImGui::SetNextItemWidth(100); ImGui::InputDouble("Y", &Camera.camera.y(), 0.1, 0.05, "%.2lf"); - ImGui::SameLine(); ImGui::SetNextItemWidth(100); ImGui::InputDouble("Z", &Camera.camera.z(), 0.1, 0.05, "%.2lf"); + ImGui::SameLine(); ImGui::SetNextItemWidth(60); + ImGui::InputInt("T", &threads); + ImGui::SetNextItemWidth(100); + ImGui::InputDouble("X", &Camera.camera.x(), 0.1, 0.05, "%.2lf"); + ImGui::SameLine(); ImGui::SetNextItemWidth(100); + ImGui::InputDouble("Y", &Camera.camera.y(), 0.1, 0.05, "%.2lf"); + ImGui::SameLine(); ImGui::SetNextItemWidth(100); + ImGui::InputDouble("Z", &Camera.camera.z(), 0.1, 0.05, "%.2lf"); ImGui::SliderInt("samples", &SamplesPerPixel, 1, 200); ImGui::SliderFloat("shade", &Daylight, 0.f, 1.f); + if (ImGui::Button("recalculate")) { initiateRender(canvas); } @@ -94,6 +102,7 @@ int main() renderer->stop(); run = false; } + if (*renderer) { SDL_DestroyTexture(tex); tex = SDL_CreateTextureFromSurface(painter, canvas); @@ -114,35 +123,13 @@ int main() ImGui::End(); ImGui::Begin("balls", nullptr, ImGuiWindowFlags_NoResize); { - char radius[] = "radius 0"; - char mat[] = "mat 0"; - char xpos[] = "x 0"; - char ypos[] = "y 0"; - char zpos[] = "z 0"; - - for (auto& o : std::views::drop(world.objects, 1)) { - ImGui::SetNextItemWidth(200); - ImGui::Combo(mat, reinterpret_cast<int *>(&o.M), - "Lambertian\0Metal\0Dielectric\0"); - ImGui::SameLine(); ImGui::SetNextItemWidth(100); - ImGui::InputDouble(radius, &o.radius, 0.1, 0.05, "%.2lf"); - ImGui::SetNextItemWidth(100); - ImGui::InputDouble(xpos, &o.center.x(), 0.05, 0.05, "%.2lf"); - ImGui::SameLine(); ImGui::SetNextItemWidth(100); - ImGui::InputDouble(ypos, &o.center.y(), 0.1, 0.05, "%.2lf"); - ImGui::SameLine(); ImGui::SetNextItemWidth(100); - ImGui::InputDouble(zpos, &o.center.z(), 0.1, 0.05, "%.2lf"); - - radius[7]++; - mat[4]++; - xpos[2]++; - ypos[2]++; - zpos[2]++; - } + std::ranges::for_each( + std::views::zip(std::views::iota(0), + std::views::drop(world.objects, 1)), + [](auto io) { std::apply(showObjectControls, io); }); + if (ImGui::Button("add")) { - const point3 pos = vec3::random() * vec3(4, 1.5, 4) - vec3(2, 0, 4); - const color col = vec3::random(); - world.add(pos, randomN() * 0.5 + 0.1, Material::Lambertian, col); + addRandomObject(); initiateRender(canvas); } if (ImGui::Button("del")) { @@ -200,5 +187,37 @@ void initiateRender(SDL_Surface *canvas) }; Camera.recalculate(); - renderer.reset(new Renderer<Threads>(func, Width, Height, (uint32_t *)canvas->pixels)); + threads = std::clamp(threads, 1, Renderer::MaxThreads); + renderer.reset(new Renderer(threads, func, Width, Height, + (uint32_t *)canvas->pixels)); } + +void showObjectControls(int index, Sphere& 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::SetNextItemWidth(100); + ImGui::InputDouble((std::string("x") + idx).c_str(), + &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"); + ImGui::SameLine(); ImGui::SetNextItemWidth(100); + ImGui::InputDouble((std::string("z") + idx).c_str(), + &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 - 1)); + world.add(pos, randomN() * 0.3 + 0.05, (Material)mat, col); +} + |