上节: 使用GLFW构建一个窗口
软件 Nuklear 版本: 4.10.5
git clone git@github.com:Immediate-Mode-UI/Nuklear.git
复制
nuklear.h
demo
-glfw_opengl4
-nuklear_glfw_gl4.h
到项目nuklear
-include
中
CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(nuklear)
add_library(nuklear INTERFACE)
target_include_directories(nuklear INTERFACE include)
目录结构
nuklear
│ CMakeLists.txt
└─include
nuklear.h
nuklear_glfw_gl4.h
添加依赖
diff --git a/testWnd/CMakeLists.txt b/testWnd/CMakeLists.txt
index b186812..12f94b3 100644
--- a/testWnd/CMakeLists.txt
+++ b/testWnd/CMakeLists.txt
@@ -18,6 +18,7 @@ endif()
add_subdirectory(glfw EXCLUDE_FROM_ALL)
add_subdirectory(glad EXCLUDE_FROM_ALL)
+add_subdirectory(nuklear EXCLUDE_FROM_ALL)
# ##############################################################################
# Targets
@@ -25,7 +26,7 @@ add_subdirectory(glad EXCLUDE_FROM_ALL)
add_executable(testWnd src/main.cpp)
target_include_directories(testWnd PRIVATE include)
-target_link_libraries(testWnd PRIVATE glfw glad)
+target_link_libraries(testWnd PRIVATE glfw glad nuklear)
Extensions
[main] Building folder: testWnd testWnd
[build] Starting build
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build e:/Codes/IngameIME_Win32/IngameIME-Common/testWnd/build --config Debug --target testWnd -j 14 --
[build] MSBuild version 17.4.1+9a89d02ff for .NET Framework
[build] glad.c
[build] glfw.vcxproj -> E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\build\glfw\src\Debug\glfw3.lib
[build] glad.vcxproj -> E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\build\glad\Debug\glad.lib
[build] main.cpp
[build] E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\nuklear\include\nuklear_glfw_gl4.h(286,24): error C3861: “glGetTextureHandleARB”: 找不到标识符 [E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\build\testWnd.vcxproj]
[build] E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\nuklear\include\nuklear_glfw_gl4.h(287,5): error C3861: “glMakeTextureHandleResidentARB”: 找不到标识符 [E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\build\testWnd.vcxproj]
[build] E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\nuklear\include\nuklear_glfw_gl4.h(300,5): error C3861: “glMakeTextureHandleNonResidentARB”: 找不到标识符 [E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\build\testWnd.vcxproj]
[build] E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\nuklear\include\nuklear_glfw_gl4.h(436,18): error C3861: “glIsTextureHandleResidentARB”: 找不到标识符 [E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\build\testWnd.vcxproj]
[build] E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\nuklear\include\nuklear_glfw_gl4.h(437,17): error C3861: “glMakeTextureHandleResidentARB”: 找不到标识符 [E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\build\testWnd.vcxproj]
[build] E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\nuklear\include\nuklear_glfw_gl4.h(439,13): error C3861: “glUniformHandleui64ARB”: 找不到标识符 [E:\Codes\IngameIME_Win32\IngameIME-Common\testWnd\build\testWnd.vcxproj]
[proc] The command: "C:\Program Files\CMake\bin\cmake.EXE" --build e:/Codes/IngameIME_Win32/IngameIME-Common/testWnd/build --config Debug --target testWnd -j 14 -- exited with code: 1
[build] Build finished with exit code 1
尝试编译, 遇到上面的错误, 搜索到这个结果 glGetTextureHandleARB not included?
解决方案: 生成 GLAD
时添加所有的 Extensions
diff --git a/testWnd/src/main.cpp b/testWnd/src/main.cpp
index ff96351..11a4a44 100644
--- a/testWnd/src/main.cpp
+++ b/testWnd/src/main.cpp
@@ -4,8 +4,24 @@
#include <glad/glad.h>
#include <GLFW/glfw3.h>
+#define NK_INCLUDE_FIXED_TYPES
+#define NK_INCLUDE_STANDARD_IO
+#define NK_INCLUDE_STANDARD_VARARGS
+#define NK_INCLUDE_DEFAULT_ALLOCATOR
+#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+#define NK_INCLUDE_FONT_BAKING
+#define NK_INCLUDE_DEFAULT_FONT
+#define NK_BUTTON_TRIGGER_ON_RELEASE
+#define NK_KEYSTATE_BASED_INPUT
+#define NK_IMPLEMENTATION
+#include <nuklear.h>
+#define NK_GLFW_GL4_IMPLEMENTATION
+#include <nuklear_glfw_gl4.h>
+
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
+struct nk_context* nk;
+
int main()
{
// GLFW Init Start
@@ -19,7 +35,7 @@ int main()
// GLFW Init End
// Create Window Start
- GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
+ GLFWwindow* window = glfwCreateWindow(800, 800, "testWnd", NULL, NULL);
if (!window)
{
std::cout << "Failed to create GLFW window" << std::endl;
@@ -39,17 +55,39 @@ int main()
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// GLAD Init End
+ // Nuklear Init Start
+ nk = nk_glfw3_init(window, NK_GLFW3_INSTALL_CALLBACKS, 512 * 1024, 128 * 1024);
+
+ // Load Font
+ struct nk_font_atlas* atlas;
+ nk_glfw3_font_stash_begin(&atlas);
+ nk_glfw3_font_stash_end();
+ // Nuklear Init End
+
// Event Loop
while (!glfwWindowShouldClose(window))
{
+ // Nuklear Window Start
+ nk_glfw3_new_frame();
+ if (nk_begin(nk,
+ "main",
+ nk_rect(800 / 2 - 300, 800 / 2 - 300, 600, 600),
+ NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE))
+ {
+ }
+ nk_end(nk);
+ // Nuklear Window End
+
// Background color
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
+ glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
+ nk_glfw3_render(NK_ANTI_ALIASING_ON);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
std::exit(EXIT_SUCCESS);
}
@@ -57,4 +95,5 @@ int main()
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
+ nk_window_set_position(nk, "main", nk_vec2(width / 2 - 300, height / 2 - 300));
}
实际效果
diff --git a/testWnd/src/main.cpp b/testWnd/src/main.cpp
index 11a4a44..29294b7 100644
--- a/testWnd/src/main.cpp
+++ b/testWnd/src/main.cpp
@@ -35,7 +35,9 @@ int main()
// GLFW Init End
// Create Window Start
- GLFWwindow* window = glfwCreateWindow(800, 800, "testWnd", NULL, NULL);
+ int wnd_w = 800, wnd_h = 800;
+
+ GLFWwindow* window = glfwCreateWindow(wnd_w, wnd_h, "testWnd", NULL, NULL);
if (!window)
{
std::cout << "Failed to create GLFW window" << std::endl;
@@ -44,7 +46,14 @@ int main()
std::exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
- // Create Window End
+
+ // Place the window at screen center
+ {
+ int x, y, sw, sh;
+ glfwGetMonitorWorkarea(glfwGetPrimaryMonitor(), &x, &y, &sw, &sh);
+ glfwSetWindowPos(window, x + sw / 2 - wnd_w / 2, y + sh / 2 - wnd_h / 2);
+ }
+ // Create Window End
diff --git a/testWnd/src/main.cpp b/testWnd/src/main.cpp
index 29294b7..84e3ef7 100644
--- a/testWnd/src/main.cpp
+++ b/testWnd/src/main.cpp
@@ -35,7 +35,7 @@ int main()
// GLFW Init End
// Create Window Start
- int wnd_w = 800, wnd_h = 800;
+ int wnd_w = 800, wnd_h = 800, wnd_x = 0, wnd_y = 0;
GLFWwindow* window = glfwCreateWindow(wnd_w, wnd_h, "testWnd", NULL, NULL);
if (!window)
@@ -85,6 +85,22 @@ int main()
nk_rect(wnd_w / 2 - main_w / 2, wnd_h / 2 - main_h / 2, main_w, main_h),
NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE))
{
+ nk_layout_row_dynamic(nk, 30, 1);
+ if (nk_button_label(nk, "Toggle Fullscreen"))
+ {
+ if (glfwGetWindowMonitor(window))
+ {
+ glfwSetWindowMonitor(window, NULL, wnd_x, wnd_y, wnd_w, wnd_h, 0);
+ }
+ else
+ {
+ GLFWmonitor* monitor = glfwGetPrimaryMonitor();
+ const GLFWvidmode* mode = glfwGetVideoMode(monitor);
+ glfwGetWindowPos(window, &wnd_x, &wnd_y);
+ glfwGetWindowSize(window, &wnd_w, &wnd_h);
+ glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
+ }
+ }
}
nk_end(nk);
// Nuklear Window End
支持CJK的字体: https://github.com/googlefonts/noto-cjk
--- a/testWnd/CMakeLists.txt
+++ b/testWnd/CMakeLists.txt
@@ -27,6 +27,9 @@ add_subdirectory(nuklear EXCLUDE_FROM_ALL)
add_executable(testWnd src/main.cpp)
target_include_directories(testWnd PRIVATE include)
target_link_libraries(testWnd PRIVATE glfw glad nuklear)
+add_custom_command(TARGET testWnd POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets $<TARGET_FILE_DIR:testWnd>/assets
+)
diff --git a/testWnd/src/main.cpp b/testWnd/src/main.cpp
index 84e3ef7..1f9a6b2 100644
--- a/testWnd/src/main.cpp
+++ b/testWnd/src/main.cpp
@@ -10,7 +10,6 @@
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
-#define NK_INCLUDE_DEFAULT_FONT
#define NK_BUTTON_TRIGGER_ON_RELEASE
#define NK_KEYSTATE_BASED_INPUT
#define NK_IMPLEMENTATION
@@ -22,6 +21,27 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height);
struct nk_context* nk;
+/**
+ * @brief Range of commonly used CJK charactors, if there still missing charactors,
+ * refer to http://www.unicode.org/charts/ and fix the table
+ */
+// clang-format off
+
+const nk_rune ranges[] = {
+ 0x0370, 0x03FF, // Greek
+ 0x0020, 0x007F, // Basic Latin(ASCII)
+ 0x3000, 0x303F, // CJK Symbols and Punctuation
+ 0xFF00, 0xFFEF, // Halfwidth and Fullwidth Forms
+ 0x4E00, 0x9FFF, // CJK Unified Ideographs (Han)
+ 0x1100, 0x11FF, // Hangul Jamo
+ 0xAC00, 0xD7AF, // Hangul Syllables
+ 0x3040, 0x309F, // Hiragana
+ 0x30A0, 0x30FF, // Katakana
+ 0
+};
+
+// clang-format on
+
int main()
{
// GLFW Init Start
@@ -68,9 +88,18 @@ int main()
nk = nk_glfw3_init(window, NK_GLFW3_INSTALL_CALLBACKS, 512 * 1024, 128 * 1024);
// Load Font
+ struct nk_font_config config = nk_font_config(0);
+ config.range = ranges;
+ /* align every character to pixel boundary (if true set oversample (1,1)) */
+ config.oversample_h = 1;
+ config.oversample_v = 1;
+ config.pixel_snap = true;
+
struct nk_font_atlas* atlas;
nk_glfw3_font_stash_begin(&atlas);
+ struct nk_font* font = nk_font_atlas_add_from_file(atlas, "assets/fonts/NotoSansCJKsc-VF.ttf", 20, &config);
nk_glfw3_font_stash_end();
+ nk_style_set_font(nk, &font->handle);
// Nuklear Init End
@@ -101,6 +134,15 @@ int main()
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
}
}
+
+ // TextEdit
+ static char buffer[256];
+ nk_layout_row_dynamic(nk, 30, 1);
+ nk_edit_string_zero_terminated(nk,
+ NK_EDIT_FIELD | NK_EDIT_SIG_ENTER | NK_EDIT_GOTO_END_ON_ACTIVATE,
+ buffer,
+ sizeof(buffer),
+ nk_filter_default);
}
nk_end(nk);
// Nuklear Window End
需要打上这个PR的Patch才能显示正确的中文字符
https://github.com/Immediate-Mode-UI/Nuklear/pull/531
需要打上这个PR才能从文本框中复制出中文字符