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.
This commit is contained in:
Bruno Herbelin
2022-12-23 20:23:39 +01:00
parent 8712923bec
commit e2c82af4d6
8 changed files with 178 additions and 110 deletions

View File

@@ -20,7 +20,6 @@
#include <sstream>
#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);

View File

@@ -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_
{

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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();

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);
}
// }