Window下C语言如何用OpenGL?

99ANYc3cd6
预计阅读时长 22 分钟
位置: 首页 C语言 正文

我会使用 GLFW 来创建窗口和上下文,并使用 GLAD 来加载 OpenGL 函数指针,这是目前最现代、最推荐的方式,因为它跨平台且避免了繁琐的手动配置。

window c语言 opengl
(图片来源网络,侵删)

第一步:理解核心概念

在开始编码前,你需要了解几个关键角色:

  1. C 语言: 我们的编程语言,负责逻辑控制。
  2. OpenGL (Open Graphics Library): 一个图形 API(应用程序编程接口),它本身不提供创建窗口的功能,它只负责在一个已经存在的窗口上进行绘图,你可以把它想象成一个画家,但需要你先给他一块画布(窗口)。
  3. GLFW (Graphics Library Framework): 一个专门用来创建窗口、管理输入(键盘、鼠标、手柄)的库,它为我们准备好了“画布”和“画架”。
  4. GLAD (OpenGL Loader-Generation library): OpenGL 的函数(如 glClearColor, glClear 等)在程序运行时才需要链接,不同版本的 OpenGL,函数的地址可能不同,GLAD 会根据你选择的 OpenGL 版本,自动加载所有正确的函数指针,让你可以轻松调用这些函数。

总结一下流程: C 程序 -> 使用 GLFW 创建一个窗口 -> GLAD 加载 OpenGL 函数 -> C 程序 通过加载的 OpenGL 函数在窗口上绘制图形。


第二步:环境准备(安装依赖)

你需要安装以下三个库的开发文件。

编译器

确保你有一个 C 语言编译器。

window c语言 opengl
(图片来源网络,侵删)
  • Windows: Visual Studio (推荐) 或 MinGW。
  • macOS: Xcode Command Line Tools (xcode-select --install)。
  • Linux (Debian/Ubuntu): sudo apt-get update && sudo apt-get install build-essential

GLFW

GLFW 用于创建窗口。

  • Windows (vcpkg 推荐):
    1. 安装 vcpkg
    2. 使用命令安装:vcpkg install glfw3
    3. 在你的 IDE(如 Visual Studio)中配置 vcpkg,它会自动帮你链接。
  • macOS (Homebrew 推荐):
    brew install glfw
  • Linux (Debian/Ubuntu):
    sudo apt-get install libglfw3-dev

GLAD

GLAD 用于加载 OpenGL 函数。 GLAD 通常是一个在线生成工具,你不需要安装它,只需要在 https://glad.dav1d.de/ 网站上生成你需要的文件。

如何生成 GLAD 文件:

  1. 打开 glad.dav1d.de。
  2. Language: 选择 C/C++
  3. API: 选择 OpenGL,版本选择 Core Profile,并指定一个版本,1
  4. Profile: 选择 Core
  5. Extensions: 保持默认的 "Generate a loader"。
  6. 点击 GENERATE 按钮。
  7. 下载生成的 ZIP 压缩包,并解压,你主要需要 include/gladsrc/glad.c 这两个文件/文件夹。

第三步:编写 C 代码

我们来编写一个完整的 C 程序,这个程序会创建一个窗口,并将窗口背景色设置为亮蓝色。

window c语言 opengl
(图片来源网络,侵删)

文件结构

为了清晰,我们创建如下文件:

my_opengl_project/
├── main.c
├── glad.c
└── glad.h

将你从 glad.dav1d.de 下载的 glad.cglad.h 放在这里。

main.c 代码详解

// main.c
// 1. 包含头文件
#include <glad/glad.h> // 必须在 GLFW 之前包含,因为 GLFW 会创建 OpenGL 上下文
#include <GLFW/glfw3.h>
#include <stdio.h>
// 2. 函数声明
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
// 3. 主函数
int main(void)
{
    // 初始化 GLFW
    if (!glfwInit())
    {
        fprintf(stderr, "Failed to initialize GLFW\n");
        return -1;
    }
    // 配置 GLFW
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // 主版本号
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // 次版本号
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 使用 Core Profile
    // 创建窗口对象
    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Window", NULL, NULL);
    if (window == NULL)
    {
        fprintf(stderr, "Failed to create GLFW window\n");
        glfwTerminate();
        return -1;
    }
    // 将窗口的上下文设置为当前线程的主上下文
    glfwMakeContextCurrent(window);
    // 初始化 GLAD,加载 OpenGL 函数指针
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        fprintf(stderr, "Failed to initialize GLAD\n");
        return -1;
    }
    // 设置视口大小,告诉 OpenGL 渲染窗口的尺寸
    glViewport(0, 0, 800, 600);
    // 注册窗口大小调整的回调函数
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    // 渲染循环
    while (!glfwWindowShouldClose(window))
    {
        // 处理输入(ESC 键退出)
        processInput(window);
        // 渲染指令
        // --- 开始绘制 ---
        // 1. 清除颜色缓冲区
        // 设置清空屏幕所用的颜色 (R, G, B, A)
        glClearColor(0.2f, 0.3f, 0.8f, 1.0f); // 亮蓝色
        // 执行清除
        glClear(GL_COLOR_BUFFER_BIT);
        // --- 结束绘制 ---
        // 检查并调用事件(键盘输入、鼠标移动等)
        glfwPollEvents();
        // 交换缓冲区
        glfwSwapBuffers(window);
    }
    // 当渲染循环结束后,正确释放/删除之前的所有资源
    glfwTerminate();
    return 0;
}
// 处理键盘输入的函数
void processInput(GLFWwindow *window)
{
    // 当用户按下 ESC 键时,将 windowShouldClose 设置为 true,然后渲染循环就会关闭
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}
// 当窗口大小被调整时,视口也应该被调整
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // 确保视口和窗口的像素尺寸相匹配
    glViewport(0, 0, width, height);
}

