From e2c82af4d6f0fddc583cb6e5097b3f4e58518948 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Fri, 23 Dec 2022 20:23:39 +0100 Subject: [PATCH] Implementation of custom session resolution Moved presets of resolution to RenderView (framebuffer class is lower level). Changed logic of UI selection of session resolution change. --- src/FrameBuffer.cpp | 48 +----------- src/FrameBuffer.h | 7 -- src/RenderView.cpp | 64 +++++++++++++++- src/RenderView.h | 20 ++++- src/Session.cpp | 2 +- src/Settings.cpp | 4 + src/Settings.h | 3 + src/UserInterfaceManager.cpp | 140 ++++++++++++++++++++++------------- 8 files changed, 178 insertions(+), 110 deletions(-) diff --git a/src/FrameBuffer.cpp b/src/FrameBuffer.cpp index deb5113..1304aba 100644 --- a/src/FrameBuffer.cpp +++ b/src/FrameBuffer.cpp @@ -20,7 +20,6 @@ #include #include "FrameBuffer.h" -#include "ImageShader.h" #include "Resource.h" #include "Settings.h" #include "Log.h" @@ -35,45 +34,6 @@ #define FRAMEBUFFER_DEBUG #endif -const char* FrameBuffer::aspect_ratio_name[5] = { "4:3", "3:2", "16:10", "16:9", "21:9" }; -glm::vec2 FrameBuffer::aspect_ratio_size[5] = { glm::vec2(4.f,3.f), glm::vec2(3.f,2.f), glm::vec2(16.f,10.f), glm::vec2(16.f,9.f) , glm::vec2(21.f,9.f) }; -const char* FrameBuffer::resolution_name[5] = { "720", "1080", "1200", "1440", "2160" }; -float FrameBuffer::resolution_height[5] = { 720.f, 1080.f, 1200.f, 1440.f, 2160.f }; - - -glm::vec3 FrameBuffer::getResolutionFromParameters(int ar, int h) -{ - float width = aspect_ratio_size[ar].x * resolution_height[h] / aspect_ratio_size[ar].y; - width -= (int)width % 2; - glm::vec3 res = glm::vec3( width, resolution_height[h] , 0.f); - - return res; -} - -glm::ivec2 FrameBuffer::getParametersFromResolution(glm::vec3 res) -{ - glm::ivec2 p = glm::ivec2(-1); - - // get aspect ratio parameter - static int num_ar = ((int)(sizeof(FrameBuffer::aspect_ratio_size) / sizeof(*FrameBuffer::aspect_ratio_size))); - float myratio = res.x / res.y; - for(int ar = 0; ar < num_ar; ar++) { - if ( myratio - (FrameBuffer::aspect_ratio_size[ar].x / FrameBuffer::aspect_ratio_size[ar].y ) < EPSILON){ - p.x = ar; - break; - } - } - // get height parameter - static int num_height = ((int)(sizeof(FrameBuffer::resolution_height) / sizeof(*FrameBuffer::resolution_height))); - for(int h = 0; h < num_height; h++) { - if ( res.y - FrameBuffer::resolution_height[h] < 1){ - p.y = h; - break; - } - } - - return p; -} FrameBuffer::FrameBuffer(glm::vec3 resolution, FrameBufferFlags flags): flags_(flags), textureid_(0), multisampling_textureid_(0), framebufferid_(0), multisampling_framebufferid_(0), mem_usage_(0) @@ -220,12 +180,8 @@ float FrameBuffer::aspectRatio() const std::string FrameBuffer::info() const { - glm::ivec2 p = FrameBuffer::getParametersFromResolution(resolution()); std::ostringstream info; - - info << attrib_.viewport.x << "x" << attrib_.viewport.y; - if (p.x > -1) - info << "px, " << FrameBuffer::aspect_ratio_name[p.x]; + info << attrib_.viewport.x << "x" << attrib_.viewport.y << "px"; return info.str(); } @@ -399,7 +355,7 @@ void FrameBuffer::checkFramebufferStatus() glm::ivec2 RAM = Rendering::getGPUMemoryInformation(); // bad case: not enough RAM, we should warn the user - if ( RAM.x < mem_usage_ * 3 ) { + if ( uint(RAM.x) < mem_usage_ * 3 ) { Log::Warning("Critical allocation of frame buffer: only %d kB RAM remaining in graphics card.", RAM.x ); if (RAM.y < INT_MAX) Log::Warning("Only %.1f %% of %d kB available.", 100.f*float(RAM.x)/float(RAM.y), RAM.y); diff --git a/src/FrameBuffer.h b/src/FrameBuffer.h index 6596d8c..7a2d085 100644 --- a/src/FrameBuffer.h +++ b/src/FrameBuffer.h @@ -38,13 +38,6 @@ public: class FrameBuffer { public: - // size descriptions - static const char* aspect_ratio_name[5]; - static glm::vec2 aspect_ratio_size[5]; - static const char* resolution_name[5]; - static float resolution_height[5]; - static glm::vec3 getResolutionFromParameters(int ar, int h); - static glm::ivec2 getParametersFromResolution(glm::vec3 res); enum FrameBufferCreationFlags_ { diff --git a/src/RenderView.cpp b/src/RenderView.cpp index 6bf1c67..ab42ded 100644 --- a/src/RenderView.cpp +++ b/src/RenderView.cpp @@ -28,10 +28,62 @@ #include "defines.h" #include "Settings.h" -#include "Decorations.h" +#include "Primitives.h" #include "RenderView.h" +const char* RenderView::ratio_preset_name[6] = { "4:3", "3:2", "16:10", "16:9", "21:9", "Custom" }; +glm::vec2 RenderView::ratio_preset_value[6] = { glm::vec2(4.f,3.f), glm::vec2(3.f,2.f), glm::vec2(16.f,10.f), glm::vec2(16.f,9.f), glm::vec2(21.f,9.f) , glm::vec2(1.f,2.f) }; +const char* RenderView::height_preset_name[5] = { "720", "1080", "1200", "1440", "2160" }; +float RenderView::height_preset_value[5] = { 720.f, 1080.f, 1200.f, 1440.f, 2160.f }; + + +glm::vec3 RenderView::resolutionFromPreset(int ar, int h) +{ + float width = ratio_preset_value[ar].x * height_preset_value[h] / ratio_preset_value[ar].y; + width -= (int)width % 2; + return glm::vec3( width, height_preset_value[h] , 0.f); +} + +glm::ivec2 RenderView::presetFromResolution(glm::vec3 resolution) +{ + static int num_height = ((int)(sizeof(RenderView::height_preset_value) / sizeof(*RenderView::height_preset_value))); + static int num_ar = ((int)(sizeof(RenderView::ratio_preset_value) / sizeof(*RenderView::ratio_preset_value))); + + glm::ivec2 ret = glm::ivec2(AspectRatio_Custom, -1); + + // get height parameter + for(int h = 0; h < num_height; h++) { + if ( ABS_DIFF(resolution.y, RenderView::height_preset_value[h]) < 1.f){ + ret.y = h; + break; + } + } + // found a preset height: find if it is a preset ratio + if (ret.y > -1) { + // get aspect ratio parameter + float myratio = resolution.x / resolution.y; + for(int ar = 0; ar < num_ar; ar++) { + if ( ABS_DIFF( myratio, RenderView::ratio_preset_value[ar].x / RenderView::ratio_preset_value[ar].y ) < EPSILON){ + ret.x = ar; + break; + } + } + } + // not a preset height (NB : ratio is custom) + else { + // find closest height preset + float diff = MAXFLOAT; + for(int h = 0; h < num_height; h++) { + if ( ABS_DIFF(resolution.y, RenderView::height_preset_value[h]) < diff){ + diff = ABS_DIFF(resolution.y, RenderView::height_preset_value[h]); + ret.y = h; + } + } + } + + return ret; +} RenderView::RenderView() : View(RENDERING), frame_buffer_(nullptr), fading_overlay_(nullptr), frame_thumbnail_(nullptr) { @@ -65,9 +117,13 @@ float RenderView::fading() const void RenderView::setResolution(glm::vec3 resolution, bool useAlpha) { - // use default resolution if invalid resolution is given (default behavior) - if (resolution.x < 2.f || resolution.y < 2.f) - resolution = FrameBuffer::getResolutionFromParameters(Settings::application.render.ratio, Settings::application.render.res); + // read settings if invalid resolution is given + if (resolution.x < 2.f || resolution.y < 2.f) { + if (Settings::application.render.ratio < AspectRatio_Custom) + resolution = resolutionFromPreset(Settings::application.render.ratio, Settings::application.render.res); + else + resolution = glm::vec3(Settings::application.render.custom_width, Settings::application.render.custom_height, 0.f); + } // do we need to change resolution ? if (frame_buffer_ && frame_buffer_->resolution() != resolution) { diff --git a/src/RenderView.h b/src/RenderView.h index 2f4725c..146b621 100644 --- a/src/RenderView.h +++ b/src/RenderView.h @@ -25,13 +25,29 @@ public: void draw () override; bool canSelect(Source *) override { return false; } - void setResolution (glm::vec3 resolution = glm::vec3(0.f), bool useAlpha = false); + void setResolution (glm::vec3 resolution, bool useAlpha = false); glm::vec3 resolution() const { return frame_buffer_->resolution(); } - // current frame inline FrameBuffer *frame () const { return frame_buffer_; } + // size descriptions + enum AspectRatio { + AspectRatio_4_3 = 0, + AspectRatio_3_2, + AspectRatio_16_10, + AspectRatio_16_9, + AspectRatio_21_9, + AspectRatio_Custom + }; + static const char* ratio_preset_name[6]; + static glm::vec2 ratio_preset_value[6]; + static const char* height_preset_name[5]; + static float height_preset_value[5]; + + static glm::vec3 resolutionFromPreset(int ar, int h); + static glm::ivec2 presetFromResolution(glm::vec3 res); + protected: void setFading(float f = 0.f); diff --git a/src/Session.cpp b/src/Session.cpp index 952e65d..ae48607 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -380,7 +380,7 @@ void Session::resetThumbnail() void Session::setResolution(glm::vec3 resolution, bool useAlpha) { - // setup the render view: if not specified the default config resulution will be used + // setup the render view: if not specified the default config resolution will be used render_.setResolution( resolution, useAlpha ); // store the actual resolution set in the render view config_[View::RENDERING]->scale_ = render_.resolution(); diff --git a/src/Settings.cpp b/src/Settings.cpp index 6fdfd3d..c8ca9f7 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -160,6 +160,8 @@ void Settings::Save(uint64_t runtime) RenderNode->SetAttribute("gpu_decoding", application.render.gpu_decoding); RenderNode->SetAttribute("ratio", application.render.ratio); RenderNode->SetAttribute("res", application.render.res); + RenderNode->SetAttribute("custom_width", application.render.custom_width); + RenderNode->SetAttribute("custom_height", application.render.custom_height); pRoot->InsertEndChild(RenderNode); // Record @@ -439,6 +441,8 @@ void Settings::Load() rendernode->QueryBoolAttribute("gpu_decoding", &application.render.gpu_decoding); rendernode->QueryIntAttribute("ratio", &application.render.ratio); rendernode->QueryIntAttribute("res", &application.render.res); + rendernode->QueryIntAttribute("custom_width", &application.render.custom_width); + rendernode->QueryIntAttribute("custom_height", &application.render.custom_height); } // Record diff --git a/src/Settings.h b/src/Settings.h index 4fa6ea0..00408c1 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -159,6 +159,7 @@ struct RenderConfig int multisampling; int ratio; int res; + int custom_width, custom_height; float fading; bool gpu_decoding; @@ -169,6 +170,8 @@ struct RenderConfig multisampling = 2; ratio = 3; res = 1; + custom_width = 1200; + custom_height = 600; fading = 0.0; gpu_decoding = true; } diff --git a/src/UserInterfaceManager.cpp b/src/UserInterfaceManager.cpp index 4f23522..1fee076 100644 --- a/src/UserInterfaceManager.cpp +++ b/src/UserInterfaceManager.cpp @@ -979,9 +979,19 @@ void UserInterface::showMenuFile() navigator.hidePannel(); } ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.54f); - ImGui::Combo("Ratio", &Settings::application.render.ratio, FrameBuffer::aspect_ratio_name, IM_ARRAYSIZE(FrameBuffer::aspect_ratio_name) ); - ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.54f); - ImGui::Combo("Height", &Settings::application.render.res, FrameBuffer::resolution_name, IM_ARRAYSIZE(FrameBuffer::resolution_name) ); + ImGui::Combo("Ratio", &Settings::application.render.ratio, RenderView::ratio_preset_name, IM_ARRAYSIZE(RenderView::ratio_preset_name) ); + if (Settings::application.render.ratio < RenderView::AspectRatio_Custom) { + // Presets height + ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.54f); + ImGui::Combo("Height", &Settings::application.render.res, RenderView::height_preset_name, IM_ARRAYSIZE(RenderView::height_preset_name) ); + } + else { + // Custom width and height + ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.54f); + ImGui::InputInt("Width", &Settings::application.render.custom_width, 100, 500); + ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.54f); + ImGui::InputInt("Height", &Settings::application.render.custom_height, 100, 500); + } // FILE OPEN AND SAVE ImGui::Separator(); @@ -7424,19 +7434,29 @@ void Navigator::RenderMainPannelVimix() // change resolution (height only) // get parameters to edit resolution - glm::ivec2 p = FrameBuffer::getParametersFromResolution(output->resolution()); - if (p.y > -1) { + glm::ivec2 preset = RenderView::presetFromResolution(output->resolution()); + glm::ivec2 custom = glm::ivec2(output->resolution()); + if (preset.x > -1) { // cannot change resolution when recording if ( UserInterface::manager().outputcontrol.isRecording() ) { // show static info (same size than combo) static char dummy_str[512]; ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.14f, 0.14f, 0.14f, 0.9f)); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - sprintf(dummy_str, "%s", FrameBuffer::aspect_ratio_name[p.x]); + sprintf(dummy_str, "%s", RenderView::ratio_preset_name[preset.x]); ImGui::InputText("Ratio", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly); - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - sprintf(dummy_str, "%s", FrameBuffer::resolution_name[p.y]); - ImGui::InputText("Height", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly); + if (preset.x < RenderView::AspectRatio_Custom) { + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + sprintf(dummy_str, "%s", RenderView::height_preset_name[preset.y]); + ImGui::InputText("Height", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly); + } else { + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + sprintf(dummy_str, "%d", custom.x); + ImGui::InputText("Width", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly); + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + sprintf(dummy_str, "%d", custom.y); + ImGui::InputText("Height", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly); + } ImGui::PopStyleColor(1); } // offer to change filename, ratio and resolution @@ -7447,18 +7467,38 @@ void Navigator::RenderMainPannelVimix() UserInterface::manager().selectSaveFilename(); } ImGui::SetCursorScreenPos(draw_pos); - // combo boxes to select Rario and Height + // combo boxes to select aspect rario ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - if (ImGui::Combo("Ratio", &p.x, FrameBuffer::aspect_ratio_name, IM_ARRAYSIZE(FrameBuffer::aspect_ratio_name) ) ) + if (ImGui::Combo("Ratio", &preset.x, RenderView::ratio_preset_name, IM_ARRAYSIZE(RenderView::ratio_preset_name) ) ) { - glm::vec3 res = FrameBuffer::getResolutionFromParameters(p.x, p.y); + // change to custom aspect ratio: propose 1:1 + glm::vec3 res = glm::vec3(custom.y, custom.y, 0.f); + // else, change to preset aspect ratio + if (preset.x < RenderView::AspectRatio_Custom) + res = RenderView::resolutionFromPreset(preset.x, preset.y); + // change resolution Mixer::manager().setResolution(res); } - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - if (ImGui::Combo("Height", &p.y, FrameBuffer::resolution_name, IM_ARRAYSIZE(FrameBuffer::resolution_name) ) ) - { - glm::vec3 res = FrameBuffer::getResolutionFromParameters(p.x, p.y); - Mixer::manager().setResolution(res); + // - preset aspect ratio : propose preset height + if (preset.x < RenderView::AspectRatio_Custom) { + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + if (ImGui::Combo("Height", &preset.y, RenderView::height_preset_name, IM_ARRAYSIZE(RenderView::height_preset_name) ) ) + { + glm::vec3 res = RenderView::resolutionFromPreset(preset.x, preset.y); + Mixer::manager().setResolution(res); + } + } + // - custom aspect ratio : input width and height + else { + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + ImGui::InputInt("Width", &custom.x, 100, 500); + if (ImGui::IsItemDeactivatedAfterEdit()) + Mixer::manager().setResolution( glm::vec3(custom, 0.f)); + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + ImGui::InputInt("Height", &custom.y, 100, 500); + if (ImGui::IsItemDeactivatedAfterEdit()) + Mixer::manager().setResolution( glm::vec3(custom, 0.f)); + } } } @@ -8347,47 +8387,47 @@ void ShowSandbox(bool* p_open) std::string tra = BaseToolkit::transliterate(std::string(str0)); ImGui::Text("Transliteration: '%s'", tra.c_str()); - ImGui::Separator(); +// ImGui::Separator(); - static bool selected[25] = { true, false, false, false, false, - true, false, false, false, false, - true, false, false, true, false, - false, false, false, true, false, - false, false, false, true, false }; +// static bool selected[25] = { true, false, false, false, false, +// true, false, false, false, false, +// true, false, false, true, false, +// false, false, false, true, false, +// false, false, false, true, false }; - ImVec2 keyIconSize = ImVec2(60,60); +// ImVec2 keyIconSize = ImVec2(60,60); - ImGuiContext& g = *GImGui; - ImVec2 itemsize = keyIconSize + g.Style.ItemSpacing; - ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE); - ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f, 0.50f)); - ImVec2 frame_top = ImGui::GetCursorScreenPos(); +// ImGuiContext& g = *GImGui; +// ImVec2 itemsize = keyIconSize + g.Style.ItemSpacing; +// ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE); +// ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f, 0.50f)); +// ImVec2 frame_top = ImGui::GetCursorScreenPos(); - static int key = 0; - static ImVec2 current(-1.f, -1.f); +//// static int key = 0; +// static ImVec2 current(-1.f, -1.f); - for (int i = 0; i < 25; ++i) { - ImGui::PushID(i); - char letter[2]; - sprintf(letter, "%c", 'A' + i); - if (ImGui::Selectable(letter, selected[i], 0, keyIconSize)) - { - current = ImVec2(i % 5, i / 5); - key = GLFW_KEY_A + i; - } - ImGui::PopID(); - if ((i % 5) < 4) ImGui::SameLine(); - } - ImGui::PopStyleVar(); - ImGui::PopFont(); +// for (int i = 0; i < 25; ++i) { +// ImGui::PushID(i); +// char letter[2]; +// sprintf(letter, "%c", 'A' + i); +// if (ImGui::Selectable(letter, selected[i], 0, keyIconSize)) +// { +// current = ImVec2(i % 5, i / 5); +//// key = GLFW_KEY_A + i; +// } +// ImGui::PopID(); +// if ((i % 5) < 4) ImGui::SameLine(); +// } +// ImGui::PopStyleVar(); +// ImGui::PopFont(); - if (current.x > -1 && current.y > -1) { - ImVec2 pos = frame_top + itemsize * current; - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - draw_list->AddRect(pos, pos + keyIconSize, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f); +// if (current.x > -1 && current.y > -1) { +// ImVec2 pos = frame_top + itemsize * current; +// ImDrawList* draw_list = ImGui::GetWindowDrawList(); +// draw_list->AddRect(pos, pos + keyIconSize, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f); - } +// }