diff --git a/includes/RT/Clusterizer.hpp b/includes/RT/Clusterizer.hpp index 14b178b..62eff43 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/25 01:49:07 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 22:26:49 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,6 +38,8 @@ typedef struct s_client t_job *curJob; uint8_t progress; bool ready; + bool readyRespond; + bool gotGo; } t_client; typedef enum e_msg @@ -46,7 +48,8 @@ typedef enum e_msg JOB, PROGRESS_UPDATE, IMG_SEND_RQ, - IMG + IMG, + ABORT } t_msg; class Clusterizer @@ -62,6 +65,7 @@ class Clusterizer bool hasJobs(void); void addJob(glm::vec3 pos, glm::vec2 dir, size_t samples, size_t frames, GPUDenoise &denoise); + void abortJobs(void); private: bool _isActive; @@ -72,19 +76,21 @@ class Clusterizer std::vector _jobs[3]; - void imguiJobStat(void); - void imguiClients(void); + void imguiJobStat(void); + void imguiClients(void); + std::string clientStatus(t_client client); private: //client - void initClient(std::string &dest); - void openClientConnection(const char *ip, int port); - void clientHandleBuffer(void); - void updateClient(Scene &scene, Window &win, std::vector &textures, ShaderProgram &denoisingProgram); - void clientGetJob(void); - void clientReceive(void); - void handleCurrentJob(Scene &scene, Window &win, std::vector &textures, ShaderProgram &denoisingProgram); - void sendProgress(uint8_t progress); - void sendImageToServer(std::vector &textures, ShaderProgram &denoisingProgram); + void initClient(std::string &dest); + void openClientConnection(const char *ip, int port); + void clientHandleBuffer(void); + void updateClient(Scene &scene, Window &win, std::vector &textures, ShaderProgram &denoisingProgram); + void clientGetJob(void); + void clientReceive(void); + void handleCurrentJob(Scene &scene, Window &win, std::vector &textures, ShaderProgram &denoisingProgram); + void sendProgress(uint8_t progress); + void sendImageToServer(std::vector &textures, ShaderProgram &denoisingProgram); + std::vector rgb32fToRgb24i(std::vector &imageFloat); int _serverFd; std::string _serverIp; @@ -102,13 +108,16 @@ class Clusterizer int acceptClients(void); void updatePollfds(void); int updateBuffer(int fd); - void handleBuffer(int fd, std::vector &buf); + bool handleBuffer(int fd, std::vector &buf); void deleteClient(int fd); + int handleSendRequests(void); + void getImageFromClient(int fd, std::vector &buf); + void redistributeJob(t_job *job); int dispatchJobs(void); int _serverSocket; struct pollfd *_pollfds; std::map _clients; - size_t _curId; + size_t _curFrame; }; diff --git a/includes/RT/Ffmpeg.hpp b/includes/RT/Ffmpeg.hpp index 15fabe3..d0b9fcc 100644 --- a/includes/RT/Ffmpeg.hpp +++ b/includes/RT/Ffmpeg.hpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/23 23:41:18 by tomoron #+# #+# */ -/* Updated: 2025/02/24 00:41:00 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 14:47:37 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,7 @@ class Ffmpeg ~Ffmpeg(); void addImageToVideo(Scene &scene, std::vector &textures, ShaderProgram &denoisingProgram); + void addImageToVideo(std::vector &buf); static void updateAvailableCodecs(std::vector &codecList, std::vector &codecListStr, std::string filename, int mode, AVCodecID id); diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index cad6015..2e9cc1e 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/24 17:21:08 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 19:16:25 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -48,11 +48,13 @@ class Renderer int rendering(void) const; bool shouldClose(void) const; + void addImageToRender(std::vector &buffer); + void endRender(Clusterizer *clust); private: void init(Scene *scene, Window *win); - void showRenderInfo(int isImgui); + void showRenderInfo(int isImgui, Clusterizer *clust); std::string floatToTime(double timef); float calcTime(glm::vec3 pos); @@ -76,7 +78,6 @@ class Renderer void createClusterJobs(Clusterizer &clust); void fillGoodCodecList(std::vector &lst); void addImageToRender(std::vector &textures, ShaderProgram &denoisingProgram); - void endRender(void); Scene *_scene; diff --git a/srcs/class/Clusterizer/Clusterizer.cpp b/srcs/class/Clusterizer/Clusterizer.cpp index 707ef44..8992481 100644 --- a/srcs/class/Clusterizer/Clusterizer.cpp +++ b/srcs/class/Clusterizer/Clusterizer.cpp @@ -6,21 +6,12 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/20 18:24:39 by tomoron #+# #+# */ -/* Updated: 2025/02/25 01:49:23 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 22:33:01 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "RT.hpp" -//TODO before push : -// - client work on image when gets job -// - handle client disconnect -// - show image number in imgui -// - client send progress update when percent change -// - server action to send map name -// - when image is done, send a image send request and wait for server response -// - when server accepts send request, send full image - Clusterizer::Clusterizer(Arguments &args, Renderer *renderer) { _isActive = 1; diff --git a/srcs/class/Clusterizer/client.cpp b/srcs/class/Clusterizer/client.cpp index d36fb7f..0338423 100644 --- a/srcs/class/Clusterizer/client.cpp +++ b/srcs/class/Clusterizer/client.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/20 21:08:38 by tomoron #+# #+# */ -/* Updated: 2025/02/25 01:48:47 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 20:41:09 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,7 @@ void shaderDenoise(ShaderProgram &denoising_program, GPUDenoise &denoise, st void Clusterizer::initClient(std::string &dest) { _serverFd = 0; + _currentJob = 0; if(dest.find(":") == std::string::npos) std::cerr << "Client Initialisation error : invalid ip provided format must be :" << std::endl; _serverIp = dest.substr(0, dest.find(":")); @@ -90,9 +91,23 @@ void Clusterizer::clientHandleBuffer(void) if(_receiveBuffer[0] == JOB) clientGetJob(); else if(_receiveBuffer[0] == RDY) + { + std::cout << "server is ready to receive" << std::endl; _srvReady = 1; - else _receiveBuffer.erase(_receiveBuffer.begin()); + } + else if(_receiveBuffer[0] == ABORT) + { + std::cout << "got a abort request, aborting current job"; + delete _currentJob; + _currentJob = 0; + _receiveBuffer.erase(_receiveBuffer.begin()); + } + else + { + std::cout << "unknown request sent, ignoring" << std::endl; + _receiveBuffer.erase(_receiveBuffer.begin()); + } if(sendBuf.size()) @@ -105,15 +120,16 @@ void Clusterizer::clientReceive(void) size_t ret; ret = recv(_serverFd, buffer, 512, MSG_DONTWAIT); - if(ret == (size_t)-1) - return; - if(!ret) + if(ret != (size_t)-1) { - close(_serverFd); - _serverFd = 0; - return ; + if(!ret) + { + close(_serverFd); + _serverFd = 0; + return ; + } + _receiveBuffer.insert(_receiveBuffer.end(), buffer, buffer + ret); } - _receiveBuffer.insert(_receiveBuffer.end(), buffer, buffer + ret); clientHandleBuffer(); } @@ -127,26 +143,62 @@ void Clusterizer::sendProgress(uint8_t progress) (void)write(_serverFd, buf, 2); } +std::vector Clusterizer::rgb32fToRgb24i(std::vector &imageFloat) +{ + std::vector buffer(WIDTH * HEIGHT * 3); + size_t rgbaIndex; + size_t rgbIndex; + + for(size_t y = 0; y < HEIGHT; y++) + { + for(size_t x = 0; x < WIDTH; x++) + { + rgbaIndex = (((HEIGHT - 1 - y) * WIDTH) + x) * 4; + rgbIndex = ((y * WIDTH) + x) * 3; + buffer[rgbIndex] = fmin(imageFloat[rgbaIndex], 1) * 254; + buffer[rgbIndex + 1] = fmin(imageFloat[rgbaIndex + 1], 1) * 254; + buffer[rgbIndex + 2] = fmin(imageFloat[rgbaIndex + 2], 1) * 254; + rgbIndex += 3; + rgbaIndex += 4; + } + } + return(buffer); +} + void Clusterizer::sendImageToServer(std::vector &textures, ShaderProgram &denoisingProgram) { _srvReady = 0; - std::vector buffer(WIDTH * HEIGHT * 4); + std::vector imageFloat(WIDTH * HEIGHT * 4); + std::vector buffer; (void)write(_serverFd, (uint8_t []){IMG_SEND_RQ}, 1); while(!_srvReady) { clientReceive(); + if(!_serverFd) + { + delete _currentJob; + _currentJob = 0; + } + if(!_currentJob) + return ; usleep(10000); } + std::cout << "server ready" << std::endl; if(_currentJob->denoise.enabled) shaderDenoise(denoisingProgram, _currentJob->denoise, textures); glBindTexture(GL_TEXTURE_2D, textures[0]); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, buffer.data()); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, imageFloat.data()); glBindTexture(GL_TEXTURE_2D, 0); + buffer = rgb32fToRgb24i(imageFloat); + std::cout << "buffer size : " << buffer.size() << std::endl; (void)write(_serverFd, (uint8_t []){IMG}, 1); (void)write(_serverFd, buffer.data(), buffer.size()); + delete _currentJob; + _currentJob = 0; + std::cout << "image sent" << std::endl; } void Clusterizer::handleCurrentJob(Scene &scene, Window &win, std::vector &textures, ShaderProgram &denoisingProgram) @@ -157,23 +209,34 @@ void Clusterizer::handleCurrentJob(Scene &scene, Window &win, std::vectorgetPosition() != _currentJob->pos || scene.getCamera()->getDirection() != _currentJob->dir) { + std::cout << "not at right place, moving" << std::endl; scene.getCamera()->setPosition(_currentJob->pos); scene.getCamera()->setDirection(_currentJob->dir.x, _currentJob->dir.y); win.setFrameCount(0); return ; } - if((size_t)win.getFrameCount() < _currentJob->samples) + + if((size_t)win.getFrameCount() <= _currentJob->samples) { progress = ((double)win.getFrameCount() / _currentJob->samples) * 100; if(progress != _progress) + { + std::cout << "new progress" << std::endl; sendProgress(progress); + } } + std::cout << "sample " << win.getFrameCount() << "/" << _currentJob->samples << std::endl; + if((size_t)win.getFrameCount() > _currentJob->samples) + win.setFrameCount(0); + if((size_t)win.getFrameCount() == _currentJob->samples) { + std::cout << "send request" << std::endl; sendImageToServer(textures, denoisingProgram); } + } void Clusterizer::updateClient(Scene &scene, Window &win, std::vector &textures, ShaderProgram &denoisingProgram) diff --git a/srcs/class/Clusterizer/imgui.cpp b/srcs/class/Clusterizer/imgui.cpp index 3c8257c..cbaf12d 100644 --- a/srcs/class/Clusterizer/imgui.cpp +++ b/srcs/class/Clusterizer/imgui.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/22 19:52:51 by tomoron #+# #+# */ -/* Updated: 2025/02/24 20:52:33 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 22:26:44 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,6 +20,21 @@ void Clusterizer::imguiJobStat(void) ImGui::Text(" done : %lu", _jobs[DONE].size()); } +std::string Clusterizer::clientStatus(t_client client) +{ + if(!client.ready) + return("not ready"); + if(client.curJob) + { + if(client.gotGo) + return("sending image to server"); + if(client.readyRespond) + return("waiting for server to send image"); + return("working on frame " + std::to_string(client.curJob->frameNb)); + } + return("idle"); +} + void Clusterizer::imguiClients(void) { std::string status; @@ -28,13 +43,7 @@ void Clusterizer::imguiClients(void) ImGui::BeginChild("clientList", ImVec2(0, 0), true, 0); for(auto it = _clients.begin();it != _clients.end(); it++) { - if(it->second.ready) - status = "idle"; - else if(!it->second.ready && it->second.curJob) - status = "working"; - else if(it->second.ready) - status = "not ready"; - + status = clientStatus(it->second); ImGui::Text("status : %s", status.c_str()); if(it->second.curJob) ImGui::ProgressBar((float)it->second.progress / 100); diff --git a/srcs/class/Clusterizer/server.cpp b/srcs/class/Clusterizer/server.cpp index 70b4c8a..d4da866 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/25 00:53:02 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 22:06:58 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,7 @@ void Clusterizer::initServer(std::string port) { _pollfds = 0; - _curId = 0; + _curFrame = 0; try { @@ -77,6 +77,47 @@ int Clusterizer::acceptClients(void) return(1); } +void Clusterizer::redistributeJob(t_job *job) +{ + size_t highestInProgress = 0; + auto clientHighest = _clients.begin(); + t_job *replaced; + std::vector::iterator found; + + if(!_clients.size()) + { + found = std::find(_jobs[IN_PROGRESS].begin(), _jobs[IN_PROGRESS].end(), job); + _jobs[IN_PROGRESS].erase(found); + _jobs[WAITING].insert(_jobs[WAITING].begin(), job); + } + + for(auto it = _clients.begin(); it != _clients.end(); it++) + { + if(!it->second.curJob) + { + highestInProgress = (size_t) -1; + clientHighest = it; + } + else if(it->second.curJob->frameNb > highestInProgress) + { + highestInProgress = it->second.curJob->frameNb; + clientHighest = it; + } + } + + if(clientHighest->second.curJob) + { + (void)write(clientHighest->first, (uint8_t []){ABORT}, 1); + replaced = clientHighest->second.curJob; + found = std::find(_jobs[IN_PROGRESS].begin(), _jobs[IN_PROGRESS].end(), replaced); + _jobs[IN_PROGRESS].erase(found); + _jobs[WAITING].insert(_jobs[WAITING].begin(), clientHighest->second.curJob); + } + clientHighest->second.curJob = job; + (void)write(clientHighest->first, (uint8_t []){JOB}, 1); + (void)write(clientHighest->first, job, sizeof(t_job)); +} + void Clusterizer::deleteClient(int fd) { std::map::iterator it; @@ -85,23 +126,88 @@ void Clusterizer::deleteClient(int fd) it = _clients.find(fd); if(it == _clients.end()) return; + if(_clients[fd].curJob) + redistributeJob(_clients[fd].curJob); _clients.erase(it); updatePollfds(); close(fd); } -void Clusterizer::handleBuffer(int fd, std::vector &buf) +void Clusterizer::getImageFromClient(int fd, std::vector &buf) { - std::vector sendBuffer; + std::cout << "client sent an image" << std::endl; + + + buf.erase(buf.begin()); + + if(_clients[fd].gotGo && _clients[fd].curJob) + _renderer->addImageToRender(buf); + else + { + std::cout << "client sent an image before receiving a ready signal, dropping image" << std::endl; + buf.erase(buf.begin(), buf.begin() + (WIDTH * HEIGHT * 3)); + return; + } + + buf.erase(buf.begin(), buf.begin() + (WIDTH * HEIGHT * 3)); + + _clients[fd].gotGo = 0; + _clients[fd].curJob = 0; + _clients[fd].readyRespond = 0; + + _jobs[IN_PROGRESS].erase(std::find(_jobs[IN_PROGRESS].begin(), _jobs[IN_PROGRESS].end(), _clients[fd].curJob)); + _jobs[DONE].push_back(_clients[fd].curJob); + _clients[fd].curJob = 0; + + _curFrame++; +} + +bool Clusterizer::handleBuffer(int fd, std::vector &buf) +{ + std::vector sendBuffer; + uint8_t tmp; if(buf[0] == RDY) { _clients[fd].ready = 1; + buf.erase(buf.begin()); std::cout << "client " << fd << " is ready !" << std::endl; } + else if(buf[0] == IMG_SEND_RQ) + { + std::cout << "client " << fd << " is ready to send its image" << std::endl; + _clients[fd].readyRespond = 1; + buf.erase(buf.begin()); + } + else if(buf[0] == PROGRESS_UPDATE) + { + if(buf.size() < 2) + return (0); + tmp = buf[1]; + std::cout << "client " << fd << " sent a progress update, new progress : " << (int)tmp << std::endl; + buf.erase(buf.begin(), buf.begin() + 2); + if (tmp <= 100) + _clients[fd].progress = tmp; + } + else if(buf[0] == IMG) + { + if(buf.size() < ((WIDTH * HEIGHT * 3) + 1)) + { + std::cout << "incomplete IMG request, " << buf.size() << "/"<< (WIDTH * HEIGHT * 3) << std::endl; + return (0); + } + + getImageFromClient(fd, buf); + } + else + { + std::cout << "client sent an unknown request, ignoring" << std::endl; + buf.erase(buf.begin()); + } if(sendBuffer.size()) (void)write(fd, sendBuffer.data(), sendBuffer.size()); + return(buf.size() != 0); } int Clusterizer::updateBuffer(int fd) @@ -113,14 +219,14 @@ int Clusterizer::updateBuffer(int fd) if(!ret || ret == (size_t)-1) return(1); _clients[fd].buffer.insert(_clients[fd].buffer.end(), buffer, buffer + ret); - handleBuffer(fd, _clients[fd].buffer); + while(handleBuffer(fd, _clients[fd].buffer)) + ;; return(0); } int Clusterizer::dispatchJobs(void) { t_job *tmp; - uint8_t sendBuf; int dispatched; dispatched = 0; @@ -129,17 +235,17 @@ int Clusterizer::dispatchJobs(void) for(auto it = _clients.begin(); it != _clients.end(); it++) { - if(it->second.ready) + if(it->second.ready && !it->second.curJob) { tmp = _jobs[WAITING].front(); _jobs[WAITING].erase(_jobs[WAITING].begin()); _jobs[IN_PROGRESS].push_back(tmp); - sendBuf = JOB; - (void)write(it->first, &sendBuf, 1); - (void)write(it->first, &tmp, sizeof(t_job)); - it->second.ready = 0; + (void)write(it->first, (uint8_t []){JOB}, 1); + (void)write(it->first, tmp, sizeof(t_job)); it->second.progress = 0; it->second.curJob = tmp; + it->second.readyRespond = 0; + it->second.gotGo = 0; dispatched = 1; } if(!_jobs[WAITING].size()) @@ -148,6 +254,23 @@ int Clusterizer::dispatchJobs(void) return (dispatched); } +int Clusterizer::handleSendRequests(void) +{ + int action; + + action = 0; + for(auto it = _clients.begin(); it != _clients.end(); it++) + { + if(it->second.curJob && it->second.curJob->frameNb == _curFrame + 1 && it->second.readyRespond && !it->second.gotGo) + { + action = 1; + (void)write(it->first, (uint8_t []){RDY}, 1); + it->second.gotGo = 1; + } + } + return(action); +} + void Clusterizer::addJob(glm::vec3 pos, glm::vec2 dir, size_t samples, size_t frame, GPUDenoise &denoise) { t_job *tmp; @@ -159,6 +282,7 @@ void Clusterizer::addJob(glm::vec3 pos, glm::vec2 dir, size_t samples, size_t fr tmp->frameNb = frame; tmp->denoise = denoise; _jobs[WAITING].push_back(tmp); + _curFrame = 0; std::cout << "new job added : " << std::endl; std::cout << " - pos : " << glm::to_string(pos) << std::endl; @@ -166,15 +290,45 @@ void Clusterizer::addJob(glm::vec3 pos, glm::vec2 dir, size_t samples, size_t fr std::cout << std::endl; } +void Clusterizer::abortJobs(void) +{ + for(auto it = _jobs[WAITING].begin(); it != _jobs[WAITING].end(); it++) + delete *it; + _jobs[WAITING].clear(); + + for(auto it = _clients.begin(); it != _clients.end(); it++) + { + if(it->second.curJob) + { + (void)write(it->first, (uint8_t []){ABORT}, 1); + delete it->second.curJob; + it->second.curJob = 0; + it->second.progress = 0; + } + } + _jobs[IN_PROGRESS].clear(); + + for(auto it = _jobs[DONE].begin(); it != _jobs[DONE].end(); it++) + delete *it; + _jobs[DONE].clear(); +} + void Clusterizer::updateServer(void) { int recv; int didSomething; + if(!_jobs[WAITING].size() && !_jobs[IN_PROGRESS].size() && _jobs[DONE].size()) + { + std::cout << "clusterized render done, closing output video" << std::endl; + _renderer->endRender(this); + } didSomething = 1; while(didSomething) { didSomething = acceptClients(); + if(handleSendRequests()) + didSomething = 1; if(dispatchJobs()) didSomething = 1; recv = poll(_pollfds, _clients.size(), 1); diff --git a/srcs/class/Ffmpeg.cpp b/srcs/class/Ffmpeg.cpp index e08ede7..d201f2a 100644 --- a/srcs/class/Ffmpeg.cpp +++ b/srcs/class/Ffmpeg.cpp @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/23 23:28:19 by tomoron #+# #+# */ -/* Updated: 2025/02/24 00:44:26 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 14:47:15 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -121,6 +121,12 @@ void Ffmpeg::addImageToVideo(Scene &scene, std::vector &textures, Shade convertAndAddToVid(); } +void Ffmpeg::addImageToVideo(std::vector &buf) +{ + memcpy(_rgb_frame->data[0], buf.data(), WIDTH * HEIGHT * 3); + convertAndAddToVid(); +} + void Ffmpeg::convertAndAddToVid(void) { AVPacket *pkt; diff --git a/srcs/class/Renderer/Renderer.cpp b/srcs/class/Renderer/Renderer.cpp index 35d66ea..c9fcd64 100644 --- a/srcs/class/Renderer/Renderer.cpp +++ b/srcs/class/Renderer/Renderer.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ -/* Updated: 2025/02/25 00:52:27 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 19:16:53 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -97,7 +97,7 @@ void Renderer::update(std::vector &textures, ShaderProgram &denoisingPr _curSamples++; if(_headless) - showRenderInfo(0); + showRenderInfo(0, 0); if((_testMode && _curSamples < _testSamples) || (!_testMode && _curSamples < _samples)) return; @@ -165,13 +165,13 @@ void Renderer::initRender(Clusterizer *clust) throw std::runtime_error("render path is 0 seconds long, aborting"); _curPathIndex = 0; + _frameCount = 0; _destPathIndex = _path.size() - 1; _renderStartTime = glfwGetTime(); if(clust && clust->isServer()) createClusterJobs(*clust); else { - _frameCount = 0; _curSamples = 0; _testMode = 0; _scene->getCamera()->setPosition(_path[0].pos); @@ -183,15 +183,29 @@ void Renderer::initRender(Clusterizer *clust) void Renderer::addImageToRender(std::vector &textures, ShaderProgram &denoisingProgram) { + if(!_ffmpegVideo) + return; _ffmpegVideo->addImageToVideo(*_scene, textures, denoisingProgram); } -void Renderer::endRender(void) +void Renderer::addImageToRender(std::vector &buf) +{ + if(!_ffmpegVideo) + return; + _ffmpegVideo->addImageToVideo(buf); + _frameCount++; +} + +void Renderer::endRender(Clusterizer *clust) { _destPathIndex = 0; if(_headless) _shouldClose = 1; - delete _ffmpegVideo; + if(_ffmpegVideo) + delete _ffmpegVideo; + if(clust && clust->isServer()) + clust->abortJobs(); + } bool Renderer::shouldClose(void) const diff --git a/srcs/class/Renderer/imgui.cpp b/srcs/class/Renderer/imgui.cpp index 64805a7..f1c9dd6 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/24 17:42:35 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 19:17:19 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -185,7 +185,7 @@ void Renderer::imguiRenderSettings(Clusterizer &clust) _renderSettings = 0; } -void Renderer::showRenderInfo(int isImgui) +void Renderer::showRenderInfo(int isImgui, Clusterizer *clust) { std::ostringstream oss; long int totalFrames; @@ -250,7 +250,7 @@ void Renderer::showRenderInfo(int isImgui) if(ImGui::Button("stop")) { _destPathIndex = 0; - endRender(); + endRender(clust); } } else @@ -312,7 +312,7 @@ void Renderer::renderImgui(Clusterizer &clust) if (ImGui::CollapsingHeader("Renderer")) { if(rendering() || clust.hasJobs()) - showRenderInfo(1); + showRenderInfo(1, &clust); else if(_renderSettings) imguiRenderSettings(clust); else diff --git a/srcs/class/Renderer/movements.cpp b/srcs/class/Renderer/movements.cpp index 5c8e9ff..001f051 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/23 22:13:32 by tomoron ### ########.fr */ +/* Updated: 2025/02/25 19:15:33 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -168,6 +168,6 @@ void Renderer::makeMovement(float time) { _destPathIndex = 0; if(!_testMode) - endRender(); + endRender(0); } }