From 2264ed7a8f8f3bac42995dccd7b4004afb6e5428 Mon Sep 17 00:00:00 2001 From: tomoron Date: Tue, 4 Feb 2025 03:19:29 +0100 Subject: [PATCH 1/4] start changing parsing of arguments to add settings and start a render with no input --- .vscode/settings.json | 86 ------------------- Makefile | 1 + imgui.ini | 4 +- includes/RT.hpp | 3 +- includes/RT/Arguments.hpp | 50 +++++++++++ includes/RT/Renderer.hpp | 17 +++- includes/RT/Scene.hpp | 10 ++- includes/RT/SceneParser.hpp | 4 +- scenes/lambo.rt | 2 +- scenes/test.rt | 2 +- srcs/RT.cpp | 15 ++-- srcs/class/Arguments.cpp | 141 +++++++++++++++++++++++++++++++ srcs/class/Renderer.cpp | 161 ++++++++++++++++++++++++++++++++---- srcs/class/Scene.cpp | 40 ++++----- srcs/class/SceneParser.cpp | 4 +- srcs/class/Window.cpp | 4 +- 16 files changed, 396 insertions(+), 148 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 includes/RT/Arguments.hpp create mode 100644 srcs/class/Arguments.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index abe297a..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "files.associations": { - "*.cs": "csharp", - "atomic": "cpp", - "bit": "cpp", - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "compare": "cpp", - "concepts": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "exception": "cpp", - "initializer_list": "cpp", - "ios": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "iterator": "cpp", - "limits": "cpp", - "memory": "cpp", - "new": "cpp", - "ostream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "typeinfo": "cpp", - "utility": "cpp", - "xfacet": "cpp", - "xiosbase": "cpp", - "xlocale": "cpp", - "xlocinfo": "cpp", - "xlocnum": "cpp", - "xmemory": "cpp", - "xstddef": "cpp", - "xstring": "cpp", - "xtr1common": "cpp", - "xutility": "cpp", - "array": "cpp", - "vector": "cpp", - "deque": "cpp", - "string_view": "cpp", - "span": "cpp", - "*.tcc": "cpp", - "chrono": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "memory_resource": "cpp", - "optional": "cpp", - "format": "cpp", - "functional": "cpp", - "sstream": "cpp", - "variant": "cpp", - "charconv": "cpp", - "cstdarg": "cpp", - "cwctype": "cpp", - "map": "cpp", - "set": "cpp", - "algorithm": "cpp", - "numeric": "cpp", - "random": "cpp", - "ratio": "cpp", - "iomanip": "cpp", - "numbers": "cpp", - "cinttypes": "cpp", - "fstream": "cpp", - "list": "cpp", - "locale": "cpp", - "xhash": "cpp", - "xlocbuf": "cpp", - "xlocmes": "cpp", - "xlocmon": "cpp", - "xloctime": "cpp", - "xtree": "cpp", - "forward_list": "cpp" - }, - "cmake.ignoreCMakeListsMissing": true -} \ No newline at end of file diff --git a/Makefile b/Makefile index 7635c57..4cb0d8d 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,7 @@ ALL_SRCS := $(IMGUI_SRCS) \ class/ObjParser.cpp \ class/BVH.cpp \ class/Renderer.cpp \ + class/Arguments.cpp SRCS := $(ALL_SRCS:%=$(SRCS_DIR)/%) OBJS := $(addprefix $(OBJS_DIR)/, $(SRCS:%.cpp=%.o)) diff --git a/imgui.ini b/imgui.ini index 633cc90..8ac2eb7 100644 --- a/imgui.ini +++ b/imgui.ini @@ -29,6 +29,6 @@ Pos=1556,610 Size=284,382 [Window][Settings] -Pos=1568,11 -Size=336,975 +Pos=532,13 +Size=336,287 diff --git a/includes/RT.hpp b/includes/RT.hpp index 84e906f..9e5aebe 100644 --- a/includes/RT.hpp +++ b/includes/RT.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:52:10 by TheRed #+# #+# */ -/* Updated: 2025/02/03 18:17:48 by ycontre ### ########.fr */ +/* Updated: 2025/02/04 01:10:20 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -57,6 +57,7 @@ struct Vertex { # include "objects/Portal.hpp" # include "objects/Cylinder.hpp" +# include "Arguments.hpp" # include "Camera.hpp" # include "Renderer.hpp" # include "Window.hpp" diff --git a/includes/RT/Arguments.hpp b/includes/RT/Arguments.hpp new file mode 100644 index 0000000..f0a41a6 --- /dev/null +++ b/includes/RT/Arguments.hpp @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Arguments.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/04 01:07:08 by tomoron #+# #+# */ +/* Updated: 2025/02/04 03:10:58 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ARGUMENTS_HPP +# define ARGUMENTS_HPP + +#include "RT.hpp" + +typedef struct s_arg +{ + char shortName; + std::string longName; + int isFlag; +} t_arg; + +class Arguments +{ + public : + Arguments(int argc, char **argv); + bool getHeadless(void) const; + std::string &getSceneName(void); + std::string getRenderPathName(void); + bool error(void) const; + + private: + void printUsage(); + + int handleArg(char **argv, int argc, int *i); + void initArguments(void); + void addArgument(char shortName, std::string longName, int isFlag); + + void parseRenderPathName(char * path); + + bool _headless; + bool _err; + + std::vector _args; + std::map _values; +}; + +#endif diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index e180dc3..6eb54db 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/01/30 22:15:55 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 00:41:10 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,21 +37,28 @@ class Renderer { public: Renderer(Scene *scene, Window *win); + Renderer(Scene *scene, Window *win, std::string filename); void renderImgui(void); void update(Shader &shader); int rendering(void) const; + bool shouldClose(void) const; private: void addPoint(float time); + void init(Scene *scene, Window *win); + void savePath(void); + void rawRead(std::ifstream &file, void *buf, size_t len); + void loadPath(std::string filename); void makeMovement(float timeFromStart, float curSplitTimeReset); void initRender(); void addImageToRender(Shader &shader); void endRender(void); void imguiPathCreation(void); void imguiRenderInfo(void); - std::string floatToTime(float timef); + void imguiRenderSettings(void); + std::string floatToTime(double timef); glm::vec2 bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time); - void updateAvailableCodecs(void); + void updateAvailableCodecs(int mode, AVCodecID id); void fillGoodCodecList(std::vector &lst); glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha); @@ -69,6 +76,10 @@ class Renderer std::vector _codecList; std::vector _codecListStr; int _codecIndex; + bool _renderSettings; + bool _ignoreUnavailableCodec; + bool _headless; + bool _shouldClose; int _curPathIndex; int _destPathIndex; diff --git a/includes/RT/Scene.hpp b/includes/RT/Scene.hpp index 7e78db4..700399c 100644 --- a/includes/RT/Scene.hpp +++ b/includes/RT/Scene.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:30:18 by ycontre #+# #+# */ -/* Updated: 2025/01/28 19:05:16 by ycontre ### ########.fr */ +/* Updated: 2025/02/04 03:11:36 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -105,11 +105,9 @@ class Camera; class Scene { public: - Scene(); + Scene(std::string &name); ~Scene(); - bool parseScene(char *name); - void addObject(Object *object); void addMaterial(Material *material); void addTexture(std::string path); @@ -141,7 +139,11 @@ class Scene Camera *getCamera(void) const; GPUMaterial getMaterial(int material_index); + bool fail(void) const; + private: + + bool _fail; std::vector _gpu_bvh_data; std::vector _gpu_bvh; diff --git a/includes/RT/SceneParser.hpp b/includes/RT/SceneParser.hpp index 59cdc0a..d5932e6 100644 --- a/includes/RT/SceneParser.hpp +++ b/includes/RT/SceneParser.hpp @@ -6,7 +6,7 @@ /* By: TheRed +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/26 21:37:37 by TheRed #+# #+# */ -/* Updated: 2025/01/21 15:15:13 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 01:21:28 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,7 +18,7 @@ class SceneParser { public: - SceneParser(Scene *scene, char *filename); + SceneParser(Scene *scene, std::string filename); bool parseLine(const std::string &line); diff --git a/scenes/lambo.rt b/scenes/lambo.rt index bc083a1..3bc0817 100644 --- a/scenes/lambo.rt +++ b/scenes/lambo.rt @@ -19,7 +19,7 @@ cu 0 10 0 5 5 5 3 sp 0 10 0 1 4 -OBJ scenes/obj/lambo.obj 0 1.5 0 1 0 0 0 +OBJ obj/lambo.obj 0 1.5 0 1 0 0 0 diff --git a/scenes/test.rt b/scenes/test.rt index 0f4cd70..750ec09 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -3,4 +3,4 @@ CAM -0.181956 1.3733 2.83437 -16 -87.8001 0 1 90 5 MAT 255 255 255 10.0 1.0 0.0 //white # sp 0 0 0 1 0 -OBJ scenes/obj/jinx.obj 0 0 0 1 +#OBJ scenes/bj/jinx.obj 0 0 0 1 diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 964f009..a518583 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:51:49 by TheRed #+# #+# */ -/* Updated: 2025/01/30 22:29:00 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 03:06:51 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,15 +14,16 @@ int main(int argc, char **argv) { - Scene scene; - - if (argc <= 1 || !scene.parseScene(argv[1])) - return (1); - + Arguments args(argc, argv); + if(args.error()) + return(1); + Scene scene(args.getSceneName()); + if(scene.fail()) + return(1); Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0); Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl"); // Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl"); - + GLint max_gpu_size; glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_gpu_size); diff --git a/srcs/class/Arguments.cpp b/srcs/class/Arguments.cpp new file mode 100644 index 0000000..3a6fbe1 --- /dev/null +++ b/srcs/class/Arguments.cpp @@ -0,0 +1,141 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Arguments.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/04 01:05:44 by tomoron #+# #+# */ +/* Updated: 2025/02/04 03:16:25 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "RT.hpp" + +Arguments::Arguments(int argc, char **argv) +{ + initArguments(); + _headless = 0; + _err = 0; + + if(argc <= 1) + { + _err = 1; + printUsage(); + return ; + } + + for(int i = 1; i < argc; i++) + { + if(!handleArg(argv, argc, &i)) + { + _err = 1; + return ; + } + } + if(_values.find("sceneName") == _values.end()) + { + std::cerr << "missing scene name" << std::endl; + _err = 1; + } +} + +void Arguments::printUsage(void) +{ + std::cerr << "usage : [options] [options]" << std::endl; + std::cerr << R""""(options : + -r | --renderpath : filename for the renderer path + -h | --headless : does the program need to start rendering as soon as it starts(and close automatically) +)""""; +} + +bool Arguments::error(void) const +{ + return(_err); +} + +std::string &Arguments::getSceneName(void) +{ + return(_values["sceneName"]); +} + +void Arguments::addArgument(char shortName, std::string longName, int isFlag) +{ + t_arg arg; + + arg.shortName = shortName; + arg.longName = longName; + arg.isFlag = isFlag; + _args.push_back(arg); +} + +void Arguments::initArguments() +{ + addArgument('r', "renderPath", 0); + addArgument('h', "headless", 1); +} + +int Arguments::handleArg(char **argv, int argc, int *i) +{ + std::string arg(argv[*i]); + + (void)i; + if(!arg.size()) + return(1); + if(arg.size() >= 2 && arg[0] == '-' && arg[1] == '-') + { + for(std::vector::iterator it = _args.begin(); it != _args.end(); it++) + { + if((*it).longName == arg.substr(2)) + { + if((*it).isFlag) + _values[(*it).longName] = "yes"; + else if(*i == argc - 1) + { + std::cerr << "missing option" << std::endl; + return(0); + } + else + _values[(*it).longName] = argv[++(*i)]; + return(1); + } + } + std::cerr<< "unrecognized option : " << arg << std::endl; + return(0); + } + else if(arg[0] == '-') + { + for(size_t j = 1; j < arg.size(); j++) + { + for(std::vector::iterator it = _args.begin(); it != _args.end(); it++) + { + if((*it).shortName == arg[j]) + { + if((*it).isFlag) + _values[(*it).longName] = "yes"; + else if(*i == argc - 1) + { + std::cerr << "missing option" << std::endl; + return(0); + } + else + _values[(*it).longName] = argv[++(*i)]; + return(1); + } + } + std::cerr << "unrecognized option : -" << arg[j] << std::endl; + return(0); + } + } + else + { + if(_values.find("sceneName") == _values.end()) + _values["sceneName"] = arg; + else + { + std::cerr << "unrecognized option : " << arg << std::endl; + return(0); + } + } + return(1); +} diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index d90692e..65e0a2e 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,25 +6,41 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/01/30 22:22:07 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 00:43:18 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "RT.hpp" Renderer::Renderer(Scene *scene, Window *win) +{ + init(scene, win); + _headless = 0; +} + +Renderer::Renderer(Scene *scene, Window *win, std::string filename) +{ + init(scene, win); + _headless = 1; + loadPath(filename); + initRender(); +} + +void Renderer::init(Scene *scene, Window *win) { _scene = scene; _win = win; _min = 0; _sec = 0; _fps = 30; + _shouldClose = 0; _autoTime = 0; _samples = 1; _testSamples = 1; _curSamples = 0; _destPathIndex = 0; _frameCount = 0; + _renderSettings = 0; _outputFilename = "output.avi"; memcpy(_filenameBuffer, _outputFilename.c_str(), _outputFilename.length()); _filenameBuffer[_outputFilename.length()] = 0; @@ -33,7 +49,87 @@ Renderer::Renderer(Scene *scene, Window *win) _yuv_frame = 0; _format = 0; _codec_context = 0; - updateAvailableCodecs(); + _ignoreUnavailableCodec = 0; + updateAvailableCodecs(_ignoreUnavailableCodec, (AVCodecID)0); +} + +void Renderer::rawRead(std::ifstream &file, void *buf, size_t len) +{ + file.read((char *)buf, len); + if(file.fail()) + throw std::runtime_error("syntax error in path file"); +} + +/* path file format (bytes): + * - output file name (terminated by a \0) + * - codec id + * - samples per image + * - fps + * - path nodes (until the end) + */ +void Renderer::savePath(void) +{ + std::ofstream outputFile; + const AVCodec *codec; + + codec = _codecList[_codecIndex]; + outputFile.open("output.path", std::ios::binary); + outputFile.write(_outputFilename.c_str(), _outputFilename.length() + 1); + outputFile.write((char *)&codec->id, sizeof(codec->id)); + outputFile.write((char *)&_samples, sizeof(_samples)); + outputFile.write((char *)&_fps, sizeof(_fps)); + for(std::vector::iterator it = _path.begin(); it != _path.end(); it++) + outputFile.write((char *)&(*it), sizeof(t_pathPoint)); + outputFile.close(); +} + + +void Renderer::loadPath(std::string filename) +{ + std::ifstream file; + AVCodecID codecId; + t_pathPoint pathPoint; + std::vector::iterator pos; + char c; + + _outputFilename = ""; + _filenameBuffer[0] = 0; + file.open(filename); + c = 1; + while(c) + { + rawRead(file, &c, 1); + if(c && c < 32 && c > 126) + throw std::runtime_error("invalid char in filename"); + if(c) + _outputFilename += c; + } + rawRead(file, &codecId, sizeof(codecId)); + updateAvailableCodecs(2, codecId); + if(_codecList.size() == 0) + throw std::runtime_error("codec not available"); + rawRead(file, &_samples, sizeof(_samples)); + rawRead(file, &_fps, sizeof(_fps)); + if(_samples < 1 || _fps < 1) + throw std::runtime_error("invalid value provided in fps or samples"); + while(!file.eof()) + { + rawRead(file, &pathPoint, sizeof(t_pathPoint)); + if(pathPoint.time < .0f) + throw std::runtime_error("invalid time provided in path"); + pos = _path.begin(); + while(pos != _path.end() && pos->time <= pathPoint.time) + pos++; + _path.insert(pos, pathPoint); + } + if(_path.size() < 2) + throw std::runtime_error("not enough path points provided in the path"); + file.close(); +} + +bool Renderer::shouldClose(void) const +{ + return(_shouldClose); } void Renderer::fillGoodCodecList(std::vector &lst) @@ -46,7 +142,12 @@ void Renderer::fillGoodCodecList(std::vector &lst) lst.push_back(AV_CODEC_ID_V210); } -void Renderer::updateAvailableCodecs(void) +/* modes : + * 0 : adds only supported codecs are showed + * 1 : adds all codecs + * 2 : adds only codec + */ +void Renderer::updateAvailableCodecs(int mode, AVCodecID id) { const AVCodec *codec; AVCodecContext *ctx; @@ -69,6 +170,11 @@ void Renderer::updateAvailableCodecs(void) codec = avcodec_find_encoder(*it); if(!codec) continue; + if (mode == 1 || (mode == 2 && codec->id == id)) + { + _codecList.push_back(codec); + continue; + } ctx = avcodec_alloc_context3(codec); if(ctx) { @@ -226,6 +332,8 @@ void Renderer::endRender(void) _rgb_frame = 0; _yuv_frame = 0; _codec_context = 0; + if(_headless) + _shouldClose = 1; } void Renderer::addPoint(float time) @@ -442,15 +550,9 @@ void Renderer::imguiPathCreation(void) prevSpeed = 0; ImGui::SliderInt("test spi", &_testSamples, 1, 10); - ImGui::SliderInt("render spi", &_samples, 1, 1000); - ImGui::SliderInt("render fps", &_fps, 30, 120); - ImGui::Combo("codec", &_codecIndex, _codecListStr.data(), _codecListStr.size()); - if(ImGui::InputText("file name", _filenameBuffer, 512)) - { - _outputFilename = _filenameBuffer; - updateAvailableCodecs(); - } + if(ImGui::Button("render settings")) + _renderSettings = 1; if(_path.size() > 1 && ImGui::Button("try full path")) { _scene->getCamera()->setPosition(_path[0].pos); @@ -461,8 +563,6 @@ void Renderer::imguiPathCreation(void) _destPathIndex = _path.size() - 1; _testMode = 1; } - if(_path.size() > 1 && _codecList.size() && ImGui::Button("start render")) - initRender(); ImGui::Separator(); @@ -485,6 +585,7 @@ void Renderer::imguiPathCreation(void) if(ImGui::Button("add step")) addPoint(time); + ImGui::Separator(); for(unsigned long i = 0; i < _path.size(); i++) @@ -529,7 +630,7 @@ void Renderer::imguiPathCreation(void) } } -std::string Renderer::floatToTime(float timef) +std::string Renderer::floatToTime(double timef) { std::string res; uint64_t time; @@ -537,13 +638,13 @@ std::string Renderer::floatToTime(float timef) int firstValue; time = timef; - values[0] = time / 3600 * 24 * 365; + values[0] = time / (3600 * 24 * 365); time = time % (3600 * 24 * 365); - values[1] = time / 3600 * 24 * 30; + values[1] = time / (3600 * 24 * 30); time = time % (3600 * 24 * 30); - values[2] = time / 3600 * 24 * 7; + values[2] = time / (3600 * 24 * 7); time = time % (3600 * 24 * 7); - values[3] = time / 3600 * 24; + values[3] = time / (3600 * 24); time = time % (3600 * 24); values[4] = time / 3600; time = time % 3600; @@ -619,6 +720,28 @@ void Renderer::imguiRenderInfo(void) } } +void Renderer::imguiRenderSettings(void) +{ + ImGui::SliderInt("render spi", &_samples, 1, 1000); + ImGui::SliderInt("render fps", &_fps, 30, 120); + ImGui::Combo("codec", &_codecIndex, _codecListStr.data(), _codecListStr.size()); + if(ImGui::InputText("file name", _filenameBuffer, 512)) + { + _outputFilename = _filenameBuffer; + updateAvailableCodecs(_ignoreUnavailableCodec, (AVCodecID)0); + } + if(_path.size() > 1 && _codecList.size()) + { + if(ImGui::Button("start render")) + initRender(); + ImGui::SameLine(); + if(ImGui::Button("save path")) + savePath(); + } + if(ImGui::Button("go back")) + _renderSettings = 0; +} + void Renderer::renderImgui(void) { // ImGui::Begin("Renderer"); @@ -626,6 +749,8 @@ void Renderer::renderImgui(void) { if(rendering()) imguiRenderInfo(); + else if(_renderSettings) + imguiRenderSettings(); else imguiPathCreation(); } diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 7e6ab5d..9ac432a 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:29:41 by ycontre #+# #+# */ -/* Updated: 2025/01/28 19:17:39 by ycontre ### ########.fr */ +/* Updated: 2025/02/04 03:11:24 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,11 +15,15 @@ #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" -Scene::Scene() +Scene::Scene(std::string &name) { + std::cout << "name : " << name << std::endl; + std::ifstream file(name); + std::string line; _camera = new Camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), -90.0f, 0.0f); _gpu_volume.enabled = 0; + _fail = 0; _gpu_volume.sigma_a = glm::vec3(0.0000f); _gpu_volume.sigma_s = glm::vec3(0.0800f); _gpu_volume.sigma_t = _gpu_volume.sigma_a + _gpu_volume.sigma_s; @@ -29,23 +33,13 @@ Scene::Scene() _gpu_debug.mode = 0; _gpu_debug.triangle_treshold = 1; _gpu_debug.box_treshold = 1; -} -Scene::~Scene() -{ - delete (_camera); -} - -bool Scene::parseScene(char *name) -{ - std::ifstream file(name); - std::string line; if (!file.is_open()) { - std::cout << "Error opening the file" << std::endl; - file.close(); - return (false); + std::cerr << "Can't open scene file" << std::endl; + _fail = 1; + return ; } SceneParser scene_parser(this, name); @@ -54,19 +48,22 @@ bool Scene::parseScene(char *name) { if (!scene_parser.parseLine(line)) { - std::cerr << line << std::endl; file.close(); - return (false); + std::cerr << line << std::endl; + _fail = 1; + return ; } } file.close(); std::cout << "Parsing done" << std::endl; - - return (true); } +Scene::~Scene() +{ + delete (_camera); +} void Scene::addObject(Object *obj) { @@ -311,6 +308,11 @@ void Scene::updateLightAndObjects(int mat_id) } } +bool Scene::fail(void) const +{ + return(_fail); +} + std::set Scene::getGPULights() { return (_gpu_lights); diff --git a/srcs/class/SceneParser.cpp b/srcs/class/SceneParser.cpp index b499c3b..a2b4887 100644 --- a/srcs/class/SceneParser.cpp +++ b/srcs/class/SceneParser.cpp @@ -6,13 +6,13 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/26 21:43:51 by TheRed #+# #+# */ -/* Updated: 2025/01/30 22:29:15 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 01:21:11 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "SceneParser.hpp" -SceneParser::SceneParser(Scene *scene, char *filename) : _scene(scene), _filename(filename) +SceneParser::SceneParser(Scene *scene, std::string filename) : _scene(scene), _filename(filename) { object_parsers["sp"] = [](std::stringstream &ss) -> Object * { return (new Sphere(ss)); }; object_parsers["pl"] = [](std::stringstream &ss) -> Object * { return (new Plane(ss)); }; diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index bfc3fa1..ef37319 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 16:16:24 by TheRed #+# #+# */ -/* Updated: 2025/01/28 15:15:53 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 00:42:01 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -161,7 +161,7 @@ void Window::pollEvents() } bool Window::shouldClose() { - return glfwWindowShouldClose(_window); + return glfwWindowShouldClose(_window) || _renderer->shouldClose(); } void Window::rendererUpdate(Shader &shader) From 9ab0212d0329dcd39c8a8d7c5d11c840c6a7a99f Mon Sep 17 00:00:00 2001 From: tomoron Date: Tue, 4 Feb 2025 19:06:41 +0100 Subject: [PATCH 2/4] renderer can now load a path --- Makefile | 2 +- imgui.ini | 2 +- includes/RT/Arguments.hpp | 14 ++++++++----- includes/RT/Renderer.hpp | 5 ++--- includes/RT/Window.hpp | 4 ++-- srcs/RT.cpp | 5 +++-- srcs/class/Arguments.cpp | 40 +++++++++++++++++++++++++++-------- srcs/class/Renderer.cpp | 44 +++++++++++++++++++++++++++------------ srcs/class/Scene.cpp | 3 +-- srcs/class/Window.cpp | 6 +++--- 10 files changed, 84 insertions(+), 41 deletions(-) diff --git a/Makefile b/Makefile index 4cb0d8d..1a789cb 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ else RM := rm -rf DIR_DUP = mkdir -p $(@D) CC := clang++ - CFLAGS := -Wall -Wextra -Werror -g -O3 + CFLAGS := -Wall -Wextra -Werror -g #-O3 IFLAGS := -I./includes -I./includes/RT -I./includes/imgui LDFLAGS += -lglfw -lGL -lGLU -lX11 -lpthread -ldl -lavformat -lavcodec -lavutil -lswscale -lswresample FILE = $(shell ls -lR srcs/ | grep -F .c | wc -l) diff --git a/imgui.ini b/imgui.ini index 8ac2eb7..1a5d442 100644 --- a/imgui.ini +++ b/imgui.ini @@ -29,6 +29,6 @@ Pos=1556,610 Size=284,382 [Window][Settings] -Pos=532,13 +Pos=478,75 Size=336,287 diff --git a/includes/RT/Arguments.hpp b/includes/RT/Arguments.hpp index f0a41a6..62c5b12 100644 --- a/includes/RT/Arguments.hpp +++ b/includes/RT/Arguments.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 01:07:08 by tomoron #+# #+# */ -/* Updated: 2025/02/04 03:10:58 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 17:04:59 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,10 +26,14 @@ class Arguments { public : Arguments(int argc, char **argv); - bool getHeadless(void) const; - std::string &getSceneName(void); - std::string getRenderPathName(void); - bool error(void) const; + + bool getHeadless(void) const; + bool error(void) const; + void show(void); + + std::string &getSceneName(void); + std::string *getRenderPath(void); + bool getHeadless(void); private: void printUsage(); diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 6eb54db..b26038e 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/02/04 00:41:10 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 18:46:22 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,8 +36,7 @@ typedef struct s_pathPoint class Renderer { public: - Renderer(Scene *scene, Window *win); - Renderer(Scene *scene, Window *win, std::string filename); + Renderer(Scene *scene, Window *win, Arguments &args); void renderImgui(void); void update(Shader &shader); int rendering(void) const; diff --git a/includes/RT/Window.hpp b/includes/RT/Window.hpp index 72cbb6a..4c654d1 100644 --- a/includes/RT/Window.hpp +++ b/includes/RT/Window.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 16:15:41 by TheRed #+# #+# */ -/* Updated: 2025/01/25 03:09:23 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 16:46:37 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,7 +20,7 @@ class Scene; class Window { public: - Window(Scene *scene, int width, int height, const char *title, int sleep); + Window(Scene *scene, int width, int height, const char *title, int sleep, Arguments &args); ~Window(void); void display(); diff --git a/srcs/RT.cpp b/srcs/RT.cpp index a518583..2d0443e 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:51:49 by TheRed #+# #+# */ -/* Updated: 2025/02/04 03:06:51 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 16:45:30 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,12 +15,13 @@ int main(int argc, char **argv) { Arguments args(argc, argv); + args.show(); if(args.error()) return(1); Scene scene(args.getSceneName()); if(scene.fail()) return(1); - Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0); + Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0, args); Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl"); // Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl"); diff --git a/srcs/class/Arguments.cpp b/srcs/class/Arguments.cpp index 3a6fbe1..9c25399 100644 --- a/srcs/class/Arguments.cpp +++ b/srcs/class/Arguments.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 01:05:44 by tomoron #+# #+# */ -/* Updated: 2025/02/04 03:16:25 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 17:10:24 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -40,25 +40,52 @@ Arguments::Arguments(int argc, char **argv) } } +void Arguments::initArguments() +{ + addArgument('r', "renderpath", 0); + addArgument('h', "headless", 1); +} + void Arguments::printUsage(void) { std::cerr << "usage : [options] [options]" << std::endl; std::cerr << R""""(options : - -r | --renderpath : filename for the renderer path + -r | --renderpath : filename for the renderer path -h | --headless : does the program need to start rendering as soon as it starts(and close automatically) )""""; } +void Arguments::show(void) +{ + for(std::map::iterator it = _values.begin();it != _values.end(); it++) + std::cout << (*it).first << ": " << (*it).second << std::endl; +} + bool Arguments::error(void) const { return(_err); } + std::string &Arguments::getSceneName(void) { return(_values["sceneName"]); } +std::string *Arguments::getRenderPath(void) +{ + if(_values.find("renderpath") != _values.end()) + return(&_values["renderpath"]); + else + return(0); +} + +bool Arguments::getHeadless(void) +{ + return(_values.find("headless") != _values.end()); +} + + void Arguments::addArgument(char shortName, std::string longName, int isFlag) { t_arg arg; @@ -69,11 +96,6 @@ void Arguments::addArgument(char shortName, std::string longName, int isFlag) _args.push_back(arg); } -void Arguments::initArguments() -{ - addArgument('r', "renderPath", 0); - addArgument('h', "headless", 1); -} int Arguments::handleArg(char **argv, int argc, int *i) { @@ -92,7 +114,7 @@ int Arguments::handleArg(char **argv, int argc, int *i) _values[(*it).longName] = "yes"; else if(*i == argc - 1) { - std::cerr << "missing option" << std::endl; + std::cerr << "missing option for --" << (*it).longName << std::endl; return(0); } else @@ -115,7 +137,7 @@ int Arguments::handleArg(char **argv, int argc, int *i) _values[(*it).longName] = "yes"; else if(*i == argc - 1) { - std::cerr << "missing option" << std::endl; + std::cerr << "missing option for --" << (*it).longName << std::endl; return(0); } else diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 65e0a2e..cc24d00 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,24 +6,33 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/04 00:43:18 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 19:06:00 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "RT.hpp" -Renderer::Renderer(Scene *scene, Window *win) +Renderer::Renderer(Scene *scene, Window *win, Arguments &args) { - init(scene, win); - _headless = 0; -} + std::string *renderPath; -Renderer::Renderer(Scene *scene, Window *win, std::string filename) -{ init(scene, win); - _headless = 1; - loadPath(filename); - initRender(); + _headless = args.getHeadless(); + renderPath = args.getRenderPath(); + if(renderPath) + { + try + { + loadPath(*renderPath); + } + catch (std::exception &e) + { + std::cout << e.what() << std::endl; + _shouldClose = 1; + } + } + if(_headless) + initRender(); } void Renderer::init(Scene *scene, Window *win) @@ -71,15 +80,20 @@ void Renderer::savePath(void) { std::ofstream outputFile; const AVCodec *codec; + (void)codec; codec = _codecList[_codecIndex]; outputFile.open("output.path", std::ios::binary); + if(!outputFile.is_open()) + std::cerr << "could open output.path for writing" << std::endl; outputFile.write(_outputFilename.c_str(), _outputFilename.length() + 1); outputFile.write((char *)&codec->id, sizeof(codec->id)); outputFile.write((char *)&_samples, sizeof(_samples)); outputFile.write((char *)&_fps, sizeof(_fps)); for(std::vector::iterator it = _path.begin(); it != _path.end(); it++) + { outputFile.write((char *)&(*it), sizeof(t_pathPoint)); + } outputFile.close(); } @@ -95,6 +109,8 @@ void Renderer::loadPath(std::string filename) _outputFilename = ""; _filenameBuffer[0] = 0; file.open(filename); + if(!file.is_open()) + std::cerr << "failed to open " << filename << std::endl; c = 1; while(c) { @@ -104,15 +120,17 @@ void Renderer::loadPath(std::string filename) if(c) _outputFilename += c; } + memcpy(_filenameBuffer, _outputFilename.c_str(), _outputFilename.length()); + _filenameBuffer[_outputFilename.length()] = 0; rawRead(file, &codecId, sizeof(codecId)); updateAvailableCodecs(2, codecId); if(_codecList.size() == 0) throw std::runtime_error("codec not available"); rawRead(file, &_samples, sizeof(_samples)); rawRead(file, &_fps, sizeof(_fps)); - if(_samples < 1 || _fps < 1) + if(_samples < 1 || _fps < 1 || _samples >= 1000 || _fps >= 120) throw std::runtime_error("invalid value provided in fps or samples"); - while(!file.eof()) + while(file.peek() != EOF) { rawRead(file, &pathPoint, sizeof(t_pathPoint)); if(pathPoint.time < .0f) @@ -201,7 +219,7 @@ void Renderer::updateAvailableCodecs(int mode, AVCodecID id) void Renderer::initRender(void) { - + //TODO: check values _codecOptions = 0; _destPathIndex = _path.size() - 1; _curPathIndex = 0; diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 9ac432a..36f5851 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:29:41 by ycontre #+# #+# */ -/* Updated: 2025/02/04 03:11:24 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 16:43:33 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,6 @@ Scene::Scene(std::string &name) { - std::cout << "name : " << name << std::endl; std::ifstream file(name); std::string line; _camera = new Camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), -90.0f, 0.0f); diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index ef37319..71c54f4 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -6,19 +6,19 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 16:16:24 by TheRed #+# #+# */ -/* Updated: 2025/02/04 00:42:01 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 16:46:29 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "Window.hpp" -Window::Window(Scene *scene, int width, int height, const char *title, int sleep) +Window::Window(Scene *scene, int width, int height, const char *title, int sleep, Arguments &args) { _scene = scene; _fps = 0; _frameCount = 0; _pixelisation = 0; - _renderer = new Renderer(scene, this); + _renderer = new Renderer(scene, this, args); if (!glfwInit()) { From 85b7b58bed67e7239a9887bbbb373c5760ed548a Mon Sep 17 00:00:00 2001 From: tomoron Date: Tue, 4 Feb 2025 22:43:01 +0100 Subject: [PATCH 3/4] renderer works in headless mode now --- Makefile | 2 +- imgui.ini | 4 +- includes/RT/Arguments.hpp | 3 +- includes/RT/Renderer.hpp | 3 +- srcs/RT.cpp | 3 +- srcs/class/Arguments.cpp | 50 ++++++++-------- srcs/class/Renderer.cpp | 119 +++++++++++++++++++++++++++++--------- 7 files changed, 126 insertions(+), 58 deletions(-) diff --git a/Makefile b/Makefile index 1a789cb..4cb0d8d 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ else RM := rm -rf DIR_DUP = mkdir -p $(@D) CC := clang++ - CFLAGS := -Wall -Wextra -Werror -g #-O3 + CFLAGS := -Wall -Wextra -Werror -g -O3 IFLAGS := -I./includes -I./includes/RT -I./includes/imgui LDFLAGS += -lglfw -lGL -lGLU -lX11 -lpthread -ldl -lavformat -lavcodec -lavutil -lswscale -lswresample FILE = $(shell ls -lR srcs/ | grep -F .c | wc -l) diff --git a/imgui.ini b/imgui.ini index 1a5d442..b3e0d68 100644 --- a/imgui.ini +++ b/imgui.ini @@ -29,6 +29,6 @@ Pos=1556,610 Size=284,382 [Window][Settings] -Pos=478,75 -Size=336,287 +Pos=83,57 +Size=336,330 diff --git a/includes/RT/Arguments.hpp b/includes/RT/Arguments.hpp index 62c5b12..f5e4eed 100644 --- a/includes/RT/Arguments.hpp +++ b/includes/RT/Arguments.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 01:07:08 by tomoron #+# #+# */ -/* Updated: 2025/02/04 17:04:59 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 22:04:04 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -41,6 +41,7 @@ class Arguments int handleArg(char **argv, int argc, int *i); void initArguments(void); void addArgument(char shortName, std::string longName, int isFlag); + int setArg(t_arg arg, char **argv, int argc, int *i); void parseRenderPathName(char * path); diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index b26038e..531b0ef 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/02/04 18:46:22 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 21:56:58 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -78,6 +78,7 @@ class Renderer bool _renderSettings; bool _ignoreUnavailableCodec; bool _headless; + bool _tp; bool _shouldClose; int _curPathIndex; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 2d0443e..2408ad9 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:51:49 by TheRed #+# #+# */ -/* Updated: 2025/02/04 16:45:30 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 22:10:33 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,6 @@ int main(int argc, char **argv) { Arguments args(argc, argv); - args.show(); if(args.error()) return(1); Scene scene(args.getSceneName()); diff --git a/srcs/class/Arguments.cpp b/srcs/class/Arguments.cpp index 9c25399..0f7e7cf 100644 --- a/srcs/class/Arguments.cpp +++ b/srcs/class/Arguments.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/04 01:05:44 by tomoron #+# #+# */ -/* Updated: 2025/02/04 17:10:24 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 22:17:04 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -96,10 +96,25 @@ void Arguments::addArgument(char shortName, std::string longName, int isFlag) _args.push_back(arg); } +int Arguments::setArg(t_arg arg, char **argv, int argc, int *i) +{ + + if(arg.isFlag) + _values[arg.longName] = "yes"; + else if(*i == argc - 1) + { + std::cerr << "missing option for " << arg.longName << std::endl; + return(0); + } + else + _values[arg.longName] = argv[++(*i)]; + return(1); +} int Arguments::handleArg(char **argv, int argc, int *i) { std::string arg(argv[*i]); + std::vector::iterator it; (void)i; if(!arg.size()) @@ -109,18 +124,7 @@ int Arguments::handleArg(char **argv, int argc, int *i) for(std::vector::iterator it = _args.begin(); it != _args.end(); it++) { if((*it).longName == arg.substr(2)) - { - if((*it).isFlag) - _values[(*it).longName] = "yes"; - else if(*i == argc - 1) - { - std::cerr << "missing option for --" << (*it).longName << std::endl; - return(0); - } - else - _values[(*it).longName] = argv[++(*i)]; - return(1); - } + return(setArg((*it), argv, argc, i)); } std::cerr<< "unrecognized option : " << arg << std::endl; return(0); @@ -129,24 +133,20 @@ int Arguments::handleArg(char **argv, int argc, int *i) { for(size_t j = 1; j < arg.size(); j++) { - for(std::vector::iterator it = _args.begin(); it != _args.end(); it++) + for(it = _args.begin(); it != _args.end(); it++) { if((*it).shortName == arg[j]) { - if((*it).isFlag) - _values[(*it).longName] = "yes"; - else if(*i == argc - 1) - { - std::cerr << "missing option for --" << (*it).longName << std::endl; + if(!setArg((*it), argv, argc, i)) return(0); - } - else - _values[(*it).longName] = argv[++(*i)]; - return(1); + break; } } - std::cerr << "unrecognized option : -" << arg[j] << std::endl; - return(0); + if(it == _args.end()) + { + std::cerr << "unrecognized option : -" << arg[j] << std::endl; + return(0); + } } } else diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index cc24d00..c72a118 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/04 19:06:00 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 21:56:44 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,8 +31,17 @@ Renderer::Renderer(Scene *scene, Window *win, Arguments &args) _shouldClose = 1; } } - if(_headless) - initRender(); + + try{ + if(_headless) + initRender(); + } + catch(std::exception &e) + { + std::cerr << "\033[31m" << e.what() << "\033[0m" << std::endl; + if(_headless) + _shouldClose = 1; + } } void Renderer::init(Scene *scene, Window *win) @@ -42,6 +51,7 @@ void Renderer::init(Scene *scene, Window *win) _min = 0; _sec = 0; _fps = 30; + _tp = 0; _shouldClose = 0; _autoTime = 0; _samples = 1; @@ -219,7 +229,13 @@ void Renderer::updateAvailableCodecs(int mode, AVCodecID id) void Renderer::initRender(void) { - //TODO: check values + if(_path.size() < 2) + throw std::runtime_error("render path doesn't have enough path points"); + if(_path[0].time != 0) + throw std::runtime_error("render path does not start at 0, aborting"); + if(_path[_path.size() - 1].time - _path[0].time <= 0) + throw std::runtime_error("render path is 0 seconds long, aborting"); + _codecOptions = 0; _destPathIndex = _path.size() - 1; _curPathIndex = 0; @@ -230,7 +246,7 @@ void Renderer::initRender(void) _renderStartTime = glfwGetTime(); _scene->getCamera()->setPosition(_path[0].pos); _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); - _win->setFrameCount(-1); + _win->setFrameCount(_headless ? 0 : -1); avformat_alloc_output_context2(&_format, nullptr, nullptr, _outputFilename.c_str()); _codec_context = avcodec_alloc_context3(_codecList[_codecIndex]); @@ -248,18 +264,27 @@ void Renderer::initRender(void) _codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; if (avcodec_open2(_codec_context, _codecList[_codecIndex], &_codecOptions) < 0) + { + endRender(); throw std::runtime_error("Failed to open codec"); + } _stream = avformat_new_stream(_format, _codecList[_codecIndex]); if (!_stream) + { + endRender(); throw std::runtime_error("Failed to create stream"); + } _stream->time_base = _codec_context->time_base; avcodec_parameters_from_context(_stream->codecpar, _codec_context); if (!(_format->flags & AVFMT_NOFILE)) { if (avio_open(&_format->pb, _outputFilename.c_str(), AVIO_FLAG_WRITE) < 0) + { + endRender(); throw std::runtime_error("couldn't open " + _outputFilename); + } } (void)avformat_write_header(_format, nullptr); @@ -327,29 +352,40 @@ void Renderer::endRender(void) { AVPacket *pkt; - avcodec_send_frame(_codec_context, 0); - pkt = av_packet_alloc(); - while (avcodec_receive_packet(_codec_context, pkt) == 0) { - pkt->stream_index = _stream->index; - pkt->pts = av_rescale_q(pkt->pts, _codec_context->time_base, _stream->time_base); - pkt->dts = av_rescale_q(pkt->dts, _codec_context->time_base, _stream->time_base); - av_interleaved_write_frame(_format, pkt); - av_packet_unref(pkt); + if(_codec_context) + { + avcodec_send_frame(_codec_context, 0); + pkt = av_packet_alloc(); + while (avcodec_receive_packet(_codec_context, pkt) == 0) { + pkt->stream_index = _stream->index; + pkt->pts = av_rescale_q(pkt->pts, _codec_context->time_base, _stream->time_base); + pkt->dts = av_rescale_q(pkt->dts, _codec_context->time_base, _stream->time_base); + av_interleaved_write_frame(_format, pkt); + av_packet_unref(pkt); + } } av_packet_free(&pkt); - av_write_trailer(_format); - av_frame_free(&_rgb_frame); - av_frame_free(&_yuv_frame); - avcodec_free_context(&_codec_context); - avio_close(_format->pb); - avformat_free_context(_format); - av_dict_free(&_codecOptions); + if(_format) + av_write_trailer(_format); + if(_rgb_frame) + av_frame_free(&_rgb_frame); + if(_yuv_frame) + av_frame_free(&_yuv_frame); + if(_codec_context) + avcodec_free_context(&_codec_context); + if(_format) + avio_close(_format->pb); + if(_format) + avformat_free_context(_format); + if(_codecOptions) + av_dict_free(&_codecOptions); _format = 0; _rgb_frame = 0; _yuv_frame = 0; _codec_context = 0; + _destPathIndex = 0; if(_headless) _shouldClose = 1; } @@ -374,7 +410,6 @@ void Renderer::update(Shader &shader) { double curTime; - (void)shader; if(!_destPathIndex) return; @@ -585,21 +620,44 @@ void Renderer::imguiPathCreation(void) ImGui::Separator(); if(ImGui::SliderInt("minutes", &_min, 0, 2)) + { _autoTime = 0; + _tp = 0; + } if(ImGui::SliderInt("seconds", &_sec, 0, 60)) + { _autoTime = 0; + _tp = 0; + } if(_autoTime) { if(_path.size() > 1) time = _path[_path.size() - 1].time + (glm::distance(_path[_path.size() - 1].pos, _scene->getCamera()->getPosition()) / prevSpeed); else time = (float)_path.size() / 60; + if(std::isnan(time)) + time = _path[_path.size() - 1].time + (1.0f / 60); + _min = time; + _sec = (time - (int)time) * 60; + } + else if(_tp) + { + if(!_path.size()) + time = 0; + else + time = _path[_path.size() - 1].time; _min = time; _sec = (time - (int)time) * 60; } else time = (float)_min + ((float)_sec / 60); + ImGui::Checkbox("guess time automatically", &_autoTime); + if(_autoTime) + _tp = 0; + ImGui::Checkbox("tp", &_tp); + if(_tp) + _autoTime = 0; if(ImGui::Button("add step")) addPoint(time); @@ -743,6 +801,8 @@ void Renderer::imguiRenderSettings(void) ImGui::SliderInt("render spi", &_samples, 1, 1000); ImGui::SliderInt("render fps", &_fps, 30, 120); ImGui::Combo("codec", &_codecIndex, _codecListStr.data(), _codecListStr.size()); + if(ImGui::Checkbox("show all codecs", &_ignoreUnavailableCodec)) + updateAvailableCodecs(_ignoreUnavailableCodec, (AVCodecID)0); if(ImGui::InputText("file name", _filenameBuffer, 512)) { _outputFilename = _filenameBuffer; @@ -750,11 +810,18 @@ void Renderer::imguiRenderSettings(void) } if(_path.size() > 1 && _codecList.size()) { - if(ImGui::Button("start render")) - initRender(); - ImGui::SameLine(); - if(ImGui::Button("save path")) - savePath(); + try + { + if(ImGui::Button("start render")) + initRender(); + ImGui::SameLine(); + if(ImGui::Button("save path")) + savePath(); + } + catch(std::exception &e) + { + std::cerr << "\033[31m" << e.what() << "\033[0m" << std::endl; + } } if(ImGui::Button("go back")) _renderSettings = 0; From 4137e04b46f5fe5d06b594cdba7e1d5947db4abd Mon Sep 17 00:00:00 2001 From: tomoron Date: Tue, 4 Feb 2025 23:44:23 +0100 Subject: [PATCH 4/4] Renderer now prints status to standard output when in headless mode --- .gitignore | 1 + includes/RT.hpp | 3 +- includes/RT/Renderer.hpp | 4 +-- srcs/class/Renderer.cpp | 70 ++++++++++++++++++++++++++++++---------- 4 files changed, 58 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 7a0338c..128c608 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /RT compile_flags.txt imgui.ini +/output* diff --git a/includes/RT.hpp b/includes/RT.hpp index 9e5aebe..c4d695f 100644 --- a/includes/RT.hpp +++ b/includes/RT.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:52:10 by TheRed #+# #+# */ -/* Updated: 2025/02/04 01:10:20 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 23:39:14 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -34,6 +34,7 @@ # include # include # include +# include # include # include # include diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 531b0ef..0e5dcdb 100644 --- a/includes/RT/Renderer.hpp +++ b/includes/RT/Renderer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ -/* Updated: 2025/02/04 21:56:58 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 23:19:37 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,7 +53,7 @@ class Renderer void addImageToRender(Shader &shader); void endRender(void); void imguiPathCreation(void); - void imguiRenderInfo(void); + void showRenderInfo(int isImgui); void imguiRenderSettings(void); std::string floatToTime(double timef); glm::vec2 bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time); diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index c72a118..70c7771 100644 --- a/srcs/class/Renderer.cpp +++ b/srcs/class/Renderer.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/04 21:56:44 by tomoron ### ########.fr */ +/* Updated: 2025/02/04 23:42:00 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -414,6 +414,9 @@ void Renderer::update(Shader &shader) return; _curSamples++; + if(_headless) + showRenderInfo(0); + if((_testMode && _curSamples < _testSamples) || (!_testMode && _curSamples < _samples)) return; @@ -429,6 +432,7 @@ void Renderer::update(Shader &shader) } makeMovement(curTime - _curSplitStart, curTime); _curSamples = 0; + } glm::vec3 Renderer::hermiteInterpolate(glm::vec3 points[4], double alpha) @@ -760,8 +764,9 @@ std::string Renderer::floatToTime(double timef) return(res); } -void Renderer::imguiRenderInfo(void) +void Renderer::showRenderInfo(int isImgui) { + std::ostringstream oss; long int totalFrames; float renderTime; float progress; @@ -776,23 +781,54 @@ void Renderer::imguiRenderInfo(void) timeEst *= (totalFrames * _samples) - ((_frameCount * _samples) + _curSamples); if(timeEst > 1e15) timeEst = 0; - ImGui::Text("render in progress"); - ImGui::Text("samples per frame : %d", _samples); - ImGui::Text("render fps : %d", _fps); - ImGui::Text("total render time : %s", floatToTime((_path[_destPathIndex].time - _path[0].time) * 60).c_str()); - ImGui::Separator(); - ImGui::Text("Frames : %ld / %ld", _frameCount, totalFrames); - ImGui::Text("Frames (with accumulation) : %ld / %ld", (_frameCount * _samples) + _curSamples, totalFrames * _samples); - ImGui::Text("Render time : %dm%f", (int)renderTime, (renderTime - (int)renderTime) * 60); - ImGui::Text("elapsed time : %s", floatToTime(timeElapsed).c_str()); - ImGui::Text("estimated time remaining : %s", floatToTime(timeEst).c_str()); + + oss << std::fixed << std::setprecision(2); + + oss << "render in progress" << std::endl; + oss << "samples per frame : " << _samples << std::endl; + oss << "render fps : " << _fps << std::endl; + oss << "total render time : "; + oss << floatToTime((_path[_destPathIndex].time - _path[0].time) * 60).c_str(); + + if(isImgui) + { + ImGui::Text("%s",oss.str().c_str()); + ImGui::Separator(); + } + else + { + std::cout << "\033[2J\033[H"; + std::cout << oss.str() << std::endl; + std::cout << "-----------------------" << std::endl; + } + oss.str(""); + oss.clear(); + + oss << "Frames : " << _frameCount << " / " << totalFrames << std::endl; + oss << "Frames (with accumulation) : " << (_frameCount * _samples) + _curSamples; + oss << " / " << totalFrames * _samples << std::endl; + oss << "Render time : " << (int)renderTime << "m"; + oss << (renderTime - (int)renderTime) * 60 << "s" << std::endl; + oss << "elapsed time : " << floatToTime(timeElapsed) << std::endl; + oss << "estimated time remaining :" << floatToTime(timeEst); + progress = ((float)_frameCount * _samples) + _curSamples; progress /= (float)totalFrames * _samples; - ImGui::ProgressBar(progress, ImVec2(0, 0)); - if(ImGui::Button("stop")) + + if(isImgui) { - _destPathIndex = 0; - endRender(); + ImGui::Text("%s",oss.str().c_str()); + ImGui::ProgressBar(progress, ImVec2(0, 0)); + if(ImGui::Button("stop")) + { + _destPathIndex = 0; + endRender(); + } + } + else + { + oss << std::endl << progress * 100 << "%"; + std::cout << oss.str() << std::endl; } } @@ -833,7 +869,7 @@ void Renderer::renderImgui(void) if (ImGui::CollapsingHeader("Renderer")) { if(rendering()) - imguiRenderInfo(); + showRenderInfo(1); else if(_renderSettings) imguiRenderSettings(); else