找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 494|回复: 14

C语言SDL2

[复制链接]
发表于 2025-12-14 12:39:01 | 显示全部楼层 |阅读模式
linxu mint22.2 C语言SDL2的学习
 楼主| 发表于 2025-12-14 12:39:19 | 显示全部楼层
本帖最后由 zzz19760225 于 2026-1-7 10:19 编辑

1234567890

  1. 开关
  2. SDL_Init(Uint32 flags)        初始化 SDL 子系统(如 SDL_INIT_VIDEO、SDL_INIT_AUDIO)
  3. SDL_Quit()        退出 SDL,释放所有资源



  4. SDL 的“命令”其实就是它的 C API 函数调用。核心流程通常是:

  5.     SDL_Init()
  6.     SDL_CreateWindow()
  7.     SDL_CreateRenderer()
  8.     渲染循环:
  9.     - 处理事件(SDL_PollEvent)
  10.     - 清屏(SDL_RenderClear)
  11.     - 绘图(SDL_RenderFillRect 等)
  12.     - 显示(SDL_RenderPresent)
  13.     清理资源 + SDL_Quit()


  14. 1. 初始化与退出
  15. 函数        作用
  16. SDL_Init(Uint32 flags)        初始化 SDL 子系统(如 SDL_INIT_VIDEO、SDL_INIT_AUDIO)
  17. SDL_Quit()        退出 SDL,释放所有资源

  18. 2. 窗口管理
  19. 函数        作用
  20. SDL_CreateWindow(const char* title, int x, int y, int w, int h, Uint32 flags)        创建窗口
  21. SDL_DestroyWindow(SDL_Window* window)        销毁窗口
  22. SDL_SetWindowTitle(SDL_Window* window, const char* title)        动态修改窗口标题

  23. 3. 渲染器(Renderer)
  24. 函数        作用
  25. SDL_CreateRenderer(SDL_Window* window, int index, Uint32 flags)        创建渲染器
  26. SDL_DestroyRenderer(SDL_Renderer* renderer)        销毁渲染器
  27. SDL_SetRenderDrawColor(SDL_Renderer* r, Uint8 r, Uint8 g, Uint8 b, Uint8 a)        设置绘图颜色(RGBA)
  28. SDL_RenderClear(SDL_Renderer* renderer)        用当前颜色清屏
  29. SDL_RenderPresent(SDL_Renderer* renderer)        将后台缓冲区内容显示到窗口(双缓冲交换)

  30. 4. 绘制基本图形(使用 Renderer)
  31. 函数        作用
  32. SDL_RenderFillRect(SDL_Renderer* r, const SDL_Rect* rect)        填充矩形
  33. SDL_RenderDrawRect(SDL_Renderer* r, const SDL_Rect* rect)        绘制矩形边框
  34. SDL_RenderDrawLine(SDL_Renderer* r, int x1, int y1, int x2, int y2)        画线
  35. SDL_RenderDrawPoint(SDL_Renderer* r, int x, int y)        画点

  36. 5. 事件处理
  37. 函数        作用
  38. SDL_PollEvent(SDL_Event* event)        轮询事件(非阻塞)
  39. SDL_WaitEvent(SDL_Event* event)        等待事件(阻塞)
  40. SDL_GetMouseState(int* x, int* y)        获取鼠标位置
  41. SDL_GetKeyboardState(int* numkeys)        获取键盘状态

  42. 6. 图像与纹理(需配合 SDL_image)

  43.     需额外链接 -lSDL2_image

  44. 函数        作用
  45. IMG_Load(const char* file)        加载图片为 SDL_Surface
  46. SDL_CreateTextureFromSurface(SDL_Renderer*, SDL_Surface*)        将 Surface 转为 Texture
  47. SDL_RenderCopy(renderer, texture, NULL, &dstRect)        渲染纹理到屏幕
  48. SDL_DestroyTexture(texture)        销毁纹理

  49. 7. 文字渲染(需 SDL_ttf)

  50.     需初始化:TTF_Init(),链接 -lSDL2_ttf

  51. 函数        作用
  52. TTF_OpenFont("font.ttf", size)        加载字体
  53. TTF_RenderText_Solid(font, "文本", color)        渲染文字为 Surface
  54. (后续同图像处理)转 Texture 并 RenderCopy       

  55. 8. 延时与时间
  56. 函数        作用
  57. SDL_Delay(Uint32 ms)        暂停程序若干毫秒
  58. Uint32 start = SDL_GetTicks();        获取启动以来的毫秒数(用于计时、帧率控制)
