diff --git a/Makefile b/Makefile index c0dbd68..410e713 100644 --- a/Makefile +++ b/Makefile @@ -58,14 +58,14 @@ ALL_SRCS := $(IMGUI_SRCS) gl.cpp \ class/BVH.cpp \ class/Arguments.cpp \ class/Renderer/Renderer.cpp \ - class/Renderer/ffmpeg.cpp \ class/Renderer/imgui.cpp \ class/Renderer/movements.cpp\ class/Renderer/saveLoad.cpp \ class/Clusterizer/Clusterizer.cpp\ class/Clusterizer/client.cpp \ class/Clusterizer/server.cpp \ - class/Clusterizer/imgui.cpp \ + class/Clusterizer/imgui.cpp \ + class/Ffmpeg.cpp \ SRCS := $(ALL_SRCS:%=$(SRCS_DIR)/%) OBJS := $(addprefix $(OBJS_DIR)/, $(SRCS:%.cpp=%.o)) diff --git a/includes/RT.hpp b/includes/RT.hpp index b30460c..fd87380 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/21 14:53:36 by tomoron ### ########.fr */ +/* Updated: 2025/02/23 23:39:46 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -77,6 +77,7 @@ struct Vertex { # include "ObjParser.hpp" # include "BVH.hpp" # include "Clusterizer.hpp" +# include "Ffmpeg.hpp" diff --git a/includes/RT/Clusterizer.hpp b/includes/RT/Clusterizer.hpp index 9279be3..21c97a2 100644 --- a/includes/RT/Clusterizer.hpp +++ b/includes/RT/Clusterizer.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/20 18:25:18 by tomoron #+# #+# */ -/* Updated: 2025/02/22 23:36:23 by tomoron ### ########.fr */ +/* Updated: 2025/02/23 22:41:25 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -61,10 +61,16 @@ class Clusterizer void update(void); bool getError(void); void imguiRender(void); + bool isServer(void); + bool hasJobs(void); + + void addJob(glm::vec3 pos, glm::vec2 dir, size_t samples); + private: bool _isActive; bool _isServer; bool _error; + std::string _sceneName; std::vector _jobs[3]; @@ -94,7 +100,6 @@ class Clusterizer void updatePollfds(void); int updateBuffer(int fd); void handleBuffer(int fd, std::vector &buf); - void addJob(std::string scene, glm::vec3 pos, glm::vec2 dir, size_t samples); void deleteClient(int fd); int dispatchJobs(void); diff --git a/includes/RT/Ffmpeg.hpp b/includes/RT/Ffmpeg.hpp new file mode 100644 index 0000000..15fabe3 --- /dev/null +++ b/includes/RT/Ffmpeg.hpp @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Ffmpeg.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/23 23:41:18 by tomoron #+# #+# */ +/* Updated: 2025/02/24 00:41:00 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FFMPEG_HPP +# define FFMPEG_HPP + +#include "RT.hpp" + +class Ffmpeg +{ + public: + Ffmpeg(std::string filename, int fps, const AVCodec *codec); + ~Ffmpeg(); + + void addImageToVideo(Scene &scene, std::vector &textures, ShaderProgram &denoisingProgram); + + static void updateAvailableCodecs(std::vector &codecList, std::vector &codecListStr, std::string filename, int mode, AVCodecID id); + + private: + void convertAndAddToVid(void); + void endVideo(void); + + static void fillGoodCodecList(std::vector &lst); + + int64_t _pts; + AVFormatContext *_format; + AVCodecContext *_codec_context; + AVFrame *_rgb_frame; + AVFrame *_yuv_frame; + SwsContext *_sws_context; + AVStream *_stream; + AVDictionary *_codecOptions; +}; + +#endif diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index f29c4fc..70f0db2 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/20 15:57:21 by tomoron ### ########.fr */ +/* Updated: 2025/02/24 00:32:38 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,7 @@ # define RENDERER_HPP # include "RT.hpp" + extern "C" { #include #include @@ -26,6 +27,8 @@ class Scene; class Window; class Shader; class ShaderProgram; +class Clusterizer; +class Ffmpeg; typedef struct s_pathPoint { @@ -41,7 +44,7 @@ class Renderer void update(std::vector &textures, ShaderProgram &denoisingProgram); void addTeleport(glm::vec3 from_pos, glm::vec2 from_dir, glm::vec3 to_pos, glm::vec2 to_dir); - void renderImgui(void); + void renderImgui(Clusterizer &clust); int rendering(void) const; bool shouldClose(void) const; @@ -54,7 +57,7 @@ class Renderer float calcTime(glm::vec3 pos); void addPoint(float time); - void imguiRenderSettings(void); + void imguiRenderSettings(Clusterizer &clust); void imguiPathCreation(void); void imguiPathNodeList(void); @@ -62,15 +65,16 @@ class Renderer void savePath(void); void loadPath(std::string filename); - void makeMovement(float timeFromStart, float curSplitTimeReset); + void makeMovement(float time); + void interpolateMovement(float time, glm::vec3 *pos, glm::vec2 *dir); glm::vec2 bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time); glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha); t_pathPoint createNextPoint(t_pathPoint from, t_pathPoint to); void getInterpolationPoints(t_pathPoint &prev, t_pathPoint &from, t_pathPoint &to, t_pathPoint &next); void initRender(); + void createClusterJobs(Clusterizer &clust); void fillGoodCodecList(std::vector &lst); - void updateAvailableCodecs(int mode, AVCodecID id); void addImageToRender(std::vector &textures, ShaderProgram &denoisingProgram); void endRender(void); @@ -82,9 +86,9 @@ class Renderer std::string _outputFilename; std::vector _path; - int _curPathIndex; - int _destPathIndex; - double _curSplitStart; + size_t _curPathIndex; + size_t _destPathIndex; + double _testStartTime; int _curSamples; int _testMode; long int _frameCount; @@ -105,16 +109,8 @@ class Renderer int _codecIndex; bool _renderSettings; - - - AVFormatContext *_format; - AVCodecContext *_codec_context; - AVFrame *_rgb_frame; - AVFrame *_yuv_frame; - SwsContext *_sws_context; - AVStream *_stream; - AVDictionary *_codecOptions; std::vector _codecList; + Ffmpeg *_ffmpegVideo; }; #endif diff --git a/srcs/class/Clusterizer/Clusterizer.cpp b/srcs/class/Clusterizer/Clusterizer.cpp index eebccda..f952707 100644 --- a/srcs/class/Clusterizer/Clusterizer.cpp +++ b/srcs/class/Clusterizer/Clusterizer.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/20 18:24:39 by tomoron #+# #+# */ -/* Updated: 2025/02/21 21:45:24 by tomoron ### ########.fr */ +/* Updated: 2025/02/23 22:41:07 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,6 +18,7 @@ Clusterizer::Clusterizer(Arguments &args) _isServer = 0; _error = 0; _serverSocket = 0; + _sceneName = args.getSceneName(); if(args.getBoolean("server")) { @@ -53,3 +54,13 @@ bool Clusterizer::getError(void) { return(_error); } + +bool Clusterizer::isServer(void) +{ + return(_isServer); +} + +bool Clusterizer::hasJobs(void) +{ + return(_jobs[WAITING].size() || _jobs[IN_PROGRESS].size()); +} diff --git a/srcs/class/Clusterizer/server.cpp b/srcs/class/Clusterizer/server.cpp index 3ee4270..a917084 100644 --- a/srcs/class/Clusterizer/server.cpp +++ b/srcs/class/Clusterizer/server.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/20 21:08:38 by tomoron #+# #+# */ -/* Updated: 2025/02/22 23:36:42 by tomoron ### ########.fr */ +/* Updated: 2025/02/23 22:15:38 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -144,17 +144,22 @@ int Clusterizer::dispatchJobs(void) return (dispatched); } -void Clusterizer::addJob(std::string scene, glm::vec3 pos, glm::vec2 dir, size_t samples) +void Clusterizer::addJob(glm::vec3 pos, glm::vec2 dir, size_t samples) { t_job *tmp; tmp = new t_job; - tmp->scene = scene; + tmp->scene = _sceneName; tmp->pos = pos; tmp->dir = dir; tmp->samples = samples; tmp->id = _curId++; _jobs[WAITING].push_back(tmp); + + std::cout << "new job added : " << std::endl; + std::cout << " - pos : " << glm::to_string(pos) << std::endl; + std::cout << " - dir : " << glm::to_string(dir) << std::endl; + std::cout << std::endl; } void Clusterizer::updateServer(void) diff --git a/srcs/class/Renderer/ffmpeg.cpp b/srcs/class/Ffmpeg.cpp similarity index 70% rename from srcs/class/Renderer/ffmpeg.cpp rename to srcs/class/Ffmpeg.cpp index 0e2c8b3..e08ede7 100644 --- a/srcs/class/Renderer/ffmpeg.cpp +++ b/srcs/class/Ffmpeg.cpp @@ -1,65 +1,56 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ffmpeg.cpp :+: :+: :+: */ +/* Ffmpeg.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/02/20 15:59:41 by tomoron #+# #+# */ -/* Updated: 2025/02/20 16:06:39 by tomoron ### ########.fr */ +/* Created: 2025/02/23 23:28:19 by tomoron #+# #+# */ +/* Updated: 2025/02/24 00:44:26 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ + #include "RT.hpp" void shaderDenoise(ShaderProgram &denoising_program, GPUDenoise &denoise, std::vector textures); -void Renderer::initRender(void) +Ffmpeg::Ffmpeg(std::string filename, int fps, const AVCodec *codec) { - 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"); - + std::cout << "ffmpeg init" << std::endl; + _rgb_frame = 0; + _yuv_frame = 0; + _format = 0; + _codec_context = 0; _codecOptions = 0; - _destPathIndex = _path.size() - 1; - _curPathIndex = 0; - _frameCount = 0; - _curSamples = 0; - _curSplitStart = 0; - _testMode = 0; - _renderStartTime = glfwGetTime(); - _scene->getCamera()->setPosition(_path[0].pos); - _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); - _win->setFrameCount(_headless ? 0 : -1); - avformat_alloc_output_context2(&_format, nullptr, nullptr, _outputFilename.c_str()); + _pts = 0; + + avformat_alloc_output_context2(&_format, nullptr, nullptr, filename.c_str()); - _codec_context = avcodec_alloc_context3(_codecList[_codecIndex]); + _codec_context = avcodec_alloc_context3(codec); _codec_context->width = WIDTH; _codec_context->height = HEIGHT; - _codec_context->time_base = {1, _fps}; - _codec_context->framerate = {_fps, 1}; + _codec_context->time_base = {1, fps}; + _codec_context->framerate = {fps, 1}; _codec_context->pix_fmt = AV_PIX_FMT_YUV420P; _codec_context->gop_size = 10; _codec_context->max_b_frames = 1; - if(_codecList[_codecIndex]->id == AV_CODEC_ID_H264 || _codecList[_codecIndex]->id == AV_CODEC_ID_HEVC) + if(codec->id == AV_CODEC_ID_H264 || codec->id == AV_CODEC_ID_HEVC) av_dict_set(&_codecOptions, "crf", "0", 0); if (_format->oformat->flags & AVFMT_GLOBALHEADER) _codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - if (avcodec_open2(_codec_context, _codecList[_codecIndex], &_codecOptions) < 0) + if (avcodec_open2(_codec_context, codec, &_codecOptions) < 0) { - endRender(); + endVideo(); throw std::runtime_error("Failed to open codec"); } - _stream = avformat_new_stream(_format, _codecList[_codecIndex]); + _stream = avformat_new_stream(_format, codec); if (!_stream) { - endRender(); + endVideo(); throw std::runtime_error("Failed to create stream"); } _stream->time_base = _codec_context->time_base; @@ -67,10 +58,10 @@ void Renderer::initRender(void) if (!(_format->flags & AVFMT_NOFILE)) { - if (avio_open(&_format->pb, _outputFilename.c_str(), AVIO_FLAG_WRITE) < 0) + if (avio_open(&_format->pb, filename.c_str(), AVIO_FLAG_WRITE) < 0) { - endRender(); - throw std::runtime_error("couldn't open " + _outputFilename); + endVideo(); + throw std::runtime_error("couldn't open " + filename); } } (void)avformat_write_header(_format, nullptr); @@ -93,22 +84,23 @@ void Renderer::initRender(void) SWS_BILINEAR, nullptr, nullptr, nullptr); } - -void Renderer::addImageToRender(std::vector &textures, ShaderProgram &denoisingProgram) +Ffmpeg::~Ffmpeg(void) { - std::vector image(WIDTH * HEIGHT * 4); + std::cout << "destruct ffmpeg" << std::endl; + endVideo(); +} - AVPacket *pkt; +void Ffmpeg::addImageToVideo(Scene &scene, std::vector &textures, ShaderProgram &denoisingProgram) +{ long int videoFrameOffset; long int outputImageOffset; - + std::vector image(WIDTH * HEIGHT * 4); - if(_scene->getDenoise().enabled) - shaderDenoise(denoisingProgram, _scene->getDenoise(), textures); + if(scene.getDenoise().enabled) + shaderDenoise(denoisingProgram, scene.getDenoise(), textures); glBindTexture(GL_TEXTURE_2D, textures[0]); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, image.data()); glBindTexture(GL_TEXTURE_2D, 0); - for (int x = 0; x < WIDTH; x++) { for(int y = 0; y < HEIGHT; y++) @@ -126,8 +118,16 @@ void Renderer::addImageToRender(std::vector &textures, ShaderProgram &d _rgb_frame->data[0][videoFrameOffset + 2] = colors.z * 255; } } + convertAndAddToVid(); +} + +void Ffmpeg::convertAndAddToVid(void) +{ + AVPacket *pkt; + + std::cout << "add img to vid" << std::endl; sws_scale(_sws_context, _rgb_frame->data, _rgb_frame->linesize, 0, HEIGHT, _yuv_frame->data, _yuv_frame->linesize); - _yuv_frame->pts = _frameCount; + _yuv_frame->pts = _pts++; if (avcodec_send_frame(_codec_context, _yuv_frame) == 0) { pkt = av_packet_alloc(); @@ -142,11 +142,11 @@ void Renderer::addImageToRender(std::vector &textures, ShaderProgram &d } } -void Renderer::endRender(void) +void Ffmpeg::endVideo(void) { AVPacket *pkt; - if(_codec_context) + if(_codec_context && _stream && _format) { avcodec_send_frame(_codec_context, 0); pkt = av_packet_alloc(); @@ -157,8 +157,8 @@ void Renderer::endRender(void) av_interleaved_write_frame(_format, pkt); av_packet_unref(pkt); } + av_packet_free(&pkt); } - av_packet_free(&pkt); if(_format) av_write_trailer(_format); @@ -179,9 +179,6 @@ void Renderer::endRender(void) _rgb_frame = 0; _yuv_frame = 0; _codec_context = 0; - _destPathIndex = 0; - if(_headless) - _shouldClose = 1; } /* modes : @@ -189,7 +186,7 @@ void Renderer::endRender(void) * 1 : adds all codecs * 2 : adds only codec */ -void Renderer::updateAvailableCodecs(int mode, AVCodecID id) +void Ffmpeg::updateAvailableCodecs(std::vector &codecList, std::vector &codecListStr, std::string filename, int mode, AVCodecID id) { const AVCodec *codec; AVCodecContext *ctx; @@ -198,13 +195,12 @@ void Renderer::updateAvailableCodecs(int mode, AVCodecID id) std::vector goodCodecList; fillGoodCodecList(goodCodecList); - _codecList.clear(); - _codecListStr.clear(); - _codecIndex = 0; + codecList.clear(); + codecListStr.clear(); av_log_set_level(AV_LOG_QUIET); - format = _outputFilename.c_str(); - if(_outputFilename.find(".") != std::string::npos) - format += _outputFilename.find(".") + 1; + format = filename.c_str(); + if(filename.find(".") != std::string::npos) + format += filename.find(".") + 1; muxer = av_guess_format(format, 0, 0); for(std::vector::iterator it = goodCodecList.begin(); it != goodCodecList.end(); it++) @@ -214,7 +210,7 @@ void Renderer::updateAvailableCodecs(int mode, AVCodecID id) continue; if (mode == 1 || (mode == 2 && codec->id == id)) { - _codecList.push_back(codec); + codecList.push_back(codec); continue; } ctx = avcodec_alloc_context3(codec); @@ -224,24 +220,24 @@ void Renderer::updateAvailableCodecs(int mode, AVCodecID id) { ctx->width = WIDTH; ctx->height = HEIGHT; - ctx->time_base = {1, _fps}; - ctx->framerate = {_fps, 1}; + ctx->time_base = {1, 60}; + ctx->framerate = {60, 1}; ctx->pix_fmt = AV_PIX_FMT_YUV420P; ctx->gop_size = 10; ctx->max_b_frames = 1; if (avcodec_open2(ctx, codec, NULL) == 0) - _codecList.push_back(codec); + codecList.push_back(codec); } avcodec_free_context(&ctx); } } - for(auto it = _codecList.begin(); it != _codecList.end(); it++) + for(auto it = codecList.begin(); it != codecList.end(); it++) { - _codecListStr.push_back((*it)->name); + codecListStr.push_back((*it)->name); } } -void Renderer::fillGoodCodecList(std::vector &lst) +void Ffmpeg::fillGoodCodecList(std::vector &lst) { lst.push_back(AV_CODEC_ID_FFV1); lst.push_back(AV_CODEC_ID_H264); diff --git a/srcs/class/Renderer/Renderer.cpp b/srcs/class/Renderer/Renderer.cpp index 45c5daf..ec958ad 100644 --- a/srcs/class/Renderer/Renderer.cpp +++ b/srcs/class/Renderer/Renderer.cpp @@ -6,12 +6,13 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/20 20:02:05 by tomoron ### ########.fr */ +/* Updated: 2025/02/24 00:49:53 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "RT.hpp" +//TODO: known problems : first image is put before starting the render and two first images are the same Renderer::Renderer(Scene *scene, Window *win, Arguments &args) { @@ -66,12 +67,9 @@ void Renderer::init(Scene *scene, Window *win) memcpy(_filenameBuffer, _outputFilename.c_str(), _outputFilename.length()); _filenameBuffer[_outputFilename.length()] = 0; - _rgb_frame = 0; - _yuv_frame = 0; - _format = 0; - _codec_context = 0; _ignoreUnavailableCodec = 0; - updateAvailableCodecs(_ignoreUnavailableCodec, (AVCodecID)0); + Ffmpeg::updateAvailableCodecs(_codecList, _codecListStr, _outputFilename, _ignoreUnavailableCodec, (AVCodecID)0); + _codecIndex = 0; } void Renderer::addPoint(float time) @@ -105,7 +103,7 @@ void Renderer::update(std::vector &textures, ShaderProgram &denoisingPr return; if(_testMode) - curTime = glfwGetTime(); + curTime = glfwGetTime() - _testStartTime; else curTime = (1 / (double)_fps) * (double)_frameCount; @@ -114,7 +112,7 @@ void Renderer::update(std::vector &textures, ShaderProgram &denoisingPr addImageToRender(textures, denoisingProgram); _frameCount++; } - makeMovement(curTime - _curSplitStart, curTime); + makeMovement(curTime); _curSamples = 0; } @@ -136,6 +134,67 @@ void Renderer::addTeleport(glm::vec3 from_pos, glm::vec2 from_dir, glm::vec3 to _path.push_back(point); } +void Renderer::createClusterJobs(Clusterizer &clust) +{ + float delta; + size_t frames; + glm::vec3 pos; + glm::vec2 dir; + + delta = 1/(double)_fps; + frames = 0; + + while(_destPathIndex) + { + interpolateMovement(delta * frames, &pos, &dir); + clust.addJob(pos, dir, _samples); + if(_curPathIndex == _destPathIndex) + _destPathIndex = 0; + (void)clust; + frames++; + } +} + +void Renderer::initRender(void) +{ + 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"); + + _curPathIndex = 0; + _destPathIndex = _path.size() - 1; + _renderStartTime = glfwGetTime(); +// if(clust && clust->isServer()) +// createClusterJobs(*clust); +// else + if(1) + { + _frameCount = 0; + _curSamples = 0; + _testMode = 0; + _scene->getCamera()->setPosition(_path[0].pos); + _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); + _win->setFrameCount(_headless ? 0 : -1); + } + _ffmpegVideo = new Ffmpeg(_outputFilename, _fps, _codecList[_codecIndex]); +} + +void Renderer::addImageToRender(std::vector &textures, ShaderProgram &denoisingProgram) +{ + _ffmpegVideo->addImageToVideo(*_scene, textures, denoisingProgram); +} + +void Renderer::endRender(void) +{ + _destPathIndex = 0; + if(_headless) + _shouldClose = 1; + delete _ffmpegVideo; +} + bool Renderer::shouldClose(void) const { return(_shouldClose); diff --git a/srcs/class/Renderer/imgui.cpp b/srcs/class/Renderer/imgui.cpp index 4926c42..8efd7e1 100644 --- a/srcs/class/Renderer/imgui.cpp +++ b/srcs/class/Renderer/imgui.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/20 15:54:35 by tomoron #+# #+# */ -/* Updated: 2025/02/20 16:10:17 by tomoron ### ########.fr */ +/* Updated: 2025/02/24 00:34:48 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -87,7 +87,7 @@ void Renderer::imguiPathNodeList(void) _scene->getCamera()->setPosition(_path[i].pos); _scene->getCamera()->setDirection(_path[i].dir.x, _path[i].dir.y); _win->setFrameCount(-1); - _curSplitStart = glfwGetTime(); + _testStartTime = glfwGetTime() - _path[i].time; _curPathIndex = i - 1; _destPathIndex = i; _testMode = 1; @@ -109,7 +109,7 @@ void Renderer::imguiPathCreation(void) _scene->getCamera()->setPosition(_path[0].pos); _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); _win->setFrameCount(-1); - _curSplitStart = glfwGetTime(); + _testStartTime = glfwGetTime(); _curPathIndex = 0; _destPathIndex = _path.size() - 1; _testMode = 1; @@ -149,17 +149,22 @@ void Renderer::imguiPathCreation(void) imguiPathNodeList(); } -void Renderer::imguiRenderSettings(void) +void Renderer::imguiRenderSettings(Clusterizer &clust) { + (void)clust; 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); + { + Ffmpeg::updateAvailableCodecs(_codecList, _codecListStr, _outputFilename, _ignoreUnavailableCodec, (AVCodecID)0); + _codecIndex = 0; + } if(ImGui::InputText("file name", _filenameBuffer, 512)) { _outputFilename = _filenameBuffer; - updateAvailableCodecs(_ignoreUnavailableCodec, (AVCodecID)0); + Ffmpeg::updateAvailableCodecs(_codecList, _codecListStr, _outputFilename, _ignoreUnavailableCodec, (AVCodecID)0); + _codecIndex = 0; } if(_path.size() > 1 && _codecList.size()) { @@ -189,7 +194,7 @@ void Renderer::showRenderInfo(int isImgui) float timeElapsed; float timeEst; - totalFrames = (_path[_destPathIndex].time - _path[0].time) * 60 * _fps; + totalFrames = (_path.back().time - _path[0].time) * 60 * _fps; renderTime = ((float)_frameCount / _fps) / 60; timeElapsed = glfwGetTime() - _renderStartTime; @@ -204,7 +209,7 @@ void Renderer::showRenderInfo(int isImgui) 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(); + oss << floatToTime((_path.back().time - _path[0].time) * 60).c_str(); if(isImgui) { @@ -226,12 +231,17 @@ void Renderer::showRenderInfo(int isImgui) 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); + if((_frameCount * _samples) + _curSamples) + oss << "estimated time remaining :" << floatToTime(timeEst); + else + oss << "Estimated time remaining : unknown"; if(_headless) oss << std::endl << "fps : " << _win->getFps(); progress = ((float)_frameCount * _samples) + _curSamples; progress /= (float)totalFrames * _samples; + if(std::isnan(progress)) + progress = 0.f; if(isImgui) { @@ -297,14 +307,14 @@ std::string Renderer::floatToTime(double timef) return(res); } -void Renderer::renderImgui(void) +void Renderer::renderImgui(Clusterizer &clust) { if (ImGui::CollapsingHeader("Renderer")) { - if(rendering()) + if(rendering() || clust.hasJobs()) showRenderInfo(1); else if(_renderSettings) - imguiRenderSettings(); + imguiRenderSettings(clust); else imguiPathCreation(); } diff --git a/srcs/class/Renderer/movements.cpp b/srcs/class/Renderer/movements.cpp index 43861af..5c8e9ff 100644 --- a/srcs/class/Renderer/movements.cpp +++ b/srcs/class/Renderer/movements.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/20 16:01:59 by tomoron #+# #+# */ -/* Updated: 2025/02/20 16:02:05 by tomoron ### ########.fr */ +/* Updated: 2025/02/23 22:13:32 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -106,8 +106,7 @@ void Renderer::getInterpolationPoints(t_pathPoint &prev, t_pathPoint &from, t_pa next = _path[_curPathIndex + 2]; } - -void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) +void Renderer::interpolateMovement(float time, glm::vec3 *pos, glm::vec2 *dir) { t_pathPoint prev; t_pathPoint from; @@ -115,22 +114,24 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) t_pathPoint next; float pathTime; - Camera *cam; - glm::vec3 pos; - glm::vec2 dir; float normalTime; bool smallDistPrev; bool smallDistNext; + float splitTime; glm::vec4 bezierControl; + std::cout << "current time : " << time << std::endl; + while(_curPathIndex < _path.size() - 2 && (_path[_curPathIndex + 1].time * 60) < time) + _curPathIndex++; + + splitTime = time - (_path[_curPathIndex].time * 60); getInterpolationPoints(prev, from, to, next); - cam = _scene->getCamera(); pathTime = (to.time - from.time) * 60; - normalTime = 1 - ((pathTime - timeFromStart) / pathTime); + normalTime = 1 - ((pathTime - splitTime) / pathTime); glm::vec3 points[4] = {prev.pos, from.pos, to.pos, next.pos}; - pos = hermiteInterpolate(points, normalTime); + *pos = hermiteInterpolate(points, normalTime); smallDistPrev = glm::distance((to.dir - from.dir) / glm::vec2(pathTime), (from.dir - prev.dir) / glm::vec2((from.time - prev.time) * 60)) < 40; smallDistNext = glm::distance((to.dir - from.dir) / glm::vec2(pathTime), (next.dir - to.dir) / glm::vec2((next.time - to.time) * 60)) < 40; @@ -139,24 +140,30 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) bezierControl.z = 0.8f; bezierControl.w = (size_t)_curPathIndex + 2 >= _path.size() || smallDistNext ? .9f : 1.0f; - dir = bezierSphereInterpolate(bezierControl, from.dir, to.dir, normalTime); - if(std::isnan(dir.x) || std::isnan(dir.y)) - dir = from.dir; - if(timeFromStart >= pathTime) + *dir = bezierSphereInterpolate(bezierControl, from.dir, to.dir, normalTime); + if(std::isnan(dir->x) || std::isnan(dir->y)) + *dir = from.dir; + if(splitTime >= pathTime) { - pos = to.pos; - dir = to.dir; - _curSplitStart = curSplitTimeReset; + *pos = to.pos; + *dir = to.dir; _curPathIndex++; - while( _curPathIndex < _destPathIndex && _path[_curPathIndex].time == _path[_curPathIndex + 1].time) - { - _curPathIndex++; - std::cout << "skip tp" << std::endl; - } } +} + +void Renderer::makeMovement(float time) +{ + glm::vec2 dir; + glm::vec3 pos; + Camera *cam; + + interpolateMovement(time, &pos, &dir); + + cam = _scene->getCamera(); cam->setPosition(pos); cam->setDirection(dir.x, dir.y); _win->setFrameCount(0); + if(_curPathIndex == _destPathIndex) { _destPathIndex = 0; diff --git a/srcs/class/Renderer/saveLoad.cpp b/srcs/class/Renderer/saveLoad.cpp index 94b6064..eb10846 100644 --- a/srcs/class/Renderer/saveLoad.cpp +++ b/srcs/class/Renderer/saveLoad.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/20 16:05:52 by tomoron #+# #+# */ -/* Updated: 2025/02/20 16:05:57 by tomoron ### ########.fr */ +/* Updated: 2025/02/24 00:35:18 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -71,7 +71,8 @@ void Renderer::loadPath(std::string filename) memcpy(_filenameBuffer, _outputFilename.c_str(), _outputFilename.length()); _filenameBuffer[_outputFilename.length()] = 0; rawRead(file, &codecId, sizeof(codecId)); - updateAvailableCodecs(2, codecId); + Ffmpeg::updateAvailableCodecs(_codecList, _codecListStr, _outputFilename, _ignoreUnavailableCodec, (AVCodecID)0); + _codecIndex = 0; if(_codecList.size() == 0) throw std::runtime_error("codec not available"); rawRead(file, &_samples, sizeof(_samples)); diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 4b0e0d8..5c11b0d 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/02/22 22:15:32 by tomoron ### ########.fr */ +/* Updated: 2025/02/23 19:05:24 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -317,7 +317,7 @@ void Window::imGuiRender(ShaderProgram &raytracing_program, Clusterizer &cluster } - _renderer->renderImgui(); + _renderer->renderImgui(clusterizer); clusterizer.imguiRender(); ImGui::End();