【SDL2】01 基础知识

前言
因为前段时间捣腾了一下SDL2,现在把之前写的笔记整理,并发布出来。

SDL简介

SDL(Simple DirectMedia Layer)是一个跨平台开发库,旨在通过OpenGL和Direct3D提供对音频、键盘、鼠标、游戏杆和图形硬件的低级访问。它被视频播放软件、模拟器和流行游戏使用,

SDL简单来说就是通过SDL提供了一层直接的接口用于做一些游戏开发。SDL 是用 C 编写的,并且提供了很多其他语言的接口。

下面是关键的资源,需要通过Github的Release获取编译好的二进制,选择SDL2-devel-2.30.3-VC.zip即可。这里我全部都是以当前2.30.3最新版为准。

官网地址:https://www.libsdl.org/

SDL的Github地址:https://github.com/libsdl-org/SDL

SDL可以做什么

视频

  • 3D图形:SDL 可与 OpenGL API 或 Direct3D API 结合使用,用于 3D 图形
  • 加速 2D 渲染 API:支持简单的旋转、缩放和 alpha 混合,所有这些都使用现代 3D API 加速,使用 OpenGL 和 Direct3D 支持加速
  • 创建和管理多个窗口

输入事件

  • 提供的事件和 API 函数用于:
    • 应用程序和窗口状态更改
    • 鼠标输入
    • 键盘输入
    • 操纵杆和游戏控制器输入
    • 多点触控手势
  • 可以使用SDL_EventState启用或禁用每个事件
  • 事件在发布到内部事件队列之前通过用户指定的过滤器函数
  • 线程安全事件队列

力反馈

  • Windows、Mac OS X 和 Linux 支持力反馈

音频

  • 设置8位和16位音频、单声道立体声或5.1环绕声的音频播放,如果硬件不支持格式,可选择转换
  • 音频在单独的线程中独立运行,通过用户回调机制填充
  • 专为定制软件混音器设计,但SDL_mixer提供完整的音频/音乐输出库

文件 I/O 抽象

  • 用于打开、读取和写入数据的通用抽象
  • 对文件和内存的内置支持

共享对象支持

  • 加载共享对象(Windows 上的 DLL,Mac OS X 上的 .dylib,Linux 上的 .so)
  • 共享对象中的查找函数

线程

  • 简单的线程创建API
  • 简单线程本地存储API
  • 互斥体、信号量和条件变量
  • 无锁编程的原子操作

计时器

  • 获取经过的毫秒数
  • 等待指定的毫秒数
  • 在单独的线程中创建与代码一起运行的计时器
  • 使用高分辨率计数器进行分析

CPU 特性检测

  • 查询CPU数量
  • 检测 CPU 特性和支持的指令集

大端小端支持

  • 检测当前系统的字节序
  • 用于快速交换数据值的例程
  • 读取和写入指定字节序的数据

电池管理

  • 查询电源管理状态

SDL 在哪些平台上运行

Windows

  • 使用 Win32 API 进行显示,利用 Direct3D 进行硬件加速
  • 使用 DirectSound 和 XAudio2 作为声音

Mac OS X

  • 使用 Cocoa 进行视频显示,利用 OpenGL 进行硬件加速
  • 使用 Core Audio 播放声音

Linux

  • 使用 X11 进行视频显示,利用 OpenGL 进行硬件加速
  • 使用 ALSA、OSS 和 PulseAudio API 来处理声音

IOS

  • 使用 UIKit 进行视频显示,利用 OpenGL ES 2.0 进行硬件加速
  • 使用 Core Audio 播放声音

Android

  • 使用 JNI 接口进行视频显示,利用 OpenGL ES 1.1 和 2.0 进行硬件加速
  • 对声音使用 JNI 音频回调

开发环境搭建

为了方便开发,因此需要搭建一个模板工程,提供三个模板,一个是VS2022的模板,一个是CMake的模板,最后一个是XMake的模板。因为做游戏一般是只针对于Windows下,而不是Linux,所以这里就只有Windows下的。

要求先下载SDL2-devel-2.30.3-VC.zip这个压缩包,并且解压。这里只推荐使用VS2022,因为Windows下VS确实很好用。

vs下的环境搭建

我这里先新建了一个SdlPractice的项目,项目和解决方案是分开的。然后我单独又在这个解决方案下添加了新的项目名字为TemplateProject

然后把前面SDL2-devel-2.30.3-VC.zip解压出来的文件夹,放在当前解决方案目录下创建的一个叫做third_party的文件夹里面。这个third_party我一般用来存放第三方库。SDL2-devel-2.30.3-VC.zip解压出来的文件夹名字应该是SDL2-2.30.3,改名为SDL2