复制代码
 楼主| 发表于 2025-12-14 12:39:30 | 显示全部楼层
本帖最后由 zzz19760225 于 2025-12-14 13:48 编辑

1234567890
需求:一个按钮切换页面,页面内集合容器内容,随着按钮切换而变。就是Five和HOPE帖子里的内容,重新过一遍。
通义:C语言SDL2 linux mint22.2 绘制一个页面显示页面1,上面有一个按钮,点击按钮,页面上显示页面2。
勇士大闯关第1节C语言SDL2.c

  1. // 引入 SDL2 图形库的主头文件,用于窗口、渲染、事件等操作
  2. #include <SDL2/SDL.h>

  3. // 引入标准输入输出库,用于向终端打印错误信息
  4. #include <stdio.h>

  5. // 定义屏幕宽度常量,值为 800 像素
  6. #define 屏幕宽数 800

  7. // 定义屏幕高度常量,值为 600 像素
  8. #define 屏幕高数 600

  9. // 定义一个枚举类型 Page,用于表示当前程序所处的页面状态
  10. typedef enum {
  11.     序1,  // 枚举值 0:代表第一页(起始页面)
  12.     序2   // 枚举值 1:代表第二页(切换后的页面)
  13. } 排序;   // 给该枚举类型起一个别名:Page

  14. // 函数:负责绘制第一页的内容(白色背景 + 绿色按钮)
  15. void 页面1(SDL_Renderer* 渲染器) {
  16.     // 设置绘图颜色为白色(RGBA: 255,255,255,255)
  17.     SDL_SetRenderDrawColor(渲染器, 255, 255, 255, 255);
  18.     // 使用当前颜色清空整个渲染目标(即绘制白色背景)
  19.     SDL_RenderClear(渲染器);
  20.    
  21.     // 设置绘图颜色为绿色(用于绘制按钮)
  22.     SDL_SetRenderDrawColor(渲染器, 0, 255, 0, 255);
  23.    
  24.     // 定义一个矩形结构体,作为“按钮”的位置和尺寸:
  25.     // x = 屏幕中心横坐标 - 按钮宽的一半(实现水平居中)
  26.     // y = 屏幕中心纵坐标 - 按钮高的一半(实现垂直居中)
  27.     // 宽度 = 100 像素,高度 = 50 像素
  28.     SDL_Rect 按钮变量 = { 屏幕宽数 / 2 - 50, 屏幕高数 / 2 - 25, 100, 50 };
  29.    
  30.     // 填充绘制这个绿色矩形(模拟一个可点击的按钮)
  31.     SDL_RenderFillRect(渲染器, &按钮变量);
  32. }

  33. // 函数:负责绘制第二页的内容(纯蓝色背景)
  34. void 页面2(SDL_Renderer* 渲染器) {
  35.     // 设置绘图颜色为蓝色(RGBA: 0,0,255,255)
  36.     SDL_SetRenderDrawColor(渲染器, 0, 0, 255, 255);
  37.     // 使用当前颜色清空整个屏幕(即绘制蓝色背景)
  38.     SDL_RenderClear(渲染器);
  39. }

  40. // 主函数:程序的入口点
  41. int main(int argc, char* argv[]) {
  42.     // 初始化 SDL 的视频子系统(用于创建窗口和图形渲染)
  43.     if (SDL_Init(SDL_INIT_VIDEO) != 0) {
  44.         // 如果初始化失败,打印错误信息到标准错误流并返回错误码 1
  45.         fprintf(stderr, "无法初始化SDL: %s\n", SDL_GetError());
  46.         return 1;
  47.     }

  48.     // 创建一个窗口:
  49.     // 标题为“页面切换示例”,
  50.     // 初始位置 (100, 100),
  51.     // 宽度 = 屏幕宽数,高度 = 屏幕高数,
  52.     // 标志为 0(普通窗口,无特殊属性)
  53.     SDL_Window* 窗口1 = SDL_CreateWindow("页面切换示例", 100, 100, 屏幕宽数, 屏幕高数, 0);
  54.    
  55.     // 如果窗口创建失败,打印错误信息,退出 SDL 并返回错误码 1
  56.     if (!窗口1) {
  57.         fprintf(stderr, "无法创建窗口: %s\n", SDL_GetError());
  58.         SDL_Quit();
  59.         return 1;
  60.     }

  61.     // 为窗口创建一个硬件加速的渲染器,并启用垂直同步(防止画面撕裂)
  62.     SDL_Renderer* 渲染器 = SDL_CreateRenderer(
  63.         窗口1,                              // 关联的窗口指针
  64.         -1,                                 // 使用默认的渲染驱动(-1 表示自动选择)
  65.         SDL_RENDERER_ACCELERATED |          // 启用 GPU 硬件加速
  66.         SDL_RENDERER_PRESENTVSYNC           // 启用垂直同步(匹配显示器刷新率)
  67.     );
  68.    
  69.     // 如果渲染器创建失败,打印错误信息,销毁窗口,退出 SDL,返回错误码 1
  70.     if (!渲染器) {
  71.         fprintf(stderr, "无法创建渲染器: %s\n", SDL_GetError());
  72.         SDL_DestroyWindow(窗口1);  // 释放窗口资源
  73.         SDL_Quit();                // 退出 SDL 子系统
  74.         return 1;
  75.     }

  76.     // 定义一个整型标志变量,用于控制主循环是否继续运行(0 表示继续,1 表示退出)
  77.     int 退出信号 = 0;

  78.     // 定义当前页面状态变量,初始值为第一页(序1)
  79.     排序 当下页面 = 序1;

  80.     // 声明一个 SDL 事件变量,用于接收和处理各种用户输入或系统事件
  81.     SDL_Event 检测变量;

  82.     // 主应用循环:只要“退出信号”为 0,就持续运行
  83.     while (!退出信号) {
  84.         // 轮询事件队列,处理所有待处理的事件
  85.         while (SDL_PollEvent(&检测变量)) {
  86.             // 如果检测到用户点击了窗口右上角的关闭按钮(SDL_QUIT 事件)
  87.             if (检测变量.type == SDL_QUIT) {
  88.                 退出信号 = 1;  // 设置退出标志,使主循环结束
  89.             }
  90.             // 如果检测到鼠标按键按下事件
  91.             else if (检测变量.type == SDL_MOUSEBUTTONDOWN) {
  92.                 int 横, 纵;  // 声明两个整数变量,用于存储鼠标坐标
  93.                 // 获取鼠标在窗口内的当前位置(横 = x, 纵 = y)
  94.                 SDL_GetMouseState(&横, &纵);
  95.                
  96.                 // 判断:当前是否处于第一页?并且鼠标点击位置是否落在按钮区域内?
  97.                 if (当下页面 == 序1 &&
  98.                     横 >= 屏幕宽数 / 2 - 50 &&  // 鼠标横坐标 ≥ 按钮左边界
  99.                     横 <= 屏幕宽数 / 2 + 50 &&  // 鼠标横坐标 ≤ 按钮右边界
  100.                     纵 >= 屏幕高数 / 2 - 25 &&  // 鼠标纵坐标 ≥ 按钮上边界
  101.                     纵 <= 屏幕高数 / 2 + 25) {  // 鼠标纵坐标 ≤ 按钮下边界
  102.                     
  103.                     // 如果满足上述条件,则切换到第二页
  104.                     当下页面 = 序2;
  105.                 }
  106.             }
  107.         }

  108.         // 根据当前页面状态,调用对应的页面渲染函数
  109.         if (当下页面 == 序1) {
  110.             页面1(渲染器);  // 渲染第一页(含绿色按钮)
  111.         } else if (当下页面 == 序2) {
  112.             页面2(渲染器);  // 渲染第二页(纯蓝色背景)
  113.         }

  114.         // 将后台渲染缓冲区的内容提交(翻转)到屏幕上显示(双缓冲机制)
  115.         SDL_RenderPresent(渲染器);
  116.     }

  117.     // 程序即将结束,释放所有占用的系统资源
  118.     SDL_DestroyRenderer(渲染器);  // 销毁渲染器对象
  119.     SDL_DestroyWindow(窗口1);     // 销毁窗口对象
  120.     SDL_Quit();                   // 退出 SDL 所有子系统

  121.     // 返回 0,表示程序正常退出
  122.     return 0;
  123. }
