From 4b8e9bd5f080d02392ac1bfb2270fb3b330026f2 Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 23 Jan 2025 13:06:22 +0100 Subject: [PATCH 01/12] add renderer window to make a path with timestamps --- Makefile | 1 + imgui.ini | 14 +++-- includes/RT.hpp | 3 +- includes/RT/Renderer.hpp | 45 ++++++++++++++ includes/RT/Window.hpp | 7 ++- scenes/test.rt | 124 +++------------------------------------ srcs/RT.cpp | 2 +- srcs/class/Camera.cpp | 4 +- srcs/class/Renderer.cpp | 84 ++++++++++++++++++++++++++ srcs/class/Window.cpp | 11 +++- 10 files changed, 166 insertions(+), 129 deletions(-) create mode 100644 includes/RT/Renderer.hpp create mode 100644 srcs/class/Renderer.cpp diff --git a/Makefile b/Makefile index 9d73d4b..ea3ad1c 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,7 @@ ALL_SRCS := $(IMGUI_SRCS) \ class/SceneParser.cpp \ class/ObjParser.cpp \ class/BVH.cpp \ + class/Renderer.cpp \ SRCS := $(ALL_SRCS:%=$(SRCS_DIR)/%) OBJS := $(addprefix $(OBJS_DIR)/, $(SRCS:%.cpp=%.o)) diff --git a/imgui.ini b/imgui.ini index e0f3220..f2af59a 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,17 +3,15 @@ Pos=60,60 Size=400,400 [Window][Camera] -Pos=1643,7 +Pos=399,48 Size=259,200 -Collapsed=1 [Window][Material] -Pos=1642,29 +Pos=646,129 Size=266,299 -Collapsed=1 [Window][Fog settings] -Pos=1641,52 +Pos=927,52 Size=247,130 Collapsed=1 @@ -22,7 +20,11 @@ Pos=1642,668 Size=260,143 [Window][Debug BVH] -Pos=1641,72 +Pos=927,72 Size=274,205 Collapsed=1 +[Window][Renderer] +Pos=636,712 +Size=307,319 + diff --git a/includes/RT.hpp b/includes/RT.hpp index bfde952..b9a2dfa 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/01/16 15:02:34 by tomoron ### ########.fr */ +/* Updated: 2025/01/22 16:37:32 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -57,6 +57,7 @@ struct Vertex { # include "objects/Cylinder.hpp" # include "Camera.hpp" +# include "Renderer.hpp" # include "Window.hpp" # include "Shader.hpp" # include "Scene.hpp" diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp new file mode 100644 index 0000000..c5b887d --- /dev/null +++ b/includes/RT/Renderer.hpp @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Renderer.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/22 16:29:26 by tomoron #+# #+# */ +/* Updated: 2025/01/22 19:34:22 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef RENDERER_HPP +# define RENDERER_HPP + +# include "RT.hpp" + +class Scene; +class Window; + +typedef struct s_pathPoint +{ + glm::vec3 pos; + glm::vec2 dir; + float time; +} t_pathPoint; + +class Renderer +{ + public: + Renderer(Scene *scene, Window *win); + void renderImgui(void); + + private: + void addPoint(void); + + int _min; + float _sec; + int _samples; + std::vector _path; + Scene *_scene; + Window *_win; +}; + +#endif diff --git a/includes/RT/Window.hpp b/includes/RT/Window.hpp index 803f58f..8b39b36 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/11 16:14:11 by tomoron ### ########.fr */ +/* Updated: 2025/01/23 00:39:11 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,7 +26,7 @@ class Window void display(); void pollEvents(); bool shouldClose(); - + void process_input(); static void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); @@ -44,9 +44,12 @@ class Window bool &getAccumulate(void); + void setFrameCount(int nb); + private: GLFWwindow *_window; Scene *_scene; + Renderer *_renderer; float _fps; float _delta; diff --git a/scenes/test.rt b/scenes/test.rt index 62a746e..dc9608d 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -15,123 +15,15 @@ MAT 255 255 255 5.0 0.0 0.0 // white light 7 MAT 255 255 255 0.0 0.0 0.0 TRN // glass 8 pl 0 0 0 0 1 0 2 // floor -pl 0 5 0 0 -1 0 5 - -qu 3 4.9 3 3 0 0 0 0 3 7 - -qu -2.5 0 -2.5 0 5 0 0 0 15 1 -qu -2.5 0 -2.5 0 5 0 15 0 0 3 -qu 11.5 0 -2.5 0 5 0 0 0 15 1 -qu -2.5 0 11.5 0 5 0 15 0 0 4 +#pl 0 5 0 0 -1 0 5 +# +#qu 3 4.9 3 3 0 0 0 0 3 7 +# +#qu -2.5 0 -2.5 0 5 0 0 0 15 1 +#qu -2.5 0 -2.5 0 5 0 15 0 0 3 +#qu 11.5 0 -2.5 0 5 0 0 0 15 1 +#qu -2.5 0 11.5 0 5 0 15 0 0 4 OBJ obj/Dragon_8K.obj 0 0.38 0 1 -OBJ obj/Dragon_8K.obj 0 0.38 1 1 -OBJ obj/Dragon_8K.obj 0 0.38 2 1 -OBJ obj/Dragon_8K.obj 0 0.38 3 1 -OBJ obj/Dragon_8K.obj 0 0.38 4 1 -OBJ obj/Dragon_8K.obj 0 0.38 5 1 -OBJ obj/Dragon_8K.obj 0 0.38 6 1 -OBJ obj/Dragon_8K.obj 0 0.38 7 1 -OBJ obj/Dragon_8K.obj 0 0.38 8 1 -OBJ obj/Dragon_8K.obj 0 0.38 9 1 - -OBJ obj/Dragon_8K.obj 1 0.38 0 1 -OBJ obj/Dragon_8K.obj 1 0.38 1 1 -OBJ obj/Dragon_8K.obj 1 0.38 2 1 -OBJ obj/Dragon_8K.obj 1 0.38 3 1 -OBJ obj/Dragon_8K.obj 1 0.38 4 1 -OBJ obj/Dragon_8K.obj 1 0.38 5 1 -OBJ obj/Dragon_8K.obj 1 0.38 6 1 -OBJ obj/Dragon_8K.obj 1 0.38 7 1 -OBJ obj/Dragon_8K.obj 1 0.38 8 1 -OBJ obj/Dragon_8K.obj 1 0.38 9 1 - -OBJ obj/Dragon_8K.obj 2 0.38 0 1 -OBJ obj/Dragon_8K.obj 2 0.38 1 1 -OBJ obj/Dragon_8K.obj 2 0.38 2 1 -OBJ obj/Dragon_8K.obj 2 0.38 3 1 -OBJ obj/Dragon_8K.obj 2 0.38 4 1 -OBJ obj/Dragon_8K.obj 2 0.38 5 1 -OBJ obj/Dragon_8K.obj 2 0.38 6 1 -OBJ obj/Dragon_8K.obj 2 0.38 7 1 -OBJ obj/Dragon_8K.obj 2 0.38 8 1 -OBJ obj/Dragon_8K.obj 2 0.38 9 1 - -OBJ obj/Dragon_8K.obj 3 0.38 0 1 -OBJ obj/Dragon_8K.obj 3 0.38 1 1 -OBJ obj/Dragon_8K.obj 3 0.38 2 1 -OBJ obj/Dragon_8K.obj 3 0.38 3 1 -OBJ obj/Dragon_8K.obj 3 0.38 4 1 -OBJ obj/Dragon_8K.obj 3 0.38 5 1 -OBJ obj/Dragon_8K.obj 3 0.38 6 1 -OBJ obj/Dragon_8K.obj 3 0.38 7 1 -OBJ obj/Dragon_8K.obj 3 0.38 8 1 -OBJ obj/Dragon_8K.obj 3 0.38 9 1 - -OBJ obj/Dragon_8K.obj 4 0.38 0 1 -OBJ obj/Dragon_8K.obj 4 0.38 1 1 -OBJ obj/Dragon_8K.obj 4 0.38 2 1 -OBJ obj/Dragon_8K.obj 4 0.38 3 1 -OBJ obj/Dragon_8K.obj 4 0.38 4 1 -OBJ obj/Dragon_8K.obj 4 0.38 5 1 -OBJ obj/Dragon_8K.obj 4 0.38 6 1 -OBJ obj/Dragon_8K.obj 4 0.38 7 1 -OBJ obj/Dragon_8K.obj 4 0.38 8 1 -OBJ obj/Dragon_8K.obj 4 0.38 9 1 - -OBJ obj/Dragon_8K.obj 5 0.38 0 1 -OBJ obj/Dragon_8K.obj 5 0.38 1 1 -OBJ obj/Dragon_8K.obj 5 0.38 2 1 -OBJ obj/Dragon_8K.obj 5 0.38 3 1 -OBJ obj/Dragon_8K.obj 5 0.38 4 1 -OBJ obj/Dragon_8K.obj 5 0.38 5 1 -OBJ obj/Dragon_8K.obj 5 0.38 6 1 -OBJ obj/Dragon_8K.obj 5 0.38 7 1 -OBJ obj/Dragon_8K.obj 5 0.38 8 1 -OBJ obj/Dragon_8K.obj 5 0.38 9 1 - -OBJ obj/Dragon_8K.obj 6 0.38 0 1 -OBJ obj/Dragon_8K.obj 6 0.38 1 1 -OBJ obj/Dragon_8K.obj 6 0.38 2 1 -OBJ obj/Dragon_8K.obj 6 0.38 3 1 -OBJ obj/Dragon_8K.obj 6 0.38 4 1 -OBJ obj/Dragon_8K.obj 6 0.38 5 1 -OBJ obj/Dragon_8K.obj 6 0.38 6 1 -OBJ obj/Dragon_8K.obj 6 0.38 7 1 -OBJ obj/Dragon_8K.obj 6 0.38 8 1 -OBJ obj/Dragon_8K.obj 6 0.38 9 1 - -OBJ obj/Dragon_8K.obj 7 0.38 0 1 -OBJ obj/Dragon_8K.obj 7 0.38 1 1 -OBJ obj/Dragon_8K.obj 7 0.38 2 1 -OBJ obj/Dragon_8K.obj 7 0.38 3 1 -OBJ obj/Dragon_8K.obj 7 0.38 4 1 -OBJ obj/Dragon_8K.obj 7 0.38 5 1 -OBJ obj/Dragon_8K.obj 7 0.38 6 1 -OBJ obj/Dragon_8K.obj 7 0.38 7 1 -OBJ obj/Dragon_8K.obj 7 0.38 8 1 -OBJ obj/Dragon_8K.obj 7 0.38 9 1 - -OBJ obj/Dragon_8K.obj 8 0.38 0 1 -OBJ obj/Dragon_8K.obj 8 0.38 1 1 -OBJ obj/Dragon_8K.obj 8 0.38 2 1 -OBJ obj/Dragon_8K.obj 8 0.38 3 1 -OBJ obj/Dragon_8K.obj 8 0.38 4 1 -OBJ obj/Dragon_8K.obj 8 0.38 5 1 -OBJ obj/Dragon_8K.obj 8 0.38 6 1 -OBJ obj/Dragon_8K.obj 8 0.38 7 1 -OBJ obj/Dragon_8K.obj 8 0.38 8 1 -OBJ obj/Dragon_8K.obj 8 0.38 9 1 - -OBJ obj/Dragon_8K.obj 9 0.38 0 1 -OBJ obj/Dragon_8K.obj 9 0.38 1 1 -OBJ obj/Dragon_8K.obj 9 0.38 2 1 -OBJ obj/Dragon_8K.obj 9 0.38 3 1 -OBJ obj/Dragon_8K.obj 9 0.38 4 1 -OBJ obj/Dragon_8K.obj 9 0.38 5 1 -OBJ obj/Dragon_8K.obj 9 0.38 6 1 -OBJ obj/Dragon_8K.obj 9 0.38 7 1 -OBJ obj/Dragon_8K.obj 9 0.38 8 1 -OBJ obj/Dragon_8K.obj 9 0.38 9 1 diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 492a9d2..2d57f86 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/20 18:55:25 by ycontre ### ########.fr */ +/* Updated: 2025/01/22 16:33:56 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index 065955e..d2604be 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/15 14:00:38 by TheRed #+# #+# */ -/* Updated: 2025/01/15 19:32:41 by ycontre ### ########.fr */ +/* Updated: 2025/01/22 19:27:03 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -166,4 +166,4 @@ void Camera::setBounce(int bounce) void Camera::setFov(float fov) { _fov = fov; -} \ No newline at end of file +} diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp new file mode 100644 index 0000000..c851375 --- /dev/null +++ b/srcs/class/Renderer.cpp @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Renderer.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/01/22 16:34:53 by tomoron #+# #+# */ +/* Updated: 2025/01/23 00:54:01 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "RT.hpp" + +Renderer::Renderer(Scene *scene, Window *win) +{ + _scene = scene; + _win = win; + _min = 0; + _sec = 0; + _samples = 1; +} + +void Renderer::addPoint(void) +{ + t_pathPoint newPoint; + Camera *cam; + std::vector::iterator pos; + + cam = _scene->getCamera(); + newPoint.pos = cam->getPosition(); + newPoint.dir = cam->getDirection(); + newPoint.time = _min + (_sec / 60); + std::cout << "position : " << glm::to_string(newPoint.pos) << std::endl; + std::cout << "direction : " << glm::to_string(newPoint.dir) << std::endl; + std::cout << "time : " << newPoint.time << std::endl; + pos = _path.begin(); + while(pos != _path.end() && pos->time <= newPoint.time) + pos++; + _path.insert(pos, newPoint); +} + +void Renderer::renderImgui(void) +{ + ImGui::Begin("Renderer"); + + ImGui::SliderInt("spi", &_samples, 1, 1000); + ImGui::Separator(); + + ImGui::SliderInt("minutes", &_min, 0, 2); + ImGui::SliderFloat("seconds", &_sec, 0, 60); + if(ImGui::Button("add step")) + addPoint(); + ImGui::Separator(); + + for(unsigned long i = 0; i < _path.size(); i++) + { + ImGui::Text("pos : %f, %f, %f",_path[i].pos.x, _path[i].pos.y, _path[i].pos.z); + ImGui::Text("dir : %f, %f",_path[i].dir.x, _path[i].dir.y); + ImGui::Text("time : %dm%ds", (int)_path[i].time, (int)(((_path[i].time - (int)_path[i].time)) * 60)); + + if(ImGui::Button(("delete##" + std::to_string(i)).c_str())) + { + _path.erase(_path.begin() + i); + } + + ImGui::SameLine(); + if(ImGui::Button(("go to pos##" + std::to_string(i)).c_str())) + { + _scene->getCamera()->setPosition(_path[i].pos); + _scene->getCamera()->setDirection(_path[i].dir.x, _path[i].dir.y); + _scene->getCamera()->updateCameraVectors(); + _win->setFrameCount(-1); + } + ImGui::SameLine(); + if(ImGui::Button(("edit pos##" + std::to_string(i)).c_str())) + { + _path[i].pos = _scene->getCamera()->getPosition(); + _path[i].dir = _scene->getCamera()->getDirection(); + } + ImGui::Separator(); + } + ImGui::End(); +} diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 5acc4cc..75774d2 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/18 19:24:04 by ycontre ### ########.fr */ +/* Updated: 2025/01/23 00:39:21 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,7 @@ Window::Window(Scene *scene, int width, int height, const char *title, int sleep _scene = scene; _frameCount = 0; _pixelisation = 0; + _renderer = new Renderer(scene, this); if (!glfwInit()) { @@ -258,9 +259,12 @@ void Window::imGuiRender() ImGui::End(); + _renderer->renderImgui();; + ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + if (has_changed) _frameCount = (accumulate == 0) - 1; } @@ -280,6 +284,11 @@ int Window::getFrameCount(void) const return (_frameCount); } +void Window::setFrameCount(int nb) +{ + _frameCount = nb; +} + bool &Window::getAccumulate(void) { return (accumulate); From 7b1be7c2d9b6879dce6e5d19625c1c1fee75e5ac Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 23 Jan 2025 19:47:41 +0100 Subject: [PATCH 02/12] rendrerer : add a test split button to see if a part of path is good --- imgui.ini | 11 +++--- includes/RT/Renderer.hpp | 9 ++++- includes/RT/Window.hpp | 3 +- srcs/RT.cpp | 6 ++-- srcs/class/Camera.cpp | 3 +- srcs/class/Renderer.cpp | 72 +++++++++++++++++++++++++++++++++++--- srcs/class/SceneParser.cpp | 3 +- srcs/class/Window.cpp | 7 +++- 8 files changed, 94 insertions(+), 20 deletions(-) diff --git a/imgui.ini b/imgui.ini index f2af59a..dc1baba 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,7 +3,7 @@ Pos=60,60 Size=400,400 [Window][Camera] -Pos=399,48 +Pos=687,817 Size=259,200 [Window][Material] @@ -11,20 +11,19 @@ Pos=646,129 Size=266,299 [Window][Fog settings] -Pos=927,52 +Pos=35,863 Size=247,130 -Collapsed=1 [Window][Debug] Pos=1642,668 Size=260,143 [Window][Debug BVH] -Pos=927,72 +Pos=772,16 Size=274,205 Collapsed=1 [Window][Renderer] -Pos=636,712 -Size=307,319 +Pos=31,66 +Size=747,496 diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index c5b887d..08d9e6b 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/22 19:34:22 by tomoron ### ########.fr */ +/* Updated: 2025/01/23 19:41:40 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,9 +30,11 @@ class Renderer public: Renderer(Scene *scene, Window *win); void renderImgui(void); + void update(void); private: void addPoint(void); + void makeMovement(float timeFromStart, float curSplitTimeReset); int _min; float _sec; @@ -40,6 +42,11 @@ class Renderer std::vector _path; Scene *_scene; Window *_win; + + int _curPathIndex; + int _destPathIndex; + double _curSplitStart; + int _curSamples; }; #endif diff --git a/includes/RT/Window.hpp b/includes/RT/Window.hpp index 8b39b36..d30eb81 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/23 00:39:11 by tomoron ### ########.fr */ +/* Updated: 2025/01/23 15:31:28 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -46,6 +46,7 @@ class Window void setFrameCount(int nb); + void rendererUpdate(void); private: GLFWwindow *_window; Scene *_scene; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 2d57f86..37006c0 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/22 16:33:56 by tomoron ### ########.fr */ +/* Updated: 2025/01/23 18:37:21 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -115,6 +115,7 @@ int main(int argc, char **argv) std::vector gpu_lights_array(gpu_lights.begin(), gpu_lights.end()); glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightSSBO); glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, gpu_lights_array.size() * sizeof(int), gpu_lights_array.data()); + window.rendererUpdate(); Camera *camera = scene.getCamera(); @@ -142,7 +143,6 @@ int main(int argc, char **argv) break; camera->setDirection(0, yaw - 180); - camera->updateCameraVectors(); } // @@ -177,7 +177,7 @@ int main(int argc, char **argv) window.imGuiRender(); window.display(); - window.pollEvents(); + window.pollEvents(); } ImGui_ImplOpenGL3_Shutdown(); diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index d2604be..2a09b80 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/15 14:00:38 by TheRed #+# #+# */ -/* Updated: 2025/01/22 19:27:03 by tomoron ### ########.fr */ +/* Updated: 2025/01/23 18:34:29 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -150,6 +150,7 @@ void Camera::setDirection(float pitch, float yaw) { _pitch = pitch; _yaw = yaw; + updateCameraVectors(); } void Camera::setDOV(float aperture, float focus) diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index c851375..94d1954 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/01/23 00:54:01 by tomoron ### ########.fr */ +/* Updated: 2025/01/23 19:42:56 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,7 @@ Renderer::Renderer(Scene *scene, Window *win) _min = 0; _sec = 0; _samples = 1; + _curSamples = 0; } void Renderer::addPoint(void) @@ -31,15 +32,64 @@ void Renderer::addPoint(void) newPoint.pos = cam->getPosition(); newPoint.dir = cam->getDirection(); newPoint.time = _min + (_sec / 60); - std::cout << "position : " << glm::to_string(newPoint.pos) << std::endl; - std::cout << "direction : " << glm::to_string(newPoint.dir) << std::endl; - std::cout << "time : " << newPoint.time << std::endl; pos = _path.begin(); while(pos != _path.end() && pos->time <= newPoint.time) pos++; _path.insert(pos, newPoint); } +void Renderer::update(void) +{ + double curTime; + + if(!_destPathIndex) + return; + curTime = glfwGetTime(); + _curSamples++; + if(_curSamples == _samples) + { + makeMovement(curTime - _curSplitStart, curTime); + _curSamples = 0; + } +} + +void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) +{ + t_pathPoint from; + t_pathPoint to; + float pathTime; + Camera *cam; + glm::vec3 posStep; + glm::vec2 dirStep; + + from = _path[_curPathIndex]; + to = _path[_curPathIndex + 1]; + cam = _scene->getCamera(); + pathTime = (to.time - from.time) * 60; + + posStep.x = ((to.pos.x - from.pos.x) / pathTime) * timeFromStart; + posStep.y = ((to.pos.y - from.pos.y) / pathTime) * timeFromStart; + posStep.z = ((to.pos.z - from.pos.z) / pathTime) * timeFromStart; + dirStep.x = ((to.dir.x - from.dir.x) / pathTime) * timeFromStart; + dirStep.y = ((to.dir.y - from.dir.y) / pathTime) * timeFromStart; + + if(timeFromStart >= pathTime) + { + posStep = to.pos - from.pos; + dirStep = to.dir - from.dir; + _curSplitStart = curSplitTimeReset; + _curPathIndex++; + } + cam->setPosition(from.pos + posStep); + cam->setDirection(from.dir.x + dirStep.x, from.dir.y + dirStep.y); + _win->setFrameCount(0); + if(_curPathIndex == _destPathIndex) + { + _destPathIndex = 0; + std::cout << "done" << std::endl; + } +} + void Renderer::renderImgui(void) { ImGui::Begin("Renderer"); @@ -69,15 +119,27 @@ void Renderer::renderImgui(void) { _scene->getCamera()->setPosition(_path[i].pos); _scene->getCamera()->setDirection(_path[i].dir.x, _path[i].dir.y); - _scene->getCamera()->updateCameraVectors(); _win->setFrameCount(-1); } + ImGui::SameLine(); if(ImGui::Button(("edit pos##" + std::to_string(i)).c_str())) { _path[i].pos = _scene->getCamera()->getPosition(); _path[i].dir = _scene->getCamera()->getDirection(); } + + if(i) + ImGui::SameLine(); + if(i && ImGui::Button(("test split##" + std::to_string(i)).c_str())) + { + _scene->getCamera()->setPosition(_path[i].pos); + _scene->getCamera()->setDirection(_path[i].dir.x, _path[i].dir.y); + _win->setFrameCount(-1); + _curSplitStart = glfwGetTime(); + _curPathIndex = i - 1; + _destPathIndex = i; + } ImGui::Separator(); } ImGui::End(); diff --git a/srcs/class/SceneParser.cpp b/srcs/class/SceneParser.cpp index 26afc05..cee946d 100644 --- a/srcs/class/SceneParser.cpp +++ b/srcs/class/SceneParser.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/26 21:43:51 by TheRed #+# #+# */ -/* Updated: 2025/01/21 15:57:42 by tomoron ### ########.fr */ +/* Updated: 2025/01/23 18:39:28 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -86,7 +86,6 @@ void SceneParser::parseCamera(std::stringstream &line) _scene->getCamera()->setPosition(glm::vec3(x, y, z)); _scene->getCamera()->setDirection(yaw, pitch); - _scene->getCamera()->updateCameraVectors(); _scene->getCamera()->setDOV(aperture, focus); _scene->getCamera()->setFov(fov); diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 75774d2..c4a56a3 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/23 00:39:21 by tomoron ### ########.fr */ +/* Updated: 2025/01/23 16:26:39 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -161,6 +161,11 @@ bool Window::shouldClose() return glfwWindowShouldClose(_window); } +void Window::rendererUpdate(void) +{ + _renderer->update(); +} + void Window::imGuiNewFrame() { ImGui_ImplOpenGL3_NewFrame(); From 25187d60ce4b23fdd6e5197a28f11013a4c573d8 Mon Sep 17 00:00:00 2001 From: tomoron Date: Sat, 25 Jan 2025 03:27:55 +0100 Subject: [PATCH 03/12] fix conditional jump problems, add functions to use ffmpeg for the render and add ffmpeg to compile the project --- Makefile | 24 +++---- imgui.ini | 8 +-- includes/RT/Renderer.hpp | 25 +++++++- includes/RT/Shader.hpp | 6 +- includes/RT/Window.hpp | 4 +- shell.nix | 2 +- srcs/RT.cpp | 4 +- srcs/class/Renderer.cpp | 135 ++++++++++++++++++++++++++++++++++++--- srcs/class/Shader.cpp | 14 +++- srcs/class/Window.cpp | 7 +- 10 files changed, 186 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index ea3ad1c..03432d3 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ else CC := clang++ CFLAGS := -Wall -Wextra -Werror -g -O3 IFLAGS := -I./includes -I./includes/RT -I./includes/imgui -I/usr/include - LDFLAGS := -L/usr/lib/x86_64-linux-gnu -lglfw -lGL -lGLU -lX11 -lpthread -ldl -lstdc++ + LDFLAGS := -L/usr/lib/x86_64-linux-gnu -lglfw -lGL -lGLU -lX11 -lpthread -ldl -lstdc++ -lavformat -lavcodec -lavutil -lswscale -lswresample FILE = $(shell ls -lR srcs/ | grep -F .c | wc -l) CMP = 1 endif @@ -62,19 +62,19 @@ OBJS := $(addprefix $(OBJS_DIR)/, $(SRCS:%.cpp=%.o)) HEADERS := includes/RT.hpp MAKEFLAGS += --no-print-directory -ifeq ($(OS),Windows_NT) -all: windows -else -all: linux -endif +all: $(NAME) -windows: $(OBJS) $(HEADERS) +ifeq ($(OS),Windows_NT) +$(NAME): $(OBJS) $(HEADERS) @$(CC) $(OBJS) $(IFLAGS) $(LDFLAGS) -o $(NAME) @echo $(WHITE) $(NAME): PROJECT COMPILED !$(RESET) - -linux: $(OBJS) $(HEADERS) +else +$(NAME): $(OBJS) $(HEADERS) @$(CC) $(OBJS) $(IFLAGS) $(CFLAGS) $(LDFLAGS) -o $(NAME) @printf "$(LINE_CLR)$(WHITE) $(NAME): PROJECT COMPILED !$(RESET)\n\n" +endif + + $(OBJS_DIR)/%.o: %.cpp @$(DIR_DUP) @@ -109,10 +109,6 @@ else @$(RM) $(OBJS_DIR) endif -ifeq ($(OS),Windows_NT) -re: fclean windows -else -re: fclean linux -endif +re: fclean $(NAME) .PHONY: all clean fclean re windows linux diff --git a/imgui.ini b/imgui.ini index dc1baba..0d09fe6 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,7 +3,7 @@ Pos=60,60 Size=400,400 [Window][Camera] -Pos=687,817 +Pos=687,417 Size=259,200 [Window][Material] @@ -11,7 +11,7 @@ Pos=646,129 Size=266,299 [Window][Fog settings] -Pos=35,863 +Pos=35,417 Size=247,130 [Window][Debug] @@ -24,6 +24,6 @@ Size=274,205 Collapsed=1 [Window][Renderer] -Pos=31,66 -Size=747,496 +Pos=32,4 +Size=404,469 diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 08d9e6b..39dcdfc 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/23 19:41:40 by tomoron ### ########.fr */ +/* Updated: 2025/01/25 03:12:38 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,9 +14,16 @@ # define RENDERER_HPP # include "RT.hpp" +extern "C" { +#include +#include +#include +#include +} class Scene; class Window; +class Shader; typedef struct s_pathPoint { @@ -30,15 +37,20 @@ class Renderer public: Renderer(Scene *scene, Window *win); void renderImgui(void); - void update(void); + void update(Shader &shader); private: void addPoint(void); void makeMovement(float timeFromStart, float curSplitTimeReset); + void initFfmpeg(std::string filename); + void addImageToRender(Shader &shader); + void endRender(void); int _min; - float _sec; + int _sec; int _samples; + int _testSamples; + int _fps; std::vector _path; Scene *_scene; Window *_win; @@ -47,6 +59,13 @@ class Renderer int _destPathIndex; double _curSplitStart; int _curSamples; + int _testMode; + long int _frameCount; + + AVFrame *_frame; + AVFormatContext *_format; + AVCodecContext *_codec_context; + }; #endif diff --git a/includes/RT/Shader.hpp b/includes/RT/Shader.hpp index cd89d6b..76c3f45 100644 --- a/includes/RT/Shader.hpp +++ b/includes/RT/Shader.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 18:10:10 by TheRed #+# #+# */ -/* Updated: 2024/10/14 19:51:46 by ycontre ### ########.fr */ +/* Updated: 2025/01/25 02:40:13 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,6 +35,8 @@ class Shader GLuint getProgram(void) const; GLuint getProgramCompute(void) const; + + std::vector getOutputImage(void); private: @@ -53,4 +55,4 @@ class Shader void checkCompileErrors(unsigned int shader); }; -#endif \ No newline at end of file +#endif diff --git a/includes/RT/Window.hpp b/includes/RT/Window.hpp index d30eb81..72cbb6a 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/23 15:31:28 by tomoron ### ########.fr */ +/* Updated: 2025/01/25 03:09:23 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -46,7 +46,7 @@ class Window void setFrameCount(int nb); - void rendererUpdate(void); + void rendererUpdate(Shader &shader); private: GLFWwindow *_window; Scene *_scene; diff --git a/shell.nix b/shell.nix index 117df0c..c445b9d 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,5 @@ { pkgs ? import {} }: pkgs.mkShell { - nativeBuildInputs = with pkgs; [ libGL xorg.libX11 libGLU glfw]; + nativeBuildInputs = with pkgs; [ libGL xorg.libX11 libGLU glfw ffmpeg]; } diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 37006c0..7ad9716 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/23 18:37:21 by tomoron ### ########.fr */ +/* Updated: 2025/01/25 02:29:18 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -115,7 +115,7 @@ int main(int argc, char **argv) std::vector gpu_lights_array(gpu_lights.begin(), gpu_lights.end()); glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightSSBO); glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, gpu_lights_array.size() * sizeof(int), gpu_lights_array.data()); - window.rendererUpdate(); + window.rendererUpdate(shader); Camera *camera = scene.getCamera(); diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 94d1954..0d07944 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/01/23 19:42:56 by tomoron ### ########.fr */ +/* Updated: 2025/01/25 03:25:48 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,11 +18,109 @@ Renderer::Renderer(Scene *scene, Window *win) _win = win; _min = 0; _sec = 0; + _fps = 30; _samples = 1; + _testSamples = 1; _curSamples = 0; + _destPathIndex = 0; + _frameCount = 0; + + _frame = 0; + _format = 0; + _codec_context = 0; } -void Renderer::addPoint(void) +void Renderer::initFfmpeg(std::string filename) +{ + const AVCodec *codec; + AVStream *stream; + + avformat_alloc_output_context2(&_format, nullptr, nullptr, filename.c_str()); + codec = avcodec_find_encoder(AV_CODEC_ID_H264); + if (!codec) + throw std::runtime_error("unable to find H264 audio/video codec, glhf"); + + _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->pix_fmt = AV_PIX_FMT_RGB24; + _codec_context->gop_size = 10; + _codec_context->max_b_frames = 1; + + if (_format->oformat->flags & AVFMT_GLOBALHEADER) + _codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + + if (avcodec_open2(_codec_context, codec, nullptr) < 0) + throw std::runtime_error("Failed to open codec"); + + stream = avformat_new_stream(_format, codec); + if (!stream) + 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, filename.c_str(), AVIO_FLAG_WRITE) < 0) + throw std::runtime_error("couldn't open " + filename); + } + (void)avformat_write_header(_format, nullptr); + + _frame = av_frame_alloc(); + _frame->format = _codec_context->pix_fmt; + _frame->width = _codec_context->width; + _frame->height = _codec_context->height; + av_image_alloc(_frame->data, _frame->linesize, WIDTH, HEIGHT, _codec_context->pix_fmt, 32); +} + +void Renderer::addImageToRender(Shader &shader) +{ + std::vector image; + AVPacket *pkt; + long int videoFrameOffset; + long int outputImageOffset; + + image = shader.getOutputImage(); + + for (int x = 0; x < WIDTH; x++) + { + for(int y = 0; y < HEIGHT; y++) + { + videoFrameOffset = (y * _frame->linesize[0]) + (x * 3); + outputImageOffset = (y * (WIDTH * 4)) + (x * 4); + _frame->data[0][videoFrameOffset] = image[outputImageOffset]; + _frame->data[0][videoFrameOffset + 1] = image[outputImageOffset + 1]; + _frame->data[0][videoFrameOffset + 2] = image[outputImageOffset + 2]; + } + } + + _frame->pts = _frameCount; + if (avcodec_send_frame(_codec_context, _frame) == 0) { + pkt = av_packet_alloc(); + while (avcodec_receive_packet(_codec_context, pkt) == 0) { + av_interleaved_write_frame(_format, pkt); + av_packet_unref(pkt); + } + av_packet_free(&pkt); + } +} + +void Renderer::endRender(void) +{ + av_write_trailer(_format); + av_frame_free(&_frame); + avcodec_free_context(&_codec_context); + avio_close(_format->pb); + avformat_free_context(_format); + + _format = 0; + _frame = 0; + _codec_context = 0; +} + +void Renderer::addPoint(void) { t_pathPoint newPoint; Camera *cam; @@ -31,26 +129,29 @@ void Renderer::addPoint(void) cam = _scene->getCamera(); newPoint.pos = cam->getPosition(); newPoint.dir = cam->getDirection(); - newPoint.time = _min + (_sec / 60); + newPoint.time = _min + ((float)_sec / 60); pos = _path.begin(); while(pos != _path.end() && pos->time <= newPoint.time) pos++; _path.insert(pos, newPoint); } -void Renderer::update(void) +void Renderer::update(Shader &shader) { double curTime; + (void)shader; if(!_destPathIndex) return; curTime = glfwGetTime(); _curSamples++; - if(_curSamples == _samples) + if(_testMode && _curSamples == _testSamples) { makeMovement(curTime - _curSplitStart, curTime); - _curSamples = 0; + _curSamples = 0; + return; } + //TODO: the rest } void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) @@ -65,7 +166,7 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) from = _path[_curPathIndex]; to = _path[_curPathIndex + 1]; cam = _scene->getCamera(); - pathTime = (to.time - from.time) * 60; + pathTime = (to.time - from.time) * 60; posStep.x = ((to.pos.x - from.pos.x) / pathTime) * timeFromStart; posStep.y = ((to.pos.y - from.pos.y) / pathTime) * timeFromStart; @@ -86,7 +187,7 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) if(_curPathIndex == _destPathIndex) { _destPathIndex = 0; - std::cout << "done" << std::endl; + _testMode = 0; } } @@ -94,11 +195,23 @@ void Renderer::renderImgui(void) { ImGui::Begin("Renderer"); - ImGui::SliderInt("spi", &_samples, 1, 1000); + ImGui::SliderInt("test spi", &_testSamples, 1, 10); + ImGui::SliderInt("render spi", &_samples, 1, 1000); + ImGui::SliderInt("render fps", &_fps, 30, 120); + if(_path.size() && ImGui::Button("try full path")) + { + _scene->getCamera()->setPosition(_path[0].pos); + _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); + _win->setFrameCount(-1); + _curSplitStart = glfwGetTime(); + _curPathIndex = 0; + _destPathIndex = _path.size() - 1; + _testMode = 1; + } ImGui::Separator(); ImGui::SliderInt("minutes", &_min, 0, 2); - ImGui::SliderFloat("seconds", &_sec, 0, 60); + ImGui::SliderInt("seconds", &_sec, 0, 60); if(ImGui::Button("add step")) addPoint(); ImGui::Separator(); @@ -139,8 +252,10 @@ void Renderer::renderImgui(void) _curSplitStart = glfwGetTime(); _curPathIndex = i - 1; _destPathIndex = i; + _testMode = 1; } ImGui::Separator(); } + ImGui::End(); } diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index a141739..b9c43a9 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 20:21:13 by ycontre #+# #+# */ -/* Updated: 2025/01/19 18:58:42 by ycontre ### ########.fr */ +/* Updated: 2025/01/25 03:11:43 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -205,4 +205,14 @@ GLuint Shader::getProgram(void) const GLuint Shader::getProgramCompute(void) const { return (_program_compute); -} \ No newline at end of file +} + +std::vector Shader::getOutputImage(void) +{ + std::vector res(WIDTH * HEIGHT * 4); + + glBindTexture(GL_TEXTURE_2D, _output_texture); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, res.data()); + glBindTexture(GL_TEXTURE_2D, 0); + return (res); +} diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index c4a56a3..57486c3 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/23 16:26:39 by tomoron ### ########.fr */ +/* Updated: 2025/01/25 03:09:56 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ Window::Window(Scene *scene, int width, int height, const char *title, int sleep) { _scene = scene; + _fps = 0; _frameCount = 0; _pixelisation = 0; _renderer = new Renderer(scene, this); @@ -161,9 +162,9 @@ bool Window::shouldClose() return glfwWindowShouldClose(_window); } -void Window::rendererUpdate(void) +void Window::rendererUpdate(Shader &shader) { - _renderer->update(); + _renderer->update(shader); } void Window::imGuiNewFrame() From cccdd259b4d009bb818b28821cd113e4585b1ddc Mon Sep 17 00:00:00 2001 From: tomoron Date: Sat, 25 Jan 2025 18:30:04 +0100 Subject: [PATCH 04/12] render works and exports to output.mp4 --- includes/RT/Renderer.hpp | 18 +++--- srcs/class/Renderer.cpp | 118 +++++++++++++++++++++++++++++---------- 2 files changed, 99 insertions(+), 37 deletions(-) diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 39dcdfc..f1d03dc 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/25 03:12:38 by tomoron ### ########.fr */ +/* Updated: 2025/01/25 17:07:46 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,10 +15,11 @@ # include "RT.hpp" extern "C" { -#include -#include -#include -#include + #include + #include + #include + #include + #include } class Scene; @@ -42,7 +43,7 @@ class Renderer private: void addPoint(void); void makeMovement(float timeFromStart, float curSplitTimeReset); - void initFfmpeg(std::string filename); + void initRender(std::string filename); void addImageToRender(Shader &shader); void endRender(void); @@ -62,9 +63,12 @@ class Renderer int _testMode; long int _frameCount; - AVFrame *_frame; AVFormatContext *_format; AVCodecContext *_codec_context; + AVFrame *_rgb_frame; + AVFrame *_yuv_frame; + SwsContext *_sws_context; + AVStream *_stream; }; diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 0d07944..70c2ebe 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/01/25 03:25:48 by tomoron ### ########.fr */ +/* Updated: 2025/01/25 18:28:19 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,16 +25,25 @@ Renderer::Renderer(Scene *scene, Window *win) _destPathIndex = 0; _frameCount = 0; - _frame = 0; + _rgb_frame = 0; + _yuv_frame = 0; _format = 0; _codec_context = 0; } -void Renderer::initFfmpeg(std::string filename) +void Renderer::initRender(std::string filename) { const AVCodec *codec; - AVStream *stream; + + _destPathIndex = _path.size() - 1; + _curPathIndex = 0; + _frameCount = 0; + _curSamples = 0; + _curSplitStart = 0; + _testMode = 0; + _scene->getCamera()->setPosition(_path[0].pos); + _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); avformat_alloc_output_context2(&_format, nullptr, nullptr, filename.c_str()); codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec) @@ -45,7 +54,7 @@ void Renderer::initFfmpeg(std::string filename) _codec_context->height = HEIGHT; _codec_context->time_base = {1, _fps}; _codec_context->framerate = {_fps, 1}; - _codec_context->pix_fmt = AV_PIX_FMT_RGB24; + _codec_context->pix_fmt = AV_PIX_FMT_YUV420P; _codec_context->gop_size = 10; _codec_context->max_b_frames = 1; @@ -55,11 +64,11 @@ void Renderer::initFfmpeg(std::string filename) if (avcodec_open2(_codec_context, codec, nullptr) < 0) throw std::runtime_error("Failed to open codec"); - stream = avformat_new_stream(_format, codec); - if (!stream) + _stream = avformat_new_stream(_format, codec); + if (!_stream) throw std::runtime_error("Failed to create stream"); - stream->time_base = _codec_context->time_base; - avcodec_parameters_from_context(stream->codecpar, _codec_context); + _stream->time_base = _codec_context->time_base; + avcodec_parameters_from_context(_stream->codecpar, _codec_context); if (!(_format->flags & AVFMT_NOFILE)) { @@ -68,11 +77,22 @@ void Renderer::initFfmpeg(std::string filename) } (void)avformat_write_header(_format, nullptr); - _frame = av_frame_alloc(); - _frame->format = _codec_context->pix_fmt; - _frame->width = _codec_context->width; - _frame->height = _codec_context->height; - av_image_alloc(_frame->data, _frame->linesize, WIDTH, HEIGHT, _codec_context->pix_fmt, 32); + _rgb_frame = av_frame_alloc(); + _rgb_frame->format = AV_PIX_FMT_RGB24; + _rgb_frame->width = WIDTH; + _rgb_frame->height = HEIGHT; + av_image_alloc(_rgb_frame->data, _rgb_frame->linesize, WIDTH, HEIGHT, AV_PIX_FMT_RGB24, 32); + + _yuv_frame = av_frame_alloc(); + _yuv_frame->format = _codec_context->pix_fmt; + _yuv_frame->width = WIDTH; + _yuv_frame->height = HEIGHT; + av_image_alloc(_yuv_frame->data, _yuv_frame->linesize, WIDTH, HEIGHT, _codec_context->pix_fmt, 32); + + _sws_context = sws_getContext( + WIDTH, HEIGHT, AV_PIX_FMT_RGB24, + WIDTH, HEIGHT, AV_PIX_FMT_YUV420P, + SWS_BILINEAR, nullptr, nullptr, nullptr); } void Renderer::addImageToRender(Shader &shader) @@ -88,18 +108,28 @@ void Renderer::addImageToRender(Shader &shader) { for(int y = 0; y < HEIGHT; y++) { - videoFrameOffset = (y * _frame->linesize[0]) + (x * 3); - outputImageOffset = (y * (WIDTH * 4)) + (x * 4); - _frame->data[0][videoFrameOffset] = image[outputImageOffset]; - _frame->data[0][videoFrameOffset + 1] = image[outputImageOffset + 1]; - _frame->data[0][videoFrameOffset + 2] = image[outputImageOffset + 2]; + videoFrameOffset = (y * _rgb_frame->linesize[0]) + (x * 3); + outputImageOffset = (((HEIGHT - 1) - y) * (WIDTH * 4)) + (x * 4); + glm::vec3 colors(image[outputImageOffset], image[outputImageOffset + 1], image[outputImageOffset + 2]); + // if(colors.x > 1 || colors.y > 1 || colors.z > 1) + // colors = glm::normalize(colors); + colors.x = fmin(colors.x, 1); + colors.y = fmin(colors.y, 1); + colors.z = fmin(colors.z, 1); + _rgb_frame->data[0][videoFrameOffset] = colors.x * 255; + _rgb_frame->data[0][videoFrameOffset + 1] = colors.y * 255; + _rgb_frame->data[0][videoFrameOffset + 2] = colors.z * 255; } } + sws_scale(_sws_context, _rgb_frame->data, _rgb_frame->linesize, 0, HEIGHT, _yuv_frame->data, _yuv_frame->linesize); + _yuv_frame->pts = _frameCount; - _frame->pts = _frameCount; - if (avcodec_send_frame(_codec_context, _frame) == 0) { + if (avcodec_send_frame(_codec_context, _yuv_frame) == 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); } @@ -109,14 +139,29 @@ void Renderer::addImageToRender(Shader &shader) 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); + } + av_packet_free(&pkt); + av_write_trailer(_format); - av_frame_free(&_frame); + av_frame_free(&_rgb_frame); + av_frame_free(&_yuv_frame); avcodec_free_context(&_codec_context); avio_close(_format->pb); avformat_free_context(_format); _format = 0; - _frame = 0; + _rgb_frame = 0; + _yuv_frame = 0; _codec_context = 0; } @@ -143,15 +188,23 @@ void Renderer::update(Shader &shader) (void)shader; if(!_destPathIndex) return; - curTime = glfwGetTime(); + _curSamples++; - if(_testMode && _curSamples == _testSamples) - { - makeMovement(curTime - _curSplitStart, curTime); - _curSamples = 0; + if((_testMode && _curSamples < _testSamples) || (!_testMode && _curSamples < _samples)) return; + + if(_testMode) + curTime = glfwGetTime(); + else + curTime = (1 / (double)_fps) * (double)_frameCount; + + if(!_testMode) + { + addImageToRender(shader); + _frameCount++; } - //TODO: the rest + makeMovement(curTime - _curSplitStart, curTime); + _curSamples = 0; } void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) @@ -187,7 +240,8 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) if(_curPathIndex == _destPathIndex) { _destPathIndex = 0; - _testMode = 0; + if(!_testMode) + endRender(); } } @@ -208,6 +262,10 @@ void Renderer::renderImgui(void) _destPathIndex = _path.size() - 1; _testMode = 1; } + if(_path.size() && ImGui::Button("start render")) + { + initRender("output.mp4"); + } ImGui::Separator(); ImGui::SliderInt("minutes", &_min, 0, 2); From 9ab134abef53b0d35a7cef4e8908d33567a13045 Mon Sep 17 00:00:00 2001 From: tomoron Date: Sun, 26 Jan 2025 05:18:03 +0100 Subject: [PATCH 05/12] change render window to show information about current render state during a render. render. --- includes/RT/Renderer.hpp | 9 +++- srcs/class/Renderer.cpp | 111 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index f1d03dc..75474d8 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/25 17:07:46 by tomoron ### ########.fr */ +/* Updated: 2025/01/26 04:15:45 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,7 +30,7 @@ typedef struct s_pathPoint { glm::vec3 pos; glm::vec2 dir; - float time; + double time; } t_pathPoint; class Renderer @@ -39,6 +39,7 @@ class Renderer Renderer(Scene *scene, Window *win); void renderImgui(void); void update(Shader &shader); + int rendering(void) const; private: void addPoint(void); @@ -46,6 +47,9 @@ class Renderer void initRender(std::string filename); void addImageToRender(Shader &shader); void endRender(void); + void imguiPathCreation(void); + void imguiRenderInfo(void); + std::string floatToTime(float timef); int _min; int _sec; @@ -62,6 +66,7 @@ class Renderer int _curSamples; int _testMode; long int _frameCount; + float _renderStartTime; AVFormatContext *_format; AVCodecContext *_codec_context; diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 70c2ebe..86cc5e5 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/01/25 18:28:19 by tomoron ### ########.fr */ +/* Updated: 2025/01/26 05:05:10 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,15 +35,16 @@ void Renderer::initRender(std::string filename) { const AVCodec *codec; - _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(-1); avformat_alloc_output_context2(&_format, nullptr, nullptr, filename.c_str()); codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec) @@ -245,10 +246,13 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) } } -void Renderer::renderImgui(void) +int Renderer::rendering(void) const { - ImGui::Begin("Renderer"); + return(_destPathIndex != 0 && !_testMode); +} +void Renderer::imguiPathCreation(void) +{ ImGui::SliderInt("test spi", &_testSamples, 1, 10); ImGui::SliderInt("render spi", &_samples, 1, 1000); ImGui::SliderInt("render fps", &_fps, 30, 120); @@ -314,6 +318,105 @@ void Renderer::renderImgui(void) } ImGui::Separator(); } +} +std::string Renderer::floatToTime(float timef) +{ + std::string res; + uint64_t time; + uint64_t values[7]; + int firstValue; + + time = timef; + values[0] = time / 3600 * 24 * 365; + time = time % (3600 * 24 * 365); + values[1] = time / 3600 * 24 * 30; + time = time % (3600 * 24 * 30); + values[2] = time / 3600 * 24 * 7; + time = time % (3600 * 24 * 7); + values[3] = time / 3600 * 24; + time = time % (3600 * 24); + values[4] = time / 3600; + time = time % 3600; + values[5] = time / 60; + time = time % 60; + values[6] = time; + + firstValue = 0; + while(firstValue < 6 && values[firstValue] == 0 ) + firstValue++; + + res = ""; + switch(firstValue) + { + case 0: + res += std::to_string(values[0]); + res += "Y"; + case 1: + res += std::to_string(values[1]); + res += "M"; + case 2: + res += std::to_string(values[2]); + res += "W"; + case 3: + res += std::to_string(values[3]); + res += "d"; + case 4: + res += std::to_string(values[4]); + res += "h"; + case 5: + res += std::to_string(values[5]); + res += "m"; + case 6: + res += std::to_string(values[6]); + res += "s"; + } + return(res); +} + +void Renderer::imguiRenderInfo(void) +{ + long int totalFrames; + float renderTime; + float progress; + float timeElapsed; + float timeEst; + + totalFrames = (_path[_destPathIndex].time - _path[0].time) * 60 * _fps; + renderTime = ((float)_frameCount / _fps) / 60; + + timeElapsed = glfwGetTime() - _renderStartTime; + timeEst = timeElapsed / ((_frameCount * _samples) + _curSamples); + 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()); + progress = ((float)_frameCount * _samples) + _curSamples; + progress /= (float)totalFrames * _samples; + ImGui::ProgressBar(progress, ImVec2(0, 0)); + if(ImGui::Button("stop")) + { + _destPathIndex = 0; + endRender(); + } +} + +void Renderer::renderImgui(void) +{ + ImGui::Begin("Renderer"); + + if(rendering()) + imguiRenderInfo(); + else + imguiPathCreation(); ImGui::End(); } From 4268a41b6a9588fb3cbe0dfdd7e23f28ec548ea0 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Mon, 27 Jan 2025 13:39:08 +0100 Subject: [PATCH 06/12] ~ | Change makefile for windows build --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 03432d3..6ba5f86 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,8 @@ ifeq ($(OS),Windows_NT) RM := del /S /Q DIR_DUP = if not exist "$(@D)" mkdir "$(@D)" CC := g++ -O3 - IFLAGS := -I./includes -I./includes/RT -I./includes/imgui - LDFLAGS := -L./lib -lglfw3 -lopengl32 -lgdi32 -lcglm + IFLAGS := -I./includes -I./includes/RT -I./includes/imgui -I"D:/ffmpeg/include" + LDFLAGS := -L./lib -L"D:/ffmpeg/lib" -lglfw3 -lopengl32 -lgdi32 -lcglm -lavformat -lavcodec -lavutil -lswscale -lswresample else BLACK = \033[30;49;3m RED = \033[31;49;3m From c909cbd6dab3f814a1d79caa932da68357e452ea Mon Sep 17 00:00:00 2001 From: tomoron Date: Mon, 27 Jan 2025 21:02:45 +0100 Subject: [PATCH 07/12] renderer, add button to mach speed of previous segment of path --- srcs/class/Renderer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 86cc5e5..0c69af0 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/01/26 05:05:10 by tomoron ### ########.fr */ +/* Updated: 2025/01/27 16:31:11 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -316,6 +316,13 @@ void Renderer::imguiPathCreation(void) _destPathIndex = i; _testMode = 1; } + if(i > 1 && ImGui::Button(("match prev speed##" + std::to_string(i)).c_str())) + { + float speed = glm::distance(_path[i - 2].pos, _path[i - 1].pos) / (_path[i - 1].time - _path[i - 2].time); + std::cout << "speed : " << speed << std::endl; + std::cout << "dist : " << glm::distance(_path[i - 1].pos, _path[i].pos) << std::endl; + _path[i].time = _path[i - 1].time + (glm::distance(_path[i - 1].pos, _path[i].pos) / speed); + } ImGui::Separator(); } } From 0f159baf9db77bf362a96fe4944d9d45a8251664 Mon Sep 17 00:00:00 2001 From: tomoron Date: Tue, 28 Jan 2025 02:27:23 +0100 Subject: [PATCH 08/12] smooth transition between points using hermite interpolation for position and sphere interpolation for rotation --- imgui.ini | 10 ++-- includes/RT/Renderer.hpp | 4 +- srcs/class/Camera.cpp | 6 ++- srcs/class/Renderer.cpp | 113 ++++++++++++++++++++++++++++++++++----- 4 files changed, 112 insertions(+), 21 deletions(-) diff --git a/imgui.ini b/imgui.ini index 0d09fe6..e266055 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,15 +3,15 @@ Pos=60,60 Size=400,400 [Window][Camera] -Pos=687,417 +Pos=927,11 Size=259,200 [Window][Material] -Pos=646,129 +Pos=9,5 Size=266,299 [Window][Fog settings] -Pos=35,417 +Pos=22,314 Size=247,130 [Window][Debug] @@ -24,6 +24,6 @@ Size=274,205 Collapsed=1 [Window][Renderer] -Pos=32,4 -Size=404,469 +Pos=344,18 +Size=514,500 diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 75474d8..bd516b5 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/26 04:15:45 by tomoron ### ########.fr */ +/* Updated: 2025/01/28 01:20:39 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,12 +50,14 @@ class Renderer void imguiPathCreation(void); void imguiRenderInfo(void); std::string floatToTime(float timef); + glm::vec2 sphereInterpolate(glm::vec2 from, glm::vec2 to, float time); int _min; int _sec; int _samples; int _testSamples; int _fps; + bool _mine; std::vector _path; Scene *_scene; Window *_win; diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index 2a09b80..aaab1b0 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/15 14:00:38 by TheRed #+# #+# */ -/* Updated: 2025/01/23 18:34:29 by tomoron ### ########.fr */ +/* Updated: 2025/01/28 02:15:41 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -59,6 +59,10 @@ void Camera::processMouse(float xoffset, float yoffset, bool constraint_pitch = _yaw += xoffset * _sensitivity; _pitch += yoffset * _sensitivity; +// while(_yaw < 0) +// _yaw += 360; +// while(_yaw > 360) +// _yaw -= 360; if (constraint_pitch) { if (_pitch > 89.0f) _pitch = 89.0f; diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 0c69af0..f52e57f 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/01/27 16:31:11 by tomoron ### ########.fr */ +/* Updated: 2025/01/28 02:19:41 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -208,35 +208,119 @@ void Renderer::update(Shader &shader) _curSamples = 0; } +glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha) +{ + double tension; + double bias; + glm::vec3 tang[2]; + double alphaSqr[2]; + glm::vec3 coef[4]; + + tension = 0; + bias = 0; + + alphaSqr[0] = alpha * alpha; + alphaSqr[1] = alphaSqr[0] * alpha; + + tang[0] = (points[1] - points[0]) * glm::vec3(1 + bias) * glm::vec3(1 - tension) / glm::vec3(2); + tang[0] += (points[2] - points[1]) * glm::vec3(1 - bias) * glm::vec3(1 - tension) / glm::vec3(2); + tang[1] = (points[2] - points[1]) * glm::vec3(1 + bias) * glm::vec3(1 - tension) / glm::vec3(2); + tang[1] += (points[3] - points[2]) * glm::vec3(1 - bias) * glm::vec3(1 - tension) / glm::vec3(2); + + coef[0] = glm::vec3(2 * alphaSqr[1] - 3 * alphaSqr[0] + 1); + coef[1] = glm::vec3(alphaSqr[1] - 2 * alphaSqr[0] + alpha); + coef[2] = glm::vec3(alphaSqr[1] - alphaSqr[0]); + coef[3] = glm::vec3(-2 * alphaSqr[1] + 3 * alphaSqr[0]); + + return(coef[0] * points[1] + coef[1] * tang[0] + coef[2] * tang[1] + coef[3] * points[2]); +} + +glm::quat eulerToQuaternion(float pitch, float yaw) { + std::cout << "input : " << pitch << ", " << yaw << std::endl; + glm::quat qPitch = glm::angleAxis(glm::radians(pitch), glm::vec3(1, 0, 0)); + glm::quat qYaw = glm::angleAxis(glm::radians(yaw), glm::vec3(0, 1, 0)); + + glm::quat result = qYaw* qPitch; + std::cout << "output : " << glm::to_string(result) << std::endl; + return(result); +} + +glm::vec2 Renderer::sphereInterpolate(glm::vec2 from, glm::vec2 to, float time) +{ + glm::vec3 eulerRes; + glm::quat qFrom; + glm::quat qTo; + glm::quat res; + float angle; + float dot; + + qFrom = glm::normalize(eulerToQuaternion(from.y, from.x)); + qTo = glm::normalize(eulerToQuaternion(to.y, to.x)); + + dot = glm::dot(qFrom, qTo); + if(dot < 0) + to = -to; + angle = 2 * glm::acos(dot); + res = (glm::sin((1 - time) * angle / glm::sin(angle)) * qFrom) + ((glm::sin(time * angle) / glm::sin(angle)) * qTo); + eulerRes = glm::degrees(glm::eulerAngles(res)); + return(glm::vec2(eulerRes.y, eulerRes.x)); +} + + void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) { t_pathPoint from; t_pathPoint to; + t_pathPoint prev; + t_pathPoint next; float pathTime; Camera *cam; - glm::vec3 posStep; - glm::vec2 dirStep; + glm::vec3 pos; + glm::vec2 dir; + float normalTime; from = _path[_curPathIndex]; to = _path[_curPathIndex + 1]; + if(_curPathIndex) + prev = _path[_curPathIndex - 1]; + else + prev = from; + if((size_t)_curPathIndex + 3 == _path.size()) + next = _path[_curPathIndex + 2]; + else + next = to; + + cam = _scene->getCamera(); pathTime = (to.time - from.time) * 60; - - posStep.x = ((to.pos.x - from.pos.x) / pathTime) * timeFromStart; - posStep.y = ((to.pos.y - from.pos.y) / pathTime) * timeFromStart; - posStep.z = ((to.pos.z - from.pos.z) / pathTime) * timeFromStart; - dirStep.x = ((to.dir.x - from.dir.x) / pathTime) * timeFromStart; - dirStep.y = ((to.dir.y - from.dir.y) / pathTime) * timeFromStart; - + normalTime = 1 - ((pathTime - timeFromStart) / pathTime); + + pos = hermiteInterpolate((glm::vec3 [4]){prev.pos, from.pos, to.pos, next.pos}, normalTime); + dir = sphereInterpolate(from.dir, to.dir, normalTime); + if(std::isnan(dir.x) || std::isnan(dir.y)) + dir = from.dir; +// dir.x = hermiteInterpolate((glm::vec3 [4]){ +// glm::vec3(prev.dir.x, prev.dir.y, 0), +// glm::vec3(from.dir.x, from.dir.y, 0), +// glm::vec3(to.dir.x, to.dir.y, 0), +// glm::vec3(next.dir.x, next.dir.y, 0) +// }, normalTime).x; +// dir.y = hermiteInterpolate((glm::vec3 [4]){ +// glm::vec3(prev.dir.x, prev.dir.y, 0), +// glm::vec3(from.dir.x, from.dir.y, 0), +// glm::vec3(to.dir.x, to.dir.y, 0), +// glm::vec3(next.dir.x, next.dir.y, 0) +// }, normalTime).y; if(timeFromStart >= pathTime) { - posStep = to.pos - from.pos; - dirStep = to.dir - from.dir; + pos = to.pos; + dir = to.dir; _curSplitStart = curSplitTimeReset; _curPathIndex++; } - cam->setPosition(from.pos + posStep); - cam->setDirection(from.dir.x + dirStep.x, from.dir.y + dirStep.y); + std::cout << glm::to_string(dir) << std::endl; + cam->setPosition(pos); + cam->setDirection(dir.x, dir.y); _win->setFrameCount(0); if(_curPathIndex == _destPathIndex) { @@ -256,6 +340,7 @@ void Renderer::imguiPathCreation(void) ImGui::SliderInt("test spi", &_testSamples, 1, 10); ImGui::SliderInt("render spi", &_samples, 1, 1000); ImGui::SliderInt("render fps", &_fps, 30, 120); + ImGui::Checkbox("mine", &_mine); if(_path.size() && ImGui::Button("try full path")) { _scene->getCamera()->setPosition(_path[0].pos); From 409a4f6def82a1e88b05d86e78ee7d3675ea3e43 Mon Sep 17 00:00:00 2001 From: tomoron Date: Wed, 29 Jan 2025 02:47:06 +0100 Subject: [PATCH 09/12] repair codec selection 42 computers, lerp and slerp might be broken :/ --- Makefile | 4 +- imgui.ini | 6 +-- includes/RT/Renderer.hpp | 54 ++++++++++++---------- shell.nix | 1 + srcs/class/Renderer.cpp | 98 ++++++++++++++++++++++++++++++++-------- srcs/class/Window.cpp | 4 +- 6 files changed, 117 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index 6ba5f86..4193dae 100644 --- a/Makefile +++ b/Makefile @@ -29,8 +29,8 @@ else DIR_DUP = mkdir -p $(@D) CC := clang++ CFLAGS := -Wall -Wextra -Werror -g -O3 - IFLAGS := -I./includes -I./includes/RT -I./includes/imgui -I/usr/include - LDFLAGS := -L/usr/lib/x86_64-linux-gnu -lglfw -lGL -lGLU -lX11 -lpthread -ldl -lstdc++ -lavformat -lavcodec -lavutil -lswscale -lswresample + 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) CMP = 1 endif diff --git a/imgui.ini b/imgui.ini index e266055..35634a5 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,7 +3,7 @@ Pos=60,60 Size=400,400 [Window][Camera] -Pos=927,11 +Pos=795,76 Size=259,200 [Window][Material] @@ -19,11 +19,11 @@ Pos=1642,668 Size=260,143 [Window][Debug BVH] -Pos=772,16 +Pos=744,269 Size=274,205 Collapsed=1 [Window][Renderer] -Pos=344,18 +Pos=374,0 Size=514,500 diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index bd516b5..16eddab 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/28 01:20:39 by tomoron ### ########.fr */ +/* Updated: 2025/01/29 02:34:11 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -44,38 +44,44 @@ class Renderer private: void addPoint(void); void makeMovement(float timeFromStart, float curSplitTimeReset); - void initRender(std::string filename); + void initRender(); void addImageToRender(Shader &shader); void endRender(void); void imguiPathCreation(void); void imguiRenderInfo(void); std::string floatToTime(float timef); glm::vec2 sphereInterpolate(glm::vec2 from, glm::vec2 to, float time); + void updateAvailableCodecs(void); + void fillGoodCodecList(std::vector &lst); - int _min; - int _sec; - int _samples; - int _testSamples; - int _fps; - bool _mine; - std::vector _path; - Scene *_scene; - Window *_win; + int _min; + int _sec; + int _samples; + int _testSamples; + int _fps; + char _filenameBuffer[512]; + std::vector _path; + std::string _outputFilename; + Scene *_scene; + Window *_win; + std::vector _codecList; + std::vector _codecListStr; + int _codecIndex; - int _curPathIndex; - int _destPathIndex; - double _curSplitStart; - int _curSamples; - int _testMode; - long int _frameCount; - float _renderStartTime; + int _curPathIndex; + int _destPathIndex; + double _curSplitStart; + int _curSamples; + int _testMode; + long int _frameCount; + float _renderStartTime; - AVFormatContext *_format; - AVCodecContext *_codec_context; - AVFrame *_rgb_frame; - AVFrame *_yuv_frame; - SwsContext *_sws_context; - AVStream *_stream; + AVFormatContext *_format; + AVCodecContext *_codec_context; + AVFrame *_rgb_frame; + AVFrame *_yuv_frame; + SwsContext *_sws_context; + AVStream *_stream; }; diff --git a/shell.nix b/shell.nix index c445b9d..016fa2c 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,6 @@ { pkgs ? import {} }: pkgs.mkShell { nativeBuildInputs = with pkgs; [ libGL xorg.libX11 libGLU glfw ffmpeg]; + shellHook="make -j"; } diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index f52e57f..2d53013 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/01/28 02:19:41 by tomoron ### ########.fr */ +/* Updated: 2025/01/29 02:43:55 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,17 +24,74 @@ Renderer::Renderer(Scene *scene, Window *win) _curSamples = 0; _destPathIndex = 0; _frameCount = 0; + _outputFilename = "output.mp4"; + memcpy(_filenameBuffer, _outputFilename.c_str(), _outputFilename.length()); + _filenameBuffer[_outputFilename.length()] = 0; _rgb_frame = 0; _yuv_frame = 0; _format = 0; _codec_context = 0; + updateAvailableCodecs(); } -void Renderer::initRender(std::string filename) +void Renderer::fillGoodCodecList(std::vector &lst) +{ + lst.push_back(AV_CODEC_ID_H264); + lst.push_back(AV_CODEC_ID_MPEG4); + lst.push_back(AV_CODEC_ID_H263); + lst.push_back(AV_CODEC_ID_MPEG2VIDEO); +} + +void Renderer::updateAvailableCodecs(void) { const AVCodec *codec; - + AVCodecContext *ctx; + const AVOutputFormat *muxer; + const char *format; + std::vector goodCodecList; + + fillGoodCodecList(goodCodecList); + _codecList.clear(); + _codecListStr.clear(); + _codecIndex = 0; + av_log_set_level(AV_LOG_QUIET); + format = _outputFilename.c_str(); + if(_outputFilename.find(".") != std::string::npos) + format += _outputFilename.find(".") + 1; + + muxer = av_guess_format(format, 0, 0); + for(std::vector::iterator it = goodCodecList.begin(); it != goodCodecList.end(); it++) + { + codec = avcodec_find_encoder(*it); + if(!codec) + continue; + ctx = avcodec_alloc_context3(codec); + if(ctx) + { + if (avformat_query_codec(muxer, codec->id, FF_COMPLIANCE_STRICT) > 0) + { + ctx->width = WIDTH; + ctx->height = HEIGHT; + ctx->time_base = {1, _fps}; + ctx->framerate = {_fps, 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); + } + avcodec_free_context(&ctx); + } + } + for(auto it = _codecList.begin(); it != _codecList.end(); it++) + { + _codecListStr.push_back((*it)->name); + } +} + +void Renderer::initRender(void) +{ _destPathIndex = _path.size() - 1; _curPathIndex = 0; _frameCount = 0; @@ -45,12 +102,9 @@ void Renderer::initRender(std::string filename) _scene->getCamera()->setPosition(_path[0].pos); _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); _win->setFrameCount(-1); - avformat_alloc_output_context2(&_format, nullptr, nullptr, filename.c_str()); - codec = avcodec_find_encoder(AV_CODEC_ID_H264); - if (!codec) - throw std::runtime_error("unable to find H264 audio/video codec, glhf"); + avformat_alloc_output_context2(&_format, nullptr, nullptr, _outputFilename.c_str()); - _codec_context = avcodec_alloc_context3(codec); + _codec_context = avcodec_alloc_context3(_codecList[_codecIndex]); _codec_context->width = WIDTH; _codec_context->height = HEIGHT; _codec_context->time_base = {1, _fps}; @@ -62,10 +116,10 @@ void Renderer::initRender(std::string filename) if (_format->oformat->flags & AVFMT_GLOBALHEADER) _codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - if (avcodec_open2(_codec_context, codec, nullptr) < 0) + if (avcodec_open2(_codec_context, _codecList[_codecIndex], nullptr) < 0) throw std::runtime_error("Failed to open codec"); - _stream = avformat_new_stream(_format, codec); + _stream = avformat_new_stream(_format, _codecList[_codecIndex]); if (!_stream) throw std::runtime_error("Failed to create stream"); _stream->time_base = _codec_context->time_base; @@ -73,8 +127,8 @@ void Renderer::initRender(std::string filename) if (!(_format->flags & AVFMT_NOFILE)) { - if (avio_open(&_format->pb, filename.c_str(), AVIO_FLAG_WRITE) < 0) - throw std::runtime_error("couldn't open " + filename); + if (avio_open(&_format->pb, _outputFilename.c_str(), AVIO_FLAG_WRITE) < 0) + throw std::runtime_error("couldn't open " + _outputFilename); } (void)avformat_write_header(_format, nullptr); @@ -236,12 +290,10 @@ glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha) } glm::quat eulerToQuaternion(float pitch, float yaw) { - std::cout << "input : " << pitch << ", " << yaw << std::endl; glm::quat qPitch = glm::angleAxis(glm::radians(pitch), glm::vec3(1, 0, 0)); glm::quat qYaw = glm::angleAxis(glm::radians(yaw), glm::vec3(0, 1, 0)); glm::quat result = qYaw* qPitch; - std::cout << "output : " << glm::to_string(result) << std::endl; return(result); } @@ -340,8 +392,14 @@ void Renderer::imguiPathCreation(void) ImGui::SliderInt("test spi", &_testSamples, 1, 10); ImGui::SliderInt("render spi", &_samples, 1, 1000); ImGui::SliderInt("render fps", &_fps, 30, 120); - ImGui::Checkbox("mine", &_mine); - if(_path.size() && ImGui::Button("try full path")) + + ImGui::Combo("codec", &_codecIndex, _codecListStr.data(), _codecListStr.size()); + if(ImGui::InputText("file name", _filenameBuffer, 512)) + { + _outputFilename = _filenameBuffer; + updateAvailableCodecs(); + } + if(_path.size() > 1 && ImGui::Button("try full path")) { _scene->getCamera()->setPosition(_path[0].pos); _scene->getCamera()->setDirection(_path[0].dir.x, _path[0].dir.y); @@ -351,16 +409,16 @@ void Renderer::imguiPathCreation(void) _destPathIndex = _path.size() - 1; _testMode = 1; } - if(_path.size() && ImGui::Button("start render")) - { - initRender("output.mp4"); - } + if(_path.size() > 1 && _codecList.size() && ImGui::Button("start render")) + initRender(); + ImGui::Separator(); ImGui::SliderInt("minutes", &_min, 0, 2); ImGui::SliderInt("seconds", &_sec, 0, 60); if(ImGui::Button("add step")) addPoint(); + ImGui::Separator(); for(unsigned long i = 0; i < _path.size(); i++) diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 57486c3..28b4f74 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/25 03:09:56 by tomoron ### ########.fr */ +/* Updated: 2025/01/28 15:15:53 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -71,6 +71,8 @@ void Window::process_input() bool up = glfwGetKey(_window, GLFW_KEY_SPACE) == GLFW_PRESS; bool down = glfwGetKey(_window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS; + if(_renderer->rendering()) + return ; if (forward || backward || left || right || up || down) _frameCount = 0; From e7cd411802789570e2f57b5b40d285cb7b4f24a3 Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 30 Jan 2025 00:01:02 +0100 Subject: [PATCH 10/12] add smoothing on camera movement with a ease in out --- includes/RT/Renderer.hpp | 3 +- srcs/class/Renderer.cpp | 92 +++++++++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 35 deletions(-) diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 16eddab..4db1297 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/29 02:34:11 by tomoron ### ########.fr */ +/* Updated: 2025/01/29 23:58:48 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,6 +53,7 @@ class Renderer glm::vec2 sphereInterpolate(glm::vec2 from, glm::vec2 to, float time); void updateAvailableCodecs(void); void fillGoodCodecList(std::vector &lst); + glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha); int _min; int _sec; diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 2d53013..3493ba5 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/01/29 02:43:55 by tomoron ### ########.fr */ +/* Updated: 2025/01/29 23:57:21 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -262,7 +262,7 @@ void Renderer::update(Shader &shader) _curSamples = 0; } -glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha) +glm::vec3 Renderer::hermiteInterpolate(glm::vec3 points[4], double alpha) { double tension; double bias; @@ -289,7 +289,8 @@ glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha) return(coef[0] * points[1] + coef[1] * tang[0] + coef[2] * tang[1] + coef[3] * points[2]); } -glm::quat eulerToQuaternion(float pitch, float yaw) { +glm::quat eulerToQuaternion(float pitch, float yaw) +{ glm::quat qPitch = glm::angleAxis(glm::radians(pitch), glm::vec3(1, 0, 0)); glm::quat qYaw = glm::angleAxis(glm::radians(yaw), glm::vec3(0, 1, 0)); @@ -297,25 +298,63 @@ glm::quat eulerToQuaternion(float pitch, float yaw) { return(result); } +//glm::vec2 Renderer::sphereInterpolate(glm::vec2 from, glm::vec2 to, float time) // gud but bad +//{ +// glm::vec3 eulerRes; +// glm::quat qFrom; +// glm::quat qTo; +// glm::quat res; +// float angle; +// float dot; +// +// qFrom = glm::normalize(eulerToQuaternion(from.y, from.x)); +// qTo = glm::normalize(eulerToQuaternion(to.y, to.x)); +// +// dot = glm::dot(qFrom, qTo); +// if(dot < 0) +// to = -to; +// angle = 2 * glm::acos(dot); +// res = (glm::sin((1 - time) * angle / glm::sin(angle)) * qFrom) + ((glm::sin(time * angle) / glm::sin(angle)) * qTo); +// eulerRes = glm::degrees(glm::eulerAngles(res)); +// return(glm::vec2(eulerRes.y, eulerRes.x)); +//} + + glm::vec2 Renderer::sphereInterpolate(glm::vec2 from, glm::vec2 to, float time) { - glm::vec3 eulerRes; - glm::quat qFrom; - glm::quat qTo; - glm::quat res; - float angle; - float dot; + glm::vec2 delta; + glm::vec2 p1, p2; + float t; - qFrom = glm::normalize(eulerToQuaternion(from.y, from.x)); - qTo = glm::normalize(eulerToQuaternion(to.y, to.x)); - - dot = glm::dot(qFrom, qTo); - if(dot < 0) - to = -to; - angle = 2 * glm::acos(dot); - res = (glm::sin((1 - time) * angle / glm::sin(angle)) * qFrom) + ((glm::sin(time * angle) / glm::sin(angle)) * qTo); - eulerRes = glm::degrees(glm::eulerAngles(res)); - return(glm::vec2(eulerRes.y, eulerRes.x)); + p1 = glm::vec2(0.20, 0); + p2 = glm::vec2(0.80, 1); + t = time; + for(int i = 0; i < 5; i++) { + float currentX = 3.0f * ((1 - t) * (1 - t)) * t * p1.x + 3.0f * (1 - t) * (t * t) * p2.x + (t * t * t); + + if(abs(currentX - time) < 0.00001f) { + break; + } + + glm::vec2 derivative = glm::vec2( + 3.0f * (1 - t) * (1 - t) * p1.x + + 6.0f * (1.0f - t) * t * (p2.x - p1.x) + + 3.0f * t * t * (1.0f - p2.x), + + 3.0f * (1 - t) * (1 - t) * p1.y + + 6.0f * (1.0f - t) * t * (p2.y - p1.y) + + 3.0f * t * t * (1.0f - p2.y) + ); + + if(abs(derivative.x) > 0.00001f){ + t = t - (currentX - time) / derivative.x; + t = glm::clamp(t, 0.0f, 1.0f); + } + } + t = 3.0f * ((1 - t) * (1 - t)) * t * p1.y + 3.0f * (1 - t) * (t * t) * p2.y + (t * t * t); + + delta = to - from; + return(from + glm::vec2(delta.x * t, delta.y * t)); } @@ -351,18 +390,6 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) dir = sphereInterpolate(from.dir, to.dir, normalTime); if(std::isnan(dir.x) || std::isnan(dir.y)) dir = from.dir; -// dir.x = hermiteInterpolate((glm::vec3 [4]){ -// glm::vec3(prev.dir.x, prev.dir.y, 0), -// glm::vec3(from.dir.x, from.dir.y, 0), -// glm::vec3(to.dir.x, to.dir.y, 0), -// glm::vec3(next.dir.x, next.dir.y, 0) -// }, normalTime).x; -// dir.y = hermiteInterpolate((glm::vec3 [4]){ -// glm::vec3(prev.dir.x, prev.dir.y, 0), -// glm::vec3(from.dir.x, from.dir.y, 0), -// glm::vec3(to.dir.x, to.dir.y, 0), -// glm::vec3(next.dir.x, next.dir.y, 0) -// }, normalTime).y; if(timeFromStart >= pathTime) { pos = to.pos; @@ -370,7 +397,6 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) _curSplitStart = curSplitTimeReset; _curPathIndex++; } - std::cout << glm::to_string(dir) << std::endl; cam->setPosition(pos); cam->setDirection(dir.x, dir.y); _win->setFrameCount(0); @@ -462,8 +488,6 @@ void Renderer::imguiPathCreation(void) if(i > 1 && ImGui::Button(("match prev speed##" + std::to_string(i)).c_str())) { float speed = glm::distance(_path[i - 2].pos, _path[i - 1].pos) / (_path[i - 1].time - _path[i - 2].time); - std::cout << "speed : " << speed << std::endl; - std::cout << "dist : " << glm::distance(_path[i - 1].pos, _path[i].pos) << std::endl; _path[i].time = _path[i - 1].time + (glm::distance(_path[i - 1].pos, _path[i].pos) / speed); } ImGui::Separator(); From ada74a584c3a2e11e01c25ba65f87aa9598413dd Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 30 Jan 2025 18:36:01 +0100 Subject: [PATCH 11/12] change camera movement smoothing when movement is similar --- includes/RT/Renderer.hpp | 4 ++-- srcs/class/Renderer.cpp | 23 ++++++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 4db1297..0134d19 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/29 23:58:48 by tomoron ### ########.fr */ +/* Updated: 2025/01/30 17:12:58 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,7 +50,7 @@ class Renderer void imguiPathCreation(void); void imguiRenderInfo(void); std::string floatToTime(float timef); - glm::vec2 sphereInterpolate(glm::vec2 from, glm::vec2 to, float time); + glm::vec2 bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time); void updateAvailableCodecs(void); void fillGoodCodecList(std::vector &lst); glm::vec3 hermiteInterpolate(glm::vec3 points[4], double alpha); diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 3493ba5..557bfcd 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/01/29 23:57:21 by tomoron ### ########.fr */ +/* Updated: 2025/01/30 18:34:15 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -320,14 +320,14 @@ glm::quat eulerToQuaternion(float pitch, float yaw) //} -glm::vec2 Renderer::sphereInterpolate(glm::vec2 from, glm::vec2 to, float time) +glm::vec2 Renderer::bezierSphereInterpolate(glm::vec4 control, glm::vec2 from, glm::vec2 to, float time) { glm::vec2 delta; glm::vec2 p1, p2; float t; - p1 = glm::vec2(0.20, 0); - p2 = glm::vec2(0.80, 1); + p1 = glm::vec2(control.x, control.y); + p2 = glm::vec2(control.z, control.w); t = time; for(int i = 0; i < 5; i++) { float currentX = 3.0f * ((1 - t) * (1 - t)) * t * p1.x + 3.0f * (1 - t) * (t * t) * p2.x + (t * t * t); @@ -369,6 +369,9 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) glm::vec3 pos; glm::vec2 dir; float normalTime; + bool smallDistPrev; + bool smallDistNext; + glm::vec4 bezierControl; from = _path[_curPathIndex]; to = _path[_curPathIndex + 1]; @@ -376,18 +379,24 @@ void Renderer::makeMovement(float timeFromStart, float curSplitTimeReset) prev = _path[_curPathIndex - 1]; else prev = from; - if((size_t)_curPathIndex + 3 == _path.size()) + if((size_t)_curPathIndex + 2 < _path.size()) next = _path[_curPathIndex + 2]; else next = to; - cam = _scene->getCamera(); pathTime = (to.time - from.time) * 60; normalTime = 1 - ((pathTime - timeFromStart) / pathTime); pos = hermiteInterpolate((glm::vec3 [4]){prev.pos, from.pos, to.pos, next.pos}, normalTime); - dir = sphereInterpolate(from.dir, to.dir, 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; + bezierControl.x = 0.2f; + bezierControl.y = !_curPathIndex || smallDistPrev ? .1f : .0f; + 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) From 06150093b9cd0fc2560c3e32fedfb7db264af8c1 Mon Sep 17 00:00:00 2001 From: tomoron Date: Thu, 30 Jan 2025 22:24:13 +0100 Subject: [PATCH 12/12] change codecs to use lossless compression, add button to guess time of path time automatically --- includes/RT/Renderer.hpp | 6 ++-- srcs/class/Renderer.cpp | 73 +++++++++++++++++++++++++++------------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/includes/RT/Renderer.hpp b/includes/RT/Renderer.hpp index 0134d19..e180dc3 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 17:12:58 by tomoron ### ########.fr */ +/* Updated: 2025/01/30 22:15:55 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,7 +42,7 @@ class Renderer int rendering(void) const; private: - void addPoint(void); + void addPoint(float time); void makeMovement(float timeFromStart, float curSplitTimeReset); void initRender(); void addImageToRender(Shader &shader); @@ -59,6 +59,7 @@ class Renderer int _sec; int _samples; int _testSamples; + bool _autoTime; int _fps; char _filenameBuffer[512]; std::vector _path; @@ -83,6 +84,7 @@ class Renderer AVFrame *_yuv_frame; SwsContext *_sws_context; AVStream *_stream; + AVDictionary *_codecOptions; }; diff --git a/srcs/class/Renderer.cpp b/srcs/class/Renderer.cpp index 557bfcd..543ddfc 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/01/30 18:34:15 by tomoron ### ########.fr */ +/* Updated: 2025/01/30 22:22:07 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,12 +19,13 @@ Renderer::Renderer(Scene *scene, Window *win) _min = 0; _sec = 0; _fps = 30; + _autoTime = 0; _samples = 1; _testSamples = 1; _curSamples = 0; _destPathIndex = 0; _frameCount = 0; - _outputFilename = "output.mp4"; + _outputFilename = "output.avi"; memcpy(_filenameBuffer, _outputFilename.c_str(), _outputFilename.length()); _filenameBuffer[_outputFilename.length()] = 0; @@ -37,10 +38,12 @@ Renderer::Renderer(Scene *scene, Window *win) void Renderer::fillGoodCodecList(std::vector &lst) { + lst.push_back(AV_CODEC_ID_FFV1); lst.push_back(AV_CODEC_ID_H264); - lst.push_back(AV_CODEC_ID_MPEG4); - lst.push_back(AV_CODEC_ID_H263); - lst.push_back(AV_CODEC_ID_MPEG2VIDEO); + lst.push_back(AV_CODEC_ID_HUFFYUV); + lst.push_back(AV_CODEC_ID_UTVIDEO); + lst.push_back(AV_CODEC_ID_PRORES); + lst.push_back(AV_CODEC_ID_V210); } void Renderer::updateAvailableCodecs(void) @@ -92,6 +95,8 @@ void Renderer::updateAvailableCodecs(void) void Renderer::initRender(void) { + + _codecOptions = 0; _destPathIndex = _path.size() - 1; _curPathIndex = 0; _frameCount = 0; @@ -112,11 +117,13 @@ void Renderer::initRender(void) _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) + 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], nullptr) < 0) + if (avcodec_open2(_codec_context, _codecList[_codecIndex], &_codecOptions) < 0) throw std::runtime_error("Failed to open codec"); _stream = avformat_new_stream(_format, _codecList[_codecIndex]); @@ -213,6 +220,7 @@ void Renderer::endRender(void) avcodec_free_context(&_codec_context); avio_close(_format->pb); avformat_free_context(_format); + av_dict_free(&_codecOptions); _format = 0; _rgb_frame = 0; @@ -220,7 +228,7 @@ void Renderer::endRender(void) _codec_context = 0; } -void Renderer::addPoint(void) +void Renderer::addPoint(float time) { t_pathPoint newPoint; Camera *cam; @@ -229,7 +237,7 @@ void Renderer::addPoint(void) cam = _scene->getCamera(); newPoint.pos = cam->getPosition(); newPoint.dir = cam->getDirection(); - newPoint.time = _min + ((float)_sec / 60); + newPoint.time = time; pos = _path.begin(); while(pos != _path.end() && pos->time <= newPoint.time) pos++; @@ -289,14 +297,14 @@ glm::vec3 Renderer::hermiteInterpolate(glm::vec3 points[4], double alpha) return(coef[0] * points[1] + coef[1] * tang[0] + coef[2] * tang[1] + coef[3] * points[2]); } -glm::quat eulerToQuaternion(float pitch, float yaw) -{ - glm::quat qPitch = glm::angleAxis(glm::radians(pitch), glm::vec3(1, 0, 0)); - glm::quat qYaw = glm::angleAxis(glm::radians(yaw), glm::vec3(0, 1, 0)); - - glm::quat result = qYaw* qPitch; - return(result); -} +//glm::quat eulerToQuaternion(float pitch, float yaw) +//{ +// glm::quat qPitch = glm::angleAxis(glm::radians(pitch), glm::vec3(1, 0, 0)); +// glm::quat qYaw = glm::angleAxis(glm::radians(yaw), glm::vec3(0, 1, 0)); +// +// glm::quat result = qYaw* qPitch; +// return(result); +//} //glm::vec2 Renderer::sphereInterpolate(glm::vec2 from, glm::vec2 to, float time) // gud but bad //{ @@ -424,6 +432,14 @@ int Renderer::rendering(void) const void Renderer::imguiPathCreation(void) { + float prevSpeed; + float time; + + if(_path.size() > 1) + prevSpeed = glm::distance(_path[_path.size() - 2].pos, _path[_path.size() - 1].pos) / (_path[_path.size() - 1].time - _path[_path.size() - 2].time); + else + prevSpeed = 0; + ImGui::SliderInt("test spi", &_testSamples, 1, 10); ImGui::SliderInt("render spi", &_samples, 1, 1000); ImGui::SliderInt("render fps", &_fps, 30, 120); @@ -449,10 +465,24 @@ void Renderer::imguiPathCreation(void) ImGui::Separator(); - ImGui::SliderInt("minutes", &_min, 0, 2); - ImGui::SliderInt("seconds", &_sec, 0, 60); + if(ImGui::SliderInt("minutes", &_min, 0, 2)) + _autoTime = 0; + if(ImGui::SliderInt("seconds", &_sec, 0, 60)) + _autoTime = 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; + _min = time; + _sec = (time - (int)time) * 60; + } + else + time = (float)_min + ((float)_sec / 60); + ImGui::Checkbox("guess time automatically", &_autoTime); if(ImGui::Button("add step")) - addPoint(); + addPoint(time); ImGui::Separator(); @@ -494,11 +524,6 @@ void Renderer::imguiPathCreation(void) _destPathIndex = i; _testMode = 1; } - if(i > 1 && ImGui::Button(("match prev speed##" + std::to_string(i)).c_str())) - { - float speed = glm::distance(_path[i - 2].pos, _path[i - 1].pos) / (_path[i - 1].time - _path[i - 2].time); - _path[i].time = _path[i - 1].time + (glm::distance(_path[i - 1].pos, _path[i].pos) / speed); - } ImGui::Separator(); } }