104 lines
2.8 KiB
C++
104 lines
2.8 KiB
C++
#include "args.hpp"
|
|
|
|
#include <charconv>
|
|
#include <format>
|
|
#include <stdexcept>
|
|
|
|
namespace rog::cli {
|
|
|
|
args parse(int argc, char **argv) {
|
|
args result{};
|
|
result.extent = {512, 512};
|
|
result.samples_per_pixel = 256;
|
|
|
|
if (argc < 2) {
|
|
throw std::runtime_error("no scene provided");
|
|
}
|
|
|
|
std::vector<std::string_view> args_view(argv + 1,
|
|
argv + argc); // skip program name
|
|
|
|
for (size_t i = 0; i < args_view.size(); ++i) {
|
|
std::string_view arg = args_view[i];
|
|
|
|
if (arg == "--help" || arg == "-h" || arg == "-?") {
|
|
result.help = true;
|
|
return result;
|
|
}
|
|
|
|
if (arg[0] != '-' && result.scene_path.empty()) {
|
|
result.scene_path = std::filesystem::path(arg);
|
|
continue;
|
|
}
|
|
|
|
if (arg == "--width" || arg == "-w") {
|
|
if (i + 1 >= args_view.size()) {
|
|
throw std::runtime_error("error: --width requires a value");
|
|
}
|
|
const auto val = args_view[++i];
|
|
uint32_t w = 0;
|
|
std::from_chars(val.data(), val.data() + val.size(), w);
|
|
result.extent.x = w;
|
|
continue;
|
|
}
|
|
|
|
if (arg == "--height" || (arg == "-h" && i + 1 < args_view.size() &&
|
|
args_view[i + 1][0] != '-')) {
|
|
if (i + 1 >= args_view.size()) {
|
|
throw std::runtime_error("error: --height requires a value");
|
|
}
|
|
const auto val = args_view[++i];
|
|
uint32_t h = 0;
|
|
std::from_chars(val.data(), val.data() + val.size(), h);
|
|
result.extent.y = h;
|
|
continue;
|
|
}
|
|
|
|
if (arg == "--spp") {
|
|
if (i + 1 >= args_view.size()) {
|
|
throw std::runtime_error("error: --spp requires a value");
|
|
}
|
|
const auto val = args_view[++i];
|
|
uint32_t spp = 0;
|
|
std::from_chars(val.data(), val.data() + val.size(), spp);
|
|
result.samples_per_pixel = spp;
|
|
continue;
|
|
}
|
|
|
|
if (arg == "--blender") {
|
|
if (i + 1 >= args_view.size()) {
|
|
throw std::runtime_error("error: --blender requires a path");
|
|
}
|
|
result.blender_path = std::filesystem::path(args_view[++i]);
|
|
continue;
|
|
}
|
|
|
|
if (arg[0] == '-') {
|
|
throw std::runtime_error(std::format("error: unknown option '{}'", arg));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
std::string_view help_message() noexcept {
|
|
return R"(Usage: rogue [OPTIONS] <scene>
|
|
|
|
positional:
|
|
<scene> Path to .glb or .blend file (required)
|
|
|
|
options:
|
|
-w, --width <uint> Render width (default: 512)
|
|
-h, --height <uint> Render height (default: 512)
|
|
--spp <uint> Samples per pixel (default: 256)
|
|
--blender <path> Custom path to Blender executable
|
|
--help Show this help message
|
|
|
|
examples:
|
|
rogue scene.glb
|
|
rogue my_scene.blend --interactive
|
|
rogue scene.blend -w 1920 -h 1080 --spp 1024
|
|
)";
|
|
}
|
|
} // namespace rog::cli
|