Beta implementation of FrameBuffer projection change for cropping.

This commit is contained in:
brunoherbelin
2020-11-22 21:58:04 +01:00
parent 61ee23455b
commit c33796e97c
8 changed files with 122 additions and 125 deletions

View File

@@ -4,6 +4,7 @@
#include "Settings.h" #include "Settings.h"
#include "Log.h" #include "Log.h"
#include <glm/gtc/matrix_transform.hpp>
#include <glad/glad.h> #include <glad/glad.h>
@@ -27,6 +28,7 @@ FrameBuffer::FrameBuffer(glm::vec3 resolution, bool useAlpha, bool multiSampling
{ {
attrib_.viewport = glm::ivec2(resolution); attrib_.viewport = glm::ivec2(resolution);
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, use_alpha_ ? 0.f : 1.f); attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, use_alpha_ ? 0.f : 1.f);
projection_ = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
} }
FrameBuffer::FrameBuffer(uint width, uint height, bool useAlpha, bool multiSampling): FrameBuffer::FrameBuffer(uint width, uint height, bool useAlpha, bool multiSampling):
@@ -35,6 +37,7 @@ FrameBuffer::FrameBuffer(uint width, uint height, bool useAlpha, bool multiSampl
{ {
attrib_.viewport = glm::ivec2(width, height); attrib_.viewport = glm::ivec2(width, height);
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, use_alpha_ ? 0.f : 1.f); attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, use_alpha_ ? 0.f : 1.f);
projection_ = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
} }
void FrameBuffer::init() void FrameBuffer::init()
@@ -243,3 +246,20 @@ void FrameBuffer::checkFramebufferStatus()
} }
} }
glm::mat4 FrameBuffer::projection() const
{
return projection_;
}
float FrameBuffer::projectionAspectRatio() const
{
return ( 1.f / projection_[0][0] ); // TODO height
}
void FrameBuffer::crop(glm::vec2 c)
{
glm::vec2 scale = glm::clamp(c, glm::vec2(0.2f, 0.2f), glm::vec2(1.f, 1.f));
projection_ = glm::ortho(-scale.x, scale.x, scale.y, -scale.y, -1.f, 1.f);
}

View File

@@ -42,6 +42,11 @@ public:
float aspectRatio() const; float aspectRatio() const;
std::string info() const; std::string info() const;
// projection and crop
glm::mat4 projection() const;
float projectionAspectRatio() const;
void crop(glm::vec2 c);
// internal pixel format // internal pixel format
inline bool use_alpha() const { return use_alpha_; } inline bool use_alpha() const { return use_alpha_; }
inline bool use_multisampling() const { return use_multi_sampling_; } inline bool use_multisampling() const { return use_multi_sampling_; }
@@ -54,6 +59,7 @@ private:
void checkFramebufferStatus(); void checkFramebufferStatus();
RenderingAttrib attrib_; RenderingAttrib attrib_;
glm::mat4 projection_;
uint textureid_, intermediate_textureid_; uint textureid_, intermediate_textureid_;
uint framebufferid_, intermediate_framebufferid_; uint framebufferid_, intermediate_framebufferid_;
bool use_alpha_, use_multi_sampling_; bool use_alpha_, use_multi_sampling_;

View File

@@ -395,8 +395,13 @@ void ImGuiVisitor::visit (Source& s)
// preview // preview
float preview_width = ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN; float preview_width = ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN;
ImVec2 imagesize ( preview_width, preview_width / s.frame()->aspectRatio()); float width = preview_width;
ImGui::Image((void*)(uintptr_t) s.frame()->texture(), imagesize); float height = width / ( s.frame()->aspectRatio() * s.frame()->projectionAspectRatio() );
if (height > 200) {
height = 200;
width = height * ( s.frame()->aspectRatio() * s.frame()->projectionAspectRatio() );
}
ImGui::Image((void*)(uintptr_t) s.frame()->texture(), ImVec2(width, height));
ImVec2 pos = ImGui::GetCursorPos(); // remember where we were... ImVec2 pos = ImGui::GetCursorPos(); // remember where we were...

View File

