reduced code bonding between the V4D class and the context classes

pull/3471/head
kallaballa 2 years ago
parent 5c3b666856
commit 479c3d645c
  1. 4
      modules/v4d/src/detail/clvacontext.cpp
  2. 2
      modules/v4d/src/detail/clvacontext.hpp
  3. 111
      modules/v4d/src/detail/framebuffercontext.cpp
  4. 5
      modules/v4d/src/detail/framebuffercontext.hpp
  5. 4
      modules/v4d/src/detail/glcontext.cpp
  6. 6
      modules/v4d/src/detail/glcontext.hpp
  7. 4
      modules/v4d/src/detail/nanoguicontext.cpp
  8. 2
      modules/v4d/src/detail/nanoguicontext.hpp
  9. 4
      modules/v4d/src/detail/nanovgcontext.cpp
  10. 3
      modules/v4d/src/detail/nanovgcontext.hpp
  11. 117
      modules/v4d/src/v4d.cpp

@ -10,8 +10,8 @@ namespace cv {
namespace v4d { namespace v4d {
namespace detail { namespace detail {
CLVAContext::CLVAContext(V4D& v4d, FrameBufferContext& mainFbContext) : CLVAContext::CLVAContext(FrameBufferContext& mainFbContext) :
mainFbContext_(mainFbContext), clvaFbContext_(v4d, "CLVA", mainFbContext) { mainFbContext_(mainFbContext), clvaFbContext_("CLVA", mainFbContext) {
} }
bool CLVAContext::capture(std::function<void(cv::UMat&)> fn, cv::UMat& output) { bool CLVAContext::capture(std::function<void(cv::UMat&)> fn, cv::UMat& output) {

@ -32,7 +32,7 @@ public:
* Create the CLVAContext * Create the CLVAContext
* @param fbContext The corresponding framebuffer context * @param fbContext The corresponding framebuffer context
*/ */
CLVAContext(V4D& v4d, FrameBufferContext& fbContext); CLVAContext(FrameBufferContext& fbContext);
/*! /*!
* Called to capture from a function object. * Called to capture from a function object.
* The functor fn is passed a UMat which it writes to which in turn is captured to the framebuffer. * The functor fn is passed a UMat which it writes to which in turn is captured to the framebuffer.

@ -21,19 +21,14 @@
namespace cv { namespace cv {
namespace v4d { namespace v4d {
namespace detail { namespace detail {
static bool contains_absolute(nanogui::Widget* w, const nanogui::Vector2i& p) {
nanogui::Vector2i d = p - w->absolute_position();
return d.x() >= 0 && d.y() >= 0 && d.x() < w->size().x() && d.y() < w->size().y();
}
int frameBufferContextCnt = 0; int frameBufferContextCnt = 0;
FrameBufferContext::FrameBufferContext(V4D& v4d, const string& title, const FrameBufferContext& other) : FrameBufferContext(v4d, other.frameBufferSize_, true, title, other.major_, other.minor_, other.compat_, other.samples_, other.debug_, other.glfwWindow_, &other) { FrameBufferContext::FrameBufferContext(const string& title, const FrameBufferContext& other) : FrameBufferContext(other.frameBufferSize_, true, title, other.major_, other.minor_, other.compat_, other.samples_, other.debug_, other.glfwWindow_, &other) {
} }
FrameBufferContext::FrameBufferContext(V4D& v4d, const cv::Size& framebufferSize, bool offscreen, FrameBufferContext::FrameBufferContext(const cv::Size& framebufferSize, bool offscreen,
const string& title, int major, int minor, bool compat, int samples, bool debug, GLFWwindow* sharedWindow, const FrameBufferContext* parent) : const string& title, int major, int minor, bool compat, int samples, bool debug, GLFWwindow* sharedWindow, const FrameBufferContext* parent) :
v4d_(&v4d), offscreen_(offscreen), title_(title), major_(major), minor_( offscreen_(offscreen), title_(title), major_(major), minor_(
minor), compat_(compat), samples_(samples), debug_(debug), viewport_(0, 0, framebufferSize.width, framebufferSize.height), frameBufferSize_(framebufferSize), isShared_(false), sharedWindow_(sharedWindow), parent_(parent), framebuffer_(framebufferSize, CV_8UC4) { minor), compat_(compat), samples_(samples), debug_(debug), viewport_(0, 0, framebufferSize.width, framebufferSize.height), frameBufferSize_(framebufferSize), isShared_(false), sharedWindow_(sharedWindow), parent_(parent), framebuffer_(framebufferSize, CV_8UC4) {
run_sync_on_main<1>([this](){ init(); }); run_sync_on_main<1>([this](){ init(); });
index_ = ++frameBufferContextCnt; index_ = ++frameBufferContextCnt;
@ -286,106 +281,6 @@ void FrameBufferContext::init() {
#endif #endif
setup(frameBufferSize_); setup(frameBufferSize_);
glfwSetWindowUserPointer(getGLFWWindow(), v4d_);
glfwSetCursorPosCallback(getGLFWWindow(), [](GLFWwindow* glfwWin, double x, double y) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx()) {
auto pt = v4d->fbCtx().toWindowCoord(cv::Point2f(x, y));
v4d->nguiCtx().screen().cursor_pos_callback_event(pt.x, pt.y);
}
#ifndef __EMSCRIPTEN__
auto cursor = v4d->getMousePosition();
auto diff = cursor - cv::Vec2f(x, y);
if (v4d->isMouseDrag()) {
v4d->pan(diff[0], -diff[1]);
}
#endif
v4d->setMousePosition(x, y);
}
);
glfwSetMouseButtonCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, int button, int action, int modifiers) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().mouse_button_callback_event(button, action, modifiers);
if (button == GLFW_MOUSE_BUTTON_RIGHT) {
v4d->setMouseDrag(action == GLFW_PRESS);
}
}
);
glfwSetKeyCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, int key, int scancode, int action, int mods) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().key_callback_event(key, scancode, action, mods);
}
);
glfwSetCharCallback(getGLFWWindow(), [](GLFWwindow* glfwWin, unsigned int codepoint) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().char_callback_event(codepoint);
}
);
glfwSetDropCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, int count, const char** filenames) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().drop_callback_event(count, filenames);
}
);
glfwSetScrollCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, double x, double y) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
std::vector<nanogui::Widget*> widgets;
if(v4d->hasNguiCtx()) {
for (auto* w : v4d->nguiCtx().screen().children()) {
auto pt = v4d->fbCtx().toWindowCoord(v4d->getMousePosition());
auto mousePos = nanogui::Vector2i(pt[0] / v4d->pixelRatioX(), pt[1] / v4d->pixelRatioY());
if(contains_absolute(w, mousePos)) {
v4d->nguiCtx().screen().scroll_callback_event(x, y);
return;
}
}
}
#ifndef __EMSCRIPTEN__
v4d->zoom(y < 0 ? 1.1 : 0.9);
#endif
}
);
glfwSetWindowSizeCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, int width, int height) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().resize_callback_event(width, height);
cv::Rect& vp = v4d->viewport();
cv::Size fbsz = v4d->framebufferSize();
vp.x = 0;
vp.y = 0;
vp.width = fbsz.width;
vp.height = fbsz.height;
});
// glfwSetFramebufferSizeCallback(getGLFWWindow(),
// [](GLFWwindow* glfwWin, int width, int height) {
// V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
// cv::Rect& vp = v4d->viewport();
// vp.x = 0;
// vp.y = 0;
// vp.width = width;
// vp.height = height;
//#ifndef __EMSCRIPTEN__
// if(v4d->isResizable()) {
// v4d->nvgCtx().fbCtx().teardown();
// v4d->glCtx().fbCtx().teardown();
// v4d->fbCtx().teardown();
// v4d->fbCtx().setup(cv::Size(width, height));
// v4d->glCtx().fbCtx().setup(cv::Size(width, height));
// v4d->nvgCtx().fbCtx().setup(cv::Size(width, height));
// }
//#endif
// });
} }
int FrameBufferContext::getIndex() { int FrameBufferContext::getIndex() {

@ -43,7 +43,6 @@ class FrameBufferContext {
friend class NanoVGContext; friend class NanoVGContext;
friend class NanoguiContext; friend class NanoguiContext;
friend class cv::v4d::V4D; friend class cv::v4d::V4D;
V4D* v4d_ = nullptr;
bool offscreen_; bool offscreen_;
string title_; string title_;
int major_; int major_;
@ -154,10 +153,10 @@ public:
* Create a FrameBufferContext with given size. * Create a FrameBufferContext with given size.
* @param frameBufferSize The frame buffer size. * @param frameBufferSize The frame buffer size.
*/ */
FrameBufferContext(V4D& v4d, const cv::Size& frameBufferSize, bool offscreen, FrameBufferContext(const cv::Size& frameBufferSize, bool offscreen,
const string& title, int major, int minor, bool compat, int samples, bool debug, GLFWwindow* sharedWindow, const FrameBufferContext* parent); const string& title, int major, int minor, bool compat, int samples, bool debug, GLFWwindow* sharedWindow, const FrameBufferContext* parent);
FrameBufferContext(V4D& v4d, const string& title, const FrameBufferContext& other); FrameBufferContext(const string& title, const FrameBufferContext& other);
/*! /*!
* Default destructor. * Default destructor.

@ -7,8 +7,8 @@
namespace cv { namespace cv {
namespace v4d { namespace v4d {
namespace detail { namespace detail {
GLContext::GLContext(V4D& v4d, FrameBufferContext& fbContext) : GLContext::GLContext(FrameBufferContext& fbContext) :
v4d_(v4d), mainFbContext_(fbContext), glFbContext_(v4d, "OpenGL", fbContext) { mainFbContext_(fbContext), glFbContext_("OpenGL", fbContext) {
run_sync_on_main<19>([&,this](){ run_sync_on_main<19>([&,this](){
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
mainFbContext_.initWebGLCopy(fbCtx()); mainFbContext_.initWebGLCopy(fbCtx());

@ -19,18 +19,14 @@ namespace detail {
* Used to setup a nanovg context * Used to setup a nanovg context
*/ */
class GLContext { class GLContext {
V4D& v4d_;
FrameBufferContext& mainFbContext_; FrameBufferContext& mainFbContext_;
FrameBufferContext glFbContext_; FrameBufferContext glFbContext_;
cv::UMat preFB_;
cv::UMat fb_;
cv::UMat postFB_;
public: public:
/*! /*!
* Creates a OpenGL Context * Creates a OpenGL Context
* @param fbContext The framebuffer context * @param fbContext The framebuffer context
*/ */
GLContext(V4D& v4d, FrameBufferContext& fbContext); GLContext(FrameBufferContext& fbContext);
/*! /*!
* Execute function object fn inside a gl context. * Execute function object fn inside a gl context.
* The context takes care of setting up opengl states. * The context takes care of setting up opengl states.

@ -10,8 +10,8 @@ namespace cv {
namespace v4d { namespace v4d {
namespace detail { namespace detail {
NanoguiContext::NanoguiContext(V4D& v4d, FrameBufferContext& fbContext) : NanoguiContext::NanoguiContext(FrameBufferContext& fbContext) :
NanoVGContext(v4d, fbContext) { NanoVGContext(fbContext) {
} }
void NanoguiContext::render() { void NanoguiContext::render() {

@ -29,7 +29,7 @@ class NanoguiContext : public NanoVGContext {
float fps_ = 0; float fps_ = 0;
bool first_ = true; bool first_ = true;
public: public:
NanoguiContext(V4D& v4d, FrameBufferContext& fbContext); NanoguiContext(FrameBufferContext& fbContext);
void render(); void render();
void updateFps(bool print, bool graphical); void updateFps(bool print, bool graphical);
void build(std::function<void(cv::v4d::FormHelper&)> fn); void build(std::function<void(cv::v4d::FormHelper&)> fn);

@ -10,8 +10,8 @@ namespace cv {
namespace v4d { namespace v4d {
namespace detail { namespace detail {
NanoVGContext::NanoVGContext(V4D& v4d, FrameBufferContext& fbContext) : NanoVGContext::NanoVGContext(FrameBufferContext& fbContext) :
v4d_(v4d), mainFbContext_(fbContext), nvgFbContext_(v4d, "NanoVG", fbContext), context_( mainFbContext_(fbContext), nvgFbContext_("NanoVG", fbContext), context_(
nullptr) { nullptr) {
UMat tmp(fbCtx().size(), CV_8UC4); UMat tmp(fbCtx().size(), CV_8UC4);

@ -25,7 +25,6 @@ namespace detail {
* Used to setup a nanovg context * Used to setup a nanovg context
*/ */
class NanoVGContext { class NanoVGContext {
V4D& v4d_;
protected: protected:
nanogui::Screen* screen_; nanogui::Screen* screen_;
cv::v4d::FormHelper* form_; cv::v4d::FormHelper* form_;
@ -61,7 +60,7 @@ public:
* @param context The native NVGContext * @param context The native NVGContext
* @param fbContext The framebuffer context * @param fbContext The framebuffer context
*/ */
NanoVGContext(V4D& v4d, FrameBufferContext& fbContext); NanoVGContext(FrameBufferContext& fbContext);
/*! /*!
* Execute function object fn inside a nanovg context. * Execute function object fn inside a nanovg context.

@ -17,6 +17,11 @@ namespace cv {
namespace v4d { namespace v4d {
namespace detail { namespace detail {
static bool contains_absolute(nanogui::Widget* w, const nanogui::Vector2i& p) {
nanogui::Vector2i d = p - w->absolute_position();
return d.x() >= 0 && d.y() >= 0 && d.x() < w->size().x() && d.y() < w->size().y();
}
void glfw_error_callback(int error, const char* description) { void glfw_error_callback(int error, const char* description) {
fprintf(stderr, "GLFW Error: (%d) %s\n", error, description); fprintf(stderr, "GLFW Error: (%d) %s\n", error, description);
} }
@ -49,13 +54,114 @@ V4D::V4D(const cv::Size& size, const cv::Size& fbsize, const string& title, bool
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
printf(""); //makes sure we have FS as a dependency printf(""); //makes sure we have FS as a dependency
#endif #endif
mainFbContext_ = new detail::FrameBufferContext(*this, fbsize.empty() ? size : fbsize, offscreen, title_, major_, mainFbContext_ = new detail::FrameBufferContext(fbsize.empty() ? size : fbsize, offscreen, title_, major_,
minor_, compat_, samples_, debug_, nullptr, nullptr); minor_, compat_, samples_, debug_, nullptr, nullptr);
nvgContext_ = new detail::NanoVGContext(*this, *mainFbContext_); nvgContext_ = new detail::NanoVGContext(*mainFbContext_);
nguiContext_ = new detail::NanoguiContext(*this, *mainFbContext_); nguiContext_ = new detail::NanoguiContext(*mainFbContext_);
clvaContext_ = new detail::CLVAContext(*this, *mainFbContext_); clvaContext_ = new detail::CLVAContext(*mainFbContext_);
glContext_ = new detail::GLContext(*this, *mainFbContext_); glContext_ = new detail::GLContext(*mainFbContext_);
glfwSetWindowUserPointer(getGLFWWindow(), this);
glfwSetCursorPosCallback(getGLFWWindow(), [](GLFWwindow* glfwWin, double x, double y) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx()) {
auto pt = v4d->fbCtx().toWindowCoord(cv::Point2f(x, y));
v4d->nguiCtx().screen().cursor_pos_callback_event(pt.x, pt.y);
}
#ifndef __EMSCRIPTEN__
auto cursor = v4d->getMousePosition();
auto diff = cursor - cv::Vec2f(x, y);
if (v4d->isMouseDrag()) {
v4d->pan(diff[0], -diff[1]);
}
#endif
v4d->setMousePosition(x, y);
}
);
glfwSetMouseButtonCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, int button, int action, int modifiers) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().mouse_button_callback_event(button, action, modifiers);
if (button == GLFW_MOUSE_BUTTON_RIGHT) {
v4d->setMouseDrag(action == GLFW_PRESS);
}
}
);
glfwSetKeyCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, int key, int scancode, int action, int mods) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().key_callback_event(key, scancode, action, mods);
}
);
glfwSetCharCallback(getGLFWWindow(), [](GLFWwindow* glfwWin, unsigned int codepoint) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().char_callback_event(codepoint);
}
);
glfwSetDropCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, int count, const char** filenames) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().drop_callback_event(count, filenames);
}
);
glfwSetScrollCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, double x, double y) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
std::vector<nanogui::Widget*> widgets;
if(v4d->hasNguiCtx()) {
for (auto* w : v4d->nguiCtx().screen().children()) {
auto pt = v4d->fbCtx().toWindowCoord(v4d->getMousePosition());
auto mousePos = nanogui::Vector2i(pt[0] / v4d->pixelRatioX(), pt[1] / v4d->pixelRatioY());
if(cv::v4d::detail::contains_absolute(w, mousePos)) {
v4d->nguiCtx().screen().scroll_callback_event(x, y);
return;
}
}
}
#ifndef __EMSCRIPTEN__
v4d->zoom(y < 0 ? 1.1 : 0.9);
#endif
}
);
glfwSetWindowSizeCallback(getGLFWWindow(),
[](GLFWwindow* glfwWin, int width, int height) {
V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
if(v4d->hasNguiCtx())
v4d->nguiCtx().screen().resize_callback_event(width, height);
cv::Rect& vp = v4d->viewport();
cv::Size fbsz = v4d->framebufferSize();
vp.x = 0;
vp.y = 0;
vp.width = fbsz.width;
vp.height = fbsz.height;
});
// glfwSetFramebufferSizeCallback(getGLFWWindow(),
// [](GLFWwindow* glfwWin, int width, int height) {
// V4D* v4d = reinterpret_cast<V4D*>(glfwGetWindowUserPointer(glfwWin));
// cv::Rect& vp = v4d->viewport();
// vp.x = 0;
// vp.y = 0;
// vp.width = width;
// vp.height = height;
//#ifndef __EMSCRIPTEN__
// if(v4d->isResizable()) {
// v4d->nvgCtx().fbCtx().teardown();
// v4d->glCtx().fbCtx().teardown();
// v4d->fbCtx().teardown();
// v4d->fbCtx().setup(cv::Size(width, height));
// v4d->glCtx().fbCtx().setup(cv::Size(width, height));
// v4d->nvgCtx().fbCtx().setup(cv::Size(width, height));
// }
//#endif
// });
} }
V4D::~V4D() { V4D::~V4D() {
@ -183,6 +289,7 @@ static void do_frame(void* void_fn_ptr) {
auto* fn_ptr = reinterpret_cast<std::function<bool()>*>(void_fn_ptr); auto* fn_ptr = reinterpret_cast<std::function<bool()>*>(void_fn_ptr);
if (fn_ptr) { if (fn_ptr) {
auto& fn = *fn_ptr; auto& fn = *fn_ptr;
//FIXME cancel main loop
fn(); fn();
} }
} }

Loading…
Cancel
Save