SDL Android 01
概要
SDL用途:
- 窗口管理
- 软件(CPU)和硬件(GPU)渲染2D图形
- 输入事件系统
- 时间管理
- 音频处理
- 文件IO和库加载
- 穿线
- 用于3D图形的OpenGL API
1、定义日志打印宏
打印宏
//头文件
#include<android/log.h>
//定义了一个标签,用于过滤
#define TAGS "Test"
//INFO
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAGS,__VA_ARGS__)
//DEBUG
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAGS,__VA_ARGS__)
//ERROR
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAGS,__VA_ARGS__)
用法就和printf一样,前一个是格式化字符串
,后一个是参数
eg:
LOGI("Initialized!");
LOGE("Error caused by SDL:%s",SDL_GetError());
LOGI("This is a int number :%d",114514);
LOGI("This is a string: %s","Hello World")
......
2、入口
SDL_main
不要奇怪为什么入口叫main
,因为在SDL_main.h
定义如下
#define main SDL_main
必须带上参数argc
,argv
//头文件
#include <SDL.h>
//必须带上参数
int main(int argc,char** args)
{
return 0;
}
3、初始化
SDL_Init()
定义
int SDL_Init(Uint32 flags);
参数
flags | 说明 |
---|---|
SDL_INIT_TIMER | 计时器子系统 |
SDL_INIT_AUDIO | 音频子系统 |
SDL_INIT_VIDEO | 视频子系统 ;自动初始化事件子系统 |
SDL_INIT_JOYSTICK | 操作杆子系统 ;自动初始化事件子系统 |
SDL_INIT_HAPTIC | 触觉(力反馈)子系统 |
SDL_INIT_GAMECONTROLLER | 控制器子系统 ;自动初始化操纵杆子系统 |
SDL_INIT_EVENTS | 事件子系统 |
SDL_INIT_EVERYTHING | 以上所有子系统 |
SDL_INIT_NOPARACHUTE | 兼容性; 该标志被忽略 |
如果要单独初始化子系统,则可以先调用SDL_Init(0)
,然后再调用带有所需子系统标志的SDL_InitSubSystem()
返回值
成功返回0,失败返回负错误代码;调用SDL_GetError()
以获得更多信息。
一般情况下直接用SDL_INIT_EVERYTHING
SDL_Init(SDL_INIT_EVERYTHING);
4、创建一个窗口
创建一个与平台无关的窗口
为了管理窗口,SDL方便地提供结构SDL_Window
和SDL_CreateWindow()
等功能。
定义
SDL_Window* SDL_CreateWindow(const char* title,
int x,
int y,
int w,
int h,
Uint32 flags)
参数
title | 窗口名称,utf8编码 |
---|---|
x | 窗口x位置, SDL_WINDOWPOS_CENTERED (中央), 或者 SDL_WINDOWPOS_UNDEFINED |
y | 窗口y座标, SDL_WINDOWPOS_CENTERED , or SDL_WINDOWPOS_UNDEFINED |
w | 宽度 |
h | 高度 |
flags | 0, 或者一个或多个宏,具体看下面 |
flags
值 | 描述 |
---|---|
SDL_WINDOW_FULLSCREEN | fullscreen window |
SDL_WINDOW_FULLSCREEN_DESKTOP | fullscreen window at the current desktop resolution |
SDL_WINDOW_OPENGL | window usable with OpenGL context |
SDL_WINDOW_VULKAN | window usable with a Vulkan instance |
SDL_WINDOW_HIDDEN | window is not visible |
SDL_WINDOW_BORDERLESS | no window decoration |
SDL_WINDOW_RESIZABLE | window can be resized |
SDL_WINDOW_MINIMIZED | window is minimized |
SDL_WINDOW_MAXIMIZED | window is maximized |
SDL_WINDOW_INPUT_GRABBED | window has grabbed input focus |
SDL_WINDOW_ALLOW_HIGHDPI | window should be created in high-DPI mode if supported (>= SDL 2.0.1) |
SDL_WINDOW_SHOWN被SDL_CreateWindow()
忽略。如果未设置SDL_WINDOW_HIDDEN
,则隐式显示SDL_Window。稍后可以使用SDL_GetWindowFlags()
查询SDL_WINDOW_SHOWN
。
返回值
返回创建的窗口,如果失败则返回NULL;否则返回NULL。调用SDL_GetError()以获得更多信息。
4.1、获取设备屏幕长宽参数
并且在安卓下,我们要创建一个匹配屏幕大小的窗口,所以需要调用SDL_GetDisplayBounds()
获取屏幕个数,
和SDL_GetDisplayBounds()
再根据每个屏幕的长宽。
由于一般的安卓手机只有一个屏幕
具体代码如下(SDL_Rect是一个包含屏幕起始座标x,y和长宽w(width),h(height)的结构)
//看看手机有几个屏幕
int nDisplays = SDL_GetNumVideoDisplays();
SDL_Rect rectDisplay;
//通常情况下,只有一个屏幕,无需判断,屏幕id从0开始,故第一个参数为0
SDL_GetDisplayBounds(0,&rectDisplay);
LOGD("number of displays:%d,width:%d,height%d",nDisplays,rectDisplay.w,rectDisplay.h);
这里我们这样创建窗口
SDL_Window *window;
window = SDL_CreateWindow("application",0,0,1440,2560,SDL_WINDOW_SHOWN);
if(!window)
{
LOGE("Error Creating Window%s",SDL_GetError());
return 1;
}
5、表面
创建窗口后,您需要一种绘制方法。SDL将您可以绘制的任何区域(包括加载的图像)抽象为“表面
”。(这是为了CPU
渲染 - 在未来,我们将进入GPU
渲染,它不使用表面
。)
结构SDL_Surface
和诸如SDL_LoadBMP()
和SDL_GetWindowSurface()
之类的函数提供软件渲染(也称为blitting
)API。
正如您所期望的那样,使用SDL_GetWindowSurface()
来获取窗口的表面。绘制到此表面后,可以通过调用SDL_UpdateWindowSurface()
在窗口中看到结果。
SDL_Surface *winSurface = SDL_GetWindowSurface(window);
if(!winSurface)
{
LOGE("Error Creating winSurface%s",SDL_GetError());
return 1;
}
6、绘制矩形
要测试窗口表面是否正常工作,可以用颜色填充它。
一个非常简单的方法是使用SDL_FillRect()
。
要填充整个窗口,只需传递NULL
(in c++11, use nullptr
)而不是SDL_Rect指针。
此外,SDL_FillRect()
采用表示颜色的特定格式编号。要获得此格式的颜色,可以使用曲面格式和所需的RGB值调用SDL_MapRGB()
。
SDL_FillRect(winSurface, nullptr,SDL_MapRGB(winSurface->format,255,90,120));
一切绘制工作完成后,使用上述的SDL_UpdateWindowSurface()
在窗口中看到结果。
SDL_UpdateWindowSurface(window);
7、退出
一旦程序完成其操作,它必须销毁窗口并释放相关资源。正如您所料,SDL_DestroyWindow()
就是这么做的。该功能将关闭窗口,释放相关内存(包括窗口表面)。
为了防止进入后过快关闭程序,使用SDL_Delay()
进行延迟。
SDL_Delay(3000);
SDL_DestroyWindow(window);
window = nullptr;
winSurface = nullptr;
最后,关闭SDL作为一个整体,请调用SDL_Quit()
。这是非常明确的。
SDL_Quit();
Extra 1、设置过滤器方便调试
在Android studio LogCat中的 右下角
然后
Log TAG与定义的宏TAG一致
完整代码
#include <SDL.h>
#include <android/log.h>
#define TAGS "Test"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAGS,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAGS,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAGS,__VA_ARGS__)
using namespace std;
int main(int argc,char** args)
{
//SDL初始化
SDL_Init(SDL_INIT_EVERYTHING);
LOGD("Initialized");
SDL_Window *window;
window = SDL_CreateWindow("application",0,0,1440,2560,SDL_WINDOW_SHOWN);
if(!window)
{
LOGE("Error Creating Window%s",SDL_GetError());
return 1;
}
SDL_Surface *winSurface = SDL_GetWindowSurface(window);
if(!winSurface)
{
LOGE("Error Creating winSurface%s",SDL_GetError());
return 1;
}
SDL_FillRect(winSurface, nullptr,SDL_MapRGB(winSurface->format,255,90,120));
SDL_UpdateWindowSurface(window);
SDL_Delay(3000);
SDL_DestroyWindow(window);
window = nullptr;
winSurface = nullptr;
SDL_Quit();
return 0;
}
参考
CSDN博主「Dwyane05」
原文链接:https://blog.csdn.net/cyf15238622067/article/details/82905897