NanoGUI使用
为什么用
NanoGUI是一个支持OpenGL绘制的gui 库,也提供python的绑定(由pybind11实现)
优点
- 支持Mac、Windows和Linux,能够在windows平台上提供OpenGL3.x支持。
- 体积小
- 支持高清屏
- 使用lambda回调函数,逻辑清晰
缺点
- 维护不及时
- 功能少
- 缺少移动版本
总体来说,对于一般应用已经足够。
编译
从github下载:
git clone --recursive https://github.com/wjakob/nanogui.git
Mac/Linux上使用CMake构建,在Windows上生成VC solution后编译。注意windows上仅支持win64 build。vsiual studio 2015需要升级update 2 或update3(见NanoGUI::issures 201)。
C++实例
使用nanogui界面时刻直接从nanogui::screen 继承:
class App : public nanogui::Screen {public:App() : nanogui::Screen(Eigen::Vector2i(1024, 768), "NanoGUI Test") {//初始化界面中第一个或多个菜单窗口}virtual void draw(NVGcontext *ctx) {//更新界面//...Screen::draw(ctx);}virtual void drawContents() {//使用OpenGL绘制窗口内容}virtual void Screen::drawAll() {glClearColor(mBackground[0], mBackground[1], mBackground[2], 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);drawContents();drawWidgets();glfwSwapBuffers(mGLFWWindow);}virtual bool keyboardEvent(int key, int scancode, int action, int modifiers);...}int main(int /* argc */, char ** /* argv */) {try {nanogui::init();/* scoped variables */ {nanogui::ref<App> app = new App();app->drawAll();app->setVisible(true);nanogui::mainloop();}nanogui::shutdown();} catch (const std::runtime_error &e) {//...return -1;}
也可将其变为实例实现在view类中。
class myViewer{public:nanogui::Screen* screen;void draw(){ngui->refresh();screen->drawWidgets();...}}
初始化菜单和窗口上的控件时,需要为其清晰的指定父窗口指针和布局(Layout)。也定义lambda函数作为button等对象的回调函数。
Window *window = new Window(this, "Button demo");window->setPosition(Vector2i(15, 15));window->setLayout(new GroupLayout());/* No need to store a pointer, the data structure will be automaticallyfreed when the parent window is deleted */new Label(window, "Push buttons", "sans-bold");Button *b = new Button(window, "Plain button");b->setCallback([] { cout << "pushed!" << endl; });b->setTooltip("short tooltip");

也可以为对象自定义回调函数,然后将其加入到系统循环的refresh()中。
std::vector<std::function<void()>> mRefreshCallbacks;void refresh() {for (auto const &callback : mRefreshCallbacks)callback();}
加入UI对象
template <typename Type> detail::FormWidget<Type> *addVariable(const std::string &label, const std::function<void(Type)> &setter, const std::function<Type()> &getter, bool editable = true) {Label *labelW = new Label(mWindow, label, mLabelFontName, mLabelFontSize);//使用专用模板将数值类型转换为对应的UI对象auto widget = new detail::FormWidget<Type>(mWindow);//getter,setter函数加入callbacks集合auto refresh = [widget, getter] {Type value = getter(), current = widget->value();if (value != current)widget->setValue(value);};refresh();widget->setCallback(setter);widget->setEditable(editable);widget->setFontSize(mWidgetFontSize);Vector2i fs = widget->fixedSize();widget->setFixedSize(Vector2i(fs.x() != 0 ? fs.x() : mFixedSize.x(),fs.y() != 0 ? fs.y() : mFixedSize.y()));mRefreshCallbacks.push_back(refresh);}
Python实例
python中直接将生成的lib文件和pyd文件放到.py文件的同一目录(或Python搜索路径),实现参考实例的中的Python代码。
关于作者
NanoGUI的作者是Wenzel Jakob,洛桑联邦理工学院(EPFL)助理教授,他的研究兴趣是真实感渲染。


浙公网安备 33010602011771号