From 0dcccf557b3182bb0de5e813ee8c32b89e456ea0 Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nwpope@utu.fi> Date: Sat, 1 Jun 2019 18:44:05 +0300 Subject: [PATCH] Initial NanoGUI code --- CMakeLists.txt | 13 ++ applications/gui/CMakeLists.txt | 23 +++ applications/gui/src/main.cpp | 140 ++++++++++++++++++ components/common/cpp/include/ftl/config.h.in | 1 + 4 files changed, 177 insertions(+) create mode 100644 applications/gui/CMakeLists.txt create mode 100644 applications/gui/src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 512d8b801..d250beab3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,15 @@ else() endif() endif() +find_library( NANOGUI_LIBRARY NAMES nanogui libnanogui) +if (NANOGUI_LIBRARY) + set(HAVE_NANOGUI TRUE) + add_library(nanogui UNKNOWN IMPORTED) + #set_property(TARGET nanogui PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${NANOGUI_EXTRA_INCS}) + set_property(TARGET nanogui PROPERTY IMPORTED_LOCATION ${NANOGUI_LIBRARY}) + message(STATUS "Found NanoGUI: ${NANOGUI_LIBRARY}") +endif() + find_program( NODE_NPM NAMES npm ) if (NODE_NPM) message(STATUS "Found NPM: ${NODE_NPM}") @@ -160,6 +169,10 @@ if (BUILD_RECONSTRUCT AND HAVE_PCL) add_subdirectory(applications/reconstruct) endif() +if (HAVE_NANOGUI) + add_subdirectory(applications/gui) +endif() + ### Generate Build Configuration Files ========================================= configure_file(${CMAKE_SOURCE_DIR}/components/common/cpp/include/ftl/config.h.in diff --git a/applications/gui/CMakeLists.txt b/applications/gui/CMakeLists.txt new file mode 100644 index 000000000..5b1ba133f --- /dev/null +++ b/applications/gui/CMakeLists.txt @@ -0,0 +1,23 @@ +# Need to include staged files and libs +#include_directories(${PROJECT_SOURCE_DIR}/reconstruct/include) +#include_directories(${PROJECT_BINARY_DIR}) + +set(GUISRC + src/main.cpp +) + +add_executable(ftl-gui ${GUISRC}) + +target_include_directories(ftl-gui PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:include> + PRIVATE src) + +#if (CUDA_FOUND) +#set_property(TARGET ftl-gui PROPERTY CUDA_SEPARABLE_COMPILATION ON) +#endif() + +#target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include) +target_link_libraries(ftl-gui ftlcommon ftlrgbd Threads::Threads ${OpenCV_LIBS} glog::glog ftlnet ftlrender nanogui GL) + + diff --git a/applications/gui/src/main.cpp b/applications/gui/src/main.cpp new file mode 100644 index 000000000..6ab767c93 --- /dev/null +++ b/applications/gui/src/main.cpp @@ -0,0 +1,140 @@ +#include <ftl/configuration.hpp> +#include <ftl/net/universe.hpp> +#include <ftl/rgbd.hpp> + +#include <glog/logging.h> + +#include <opencv2/opencv.hpp> + +#include <nanogui/opengl.h> +#include <nanogui/glutil.h> +#include <nanogui/screen.h> +#include <nanogui/window.h> +#include <nanogui/layout.h> +#include <nanogui/imageview.h> + +using ftl::config; +using std::string; +using ftl::rgbd::RGBDSource; + +class GLTexture { + public: + GLTexture() { + glGenTextures(1, &glid_); + glBindTexture(GL_TEXTURE_2D, glid_); + cv::Mat m(cv::Size(100,100), CV_8UC3); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m.cols, m.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, m.data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + ~GLTexture() { + glDeleteTextures(1, &glid_); + } + + void update(cv::Mat &m) { + if (m.rows == 0) return; + glBindTexture(GL_TEXTURE_2D, glid_); + // TODO Allow for other formats + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m.cols, m.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, m.data); + auto err = glGetError(); + if (err != 0) LOG(ERROR) << "OpenGL Texture error: " << err; + } + + unsigned int texture() const { return glid_; } + + private: + unsigned int glid_; +}; + +struct SourceViews { + ftl::rgbd::RGBDSource *source; + GLTexture texture; + nanogui::ImageView *view; +}; + +class FTLApplication : public nanogui::Screen { + public: + explicit FTLApplication(ftl::net::Universe *net) : nanogui::Screen(Eigen::Vector2i(1024, 768), "FT-Lab GUI") { + using namespace nanogui; + net_ = net; + + for (auto &src : config["sources"]) { + RGBDSource *in = ftl::rgbd::RGBDSource::create(src, net); //new ftl::rgbd::NetSource(src, &net); + if (!in) { + LOG(ERROR) << "Unrecognised source: " << src; + } else { + auto &cam = sources_.emplace_back(); + cam.source = in; + + auto imageWindow = new Window(this, "Source"); + imageWindow->setPosition(Eigen::Vector2i(710, 15)); + imageWindow->setLayout(new GroupLayout()); + imageWindow->setSize(Vector2i(400,400)); + + auto imageView = new ImageView(imageWindow, 0); + cam.view = imageView; + imageView->setGridThreshold(20); + //imageView->setPixelInfoThreshold(20); + + //displays.emplace_back(config["display"], src["uri"]); + LOG(INFO) << (string)src["uri"] << " loaded "; + } + } + + setVisible(true); + performLayout(); + } + + virtual void draw(NVGcontext *ctx) { + net_->broadcast("grab"); + for (auto &src : sources_) { + cv::Mat rgb, depth; + src.source->grab(); + src.source->getRGBD(rgb, depth); + if (rgb.rows > 0) { + src.texture.update(rgb); + src.view->bindImage(src.texture.texture()); + } + } + performLayout(); + + /* Draw the user interface */ + Screen::draw(ctx); + } + + private: + std::vector<SourceViews> sources_; + ftl::net::Universe *net_; +}; + +int main(int argc, char **argv) { + ftl::configure(argc, argv, "gui"); + ftl::net::Universe net(config["net"]); + + net.waitConnections(); + + try { + nanogui::init(); + + /* scoped variables */ { + nanogui::ref<FTLApplication> app = new FTLApplication(&net); + app->drawAll(); + app->setVisible(true); + nanogui::mainloop(); + } + + nanogui::shutdown(); + } catch (const std::runtime_error &e) { + std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what()); + #if defined(_WIN32) + MessageBoxA(nullptr, error_msg.c_str(), NULL, MB_ICONERROR | MB_OK); + #else + std::cerr << error_msg << std::endl; + #endif + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/components/common/cpp/include/ftl/config.h.in b/components/common/cpp/include/ftl/config.h.in index 3d2b7d296..296da9eec 100644 --- a/components/common/cpp/include/ftl/config.h.in +++ b/components/common/cpp/include/ftl/config.h.in @@ -19,6 +19,7 @@ #cmakedefine HAVE_PCL #cmakedefine HAVE_RENDER #cmakedefine HAVE_LIBSGM +#cmakedefine HAVE_NANOGUI extern const char *FTL_VERSION_LONG; extern const char *FTL_VERSION; -- GitLab