mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-12 18:59:59 +01:00
Beta implementation of FrameBuffer projection change for cropping.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "Settings.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
@@ -27,6 +28,7 @@ FrameBuffer::FrameBuffer(glm::vec3 resolution, bool useAlpha, bool multiSampling
|
||||
{
|
||||
attrib_.viewport = glm::ivec2(resolution);
|
||||
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):
|
||||
@@ -35,6 +37,7 @@ FrameBuffer::FrameBuffer(uint width, uint height, bool useAlpha, bool multiSampl
|
||||
{
|
||||
attrib_.viewport = glm::ivec2(width, height);
|
||||
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()
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,11 @@ public:
|
||||
float aspectRatio() const;
|
||||
std::string info() const;
|
||||
|
||||
// projection and crop
|
||||
glm::mat4 projection() const;
|
||||
float projectionAspectRatio() const;
|
||||
void crop(glm::vec2 c);
|
||||
|
||||
// internal pixel format
|
||||
inline bool use_alpha() const { return use_alpha_; }
|
||||
inline bool use_multisampling() const { return use_multi_sampling_; }
|
||||
@@ -54,6 +59,7 @@ private:
|
||||
void checkFramebufferStatus();
|
||||
|
||||
RenderingAttrib attrib_;
|
||||
glm::mat4 projection_;
|
||||
uint textureid_, intermediate_textureid_;
|
||||
uint framebufferid_, intermediate_framebufferid_;
|
||||
bool use_alpha_, use_multi_sampling_;
|
||||
|
||||
@@ -395,8 +395,13 @@ void ImGuiVisitor::visit (Source& s)
|
||||
|
||||
// preview
|
||||
float preview_width = ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN;
|
||||
ImVec2 imagesize ( preview_width, preview_width / s.frame()->aspectRatio());
|
||||
ImGui::Image((void*)(uintptr_t) s.frame()->texture(), imagesize);
|
||||
float width = preview_width;
|
||||
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...
|
||||
|
||||
|
||||
@@ -127,13 +127,13 @@ void MediaSource::render()
|
||||
// blendingshader_->color.g = mediaplayer_->currentTimelineFading();
|
||||
// blendingshader_->color.b = mediaplayer_->currentTimelineFading();
|
||||
// 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();
|
||||
// texturesurface_->shader()->color.a = mediaplayer_->currentTimelineFading();
|
||||
texturesurface_->shader()->color.r = mediaplayer_->currentTimelineFading();
|
||||
texturesurface_->shader()->color.g = 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();
|
||||
}
|
||||
}
|
||||
|
||||
44
Source.cpp
44
Source.cpp
@@ -307,13 +307,14 @@ void Source::render()
|
||||
init();
|
||||
else {
|
||||
// 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();
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), renderbuffer_->projection());
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Source::attach(FrameBuffer *renderbuffer)
|
||||
{
|
||||
renderbuffer_ = renderbuffer;
|
||||
@@ -339,37 +340,22 @@ void Source::attach(FrameBuffer *renderbuffer)
|
||||
groups_[View::MIXING]->attach(surfacemix);
|
||||
groups_[View::LAYER]->attach(surfacemix);
|
||||
|
||||
// // for appearance view, a dedicated surface without blending
|
||||
// Surface *surfacepreview = new FrameBufferSurface(renderbuffer_);
|
||||
// for appearance view, a dedicated surface without blending
|
||||
Surface *surfacetmp = new Surface();
|
||||
surfacetmp->setTextureIndex(Resource::getTextureTransparent());
|
||||
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
|
||||
if ( groups_[View::TRANSITION]->numChildren() > 0 ) {
|
||||
groups_[View::TRANSITION]->attach(rendersurface_);
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -381,6 +367,7 @@ void Source::attach(FrameBuffer *renderbuffer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Source::setActive (bool on)
|
||||
{
|
||||
active_ = on;
|
||||
@@ -447,6 +434,7 @@ void Source::update(float dt)
|
||||
glm::vec3 center = groups_[View::APPEARANCE]->translation_;
|
||||
if (renderbuffer_)
|
||||
center.x /= renderbuffer_->aspectRatio();
|
||||
|
||||
glm::vec3 UL = 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_;
|
||||
@@ -458,6 +446,12 @@ void Source::update(float dt)
|
||||
uv.w = BR.y * -0.5f + 0.5f;
|
||||
texturesurface_->setTextureUV(uv);
|
||||
|
||||
// MODIFY CROP
|
||||
if (renderbuffer_) {
|
||||
groups_[View::MIXING]->scale_.x *= renderbuffer_->projectionAspectRatio();
|
||||
groups_[View::LAYER]->scale_.x = renderbuffer_->projectionAspectRatio();
|
||||
}
|
||||
|
||||
need_update_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
20
Source.h
20
Source.h
@@ -35,11 +35,11 @@ class Source
|
||||
public:
|
||||
// create a source and add it to the list
|
||||
// only subclasses of sources can actually be instanciated
|
||||
Source();
|
||||
virtual ~Source();
|
||||
Source ();
|
||||
virtual ~Source ();
|
||||
|
||||
// Get unique id
|
||||
inline uint64_t id() const { return id_; }
|
||||
inline uint64_t id () const { return id_; }
|
||||
|
||||
// manipulate name of source
|
||||
void setName (const std::string &name);
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
bool contains (Node *node) const;
|
||||
|
||||
// a Source has a shader used to render in fbo
|
||||
inline Shader *renderingShader() const { return renderingshader_; }
|
||||
inline Shader *renderingShader () const { return renderingshader_; }
|
||||
|
||||
// the rendering shader always have an image processing shader
|
||||
inline ImageProcessingShader *processingShader () const { return processingshader_; }
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
// the image processing shader can be enabled or disabled
|
||||
// (NB: when disabled, a simple ImageShader is applied)
|
||||
void setImageProcessingEnabled (bool on);
|
||||
bool imageProcessingEnabled();
|
||||
bool imageProcessingEnabled ();
|
||||
|
||||
// a Source has a shader to control mixing effects
|
||||
inline ImageShader *blendingShader () const { return blendingshader_; }
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
inline void touch () { need_update_ = true; }
|
||||
|
||||
// informs if its ready (i.e. initialized)
|
||||
inline bool ready() const { return initialized_; }
|
||||
inline bool ready () const { return initialized_; }
|
||||
|
||||
// a Source shall be updated before displayed (Mixing, Geometry and Layer)
|
||||
virtual void update (float dt);
|
||||
@@ -97,13 +97,13 @@ public:
|
||||
inline bool active () { return active_; }
|
||||
|
||||
// a Source shall informs if the source failed (i.e. shall be deleted)
|
||||
virtual bool failed() const = 0;
|
||||
virtual bool failed () const = 0;
|
||||
|
||||
// a Source shall define a way to get a texture
|
||||
virtual uint texture() const = 0;
|
||||
virtual uint texture () const = 0;
|
||||
|
||||
// a Source shall define how to render into the frame buffer
|
||||
virtual void render();
|
||||
virtual void render ();
|
||||
|
||||
// accept all kind of visitors
|
||||
virtual void accept (Visitor& v);
|
||||
@@ -136,7 +136,7 @@ public:
|
||||
uint64_t _id;
|
||||
};
|
||||
|
||||
virtual glm::ivec2 icon() const { return glm::ivec2(12, 11); }
|
||||
virtual glm::ivec2 icon () const { return glm::ivec2(12, 11); }
|
||||
|
||||
protected:
|
||||
// name
|
||||
|
||||
142
View.cpp
142
View.cpp
@@ -1964,58 +1964,32 @@ std::pair<Node *, glm::vec2> AppearanceView::pick(glm::vec2 P)
|
||||
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()
|
||||
{
|
||||
// Source *current_source = Mixer::manager().currentSource();
|
||||
// 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)
|
||||
// edit view needs to be updated (source changed)
|
||||
if ( need_edit_update_ ) {
|
||||
need_edit_update_ = false;
|
||||
|
||||
@@ -2023,31 +1997,10 @@ void AppearanceView::draw()
|
||||
// & remember source to edit
|
||||
edit_source_ = EditCurrent();
|
||||
|
||||
// by default consider edit source is null
|
||||
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;
|
||||
}
|
||||
|
||||
// update background and frame to match editsource
|
||||
adjustBackground();
|
||||
}
|
||||
|
||||
Shader::force_blending_opacity = true;
|
||||
View::draw();
|
||||
Shader::force_blending_opacity = false;
|
||||
|
||||
// display popup menu
|
||||
if (show_context_menu_) {
|
||||
ImGui::OpenPopup( "AppearanceContextMenu" );
|
||||
@@ -2055,21 +2008,38 @@ void AppearanceView::draw()
|
||||
}
|
||||
showContextMenu(mode_,"AppearanceContextMenu");
|
||||
|
||||
// // display interface duration
|
||||
// glm::vec2 P = Rendering::manager().project(glm::vec3(1.1f, 1.14f, 0.f), scene.root()->transform_, false);
|
||||
// ImGui::SetNextWindowPos(ImVec2(P.x, P.y), ImGuiCond_Always);
|
||||
// if (ImGui::Begin("##WIDTH", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground
|
||||
// | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings
|
||||
// | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav))
|
||||
// {
|
||||
// ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE);
|
||||
// ImGui::SetNextItemWidth(100.f);
|
||||
// float width = 1.f;
|
||||
// ImGui::DragFloat("##apppearancewidth", &width, 0.1f, 0.3f, 2.f, "%.1f ");
|
||||
// display interface duration
|
||||
if ( edit_source_ != nullptr ) {
|
||||
|
||||
glm::vec2 P = Rendering::manager().project(glm::vec3(1.1f, 1.14f, 0.f), scene.root()->transform_, false);
|
||||
ImGui::SetNextWindowPos(ImVec2(P.x, P.y), ImGuiCond_Always);
|
||||
if (ImGui::Begin("##WIDTH", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground
|
||||
| ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings
|
||||
| ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav))
|
||||
{
|
||||
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE);
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user