@@ -127,13 +127,13 @@ void MediaSource::render()
// blendingshader_->color.g = mediaplayer_->currentTimelineFading(); // blendingshader_->color.g = mediaplayer_->currentTimelineFading();
// blendingshader_->color.b = mediaplayer_->currentTimelineFading(); // blendingshader_->color.b = mediaplayer_->currentTimelineFading();
// render the media player into frame buffer // render the media player into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f); // static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
renderbuffer_->begin(); renderbuffer_->begin();
// texturesurface_->shader()->color.a = mediaplayer_->currentTimelineFading(); // texturesurface_->shader()->color.a = mediaplayer_->currentTimelineFading();
texturesurface_->shader()->color.r = mediaplayer_->currentTimelineFading(); texturesurface_->shader()->color.r = mediaplayer_->currentTimelineFading();
texturesurface_->shader()->color.g = mediaplayer_->currentTimelineFading(); texturesurface_->shader()->color.g = mediaplayer_->currentTimelineFading();
texturesurface_->shader()->color.b = mediaplayer_->currentTimelineFading(); texturesurface_->shader()->color.b = mediaplayer_->currentTimelineFading();
texturesurface_->draw(glm::identity<glm::mat4>(), projection); texturesurface_->draw(glm::identity<glm::mat4>(), renderbuffer_->projection());
renderbuffer_->end(); renderbuffer_->end();
} }
} }

View File

@@ -307,13 +307,14 @@ void Source::render()
init(); init();
else { else {
// render the view into frame buffer // render the view into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f); // static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
renderbuffer_->begin(); renderbuffer_->begin();
texturesurface_->draw(glm::identity<glm::mat4>(), projection); texturesurface_->draw(glm::identity<glm::mat4>(), renderbuffer_->projection());
renderbuffer_->end(); renderbuffer_->end();
} }
} }
void Source::attach(FrameBuffer *renderbuffer) void Source::attach(FrameBuffer *renderbuffer)
{ {
renderbuffer_ = renderbuffer; renderbuffer_ = renderbuffer;
@@ -339,37 +340,22 @@ void Source::attach(FrameBuffer *renderbuffer)
groups_[View::MIXING]->attach(surfacemix); groups_[View::MIXING]->attach(surfacemix);
groups_[View::LAYER]->attach(surfacemix); groups_[View::LAYER]->attach(surfacemix);
// // for appearance view, a dedicated surface without blending // for appearance view, a dedicated surface without blending
// Surface *surfacepreview = new FrameBufferSurface(renderbuffer_);
Surface *surfacetmp = new Surface(); Surface *surfacetmp = new Surface();
surfacetmp->setTextureIndex(Resource::getTextureTransparent()); surfacetmp->setTextureIndex(Resource::getTextureTransparent());
groups_[View::APPEARANCE]->attach(surfacetmp); groups_[View::APPEARANCE]->attach(surfacetmp);
// scale all icon nodes to match aspect ratio of the media
NodeSet::iterator node;
for (node = groups_[View::MIXING]->begin();
node != groups_[View::MIXING]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
for (node = groups_[View::GEOMETRY]->begin();
node != groups_[View::GEOMETRY]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
for (node = groups_[View::LAYER]->begin();
node != groups_[View::LAYER]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
for (node = groups_[View::APPEARANCE]->begin();
node != groups_[View::APPEARANCE]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
// Transition group node is optionnal // Transition group node is optionnal
if ( groups_[View::TRANSITION]->numChildren() > 0 ) { if ( groups_[View::TRANSITION]->numChildren() > 0 ) {
groups_[View::TRANSITION]->attach(rendersurface_); groups_[View::TRANSITION]->attach(rendersurface_);
groups_[View::TRANSITION]->attach(surfacemix); groups_[View::TRANSITION]->attach(surfacemix);
for (NodeSet::iterator node = groups_[View::TRANSITION]->begin(); }
node != groups_[View::TRANSITION]->end(); node++) {
// scale all icon nodes to match aspect ratio
for (int v = View::MIXING; v < View::INVALID; v++) {
NodeSet::iterator node;
for (node = groups_[(View::Mode) v]->begin();
node != groups_[(View::Mode) v]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio(); (*node)->scale_.x = renderbuffer_->aspectRatio();
} }
} }
@@ -381,6 +367,7 @@ void Source::attach(FrameBuffer *renderbuffer)
} }
} }
void Source::setActive (bool on) void Source::setActive (bool on)
{ {
active_ = on; active_ = on;
@@ -447,6 +434,7 @@ void Source::update(float dt)
glm::vec3 center = groups_[View::APPEARANCE]->translation_; glm::vec3 center = groups_[View::APPEARANCE]->translation_;
if (renderbuffer_) if (renderbuffer_)
center.x /= renderbuffer_->aspectRatio(); center.x /= renderbuffer_->aspectRatio();
glm::vec3 UL = glm::vec3(-1.f, 1.f, 0.f) - center; glm::vec3 UL = glm::vec3(-1.f, 1.f, 0.f) - center;
glm::vec3 BR = glm::vec3(1.f, -1.f, 0.f) - center; glm::vec3 BR = glm::vec3(1.f, -1.f, 0.f) - center;
UL /= groups_[View::APPEARANCE]->scale_; UL /= groups_[View::APPEARANCE]->scale_;
@@ -458,6 +446,12 @@ void Source::update(float dt)
uv.w = BR.y * -0.5f + 0.5f; uv.w = BR.y * -0.5f + 0.5f;
texturesurface_->setTextureUV(uv); texturesurface_->setTextureUV(uv);
// MODIFY CROP
if (renderbuffer_) {
groups_[View::MIXING]->scale_.x *= renderbuffer_->projectionAspectRatio();
groups_[View::LAYER]->scale_.x = renderbuffer_->projectionAspectRatio();
}
need_update_ = false; need_update_ = false;
} }
} }