最终项目路径应该是像下面这样。

.
│  SdlPractice.sln
│
├─SdlPractice
│      SdlPractice.cpp
│      SdlPractice.vcxproj
│      SdlPractice.vcxproj.filters
│      SdlPractice.vcxproj.user
│
├─TemplateProject
│      main.c
│      TemplateProject.vcxproj
│      TemplateProject.vcxproj.filters
│      TemplateProject.vcxproj.user
│
└─third_party
    └─SDL2
        │
        ├─cmake
        │
        ├─docs
        │
        ├─include
        │
        └─lib
            ├─x64
            │      SDL2.dll
            │      SDL2.lib
            │      SDL2main.lib
            │      SDL2test.lib
            │
            └─x86
                    SDL2.dll
                    SDL2.lib
                    SDL2main.lib
                    SDL2test.lib

对于一个动态库的使用,一般是包括头文件、lib文件、dll文件等,接下来分别对其进行配置。

配置头文件路径

接下来就是配置头文件路径,把SDL的头文件加入包含路径,这样就可以写#include <SDL.h>这样的代码,即使用<>来包含,如果不配置,而是直接把头文件复制到当前源文件附近,使用""包含,也可以,不过这样会导致库的代码和自己的代码混在一起。

VC++目录里找到包含目录,这里写为下面的内容。

$(SolutionDir)third_party\SDL2\include

其中$(SolutionDir)代表当前解决方案的路径,也就是SdlPractice.sln的路径,对路径进行一个拼接。如果不是这样自己编辑路径,而是使用预览选择一个目录,就会使用绝对路径。这会使得代码复制到另外一个目录就不能使用。

操作完了以后,项目的属性页信息如下。

在这里插入图片描述

配置库目录

前面那张图里,我已经配置好库目录了。就是属性页中的库目录,我填的是下面这个内容。

$(SolutionDir)third_party\SDL2\lib\x64;

这里库目录也就是lib文件的目录,是分32位和64位的,其中32位在SDL2\lib\x86内,而64位在SDL2\lib\x64内。所以对于不同的构建目标也需要不同目录下的lib文件。

接下来就是在链接器中的输入里找到附加依赖项,填入下面这些内容。

SDL2.lib;SDL2main.lib

之所以是填SDL2.libSDL2main.lib是因为,下载的SDL的压缩包内,解压出来就有这些lib文件。

配置好的lib文件效果如下,库目录见前面配置头文件路径时的图片。

在这里插入图片描述

添加一下下面这一段代码来测试是否可以正常构建项目。

#include<SDL.h>

int main(int argc, char* argv[])
{
	SDL_version ver;
	SDL_GetVersion(&ver);
	SDL_Log("%d %d %d\n", ver.major, ver.minor, ver.patch);
	return 0;
}

我一开始用的是下面这个测试代码,所以VS的模板文件是这个源代码。

#include <SDL.h>

int main(int argc, char* argv[])
{
    // 初始化SDL
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        SDL_Log("SDL_Init Error: %s", SDL_GetError());
        return -1;
    }

    // 创建一个窗口
    SDL_Window* window = SDL_CreateWindow("SDL2 Test Window",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        640, 480,
        SDL_WINDOW_SHOWN);
    if (window == NULL) {
        SDL_Log("SDL_CreateWindow Error: %s", SDL_GetError());
        SDL_Quit();
        return -1;
    }

    // 等待几秒钟
    SDL_Delay(3000);

    // 销毁窗口并退出SDL
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

配置调试环境

这个时候VS2022已经能够正确识别库,并且语法高亮已经正常工作,而且能够正常构建项目了。但是调试和运行的时候会报错,说缺乏SDL.dll文件。接下来就解决这个问题。

调试中的环境填入dll文件的路径,如下。

PATH=$(SolutionDir)third_party\SDL2\lib\x64

这里不把这个dll添加到环境变量PATH的目的是,让项目复制到另外一个机器上的时候,不需要重新配置环境变量。

下面图片这样以后,就是可以了。

在这里插入图片描述

优化构建输出路径

接下来优化一下构建的输出路径,因为VS2022的默认是会让生成的文件在项目下,所以会导致源代码和构建的文件不能分开,这样就很乱。所以我就修改了一下,不同的构建配置是不同的路径。

在这里插入图片描述

导出项目模板

在VS2022的菜单中选择项目,然后点击导出模板

在这里插入图片描述

接下来利用导出模板向导进行导出模板。
在这里插入图片描述

