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號