代码关键点解释

  1. 头文件包含顺序: #include <glad/glad.h> 必须在 #include <GLFW/glfw3.h> 之前,因为 GLFW 创建了 OpenGL 上下文,而 GLAD 需要这个上下文来找到正确的函数地址。
  2. glfwInit(): 初始化 GLFW 库。
  3. glfwWindowHint(): 配置 GLFW,这里我们指定了 OpenGL 的版本为 3.3,并使用 Core Profile,Core Profile 移除了一些老旧的、已被废弃的功能,是现代 OpenGL 的标准。
  4. glfwCreateWindow(): 创建一个窗口对象,参数分别是宽度、高度、窗口标题等。
  5. glfwMakeContextCurrent(): 将我们创建的窗口设置为当前线程的上下文,之后所有的 OpenGL 调用都将作用于这个窗口。
  6. gladLoadGLLoader(): 这是 GLAD 的核心功能,它告诉 GLAD 使用 glfwGetProcAddress 函数来获取 OpenGL 函数的地址。
  7. glViewport(): 设置 OpenGL 视口的大小和位置,它将窗口的像素坐标映射到 OpenGL 的坐标系统,这个非常重要,否则你的图像可能会被拉伸或显示不全。
  8. glfwSetFramebufferSizeCallback(): 注册一个回调函数,当用户调整窗口大小时,这个函数会被自动调用,我们可以在里面更新 glViewport
  9. 渲染循环 (while !glfwWindowShouldClose): 这是所有图形程序的核心,它不断地进行渲染、处理输入、交换缓冲,直到窗口被关闭。
  10. glClearColor() & glClear(): glClearColor 设置了“清空画笔”的颜色。glClear(GL_COLOR_BUFFER_BIT) 则执行了清空操作,把整个窗口用 glClearColor 设置的颜色填充。
  11. glfwPollEvents(): 检查是否有任何事件触发(键盘输入、鼠标移动等)。
  12. glfwSwapBuffers(): 交换颜色缓冲区,因为绘图是双缓冲的,你在后台缓冲区绘制,绘制完成后,将其“交换”到前台显示,这样可以避免画面闪烁。
  13. glfwTerminate(): 程序结束时,释放所有 GLFW 分配的资源。

第四步:编译与运行

你需要编译并运行这个程序,根据你的操作系统,使用以下命令。

编译命令

你需要链接 glfw3m (数学库)。

Linux (GCC/G++):

# 编译
gcc main.c glad.c -o my_app -lglfw -lGL -lm
# 运行
./my_app

macOS (Clang):

# 编译
clang main.c glad.c -o my_app -lglfw -framework OpenGL
# 运行
./my_app

Windows (使用 vcpkg 和 Visual Studio 命令行工具) 如果你用 vcpkg 安装了 GLFW,并且已经配置好了环境变量,编译会非常简单。

# 在 x64 Native Tools Command Prompt 中打开
# 编译
cl main.c glad.c /I "path\to\vcpkg\installed\x64-windows\include" /link /LIBPATH:"path\to\vcpkg\installed\x64-windows\lib" glfw3.lib opengl32.lib gdi32.lib
# 运行
my_app.exe

注意: 将 path\to\vcpkg 替换为你 vcpkg 的实际安装路径。

如果一切顺利,你应该会看到一个 800x600 大小的窗口,背景是亮蓝色,并且按 ESC 键可以关闭它。

总结与下一步

恭喜!你已经成功使用 C 语言、GLFW 和 GLAD 创建了你的第一个 OpenGL 窗口。

接下来的学习方向:

  1. 绘制三角形: 了解了如何清空屏幕后,下一步就是学习如何定义顶点数据,并使用 着色器 将它们绘制成图形。
  2. 学习着色器: 着色器是运行在 GPU 上的小程序,用于处理顶点数据和像素颜色,这是现代 OpenGL 的核心。
  3. 使用更现代的库: 对于更复杂的程序,通常会使用 GLM (OpenGL Mathematics) 库来处理矩阵和向量运算,以及 ImGuiDear ImGui 来创建用户界面。

这个例子为你打下了坚实的基础,是学习 OpenGL 图形编程的第一步。

-- 展开阅读全文 --
头像
C语言中sizeof struct内存对齐如何计算?
« 上一篇 昨天
织梦CMS如何添加图片和Flash?
下一篇 » 昨天

相关文章

取消
微信二维码
支付宝二维码

目录[+]