后面的信息可以随便填,然后选择完成。这里我的VS2022的模板目录为C:\Users\Canrad\Documents\Visual Studio 2022\My Exported Templates\,然后这里因为我设置的是SDL_Template_Project_MSVC为名字,我就得到了SDL_Template_Project_MSVC.zip这个模板文件。

使用项目模板

模板文件放到VS2022的模板路径里,如果是前面自己导出的,就不需要了,这是针对使用别人的模板的情况。

接下来就可以跟其他VS2022内部自带的项目一样新建即可,这样建出来的项目就是配置好的项目。

使用cmake进行环境搭建

使用cmake也是一样的操作,只不过是要建一个CMakeLists.txt来描述构建。还是跟VS的环境配置一样的操作,新建third_party目录。

文件组织差不多就是如下图所示。

.
│
├─src
│    main.c
│
├─third_party
│   └─SDL2
│
└─CMakeLists.txt

下面这里我给出我的cmake脚本。

# cmake的最低版本号,注意VERSION需要大写
cmake_minimum_required(VERSION 3.25)

# 设置一个工程名字
project(SDL_Template_Project_cmake)

# 添加可执行项目
add_executable(TemplateProject "")

# 添加源文件
target_sources(TemplateProject
    PRIVATE
        ${CMAKE_CURRENT_LIST_DIR}/src/main.c
    # PUBLIC
    #     ${CMAKE_CURRENT_LIST_DIR}/src/main.h
)

# 添加头文件路径
target_include_directories(TemplateProject
    PUBLIC
        ${CMAKE_CURRENT_LIST_DIR}
        ${CMAKE_CURRENT_LIST_DIR}/third_party/SDL2/include
)

# 添加库
target_link_libraries(TemplateProject
    PUBLIC
        ${CMAKE_CURRENT_LIST_DIR}/third_party/SDL2/lib/x64/SDL2.lib
        ${CMAKE_CURRENT_LIST_DIR}/third_party/SDL2/lib/x64/SDL2main.lib
)

还有另外一个方法就是利用cmake的包,因为SDL2是用cmake构建的,所以有包可以用。下面用包机制来写构建脚本,这样的话,需要把前面third_party/SDL2这个目录配置到环境变量。

#CMake最小请求版本
cmake_minimum_required (VERSION 3.25)

#项目名称
project("SDL_Template_Project_cmake")

#查找SDL2包,REQUIRED强制请求,没找到报错
find_package(SDL2 REQUIRED)

#使用指定的源文件生成目标(SDL2_CMake)
add_executable (SDL_Template_Project_cmake "main.c")

#指定目标在链接时需要的依赖(库)
target_link_libraries(SDL_Template_Project_cmake SDL2::SDL2 SDL2::SDL2main)

然后就是构建项目的方式了。

使用下面这条命令来创建一个build文件夹。

mkdir build

然后进去目录。

cd build

使用下面这条指令来生成VS2022项目

cmake ..

最后这个项目就打包为SDL_Template_Project_cmake.zip

使用xmake进行环境搭建

使用xmake的话就很简单了,先利用下面这条指令初始化一个xmake项目出来。

xmake create -l c -P ./SDL_Template_Project_xmake

然后在创建的SDL_Template_Project_xmake目录里,建一个third_party,把之前的SDL2-devel-2.30.3-VC.zip解压进去,然后去除版本号,改名为SDL2

此时的目录结构大致如下所示。

.
│
├─src
│    main.c
│
├─third_party
│   └─SDL2
│
└─xmake.lua

修改构建脚本xmake.lua文件为以下内容。

add_rules("mode.debug", "mode.release")

add_requires("libsdl")

target("SDL_Template_Project_xmake")
    set_kind("binary")
    add_files("src/**.c")
    add_packages("libsdl")

使用xmake有一个很大的问题,在Windows上xmake如果是自己写链接SDL的话需要自己额外链接很多库,很麻烦。我这里用的是xrepo的办法。但是这依然有可能导致包因为网络导致不能正常安装。所以xmake这个方法不推荐,xmake还是在Linux上比较好用。

使用下面这条命令可以生成一个VS2022的项目在vsxmake2022文件夹下。

xmake project -k vsxmake

最后这个项目就打包为SDL_Template_Project_xmake.zip

参考资料

SDL2 维基文档

SDL2各种教程集合

博客:

https://gigi.nullneuron.net/gigilabs/writing/sdl2-tutorials/

https://blog.youkuaiyun.com/weiwei9363/category_11923460.html

https://blog.youkuaiyun.com/cyf15238622067/category_8096110.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值