3
社区成员
发帖
与我相关
我的任务
分享打开PowerShell,进入vcpkg目录:
powershell
cd C:\Users\Candy.CHINAMI-6LP8UH3\vcpkg # 安装ImGui(带glfw和opengl3绑定) .\vcpkg install imgui[core,glfw-binding,opengl3-binding] --triplet x64-windows
powershell
.\vcpkg list | findstr imgui
应该看到类似:
text
imgui:x64-windows 1.90.5#1 Bloat-free Graphical User Interface... imgui[core]:x64-windows 1.90.5#1 Bloat-free Graphical User Interface... imgui[glfw-binding]:x64-windows 1.90.5#1 Make glfw-binding available for imgui imgui[opengl3-binding]:x64-windows 1.90.5#1 Make opengl3-binding available for imgui
在Visual Studio中打开您的项目
右键点击项目 -> 属性
配置选 "所有配置",平台选 "x64"
导航到:链接器 -> 输入 -> 附加依赖项
点击编辑,添加以下内容(每行一个):
text
glfw3.lib opengl32.lib
(您可能已经有这两个,检查一下即可)
vcpkg安装的ImGui可能依赖DLL文件。将以下DLL复制到您的可执行文件输出目录(通常是 x64\Debug\ 或 x64\Release\):
text
C:\Users\Candy.CHINAMI-6LP8UH3\vcpkg\installed\x64-windows\bin\glfw3.dll
如何找到输出目录:
在VS中,右键点击项目 -> 属性
配置属性 -> 常规 -> 输出目录 就是可执行文件生成的位置
将您提供的完整代码复制到现有的 main.cpp 中,覆盖原有内容。
您的代码会自动尝试加载系统字体,通常不需要额外操作。如果中文显示为方框:
从网上下载微软雅黑字体文件 msyh.ttc
将其复制到您的可执行文件输出目录(与exe同一文件夹)
点击 "本地Windows调试器" 运行程序。
text
#include <imgui.h> // 找不到 #include <imgui_impl_glfw.h> // 找不到
解决方案:
检查vcpkg的include目录是否已添加到项目:
项目属性 -> C/C++ -> 常规 -> 附加包含目录
确认包含:C:\Users\Candy.CHINAMI-6LP8UH3\vcpkg\installed\x64-windows\include
text
error LNK2019: 无法解析的外部符号 "void __cdecl ImGui::Text..."
解决方案:
确认链接器附加依赖项中有 glfw3.lib 和 opengl32.lib
如果还是报错,尝试添加 imgui.lib:
查看 C:\Users\Candy.CHINAMI-6LP8UH3\vcpkg\installed\x64-windows\lib 下是否有 imgui.lib
如果有,在链接器附加依赖项中添加 imgui.lib
text
程序无法启动,因为计算机中丢失 glfw3.dll
解决方案:
将 C:\Users\Candy.CHINAMI-6LP8UH3\vcpkg\installed\x64-windows\bin\glfw3.dll 复制到exe所在目录
解决方案:
检查控制台输出,看字体加载是否成功。如果失败,可以:
确认系统有中文字体(Windows一般都有)
或手动下载 msyh.ttc 放到exe目录
或在代码中指定其他字体路径
如果一切正常,运行后会看到:
深灰色背景的OpenGL窗口
一个彩色的三角形
左上角有ImGui窗口,可以调整三角形颜色
控制台输出OpenGL版本和字体加载信息
#include <iostream>
#include <vector>
#include <windows.h>
#include <fstream>
#include <string>
// 【关键】GLFW DLL 定义
#define GLFW_DLL
#include <GLFW/glfw3.h>
#include <glad/glad.h>
// ImGui 头文件
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
// --- 着色器源码 ---
const char* vertexShaderSource = R"(
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 ourColor;
void main() {
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
}
)";
const char* fragmentShaderSource = R"(
#version 330 core
in vec3 ourColor;
out vec4 FragColor;
void main() {
FragColor = vec4(ourColor, 1.0);
}
)";
// 全局变量:三角形的颜色
float triColorR = 1.0f;
float triColorG = 0.0f;
float triColorB = 0.0f;
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
// 辅助函数:检查文件是否存在
bool fileExists(const std::string& filename) {
std::ifstream f(filename.c_str());
return f.good();
}
int main() {
// 设置控制台输出编码为UTF-8
SetConsoleOutputCP(CP_UTF8);
// 1. 初始化 GLFW
if (!glfwInit()) {
std::cout << "Failed to initialize GLFW" << std::endl;
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL + ImGui Color Picker", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// 2. 初始化 GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// ==========================================
// 3. 初始化 ImGui(支持中文)
// ==========================================
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
std::cout << "尝试加载中文字体..." << std::endl;
// 获取当前可执行文件路径
char exePath[MAX_PATH];
GetModuleFileNameA(NULL, exePath, MAX_PATH);
std::string exeDir = std::string(exePath);
exeDir = exeDir.substr(0, exeDir.find_last_of("\\/"));
// 要尝试的字体路径列表
std::vector<std::string> fontPaths;
// 首先尝试系统字体目录(从输出看这个成功了)
fontPaths.push_back("C:\\Windows\\Fonts\\msyh.ttc");
fontPaths.push_back("C:\\Windows\\Fonts\\simhei.ttf");
fontPaths.push_back("C:\\Windows\\Fonts\\simkai.ttf");
// 然后尝试当前目录
fontPaths.push_back(exeDir + "\\msyh.ttc");
fontPaths.push_back(exeDir + "\\simhei.ttf");
ImFont* font = nullptr;
for (const auto& path : fontPaths) {
std::cout << "尝试字体: " << path << std::endl;
if (fileExists(path)) {
std::cout << "文件存在,尝试加载..." << std::endl;
// 【关键修复】先清除之前的字体配置
io.Fonts->Clear();
// 尝试加载字体
font = io.Fonts->AddFontFromFileTTF(
path.c_str(),
18.0f,
NULL,
io.Fonts->GetGlyphRangesChineseFull()
);
if (font) {
std::cout << "✓ 成功加载字体: " << path << std::endl;
// 【关键】加载字体后必须构建
io.Fonts->Build();
break;
}
else {
std::cout << "✗ 文件存在但加载失败" << std::endl;
}
}
else {
std::cout << "✗ 文件不存在" << std::endl;
}
}
if (font == NULL) {
std::cout << "⚠ 警告:所有字体加载失败,使用默认字体" << std::endl;
io.Fonts->AddFontDefault();
io.Fonts->Build();
}
// 设置 ImGui 样式
ImGui::StyleColorsDark();
// ==========================================
// 4. 初始化 ImGui 后端(在字体加载之后)
// ==========================================
std::cout << "初始化 ImGui 后端..." << std::endl;
// 必须先初始化后端,再使用 ImGui
if (!ImGui_ImplGlfw_InitForOpenGL(window, true)) {
std::cout << "Failed to initialize ImGui GLFW backend" << std::endl;
return -1;
}
if (!ImGui_ImplOpenGL3_Init("#version 330")) {
std::cout << "Failed to initialize ImGui OpenGL3 backend" << std::endl;
return -1;
}
std::cout << "ImGui 初始化完成!" << std::endl;
// ==========================================
// 5. 编译着色器
// ==========================================
std::cout << "编译着色器..." << std::endl;
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// 检查顶点着色器编译错误
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "顶点着色器编译失败:\n" << infoLog << std::endl;
return -1;
}
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "片段着色器编译失败:\n" << infoLog << std::endl;
return -1;
}
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "着色器程序链接失败:\n" << infoLog << std::endl;
return -1;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// ==========================================
// 6. 准备三角形数据
// ==========================================
std::cout << "准备顶点数据..." << std::endl;
float vertices[] = {
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
float inputR = 1.0f, inputG = 0.0f, inputB = 0.0f;
std::cout << "初始化完成,开始渲染循环..." << std::endl;
// ==========================================
// 7. 渲染循环
// ==========================================
while (!glfwWindowShouldClose(window)) {
processInput(window);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// --- 创建 UI 窗口(全部添加 u8 前缀)---
ImGui::Begin(u8"颜色控制器");
ImGui::Text(u8"调整三角形的颜色:");
ImGui::Separator();
ImVec4 color = ImVec4(triColorR, triColorG, triColorB, 1.0f);
if (ImGui::ColorEdit3(u8"选择颜色", (float*)&color)) {
triColorR = color.x;
triColorG = color.y;
triColorB = color.z;
inputR = triColorR;
inputG = triColorG;
inputB = triColorB;
}
ImGui::Separator();
ImGui::Text(u8"或者手动输入 (0.0 - 1.0):");
ImGui::InputFloat(u8"红色", &inputR, 0.1f, 1.0f, "%.2f");
ImGui::InputFloat(u8"绿色", &inputG, 0.1f, 1.0f, "%.2f");
ImGui::InputFloat(u8"蓝色", &inputB, 0.1f, 1.0f, "%.2f");
if (ImGui::Button(u8"应用输入框颜色")) {
triColorR = (inputR < 0) ? 0 : (inputR > 1 ? 1 : inputR);
triColorG = (inputG < 0) ? 0 : (inputG > 1 ? 1 : inputG);
triColorB = (inputB < 0) ? 0 : (inputB > 1 ? 1 : inputB);
}
ImGui::Separator();
ImGui::Text(u8"当前颜色:");
ImGui::ColorButton(u8"当前颜色", ImVec4(triColorR, triColorG, triColorB, 1.0f),
ImGuiColorEditFlags_NoTooltip, ImVec2(100, 20));
ImGui::End();
// 更新三角形颜色
float updatedVertices[] = {
0.0f, 0.5f, 0.0f, triColorR, triColorG, triColorB,
0.5f, -0.5f, 0.0f, triColorR, triColorG, triColorB,
-0.5f, -0.5f, 0.0f, triColorR, triColorG, triColorB
};
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(updatedVertices), updatedVertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// OpenGL 渲染
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// 渲染 ImGui
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
glfwPollEvents();
}
// 清理资源
std::cout << "清理资源..." << std::endl;
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
std::cout << "程序正常退出" << std::endl;
return 0;
}