restructured gl loading and context handling

pull/3471/head
kallaballa 2 years ago
parent d98160c0ea
commit 52dbb39bbd
  1. 2
      modules/v4d/include/opencv2/v4d/detail/framebuffercontext.hpp
  2. 1
      modules/v4d/include/opencv2/v4d/detail/imguicontext.hpp
  3. 17
      modules/v4d/include/opencv2/v4d/v4d.hpp
  4. 2
      modules/v4d/samples/beauty-demo.cpp
  5. 2
      modules/v4d/samples/cube-demo.cpp
  6. 2
      modules/v4d/samples/custom_source_and_sink.cpp
  7. 2
      modules/v4d/samples/display_image.cpp
  8. 2
      modules/v4d/samples/display_image_fb.cpp
  9. 2
      modules/v4d/samples/font-demo.cpp
  10. 2
      modules/v4d/samples/font_rendering.cpp
  11. 2
      modules/v4d/samples/font_with_gui.cpp
  12. 2
      modules/v4d/samples/many_cubes-demo.cpp
  13. 2
      modules/v4d/samples/nanovg-demo.cpp
  14. 2
      modules/v4d/samples/optflow-demo.cpp
  15. 2
      modules/v4d/samples/pedestrian-demo.cpp
  16. 2
      modules/v4d/samples/render_opengl.cpp
  17. 2
      modules/v4d/samples/shader-demo.cpp
  18. 2
      modules/v4d/samples/vector_graphics.cpp
  19. 2
      modules/v4d/samples/vector_graphics_and_fb.cpp
  20. 2
      modules/v4d/samples/video-demo.cpp
  21. 2
      modules/v4d/samples/video_editing.cpp
  22. 6
      modules/v4d/src/detail/framebuffercontext.cpp
  23. 2
      modules/v4d/src/detail/glcontext.cpp
  24. 26
      modules/v4d/src/detail/imguicontext.cpp
  25. 2
      modules/v4d/src/detail/nanovgcontext.cpp
  26. 27
      modules/v4d/src/v4d.cpp

@ -204,7 +204,7 @@ public:
bool isClosed();
bool isShared();
protected:
V4D& getV4D();
cv::Ptr<V4D> getV4D();
int getIndex();
void setup(const cv::Size& sz);
void teardown();

@ -20,6 +20,7 @@ CV_EXPORTS class ImGuiContext {
FrameBufferContext& mainFbContext_;
FrameBufferContext glFbContext_;
std::function<void(const cv::Size&)> renderCallback_;
bool firstFrame_ = true;
public:
CV_EXPORTS ImGuiContext(FrameBufferContext& fbContext);
CV_EXPORTS FrameBufferContext& fbCtx();

@ -6,9 +6,8 @@
#ifndef SRC_OPENCV_V4D_V4D_HPP_
#define SRC_OPENCV_V4D_V4D_HPP_
#if !defined(OPENCV_V4D_USE_ES3) && !defined(__EMSCRIPTEN__)
# define V4D_INIT(w, h, title, offscreen, debug, samples) ({ \
cv::Ptr<cv::v4d::V4D> v4d = cv::v4d::V4D::make(cv::Size(w, h), cv::Size(), title, offscreen, debug, samples); \
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) \
# define V4D_INIT_PRIVATE(v4d, install_hooks) ({ \
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) \
throw std::runtime_error("Could not initialize GLAD!"); \
glGetError(); \
FrameBufferContext::GLScope glScope(v4d->fbCtx(), GL_FRAMEBUFFER); \
@ -19,8 +18,12 @@
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; \
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; \
ImGui::StyleColorsDark(); \
ImGui_ImplGlfw_InitForOpenGL(v4d->getGLFWWindow(), true); \
ImGui_ImplGlfw_InitForOpenGL(v4d->getGLFWWindow(), install_hooks); \
ImGui_ImplOpenGL3_Init(); \
})
# define V4D_INIT_MAIN(w, h, title, offscreen, debug, samples) ({ \
cv::Ptr<cv::v4d::V4D> v4d = cv::v4d::V4D::make(cv::Size(w, h), cv::Size(), title, offscreen, debug, samples); \
V4D_INIT_PRIVATE(v4d, true); \
v4d; \
})
#endif
@ -43,6 +46,7 @@
#include <map>
#include <string>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
@ -373,13 +377,12 @@ private:
V4D(const cv::Size& size, const cv::Size& fbsize,
const string& title, bool offscreen, bool debug, int samples);
cv::Ptr<V4D> self();
cv::Point2f getMousePosition();
void setMousePosition(const cv::Point2f& pt);
void swapContextBuffers();
protected:
cv::Ptr<V4D> self();
};
}
} /* namespace kb */

