39、C语言中的图形编程
大约 5 分钟C语言基础程序程序厨
C/C++语言中,如果要进行图形编程,都需要引入图形库。
图形库简介
图形库用于在屏幕上渲染图像,它通常提供一组经过优化的函数来执行渲染任务。
由于C/C++语言可以适配非常广泛的设备,甚至有些设备不通过屏幕进行输入输出,即使使用屏幕的设备,也有非常大的差异性,因此图形库并未包含在标准库中。
对于PC机而言,有很多种图形库可供选用,如Qt、GTK+、Windows GDI、SDL和OpenGL等。
- GTK+(GIMP Toolkit):一个开源的图形用户界面工具包,主要用于构建跨平台的应用程序,支持Linux、Windows和macOS等操作系统。GTK+提供了大量的UI组件,如按钮、文本框、复选框等,开发者使用GTK+能够快速搭建用户界面。
- SDL(Simple DirectMedia Layer):一个跨平台开发库,通过OpenGL和Direct3D提供对音频、键盘、鼠标、游戏杆和图形硬件的底层访问。SDL可用于视频、3D图形、2D渲染、事件处理、音频、文件I/O、共享对象支持、线程和计时器等多个方面。
- OpenGL:一个跨平台、跨语言的编程接口,用于渲染2D和3D矢量图形。OpenGL被广泛应用于计算机图形学领域,包括CAD、虚拟现实以及游戏开发。
SDL库的基本使用
SDL库的安装和配置过程因操作系统而异。以Visual Studio为例,需要下载SDL2库,并将其头文件和库文件添加到项目的包含目录和库目录中。之后,链接SDL2.lib和SDLmain2.lib,我更建议直接通过vcpkg安装和链接。
以下是一个使用SDL库创建简单窗口的示例代码:
#include <SDL.h>
// 屏幕尺寸常量
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main(int argc, char* argv[]) {
// 初始化SDL子系统
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
SDL_Log("can not init SDL:%s", SDL_GetError());
return -1;
}
// 创建窗口
SDL_Window* window = SDL_CreateWindow("SDL Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SDL_WINDOW_SHOWN);
if (window == NULL) {
SDL_Log("Could not create window: %s\n", SDL_GetError());
SDL_Quit();
return -1;
}
// 窗口渲染器
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
SDL_Log("Could not create renderer: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return -1;
}
// 清屏并显示窗口
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
// 等待5秒
SDL_Delay(5000);
// 销毁渲染器和窗口,退出SDL
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
OpenGL与3D图形编程
OpenGL想必每个开发者都听过,它是一个强大的图形API,支持2D和3D图形的渲染。与SDL类似,OpenGL也需要配置开发环境,包括安装OpenGL库、配置包含目录和库目录等。
OpenGL编程通常涉及以下几个步骤:
- 初始化OpenGL上下文:这通常是通过使用SDL、GLFW等库来完成的(Win中)。
- 编写着色器:着色器是OpenGL中的小程序,用于处理顶点数据和片段数据。
- 设置顶点数据:这包括定义顶点坐标、颜色、纹理坐标等。
- 渲染循环:在渲染循环中,清除屏幕、绘制对象并交换前后缓冲区。
以下是一个使用OpenGL和GLFW库创建简单窗口并绘制三角形的示例代码(仅展示关键部分):
// 初始化GLFW并创建窗口的代码(略)
// 创建着色器程序(略)
// 设置顶点数据和缓冲区(略)
// 渲染循环
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
// 绑定着色器程序并设置顶点属性指针(略)
// 绘制三角形
glDrawArrays(GL_TRIANGLES, 0, 3);
// 交换缓冲区并检查事件
glfwSwapBuffers(window);
glfwPollEvents();
}
// 清理资源并退出(略)
图形界面的设计与实现
图形界面的设计通常涉及窗口、控件、布局管理器、事件处理和样式与主题等多个方面。以GTK+为例,可以通过以下步骤创建一个简单的图形界面:
- 初始化GTK+库。
- 创建窗口并设置其属性(如大小、标题等)。
- 添加控件到窗口中,如按钮、文本框等。
- 编写回调函数处理用户事件,如点击按钮。
- 进入消息循环等待用户事件并调用相应的处理函数。
以下是一个使用GTK+库创建简单窗口并包含一个按钮的示例代码:
#include <gtk/gtk.h>
// 按钮点击回调函数
static void on_button_clicked(GtkWidget *widget, gpointer data) {
g_print("Button clicked!\n");
}
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;
// 初始化GTK+
gtk_init(&argc, &argv);
// 创建窗口
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Hello, GTK+!");
gtk_window_set_default_size(GTK_WINDOW(window), 250, 150);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// 创建按钮并添加到窗口中
button = gtk_button_new_with_label("Click Me");
g_signal_connect(button, "clicked", G_CALLBACK(on_button_clicked), NULL);
gtk_container_add(GTK_CONTAINER(window), button);
// 显示窗口和按钮
gtk_widget_show_all(window);
// 进入消息循环
gtk_main();
return 0;
}
扩展
- 图形库的选择:根据应用程序的需求和目标平台选择合适的图形库。例如,对于跨平台的应用程序,可以选择
GTK+
或SDL
;对于需要高性能3D
渲染的应用程序,可以选择OpenGL
或Vulkan
。 - 性能优化:在图形编程中,性能优化是一个重要方面。可以通过减少绘制调用、使用纹理映射、优化着色器代码等方式来提高性能。
本文内容简单了解下就行,不需要实践,大多数情况下我们进行窗口类的GUI编程直接使用QT即可,只要做图形编程时,才会用到GLFW
、OpenGL
、vulkan
等库,如果要用到,我们针对性学习即可。