142
View.cpp
View File

@@ -1964,58 +1964,32 @@ std::pair<Node *, glm::vec2> AppearanceView::pick(glm::vec2 P)
return pick; return pick;
} }
void AppearanceView::adjustBackground()
{
// by default consider edit source is null
float width_scale = 1.f;
surfacepreview->setTextureIndex(0);
// if its a valid index
if (edit_source_ != nullptr) {
// update rendering frame to match edit source AR
width_scale = edit_source_->frame()->aspectRatio();
width_scale *= edit_source_->frame()->projectionAspectRatio();;
surfacepreview->setTextureIndex( edit_source_->frame()->texture() );
}
// update aspect ratio
surfacepreview->scale_.x = width_scale;
backgroundpreview->scale_.x = width_scale;
backgroundpreview->setTextureUV(glm::vec4(0.5f, 0.5f, 64.f * width_scale, 64.f));
for (NodeSet::iterator node = scene.fg()->begin(); node != scene.fg()->end(); node++) {
(*node)->scale_.x = width_scale;
}
}
void AppearanceView::draw() void AppearanceView::draw()
{ {
// Source *current_source = Mixer::manager().currentSource(); // edit view needs to be updated (source changed)
// if ( current_source != edit_source_ )
// {
// // current source is not the edited source
// if (current_source != nullptr) {
// // there is a valid current source, just edit it
// edit_source_ = current_source;
// }
// // no current source, but we have a pointer to source to edit
// else {
// // if the edit source exists?
// if (Mixer::manager().session()->find(edit_source_)!=Mixer::manager().session()->end()) {
// // restore current as current
// Mixer::manager().setCurrentSource(edit_source_);
// }
// else {
// if (Mixer::manager().session()->empty())
// // nothing in the session, nothing to edit
// edit_source_ = nullptr;
// else {
// // pick the first source of the session
// edit_source_ = *Mixer::manager().session()->begin();
// Mixer::manager().setCurrentSource(edit_source_);
// }
// }
// }
// // Update display
// float scale = 1.f;
// surfacepreview->setTextureIndex(0);
// // if its a valid index
// if (edit_source_ != nullptr) {
// // update rendering frame to match edit source AR
// scale = edit_source_->frame()->aspectRatio();
// surfacepreview->setTextureIndex( edit_source_->frame()->texture() );
// }
// // update aspect ratio
// surfacepreview->scale_.x = scale;
// backgroundpreview->scale_.x = scale;
// backgroundpreview->setTextureUV(glm::vec4(0.5f, 0.5f, 64.f * scale, 64.f));
// for (NodeSet::iterator node = scene.fg()->begin(); node != scene.fg()->end(); node++) {
// (*node)->scale_.x = scale;
// }
// }
// a more complete update is requested (e.g. after switching to view)
if ( need_edit_update_ ) { if ( need_edit_update_ ) {
need_edit_update_ = false; need_edit_update_ = false;
@@ -2023,31 +1997,10 @@ void AppearanceView::draw()
// & remember source to edit // & remember source to edit
edit_source_ = EditCurrent(); edit_source_ = EditCurrent();
// by default consider edit source is null // update background and frame to match editsource
float scale = 1.f; adjustBackground();
surfacepreview->setTextureIndex(0);
// if its a valid index
if (edit_source_ != nullptr) {
// update rendering frame to match edit source AR
scale = edit_source_->frame()->aspectRatio();
surfacepreview->setTextureIndex( edit_source_->frame()->texture() );
} }
// update aspect ratio
surfacepreview->scale_.x = scale;
backgroundpreview->scale_.x = scale;
backgroundpreview->setTextureUV(glm::vec4(0.5f, 0.5f, 64.f * scale, 64.f));
for (NodeSet::iterator node = scene.fg()->begin(); node != scene.fg()->end(); node++) {
(*node)->scale_.x = scale;
}
}
Shader::force_blending_opacity = true;
View::draw();
Shader::force_blending_opacity = false;
// display popup menu // display popup menu
if (show_context_menu_) { if (show_context_menu_) {
ImGui::OpenPopup( "AppearanceContextMenu" ); ImGui::OpenPopup( "AppearanceContextMenu" );
@@ -2055,21 +2008,38 @@ void AppearanceView::draw()
} }
showContextMenu(mode_,"AppearanceContextMenu"); showContextMenu(mode_,"AppearanceContextMenu");
// // display interface duration // display interface duration
// glm::vec2 P = Rendering::manager().project(glm::vec3(1.1f, 1.14f, 0.f), scene.root()->transform_, false); if ( edit_source_ != nullptr ) {
// ImGui::SetNextWindowPos(ImVec2(P.x, P.y), ImGuiCond_Always);
// if (ImGui::Begin("##WIDTH", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground glm::vec2 P = Rendering::manager().project(glm::vec3(1.1f, 1.14f, 0.f), scene.root()->transform_, false);
// | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings ImGui::SetNextWindowPos(ImVec2(P.x, P.y), ImGuiCond_Always);
// | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav)) if (ImGui::Begin("##WIDTH", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground
// { | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings
// ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE); | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav))
// ImGui::SetNextItemWidth(100.f); {
// float width = 1.f; ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE);
// ImGui::DragFloat("##apppearancewidth", &width, 0.1f, 0.3f, 2.f, "%.1f "); ImGui::SetNextItemWidth(100.f);
float crop_width = edit_source_->frame()->projectionAspectRatio();
if ( ImGui::DragFloat("##apppearancewidth", &crop_width, 0.05f, 0.2f, 1.f, "%.1f ") )
{
// crop horizontally
edit_source_->frame()->crop(glm::vec2(crop_width, 1.f));
// TODO scale GEOMETRY and RENDER groups
edit_source_->touch();
// update background and frame
adjustBackground();
}
ImGui::PopFont();
ImGui::End();
}
}
Shader::force_blending_opacity = true;
View::draw();
Shader::force_blending_opacity = false;
// ImGui::PopFont();
// ImGui::End();
// }
} }
View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)

2
View.h
View File

@@ -245,6 +245,8 @@ private:
bool need_edit_update_; bool need_edit_update_;
Source *EditCurrent(); Source *EditCurrent();
void adjustBackground();
Surface *backgroundpreview; Surface *backgroundpreview;
Surface *surfacepreview; Surface *surfacepreview;