From 25187d60ce4b23fdd6e5197a28f11013a4c573d8 Mon Sep 17 00:00:00 2001 From: tomoron Date: Sat, 25 Jan 2025 03:27:55 +0100 Subject: [PATCH] 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()