复制代码
出现一个空白页面,有一个绿色长条,按钮点击绿色,就会切换到一个蓝色的页面。
自从使用了中文变量,眼睛就好使多了。
 楼主| 发表于 2025-12-14 12:39:46 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:40:03 | 显示全部楼层

nasm+SDL2

本帖最后由 zzz19760225 于 2026-1-7 11:04 编辑

1234567890

  1. extern SDL_Init               ; 初始化SDL
  2. extern SDL_Quit               ; 退出SDL

  3. extern SDL_CreateWindow       ; 创建窗口
  4. extern SDL_DestroyWindow      ; 销毁窗口

  5. extern SDL_CreateRenderer     ; 创建渲染器
  6. extern SDL_DestroyRenderer    ; 销毁渲染器

  7. extern SDL_SetRenderDrawColor ; 设置绘图颜色

  8. extern SDL_RenderClear        ; 清除渲染目标

  9. extern SDL_RenderDrawPoints   ; 绘制点

  10. extern SDL_RenderPresent      ; 显示绘制内容

  11. extern SDL_Delay              ; 延迟若干毫秒

  12. section .data               ;section .data:初始化数据段,用于存放程序中已初始化的全局变量和常量字符串。
  13.     ; 定义一个以空字符(0)结尾的字符串,用作 SDL 窗口的标题
  14.     ; "两个大点 - SDL2" 是窗口显示的标题文本
  15.     ; 末尾的 0 是 C 风格字符串必需的终止符(null terminator)
  16.     window_title db "两个大点 - SDL2", 0                          ;db:定义字节(define byte),此处用于存储 UTF-8 编码的字符串(每个汉字通常占 3 字节)加上结尾的 \0。
  17.     ; 定义一个常量,表示窗口位置“未定义”(由系统自动选择)
  18.     ; 这是 SDL 库中常用的特殊值:SDL_WINDOWPOS_UNDEFINED
  19.     ; 在 32 位或 64 位系统中,该值通常为 0x1FFF0000
  20.     ; 使用 equ 定义,仅在汇编时替换,不占用运行时内存
  21.     WIN_POS_UNDEFINED equ 0x1FFF0000                      ;    WIN_POS_UNDEFINED 常用于调用 SDL_CreateWindow 时指定窗口的 x 或 y 坐标,让操作系统决定窗口初始位置。
  22. 这种写法常见于使用 SDL2 库创建图形窗口的汇编程序中。

  23.    centers:                 ;这段汇编代码使用 NASM 语法,定义了一个名为 centers 的数据标签,用于存储若干二维坐标点(每个点由两个 32 位整数表示 x 和 y)。
  24.         dd 200, 200       ; 第一个中心点坐标 (x=200, y=200),每个值占4字节,共8字节
  25.         dd 400, 400       ; 第二个中心点坐标 (x=400, y=400),同样占8字节
  26.     ; 计算 centers 中包含的点的数量:
  27.     ;   $ 表示当前地址(即 centers 结束后的地址)
  28.     ;   ($ - centers) 得到 centers 所占的总字节数(这里是 16 字节)
  29.     ;   每个点由两个 32 位整数(dd)组成,共 8 字节
  30.     ;   因此除以 8 即可得到点的个数
  31.     num_centers equ ($ - centers) / 8   ; 结果为 2,表示共有2个点
  32.     POINT_SIZE equ 16      ; 每个“点”是 16x16 像素

  33. section .bss                ;这段汇编代码使用了 NASM(Netwide Assembler)语法,定义在 .bss 段中。.bss 段用于声明未初始化的全局或静态变量,这些变量在程序加载时会被操作系统初始化为零。
  34.     window    resq 1       ; 声明一个8字节的未初始化变量,用于存储 SDL_Window 指针(64位系统下指针占8字节)
  35.     renderer  resq 1       ; 声明一个8字节的未初始化变量,用于存储 SDL_Renderer 指针
  36.     event     resb 56      ; 声明56字节空间,用于存放一个 SDL_Event 结构体(其大小通常为56字节)
  37.     rect      resb 16      ; 声明16字节空间,用于存放一个 SDL_Rect 结构体(包含4个32位整数:x, y, w, h,共4×4=16字节

复制代码
 楼主| 发表于 2025-12-14 12:40:15 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:40:34 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:40:47 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:41:00 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:41:10 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:41:22 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:41:32 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:41:38 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:41:49 | 显示全部楼层
1234567890
 楼主| 发表于 2025-12-14 12:41:56 | 显示全部楼层
1234567890
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 19:15 , Processed in 0.030777 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表