1/*
2 src/example3.cpp -- C++ version of an example application that shows
3 how to use nanogui in an application with an already created and managed
4 glfw context.
5
6 NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>.
7 The widget drawing code is based on the NanoVG demo application
8 by Mikko Mononen.
9
10 All rights reserved. Use of this source code is governed by a
11 BSD-style license that can be found in the LICENSE.txt file.
12*/
13
14// GLFW
15//
16#if defined(NANOGUI_GLAD)
17 #if defined(NANOGUI_SHARED) && !defined(GLAD_GLAPI_EXPORT)
18 #define GLAD_GLAPI_EXPORT
19 #endif
20
21 #include <glad/glad.h>
22#else
23 #if defined(__APPLE__)
24 #define GLFW_INCLUDE_GLCOREARB
25 #else
26 #define GL_GLEXT_PROTOTYPES
27 #endif
28#endif
29
30#include <GLFW/glfw3.h>
31
32#include <nanogui/nanogui.h>
33#include <iostream>
34
35using namespace nanogui;
36
37enum test_enum {
38 Item1 = 0,
39 Item2,
40 Item3
41};
42
43bool bvar = true;
44int ivar = 12345678;
45double dvar = 3.1415926;
46float fvar = (float)dvar;
47std::string strval = "A string";
48test_enum enumval = Item2;
49Color colval(0.5f, 0.5f, 0.7f, 1.f);
50
51Screen *screen = nullptr;
52
53int main(int /* argc */, char ** /* argv */) {
54
55 glfwInit();
56
57 glfwSetTime(0);
58
59 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
60 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
61 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
62 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
63
64 glfwWindowHint(GLFW_SAMPLES, 0);
65 glfwWindowHint(GLFW_RED_BITS, 8);
66 glfwWindowHint(GLFW_GREEN_BITS, 8);
67 glfwWindowHint(GLFW_BLUE_BITS, 8);
68 glfwWindowHint(GLFW_ALPHA_BITS, 8);
69 glfwWindowHint(GLFW_STENCIL_BITS, 8);
70 glfwWindowHint(GLFW_DEPTH_BITS, 24);
71 glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
72
73 // Create a GLFWwindow object
74 GLFWwindow* window = glfwCreateWindow(800, 800, "example3", nullptr, nullptr);
75 if (window == nullptr) {
76 std::cout << "Failed to create GLFW window" << std::endl;
77 glfwTerminate();
78 return -1;
79 }
80 glfwMakeContextCurrent(window);
81
82#if defined(NANOGUI_GLAD)
83 if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
84 throw std::runtime_error("Could not initialize GLAD!");
85 glGetError(); // pull and ignore unhandled errors like GL_INVALID_ENUM
86#endif
87
88 glClearColor(0.2f, 0.25f, 0.3f, 1.0f);
89 glClear(GL_COLOR_BUFFER_BIT);
90
91 // Create a nanogui screen and pass the glfw pointer to initialize
92 screen = new Screen();
93 screen->initialize(window, true);
94
95 int width, height;
96 glfwGetFramebufferSize(window, &width, &height);
97 glViewport(0, 0, width, height);
98 glfwSwapInterval(0);
99 glfwSwapBuffers(window);
100
101 // Create nanogui gui
102 bool enabled = true;
103 FormHelper *gui = new FormHelper(screen);
104 ref<Window> nanoguiWindow = gui->addWindow(Eigen::Vector2i(10, 10), "Form helper example");
105 gui->addGroup("Basic types");
106 gui->addVariable("bool", bvar)->setTooltip("Test tooltip.");
107 gui->addVariable("string", strval);
108
109 gui->addGroup("Validating fields");
110 gui->addVariable("int", ivar)->setSpinnable(true);
111 gui->addVariable("float", fvar)->setTooltip("Test.");
112 gui->addVariable("double", dvar)->setSpinnable(true);
113
114 gui->addGroup("Complex types");
115 gui->addVariable("Enumeration", enumval, enabled)->setItems({ "Item 1", "Item 2", "Item 3" });
116 gui->addVariable("Color", colval)
117 ->setFinalCallback([](const Color &c) {
118 std::cout << "ColorPicker Final Callback: ["
119 << c.r() << ", "
120 << c.g() << ", "
121 << c.b() << ", "
122 << c.w() << "]" << std::endl;
123 });
124
125 gui->addGroup("Other widgets");
126 gui->addButton("A button", []() { std::cout << "Button pressed." << std::endl; })->setTooltip("Testing a much longer tooltip, that will wrap around to new lines multiple times.");;
127
128 screen->setVisible(true);
129 screen->performLayout();
130 nanoguiWindow->center();
131
132 glfwSetCursorPosCallback(window,
133 [](GLFWwindow *, double x, double y) {
134 screen->cursorPosCallbackEvent(x, y);
135 }
136 );
137
138 glfwSetMouseButtonCallback(window,
139 [](GLFWwindow *, int button, int action, int modifiers) {
140 screen->mouseButtonCallbackEvent(button, action, modifiers);
141 }
142 );
143
144 glfwSetKeyCallback(window,
145 [](GLFWwindow *, int key, int scancode, int action, int mods) {
146 screen->keyCallbackEvent(key, scancode, action, mods);
147 }
148 );
149
150 glfwSetCharCallback(window,
151 [](GLFWwindow *, unsigned int codepoint) {
152 screen->charCallbackEvent(codepoint);
153 }
154 );
155
156 glfwSetDropCallback(window,
157 [](GLFWwindow *, int count, const char **filenames) {
158 screen->dropCallbackEvent(count, filenames);
159 }
160 );
161
162 glfwSetScrollCallback(window,
163 [](GLFWwindow *, double x, double y) {
164 screen->scrollCallbackEvent(x, y);
165 }
166 );
167
168 glfwSetFramebufferSizeCallback(window,
169 [](GLFWwindow *, int width, int height) {
170 screen->resizeCallbackEvent(width, height);
171 }
172 );
173
174 // Game loop
175 while (!glfwWindowShouldClose(window)) {
176 // Check if any events have been activated (key pressed, mouse moved etc.) and call corresponding response functions
177 glfwPollEvents();
178
179 glClearColor(0.2f, 0.25f, 0.3f, 1.0f);
180 glClear(GL_COLOR_BUFFER_BIT);
181
182 // Draw nanogui
183 screen->drawContents();
184 screen->drawWidgets();
185
186 glfwSwapBuffers(window);
187 }
188
189 // Terminate GLFW, clearing any resources allocated by GLFW.
190 glfwTerminate();
191
192 return 0;
193}
194