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