@ -379,7 +379,7 @@ int main(int argc, char **argv) {
int main() {
#endif
using namespace cv::v4d;
cv::Ptr<V4D> window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Beauty Demo", OFFSCREEN);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Beautification Demo", false, false, 0);
facemark->loadModel("assets/lbfmodel.yaml");
window->setScaling(scale);

@ -245,7 +245,7 @@ int main(int argc, char** argv) {
#else
int main() {
#endif
cv::Ptr<V4D> window = V4D_INIT(WIDTH, HEIGHT, "Cube Demo", false, false, 0);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Cube Demo", false, false, 0);
window->printSystemInfo();

@ -7,7 +7,7 @@ using namespace cv;
using namespace cv::v4d;
int main() {
Ptr<V4D> window = V4D::make(Size(960, 960), cv::Size(), "Custom Source/Sink");
Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "Custom Source/Sink", false, false, 0);
string hr = "Hello Rainbow!";
//Make a source that generates rainbow frames.

@ -8,7 +8,7 @@ int main() {
//Creates a V4D window for on screen rendering with a window size of 720p and a framebuffer of the same size.
//Please note that while the window size may change the framebuffer size may not. If you need multiple framebuffer
//sizes you need multiple V4D objects
Ptr<V4D> window = V4D::make(Size(960, 960), cv::Size(), "Display image");
cv::Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "Display Image", false, false, 0);
//Loads an image as a UMat (just in case we have hardware acceleration available)
#ifdef __EMSCRIPTEN__

@ -6,7 +6,7 @@ using namespace cv::v4d;
int main() {
//Creates a V4D object
Ptr<V4D> window = V4D::make(Size(960, 960), cv::Size(), "Display image and FB");
Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "Display Image and FB", false, false, 0);
//Loads an image as a UMat (just in case we have hardware acceleration available)
#ifdef __EMSCRIPTEN__

@ -204,7 +204,7 @@ static bool iteration(cv::Ptr<V4D> window) {
int main() {
try {
cv::Ptr<V4D> window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Font Demo", OFFSCREEN);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Font Demo", false, false, 0);
// if(!OFFSCREEN) {
// setup_gui(window);
// }

@ -4,7 +4,7 @@ using namespace cv;
using namespace cv::v4d;
int main() {
Ptr<V4D> window = V4D::make(Size(960, 960), cv::Size(), "Font Rendering");
cv::Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "Font Rendering", false, false, 0);
//The text to render
string hw = "Hello World";

@ -4,7 +4,7 @@ using namespace cv;
using namespace cv::v4d;
int main() {
Ptr<V4D> window = V4D::make(Size(960, 960), cv::Size(), "Font Rendering with GUI");
Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "Font Rendering with GUI", false, false, 0);
//The text color. NanoGUI uses rgba with floating point
// nanogui::Color textColor = {0.0f, 0.0f, 1.0f, 1.0f};

@ -258,7 +258,7 @@ int main(int argc, char** argv) {
#else
int main() {
#endif
cv::Ptr<V4D> window = V4D_INIT(WIDTH, HEIGHT, "Many Cubes Demo", false, false, 0);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Many Cubes Demo", false, false, 0);
window->printSystemInfo();
#ifndef __EMSCRIPTEN__

@ -184,7 +184,7 @@ int main(int argc, char **argv) {
#else
int main() {
#endif
cv::Ptr<V4D> window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "NanoVG Demo", OFFSCREEN);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Mandelbrot Shader Demo", false, false, 0);
window->printSystemInfo();
#ifndef __EMSCRIPTEN__

@ -506,7 +506,7 @@ int main() {
#endif
try {
using namespace cv::v4d;
cv::Ptr<V4D> window = V4D_INIT(WIDTH, HEIGHT, "Sparse Optical Flow Demo", false, false, 0);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Sparse Optical Flow Demo", false, false, 0);
#ifndef __EMSCRIPTEN__
menuWindow = V4D::make(cv::Size(240, 360), cv::Size(), "Display Settings", OFFSCREEN);

@ -235,7 +235,7 @@ int main(int argc, char **argv) {
int main() {
#endif
using namespace cv::v4d;
cv::Ptr<V4D> window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Pedestrian Demo", OFFSCREEN);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Pedestrian Demo", false, false, 0);
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
window->printSystemInfo();

@ -5,7 +5,7 @@ using namespace cv;
using namespace cv::v4d;
int main() {
Ptr<V4D> window = V4D_INIT(960, 960, "GL Blue Screen", false, false, 0);
Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "GL Blue Screen", false, false, 0);
window->run([=](Ptr<V4D> window) {
window->gl([]() {

@ -339,7 +339,7 @@ int main(int argc, char** argv) {
int main() {
#endif
try {
cv::Ptr<V4D> window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Shader Demo", OFFSCREEN);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Mandelbrot Shader Demo", false, false, 0);
// if (!OFFSCREEN) {
// setup_gui(window);

@ -4,7 +4,7 @@ using namespace cv;
using namespace cv::v4d;
int main() {
Ptr<V4D> window = V4D::make(Size(960, 960), cv::Size(), "Vector Graphics");
Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "Vector Graphics", false, false, 0);
window->run([=](Ptr<V4D> window) {
//Creates a NanoVG context and draws googly eyes that occasionally blink.

@ -5,7 +5,7 @@ using namespace cv;
using namespace cv::v4d;
int main() {
Ptr<V4D> window = V4D::make(Size(960, 960), cv::Size(), "Vector Graphics and Framebuffer");
Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "Vector Graphics and Framebuffer", false, false, 0);
window->run([=](Ptr<V4D> window) {
//Again creates a NanoVG context and draws googly eyes

@ -218,7 +218,7 @@ int main(int argc, char** argv) {
int main() {
#endif
using namespace cv::v4d;
cv::Ptr<V4D> window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Video Demo", OFFSCREEN, false);
cv::Ptr<V4D> window = V4D_INIT_MAIN(WIDTH, HEIGHT, "Video Demo", false, false, 0);
window->printSystemInfo();
#ifndef __EMSCRIPTEN__

@ -4,7 +4,7 @@ using namespace cv;
using namespace cv::v4d;
int main(int argc, char** argv) {
Ptr<V4D> window = V4D::make(cv::Size(960, 960), cv::Size(), "Video Editing");
Ptr<V4D> window = V4D_INIT_MAIN(960, 960, "Video Editing", false, false, 0);
//In case of WebAssembly
CV_UNUSED(argc);

@ -271,7 +271,7 @@ void FrameBufferContext::init() {
}
this->makeCurrent();
#ifndef __EMSCRIPTEN__
glfwSwapInterval(1);
glfwSwapInterval(0);
#endif
#if !defined(OPENCV_V4D_USE_ES3) && !defined(__EMSCRIPTEN__)
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
@ -367,8 +367,8 @@ void FrameBufferContext::init() {
// });
}
V4D& FrameBufferContext::getV4D() {
return *v4d_;
cv::Ptr<V4D> FrameBufferContext::getV4D() {
return v4d_->self();
}
int FrameBufferContext::getIndex() {

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

@ -19,7 +19,8 @@ namespace cv {
namespace v4d {
namespace detail {
ImGuiContext::ImGuiContext(FrameBufferContext& fbContext) :
mainFbContext_(fbContext), glFbContext_(fbContext.getV4D(), "ImGUI", fbContext) {
mainFbContext_(fbContext), glFbContext_(*fbContext.getV4D(), "ImGUI", fbContext) {
V4D_INIT_PRIVATE(mainFbContext_.getV4D(), false);
#ifdef __EMSCRIPTEN__
run_sync_on_main<24>([&,this](){
mainFbContext_.initWebGLCopy(fbCtx().getIndex());
@ -27,12 +28,12 @@ ImGuiContext::ImGuiContext(FrameBufferContext& fbContext) :
#endif
}
bool show_demo_window = true;
void ImGuiContext::build(std::function<void(const cv::Size&)> fn) {
renderCallback_ = fn;
}
bool show_demo_window = true;
void ImGuiContext::render() {
run_sync_on_main<25>([&,this](){
#ifndef __EMSCRIPTEN__
@ -43,24 +44,19 @@ void ImGuiContext::render() {
}
#endif
{
fbCtx().getV4D().makeCurrent();
fbCtx().getV4D()->makeCurrent();
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
GL_CHECK(glDrawBuffer(GL_BACK));
GL_CHECK(glViewport(0, 0, fbCtx().getV4D().size().width, fbCtx().getV4D().size().height));
// GL_CHECK(glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
//#ifdef __EMSCRIPTEN__
// //Preserve the clear color state though it is a bit costly. We don't want to interfere.
// GLfloat cColor[4];
// GL_CHECK(glGetFloatv(GL_COLOR_CLEAR_VALUE, cColor));
// GL_CHECK(glClearColor(0,0,0,0));
// GL_CHECK(glClear(GL_COLOR_BUFFER_BIT));
// GL_CHECK(glClearColor(cColor[0], cColor[1], cColor[2], cColor[3]));
//#endif
GL_CHECK(glViewport(0, 0, fbCtx().getV4D()->size().width, fbCtx().getV4D()->size().height));
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
renderCallback_(fbCtx().getV4D().size());
ImGui::Begin("Display"); \
ImGuiIO& io = ImGui::GetIO(); \
ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); \
ImGui::End();
if(renderCallback_)
renderCallback_(fbCtx().getV4D()->size());
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

@ -12,7 +12,7 @@ namespace v4d {
namespace detail {
NanoVGContext::NanoVGContext(FrameBufferContext& fbContext) :
mainFbContext_(fbContext), nvgFbContext_(fbContext.getV4D(), "NanoVG", fbContext), context_(
mainFbContext_(fbContext), nvgFbContext_(*fbContext.getV4D(), "NanoVG", fbContext), context_(
nullptr) {
run_sync_on_main<13>([this]() {
{

@ -25,15 +25,15 @@ V4D::V4D(const cv::Size& size, const cv::Size& fbsize, const string& title, bool
#ifdef __EMSCRIPTEN__
printf(""); //makes sure we have FS as a dependency
#endif
mainFbContext_ = new detail::FrameBufferContext(*this, fbsize.empty() ? size : fbsize, offscreen, title_, 3,
self_ = cv::Ptr<V4D>(this);
mainFbContext_ = new detail::FrameBufferContext(*this, fbsize.empty() ? size : fbsize, offscreen, title_, 3,
2, samples_, debug_, nullptr, nullptr);
#ifndef __EMSCRIPTEN__
CLExecScope_t scope(mainFbContext_->getCLExecContext());
CLExecScope_t scope(mainFbContext_->getCLExecContext());
#endif
nvgContext_ = new detail::NanoVGContext(*mainFbContext_);
clvaContext_ = new detail::CLVAContext(*mainFbContext_);
imguiContext_ = new detail::ImGuiContext(*mainFbContext_);
self_ = cv::Ptr<V4D>(this);
nvgContext_ = new detail::NanoVGContext(*mainFbContext_);
clvaContext_ = new detail::CLVAContext(*mainFbContext_);
imguiContext_ = new detail::ImGuiContext(*mainFbContext_);
}
V4D::~V4D() {
@ -447,6 +447,7 @@ void V4D::swapContextBuffers() {
FrameBufferContext::GLScope glScope(glCtx(i).fbCtx(), GL_READ_FRAMEBUFFER);
glCtx(i).fbCtx().blitFrameBufferToScreen(viewport(), glCtx(i).fbCtx().getWindowSize(), isScaling());
// GL_CHECK(glFinish());
glfwSwapInterval(0);
#ifndef __EMSCRIPTEN__
glfwSwapBuffers(glCtx(i).fbCtx().getGLFWWindow());
#else
@ -459,6 +460,7 @@ void V4D::swapContextBuffers() {
FrameBufferContext::GLScope glScope(nvgCtx().fbCtx(), GL_READ_FRAMEBUFFER);
nvgCtx().fbCtx().blitFrameBufferToScreen(viewport(), nvgCtx().fbCtx().getWindowSize(), isScaling());
// GL_CHECK(glFinish());
glfwSwapInterval(0);
#ifndef __EMSCRIPTEN__
glfwSwapBuffers(nvgCtx().fbCtx().getGLFWWindow());
#else
@ -469,6 +471,7 @@ void V4D::swapContextBuffers() {
FrameBufferContext::GLScope glScope(imguiCtx().fbCtx(), GL_READ_FRAMEBUFFER);
imguiCtx().fbCtx().blitFrameBufferToScreen(viewport(), imguiCtx().fbCtx().getWindowSize(), isScaling());
// GL_CHECK(glFinish());
glfwSwapInterval(0);
#ifndef __EMSCRIPTEN__
glfwSwapBuffers(imguiCtx().fbCtx().getGLFWWindow());
#else
@ -484,15 +487,13 @@ bool V4D::display() {
#else
if (true) {
#endif
run_sync_on_main<6>([&, this](){
run_sync_on_main<6>([&, this]() {
{
FrameBufferContext::GLScope glScope(fbCtx(), GL_READ_FRAMEBUFFER);
fbCtx().blitFrameBufferToScreen(viewport(), fbCtx().getWindowSize(), isScaling());
FrameBufferContext::GLScope glScope(fbCtx(), GL_READ_FRAMEBUFFER);
fbCtx().blitFrameBufferToScreen(viewport(), fbCtx().getWindowSize(), isScaling());
}
imguiCtx().render();
// if(debug_)
swapContextBuffers();
swapContextBuffers();
fbCtx().makeCurrent();
#ifndef __EMSCRIPTEN__
glfwSwapBuffers(fbCtx().getGLFWWindow());
@ -503,7 +504,7 @@ bool V4D::display() {
result = !glfwWindowShouldClose(getGLFWWindow());
});
}
if(frameCnt_ == (std::numeric_limits<uint64_t>().max() - 1))
if (frameCnt_ == (std::numeric_limits<uint64_t>().max() - 1))
frameCnt_ = 0;
else
++frameCnt_;

Loading…
Cancel
Save