1Compilation 2======================================================================================== 3 4NanoGUI uses a CMake build system to ensure portability. All dependencies are 5cloned and compiled in one batch, which should generally reduce the amount of 6configuration effort to zero. Assuming that NanoGUI was cloned into the current 7working directory, the following commands need to be executed: 8 9.. code-block:: bash 10 11 # enter the top-level NanoGUI directory 12 $ cd nanogui 13 14 # make a build directory and enter that 15 $ mkdir build 16 $ cd build 17 18 # generate your Makefile 19 $ cmake .. 20 21 # now that you have a Makefile, use that to build 22 $ make -j 4 23 24For Windows, the process is nearly the same: 25 26.. code-block:: bash 27 28 # enter the top-level NanoGUI directory 29 $ cd nanogui 30 31 # make a build directory and enter that 32 $ mkdir build 33 $ cd build 34 35 # Specify VS Version AND 64bit, otherwise it defaults to 32. 36 # The version number and year may be different for you, Win64 37 # can be appended to any of them. Execute `cmake -G` to get 38 # a listing of the available generators. 39 # 40 # 32 bit Windows builds are /not/ supported 41 $ cmake -G "Visual Studio 14 2015 Win64" .. 42 43 # Either open the .sln with Visual Studio, or run 44 $ cmake --build . --config Release 45 46Default Configurations 47---------------------------------------------------------------------------------------- 48 49By default, NanoGUI will 50 51+---------------------------------+---------------------------+ 52| Impact / effect | CMake Option | 53+=================================+===========================+ 54| Build the example programs. | ``NANOGUI_BUILD_EXAMPLE`` | 55+---------------------------------+---------------------------+ 56| Build as a *shared* library. | ``NANOGUI_BUILD_SHARED`` | 57+---------------------------------+---------------------------+ 58| Build the Python plugins. | ``NANOGUI_BUILD_PYTHON`` | 59+---------------------------------+---------------------------+ 60| Use GLAD if on Windows. | ``NANOGUI_USE_GLAD`` | 61+---------------------------------+---------------------------+ 62| Generate an ``install`` target. | ``NANOGUI_INSTALL`` | 63+---------------------------------+---------------------------+ 64 65Users developing projects that reference NanoGUI as a ``git submodule`` (this 66is **strongly** encouraged) can set up the parent project's CMake configuration 67file as follows (this assumes that ``nanogui`` lives in the directory 68``ext/nanogui`` relative to the parent project): 69 70.. code-block:: cmake 71 72 # Disable building extras we won't need (pure C++ project) 73 set(NANOGUI_BUILD_EXAMPLE OFF CACHE BOOL " " FORCE) 74 set(NANOGUI_BUILD_PYTHON OFF CACHE BOOL " " FORCE) 75 set(NANOGUI_INSTALL OFF CACHE BOOL " " FORCE) 76 77 # Add the configurations from nanogui 78 add_subdirectory(ext/nanogui) 79 80 # For reliability of parallel build, make the NanoGUI targets dependencies 81 set_property(TARGET glfw glfw_objects nanogui PROPERTY FOLDER "dependencies") 82 83Required Variables Exposed 84---------------------------------------------------------------------------------------- 85 86Due to the nature of building an OpenGL application for different platforms, three 87variables are populated to allow for easy incorporation with your CMake build. After 88you have executed ``add_subdirectory`` as shown above, you will need to add the 89following (assuming the target you are building is called ``myTarget``): 90 91.. code-block:: cmake 92 93 # Various preprocessor definitions have been generated by NanoGUI 94 add_definitions(${NANOGUI_EXTRA_DEFS}) 95 96 # On top of adding the path to nanogui/include, you may need extras 97 include_directories(${NANOGUI_EXTRA_INCS}) 98 99 # Compile a target using NanoGUI 100 add_executable(myTarget myTarget.cpp) 101 102 # Lastly, additional libraries may have been built for you. In addition to linking 103 # against NanoGUI, we need to link against those as well. 104 target_link_libraries(myTarget nanogui ${NANOGUI_EXTRA_LIBS}) 105 106Advanced Compilation Details 107---------------------------------------------------------------------------------------- 108 109NanoGUI and Python 110**************************************************************************************** 111 112Although it is |year|, you may still for example wish to build the Python bindings for 113Python 2.7. The variable you would set **before** ``add_subdirectory`` is 114``NANOGUI_PYTHON_VERSION``. For example, 115 116.. code-block:: cmake 117 118 set(NANOGUI_PYTHON_VERSION "2.7") 119 # can also use minor versions 120 set(NANOGUI_PYTHON_VERSION "3.6.2") 121 122 123NanoGUI and Eigen 124**************************************************************************************** 125 126NanoGUI uses Eigen_ internally for various vector types. Eigen is an advanced header 127only template library, which NanoGUI vendors in the ``ext`` folder. It is important to 128understand the implication of Eigen being header only: **only one version of Eigen can 129be included**. 130 131There is a CMake bypass variable available in NanoGUI: ``NANOGUI_EIGEN_INCLUDE_DIR``. 132You would set this variable **before** ``add_subdirectory``. Since you will want to 133provide the same kind of bypass for users of your library, the following snippet is a 134good starting point. For this example code: 135 1361. The parent CMake project is called ``myproj``. A good CMake practice to adopt is to 137 prefix your project's name to any variables you intend to expose. This allows parent 138 projects to know where the variable came from, and avoids name collisions. 1392. First ``find_package`` is used to try and find Eigen. The philosophy is that the 140 user is responsible for ensuring that the version of Eigen they want to use will be 141 found. 1423. Since NanoGUI needs to remain self-contained, the side-effect is that even if the 143 user does *not* have Eigen installed, you can fallback and use the one vendored with 144 NanoGUI. 1454. The following directory structure: 146 147 .. code-block:: none 148 149 myproj/ 150 CMakeLists.txt <- Where this example code is 151 ext/ 152 nanogui/ 153 CMakeLists.txt <- NanoGUI's build system 154 ext/ 155 eigen/ <- NanoGUI's internal copy of Eigen 156 157 158.. code-block:: cmake 159 160 # `if NOT` is what enables the same bypass for your project 161 if(NOT MYPROJ_EIGEN3_INCLUDE_DIR) 162 # Grab or find the Eigen3 include directory. 163 find_package(Eigen3 QUIET) 164 if(EIGEN3_INCLUDE_DIR) 165 set(MYPROJ_EIGEN3_INCLUDE_DIR ${EIGEN3_INCLUDE_DIR}) 166 else() 167 # use the internal NanoGUI copy of Eigen 168 set(MYPROJ_EIGEN3_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/nanogui/ext/eigen) 169 endif() 170 endif() 171 172 message(STATUS "Using Eigen3 from directory: ${MYPROJ_EIGEN3_INCLUDE_DIR}") 173 set(NANOGUI_EIGEN_INCLUDE_DIR ${EIGEN3_INCLUDE_DIR} CACHE BOOL " " FORCE) 174 # set any other NanoGUI specific variables you need (shown in above sections) 175 add_subdirectory(ext/nanogui) 176 177 # include it for your project as well (or append to a list 178 # and include that list later, depending on your setup) 179 include_directories(${MYPROJ_EIGEN3_INCLUDE_DIR}) 180 181.. _Eigen: https://eigen.tuxfamily.org/dox/ 182 183NanoGUI, GLFW, and Other Projects 184**************************************************************************************** 185 186Suppose you want to use NanoGUI as your GUI toolkit, but you also have another library 187you want to use that depends on ``glfw``. Call the second library Foo. Generally 188speaking, it is unlikely that library Foo will provide you with mechanisms to explicitly 189specify where ``glfw`` comes from. You could try to work on a patch with the developers 190of library Foo to allow this to be overridden, but you may need to maintain your own 191fork of library Foo. There is just as much justification to allow the bypass as there 192is to not want it in a build system. 193 194Since NanoGUI merges the ``glfw`` objects into the library being built, you can actually 195just specify ``nanogui`` as the ``glfw`` dependency directly. So lets suppose that 196library Foo was looking for ``glfw`` like this: 197 198.. code-block:: cmake 199 200 find_package(GLFW3) 201 if(GLFW3_FOUND) 202 include_directories(${GLFW3_INCLUDE_DIRS}) 203 target_link_libraries(foo ${GLFW3_LIBRARIES}) 204 endif() 205 206You can cheat around this pretty easily. For the modification to library Foo's build 207system, all we do is wrap ``find_package``: 208 209.. code-block:: diff 210 211 + if(NOT GLFW3_FOUND) 212 find_package(GLFW3) 213 + endif() 214 if(GLFW3_FOUND) 215 include_directories(${GLFW3_INCLUDE_DIRS}) 216 target_link_libraries(foo ${GLFW3_LIBRARIES}) 217 endif() 218 219Now that ``find_package`` will only execute if ``NOT GLFW3_FOUND``, in your build system 220you make sure to set all three ``glfw`` variables (found, include, and libraries). It 221might look something like this: 222 223.. code-block:: cmake 224 225 # ... any other nanogui configs ... 226 # same directory structure as Eigen example 227 add_subdirectory(ext/nanogui) 228 229 # nanogui needs to be added first so the 'nanogui' target is defined 230 # and can be used in the generator expression for the libraries 231 set(GLFW3_FOUND ON) 232 set(GLFW3_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/nanogui/ext/glfw/include) 233 set(GLFW3_LIBRARIES $<TARGET_FILE:nanogui>) 234 235 add_subdirectory(ext/foo) 236 237 # IMPORTANT! You need to force NanoGUI to build first 238 # Assuming their library target is called 'foo' 239 add_dependencies(foo nanogui) 240 241 242Depending on what you need to do, the above may not be sufficient. But it is at least 243a starting point to being able to "share" NanoGUI as the vendor of ``glfw``. 244 245.. _nanogui_including_custom_fonts: 246 247Including Custom Fonts 248**************************************************************************************** 249 250NanoGUI uses the Roboto_ font for text, and Entypo_ font for icons. If you wish to add 251your own custom font, all you need is a True Type file (a ``.ttf`` extension). NanoGUI 252will glob all fonts found in ``resources`` by expanding ``resources/*.ttf``. So if you 253had the directory structure 254 255.. code-block:: none 256 257 myproject/ 258 CMakeLists.txt <- where this code is 259 fonts/ 260 superfont.ttf 261 ext/ 262 nanogui/ 263 resources/ 264 265You simply need to copy the ``superfont.ttf`` to NanoGUI's resources directory: 266 267.. code-block:: cmake 268 269 file( 270 COPY ${CMAKE_CURRENT_SOURCE_DIR}/fonts/superfont.ttf 271 DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/ext/nanogui/resources/superfont.ttf 272 ) 273 274When you build the code, there should be a file ``nanogui_resources.h`` generated. If 275everything worked, your new font should have been included. 276 277.. note:: 278 279 Since NanoGUI can support images as icons, you will want to make sure that the 280 *codepoint* for any *icon* fonts you create is greater than ``1024``. See 281 :func:`nanogui::nvgIsImageIcon`. 282 283.. tip:: 284 285 Some widgets allow you to set fonts directly, but if you want to apply the font 286 globally, you should create a sub-class of :class:`nanogui::Theme` and explicitly 287 call :func:`nanogui::Widget::setTheme` for each widget you create. 288 289.. _Roboto: https://fonts.google.com/specimen/Roboto 290 291.. _Entypo: http://www.entypo.com 292 293.. _utf8: http://www.utf8-chartable.de/ 294 295.. _nanogui_compiling_the_docs: 296 297Compiling the Documentation 298---------------------------------------------------------------------------------------- 299 300The documentation system relies on 'Doxygen', 'Sphinx', 'Breathe', and 301'Exhale'. It uses the 'Read the Docs' theme for the layout of the generated 302html. So you will need to first 303 3041. Install Doxygen for your operating system. On Unix based systems, this 305 should be available through your package manager (apt-get, brew, dnf, etc). 306 3072. Install Sphinx, Breathe, Exhale, and the theme: 308 309 .. code-block:: py 310 311 pip3 install -r <path/to/nanogui>/docs/requirements.txt 312 313Now that you have the relevant tools, you can build the documentation with 314 315.. code-block:: bash 316 317 # Enter the documentation directory 318 $ cd <path/to/nanogui>/docs 319 320 # Build the documentation 321 $ make html 322 323The output will be generated in ``_build``, the root html document is located 324at ``_build/html/index.html``. 325 326.. note:: 327 328 When building the documentation locally, there can be subtle differences in 329 the rendered pages than what is hosted online. You should largely be able 330 to ignore this. 331