当前位置: 首页 > news >正文

SDL3.0 学习随笔:其一

1、随谈

十年前,我在安卓端使用C4droid学习编写C/C++程序获得了巨大成功,并且该工具支持Turbo C、GCC、G++编译工具、支持SDL2.0(Simple DirectMedia Layer)、QT,并支持导出为apk程序。那个时候 贴吧还是各路大神菜鸟一起交流的圣地,物是人非呀。

2、回忆

之前学习SDL2.0的时候,遇到很多SDL本身的bug,却无可奈何,导致程序很不稳定,如今想起来,想试着学习一下SDL3.0看看能不能比较方便的写一些2D的可视化程序。

本篇文档完全基于VS 2019 MSVC或者VS 2022 MSVC,其间可能会涉及到其他平台,会进行提示。

3、正题:

SDL官方网站:Simple DirectMedia Layer - Homepage

SDL GitHub:Simple Directmedia Layer · GitHub

4、编译

在git上下载好 SDL-release-3.2.20.zip,以及cmake-gui

打开cmake-gui,依次配置好第一行Browse Source源代码目录和第三行Browse build 输出目录

点击左下角的Configure,就会出现工具链选择,选好vs和x64,然后确定,点击Genrate,会生成解决方案,点击open project,选择用vs打开,即可进行编译,编译debug和release两种。

然后,打开源码目录,找到 include,把里面SDL3整个目录移到一个自己的目录,把out里面的debug和release目录整个也复制到自己的目录里。

5、在自己的项目中导入该库

这个自己琢磨吧,就是设置C++附加包含目录为include,附加库目录分别为debug和release编译选项分别配置为刚刚输出的目录,然后在项目邮件属性,配置属性的调试中设置环境为:PATH=D:\proj_2022\thirdParty\SDL3\lib\Release;%PATH%

debug生成就设debug路径。

6、初步学习解读

代码是抄的SDL官网的一段代码删减了一些,大致解读一下我学到的一些概念

#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
#include <SDL3/SDL_main.h>

此两行会帮我们生成main函数,并且整个程序会自动调用SDL_AppInit(初始化窗口等)、SDL_AppEvent(产生事件会调用这个)、SDL_AppIterate(每一帧该绘制时会调用,不保证调用的时间间隔,具体请查看SDL3/SDL_AppIterate - SDL Wiki)、SDL_AppQuit(退出时清理程序)
#include <SDL3/SDL.h>

SDL头文件
 

/* snake.c ... *//** Logic implementation of the Snake game. It is designed to efficiently* represent the state of the game in memory.** This code is public domain. Feel free to use it for any purpose!*/#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>#pragma comment(lib, "SDL3.lib")#define STEP_RATE_IN_MILLISECONDS  125typedef enum
{SNAKE_DIR_RIGHT,SNAKE_DIR_UP,SNAKE_DIR_LEFT,SNAKE_DIR_DOWN
} SnakeDirection;static SDL_AudioStream* stream = NULL;
static Uint8* wav_data = NULL;
static Uint32 wav_data_len = 0;
static SDL_Joystick* joystick = NULL;typedef struct
{SDL_Window* window;SDL_Renderer* renderer;Uint64 last_step;
} AppState;static void set_rect_xy_(SDL_FRect* r, short x, short y)
{r->x = (float)(x * 24);r->y = (float)(y * 24);
}static SDL_AppResult handle_hat_event_(Uint8 hat) {switch (hat) {}return SDL_APP_CONTINUE;
}SDL_AppResult SDL_AppIterate(void* appstate)
{AppState* as = (AppState*)appstate;const Uint64 now = SDL_GetTicks();SDL_FRect r;int ct;if (SDL_GetAudioStreamQueued(stream) < (int)wav_data_len) {/* feed more data to the stream. It will queue at the end, and trickle out as the hardware needs more data. */SDL_PutAudioStreamData(stream, wav_data, wav_data_len);}while ((now - as->last_step) >= STEP_RATE_IN_MILLISECONDS) {// 在此处写经过125ms后蛇移动逻辑as->last_step += STEP_RATE_IN_MILLISECONDS;}r.w = r.h = 24;SDL_SetRenderDrawColor(as->renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);SDL_RenderClear(as->renderer);// 绘制场景set_rect_xy_(&r, 0, 0);SDL_SetRenderDrawColor(as->renderer, 80, 80, 255, SDL_ALPHA_OPAQUE);SDL_SetRenderDrawColor(as->renderer, 0, 128, 0, SDL_ALPHA_OPAQUE);SDL_RenderFillRect(as->renderer, &r);SDL_SetRenderDrawColor(as->renderer, 255, 255, 0, SDL_ALPHA_OPAQUE); /*head*/set_rect_xy_(&r, 1, 1);SDL_RenderFillRect(as->renderer, &r);SDL_RenderPresent(as->renderer);return SDL_APP_CONTINUE;
}static const struct
{const char* key;const char* value;
} extended_metadata[] =
{{ SDL_PROP_APP_METADATA_URL_STRING, "https://examples.libsdl.org/SDL3/demo/01-snake/" },{ SDL_PROP_APP_METADATA_CREATOR_STRING, "SDL team" },{ SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Placed in the public domain" },{ SDL_PROP_APP_METADATA_TYPE_STRING, "game" }
};SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[])
{size_t i;SDL_AudioSpec spec;char* wav_path = NULL;if (!SDL_SetAppMetadata("Example Snake game", "1.0", "com.example.Snake")) {return SDL_APP_FAILURE;}for (i = 0; i < SDL_arraysize(extended_metadata); i++) {if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) {return SDL_APP_FAILURE;}}if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO)) {SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());return SDL_APP_FAILURE;}AppState* as = (AppState*)SDL_calloc(1, sizeof(AppState));if (!as) {return SDL_APP_FAILURE;}*appstate = as;if (!SDL_CreateWindowAndRenderer("examples/demo/snake", 24 * 24, 18 * 24, SDL_WINDOW_BORDERLESS, &as->window, &as->renderer)) {return SDL_APP_FAILURE;}as->last_step = SDL_GetTicks();/* Load the .wav file from wherever the app is being run from. */SDL_asprintf(&wav_path, "%smu.wav", SDL_GetBasePath());  /* allocate a string of the full file path */if (!SDL_LoadWAV(wav_path, &spec, &wav_data, &wav_data_len)) {SDL_Log("Couldn't load .wav file: %s", SDL_GetError());return SDL_APP_FAILURE;}SDL_free(wav_path);  /* done with this string. *//* Create our audio stream in the same format as the .wav file. It'll convert to what the audio hardware wants. */stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL);if (!stream) {SDL_Log("Couldn't create audio stream: %s", SDL_GetError());return SDL_APP_FAILURE;}/* SDL_OpenAudioDeviceStream starts the device paused. You have to tell it to start! */SDL_ResumeAudioStreamDevice(stream);return SDL_APP_CONTINUE;
}SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
{switch (event->type) {case SDL_EVENT_QUIT:return SDL_APP_SUCCESS;case SDL_EVENT_JOYSTICK_ADDED:if (joystick == NULL) {joystick = SDL_OpenJoystick(event->jdevice.which);if (!joystick) {SDL_Log("Failed to open joystick ID %u: %s", (unsigned int)event->jdevice.which, SDL_GetError());}}break;case SDL_EVENT_JOYSTICK_REMOVED:if (joystick && (SDL_GetJoystickID(joystick) == event->jdevice.which)) {SDL_CloseJoystick(joystick);joystick = NULL;}break;case SDL_EVENT_JOYSTICK_HAT_MOTION://return handle_hat_event_(ctx, event->jhat.value);case SDL_EVENT_KEY_DOWN://return handle_key_event_(ctx, event->key.scancode);default:break;}return SDL_APP_CONTINUE;
}void SDL_AppQuit(void* appstate, SDL_AppResult result)
{if (joystick) {SDL_CloseJoystick(joystick);}if (appstate != NULL) {AppState* as = (AppState*)appstate;SDL_DestroyRenderer(as->renderer);SDL_DestroyWindow(as->window);SDL_free(as);}
}

http://www.xdnf.cn/news/1406647.html

相关文章:

  • 自底向上了解CPU的运算
  • 嵌入式常见架构
  • 【MYSQL】从混乱到清晰:联合查询帮你打通数据孤岛
  • 算法:插入排序
  • 公益免费二级域名
  • 解锁Tensor Core性能:深入探索CUDA Warp矩阵操作
  • Junior Engineer浅谈CAS
  • 【百度】C++开发(25届提前批 一面)面经
  • 时序数据库
  • GitHub 热榜项目 - 日榜(2025-08-31)
  • 使用cursor claude sonnet4的一些感受
  • PY32F002不小心设置了SWD复用的恢复
  • Chrome++插件与GreenChrome:增强Chrome浏览器功能
  • Spring Boot 3.0 应用 HTTP 到 HTTPS 技术改造方案
  • 《潮汐调和分析原理和应用》之四S_Tide使用2
  • Java中不太常见的语法-总结
  • 架构进阶——解读 69页 方法轮IT规划培训 架构-重点-细节【附全文阅读】
  • Shell编程核心入门:参数传递、运算符与流程控制全解析
  • 2025年9月计算机二级C++语言程序设计——选择题打卡Day11
  • 学习日志41 python
  • Linux/UNIX系统编程手册笔记:文件I/O、进程和内存分配
  • vue2下拉菜单
  • 【小宁学习日记5 PCB】电路定理
  • 9. 函数和匿名函数(一)
  • 快消品牌如何用 DAM 管理万张素材?
  • 【光照】[光照模型]是什么?以UnityURP为例
  • C++的反向迭代器
  • BEV-VAE
  • 二进制方式安装部署 Logstash
  • Java试题-选择题(23)