前言
(*  ̄︿ ̄) 因為作者這段時間偷懶了一下,然后被某人乖巧催更,迫不得已,繼續(xù)更新吧
在上一篇文章中,我已經(jīng)介紹了Skia+SDL2的開發(fā)環(huán)境搭建,并且,放了一段程序的代碼,那么,你的程序是否跑起來了呢?
都跑起來之后,是不是感覺幾秒鐘就消失了有點不爽啊?沒關系,這次我們讓他一直跑,就像給他吃了 炫邁 一樣,你不叫停他是不會停的.
準備工作
還是老樣子吧,新建一個項目,這里我就不多說啦,不知道的小伙伴或者忘記了的小伙伴去翻翻我的上一篇文章吧
讓項目跑起來
首先呢,我們還是像之前一樣,先讓項目跑起來,然后呢,我們在對項目進行進一步修改,達到我們想要的效果
我就不用Ubuntu啦,在Windows上做吧 Σ( ° △ °|||)︴懶得開另一臺電腦啦
不墨跡了,我直接上代碼吧ヽ(??▽?)ノ
#include <SkBitmap.h>
#include <core/SkCanvas.h>
#include <core/SkTypeface.h>
#ifdef _WIN32
#include <SDL.h>
#else
#include <SDL2/SDL.h>
#endif
//創(chuàng)建RGBA結構體
struct RGBA {
//設置Red
Uint32 rmask = 0x00ff0000;
//設置Green
Uint32 gmask = 0x0000ff00;
//設置Blue
Uint32 bmask = 0x000000ff;
//設置Alpha
Uint32 amask = 0xff000000;
};
//創(chuàng)建SkBitmap對象并在Bitmap上繪制
SkBitmap draw(int w, int h) {
//聲明
SkBitmap bitmap;
//設置Bitmap的配置信息
bitmap.setInfo(SkImageInfo::Make(w, h, kBGRA_8888_SkColorType, kOpaque_SkAlphaType));
//轉換為像素填充
bitmap.allocPixels();
//創(chuàng)建畫布
SkCanvas canvas(bitmap);
//創(chuàng)建畫筆
SkPaint paint;
//設置畫布顏色
canvas.clear(SK_ColorWHITE);
//設置畫筆抗鋸齒
paint.setAntiAlias(true);
//設置畫筆顏色(此處為紅色)
paint.setARGB(255, 255, 0, 0);
//繪制圓形
canvas.drawCircle(80, 80, 40, paint);
//繪制線段
canvas.drawLine(0, 280, w, 280, paint);
//設置字體大小
paint.setTextSize(60);
//繪制字體
canvas.drawString("Hello Skia", 300, 150, paint);
//返回SkBitmap對象
return bitmap;
}
//通過SDL_Surface創(chuàng)建SDL_Rect
SDL_Rect create_rect(SDL_Surface *surface) {
//創(chuàng)建SDL_Rect對象
SDL_Rect src = { 0, 0, surface->w, surface->h };
//返回SDL_Rect對象
return src;
}
//程序的入口點
int main(int args, char *argv[]) {
//聲明窗口
SDL_Window *window;
//聲明繪圖表面
SDL_Surface *surface;
//聲明渲染器
SDL_Renderer *renderer;
//聲明紋理
SDL_Texture *texture;
//聲明Bitmap
SkBitmap bitmap;
//聲明RGBA結構體
RGBA rgba;
//聲明矩形
SDL_Rect rect;
//聲明窗口的寬高
int width = 800;
int height = 480;
//初始化SDL為視頻顯示
SDL_Init(SDL_INIT_VIDEO);
//創(chuàng)建窗口
window = SDL_CreateWindow("Hello Skia", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
if (window == NULL) {
return -1;
}
//獲取繪制后的Bitmap
bitmap = draw(width, height);
//通過Bitmap的像素數(shù)據(jù)創(chuàng)建表面
surface = SDL_CreateRGBSurfaceFrom(bitmap.getPixels(), width, height, 32, width * 4, rgba.rmask, rgba.gmask,
rgba.bmask, rgba.amask);
//通過SDL_Surface創(chuàng)建矩形
rect = create_rect(surface);
//創(chuàng)建渲染器
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
//清理渲染器
SDL_RenderClear(renderer);
//創(chuàng)建紋理
texture = SDL_CreateTextureFromSurface(renderer, surface);
//輔助紋理到渲染器
SDL_RenderCopy(renderer, texture, NULL, &rect);
//顯示到窗口
SDL_RenderPresent(renderer);
//延時5秒鐘
SDL_Delay(5000);
//釋放表面
SDL_FreeSurface(surface);
//釋放紋理
SDL_DestroyTexture(texture);
//釋放渲染器
SDL_DestroyRenderer(renderer);
//釋放窗口
SDL_DestroyWindow(window);
//結束SDL
SDL_Quit();
//程序退出
return 0;
}
其實呢,還是和上次一樣的,因為我懶 ︿( ̄︶ ̄)︿ 復制粘貼多快呀
還是跑一下吧,給你們解解饞
skia_run_with_windows.png
為了讓程序一直更新,并且受我們自己控制,就需要對代碼進行修改
那么,怎么樣才能讓程序一直刷新不斷的重繪呢?
最簡單的辦法
一直調用while,我們只需要把
SDL_Delay(5000);
換成
while (true) {
//判斷表面是否為空
if (surface != NULL){
//釋放表面
SDL_FreeSurface(surface);
}
//判斷紋理是否為空
if (texture != NULL) {
//釋放紋理
SDL_DestroyTexture(texture);
}
//繪制位圖
bitmap = draw(width, height);
//創(chuàng)建紋理
surface = SDL_CreateRGBSurfaceFrom(bitmap.getPixels(), width, height, 32, width * 4, rgba.rmask, rgba.gmask,
rgba.bmask, rgba.amask);
//創(chuàng)建紋理
texture = SDL_CreateTextureFromSurface(renderer, surface);
//復制紋理
SDL_RenderCopy(renderer, texture, NULL, &rect);
//提交渲染
SDL_RenderPresent(renderer);
//休眠16.6毫秒
SDL_Delay(16.6);
}
這樣基本上就可以實現(xiàn)窗口一直存在并且一直在更新,但是呢,跑起來過后,你會發(fā)現(xiàn)這破玩意關不掉,那是因為一直在循環(huán),根本沒有機會處理其他的事情,而且是單線程,進入了死循環(huán)之后,后果大概就不用我說了吧
那么這種方法肯定就不能用啦,怎么解決呢?SDL這么強大一個媒體庫,不可能沒有辦法把?答案是肯定有辦法解決的,那么用什么辦法解決呢?當然是用線程解決啦
讓程序飛一會
SDL中有這么一個方法
SDL_Thread* SDL_CreateThread(SDL_ThreadFunction fn,
const char* name,
void* data)
這個方法用來干嘛的呢?當然是用來創(chuàng)建線程的啦 ╰(°▽°)╯ 簡單的介紹一下參數(shù),
第一個參數(shù) 表示 線程執(zhí)行時調用的方法名 ,
第二個參數(shù) 表示 線程的名稱 ,
第三個參數(shù) 表示 線程執(zhí)行需要的數(shù)據(jù)
那么知道了有這個方法,我們怎么去用呢?我們需要這樣修改程序
首先我們需要 把變量聲明搬到上邊去 ,然后創(chuàng)建一個 返回值為int類型且參數(shù)列表為 void* 的方法
//聲明窗口
SDL_Window *window;
//聲明繪圖表面
SDL_Surface *surface;
//聲明渲染器
SDL_Renderer *renderer;
//聲明紋理
SDL_Texture *texture;
//聲明Bitmap
SkBitmap bitmap;
//聲明RGBA結構體
RGBA rgba;
//聲明矩形
SDL_Rect rect;
int update(void *data) {
while (true) {
//判斷表面是否為空
if (surface != NULL) {
//釋放表面
SDL_FreeSurface(surface);
}
//判斷紋理是否為空
if (texture != NULL) {
//釋放紋理
SDL_DestroyTexture(texture);
}
//繪制位圖
bitmap = draw(rect.w, rect.h);
//創(chuàng)建紋理
surface = SDL_CreateRGBSurfaceFrom(bitmap.getPixels(), rect.w, rect.h, 32, rect.w * 4, rgba.rmask, rgba.gmask,
rgba.bmask, rgba.amask);
//創(chuàng)建紋理
texture = SDL_CreateTextureFromSurface(renderer, surface);
//復制紋理
SDL_RenderCopy(renderer, texture, NULL, &rect);
//提交渲染
SDL_RenderPresent(renderer);
//休眠16.6毫秒
SDL_Delay(16.6);
}
return 0;
}
然后在main方法中替換
SDL_Delay(5000);
為
SDL_Thread *thread = SDL_CreateThread(update, "update", (void *)NULL);
為了方便查看代碼,我將代碼結構稍微調整了一下,之后整篇代碼大概是這樣子的
#include <SkBitmap.h>
#include <core/SkCanvas.h>
#include <core/SkTypeface.h>
#ifdef _WIN32
#include <SDL.h>
#include <SDL_thread.h>
#else
#include <SDL2/SDL.h>
#endif
//聲明窗口
SDL_Window *window;
//聲明繪圖表面
SDL_Surface *surface;
//聲明渲染器
SDL_Renderer *renderer;
//聲明紋理
SDL_Texture *texture;
//聲明Bitmap
SkBitmap bitmap;
//聲明矩形
SDL_Rect rect;
//聲明窗口的寬高
int width = 800;
int height = 480;
//創(chuàng)建RGBA結構體
struct RGBA {
//設置Red
Uint32 rmask = 0x00ff0000;
//設置Green
Uint32 gmask = 0x0000ff00;
//設置Blue
Uint32 bmask = 0x000000ff;
//設置Alpha
Uint32 amask = 0xff000000;
}RGBA;
//創(chuàng)建SkBitmap對象并在Bitmap上繪制
SkBitmap draw(int w, int h) {
//聲明
SkBitmap bitmap;
//設置Bitmap的配置信息
bitmap.setInfo(SkImageInfo::Make(w, h, kBGRA_8888_SkColorType, kOpaque_SkAlphaType));
//轉換為像素填充
bitmap.allocPixels();
//創(chuàng)建畫布
SkCanvas canvas(bitmap);
//創(chuàng)建畫筆
SkPaint paint;
//設置畫布顏色
canvas.clear(SK_ColorWHITE);
//設置畫筆抗鋸齒
paint.setAntiAlias(true);
//設置畫筆顏色(此處為紅色)
paint.setARGB(255, 255, 0, 0);
//繪制圓形
canvas.drawCircle(80, 80, 40, paint);
//繪制線段
canvas.drawLine(0, 280, w, 280, paint);
//設置字體大小
paint.setTextSize(60);
//繪制字體
canvas.drawString("Hello Skia", 300, 150, paint);
//返回SkBitmap對象
return bitmap;
}
//通過SDL_Surface創(chuàng)建SDL_Rect
SDL_Rect create_rect(SDL_Surface *surface) {
//創(chuàng)建SDL_Rect對象
SDL_Rect src = { 0, 0, surface->w, surface->h };
//返回SDL_Rect對象
return src;
}
//SDL線程調用的方法
int update(void *data) {
while (true) {
//判斷表面是否為空
if (surface != NULL) {
//釋放表面
SDL_FreeSurface(surface);
}
//判斷紋理是否為空
if (texture != NULL) {
//釋放紋理
SDL_DestroyTexture(texture);
}
//繪制位圖
bitmap = draw(rect.w, rect.h);
//創(chuàng)建紋理
surface = SDL_CreateRGBSurfaceFrom(bitmap.getPixels(), rect.w, rect.h, 32, rect.w * 4, RGBA.rmask, RGBA.gmask,
RGBA.bmask, RGBA.amask);
//創(chuàng)建紋理
texture = SDL_CreateTextureFromSurface(renderer, surface);
//復制紋理
SDL_RenderCopy(renderer, texture, NULL, &rect);
//提交渲染
SDL_RenderPresent(renderer);
//休眠16.6毫秒
SDL_Delay(16.6);
}
return 0;
}
//初始化
void init() {
//初始化SDL為視頻顯示
SDL_Init(SDL_INIT_VIDEO);
//創(chuàng)建窗口
window = SDL_CreateWindow("Hello Skia", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
//創(chuàng)建渲染器
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
//清理渲染器
SDL_RenderClear(renderer);
//獲取窗口表面
surface = SDL_GetWindowSurface(window);
//通過SDL_Surface創(chuàng)建矩形
rect = create_rect(surface);
}
//程序的入口點
int main(int args, char *argv[]) {
//初始化
init();
//創(chuàng)建并啟動線程
SDL_Thread *thread = SDL_CreateThread(update, "update", (void *)NULL);
//釋放表面
SDL_FreeSurface(surface);
//釋放紋理
SDL_DestroyTexture(texture);
//釋放渲染器
SDL_DestroyRenderer(renderer);
//釋放窗口
SDL_DestroyWindow(window);
//結束SDL
SDL_Quit();
//程序退出
return 0;
}
現(xiàn)在運行程序你會發(fā)現(xiàn)窗口一閃而過,為什么呢?因為我們把所有的操作都放到子線程中了,主線程沒有阻塞,所以主線程運行完了,整個程序就結束了,那么我們需要阻塞主線程,那就需要搞點事情,那搞點什么事情呢?想想我們還沒有做退出事件監(jiān)聽吧?那么我們就寫個事件阻塞
需要事件處理就需要在SDL初始化的時候加上事件系統(tǒng),大概是這樣子,需要修改一下代碼
SDL_Init(SDL_INIT_VIDEO);
修改為
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
然后添加我們的事件處理循環(huán),添加一個全局變量 qiut ,之后吧我們的子線程中的while循環(huán)標記替換成 quit
while (!quit) {
//Handle events on queue
while (SDL_PollEvent(&e) != 0) {
//User requests quit
if (e.type == SDL_QUIT) {
quit = true;
}
if (e.type == SDL_FINGERUP) {
quit = true;
}
}
然后我們在釋放內(nèi)存的時候為了避免重復釋放,所以需要在釋放之前對數(shù)據(jù)進行判斷,之后整篇代碼大概是這樣子的
#include <SkBitmap.h>
#include <core/SkCanvas.h>
#include <core/SkTypeface.h>
#ifdef _WIN32
#include <SDL.h>
#include <SDL_thread.h>
#else
#include <SDL2/SDL.h>
#endif
//聲明窗口
SDL_Window *window;
//聲明繪圖表面
SDL_Surface *surface;
//聲明渲染器
SDL_Renderer *renderer;
//聲明紋理
SDL_Texture *texture;
//聲明Bitmap
SkBitmap bitmap;
//聲明矩形
SDL_Rect rect;
//聲明窗口的寬高
int width = 800;
int height = 480;
//線程循環(huán)標記
bool quit = false;
//創(chuàng)建RGBA結構體
struct RGBA {
//設置Red
Uint32 rmask = 0x00ff0000;
//設置Green
Uint32 gmask = 0x0000ff00;
//設置Blue
Uint32 bmask = 0x000000ff;
//設置Alpha
Uint32 amask = 0xff000000;
}RGBA;
//創(chuàng)建SkBitmap對象并在Bitmap上繪制
SkBitmap draw(int w, int h) {
//聲明
SkBitmap bitmap;
//設置Bitmap的配置信息
bitmap.setInfo(SkImageInfo::Make(w, h, kBGRA_8888_SkColorType, kOpaque_SkAlphaType));
//轉換為像素填充
bitmap.allocPixels();
//創(chuàng)建畫布
SkCanvas canvas(bitmap);
//創(chuàng)建畫筆
SkPaint paint;
//設置畫布顏色
canvas.clear(SK_ColorWHITE);
//設置畫筆抗鋸齒
paint.setAntiAlias(true);
//設置畫筆顏色(此處為紅色)
paint.setARGB(255, 255, 0, 0);
//繪制圓形
canvas.drawCircle(80, 80, 40, paint);
//繪制線段
canvas.drawLine(0, 280, w, 280, paint);
//設置字體大小
paint.setTextSize(60);
//繪制字體
canvas.drawString("Hello Skia", 300, 150, paint);
//返回SkBitmap對象
return bitmap;
}
//通過SDL_Surface創(chuàng)建SDL_Rect
SDL_Rect create_rect(SDL_Surface *surface) {
//創(chuàng)建SDL_Rect對象
SDL_Rect src = { 0, 0, surface->w, surface->h };
//返回SDL_Rect對象
return src;
}
//SDL線程調用的方法
int update(void *data) {
while (!quit) {
//判斷表面是否為空
if (surface != NULL) {
//釋放表面
SDL_FreeSurface(surface);
}
//判斷紋理是否為空
if (texture != NULL) {
//釋放紋理
SDL_DestroyTexture(texture);
}
//繪制位圖
bitmap = draw(rect.w, rect.h);
//創(chuàng)建紋理
surface = SDL_CreateRGBSurfaceFrom(bitmap.getPixels(), rect.w, rect.h, 32, rect.w * 4, RGBA.rmask, RGBA.gmask,
RGBA.bmask, RGBA.amask);
//創(chuàng)建紋理
texture = SDL_CreateTextureFromSurface(renderer, surface);
//復制紋理
SDL_RenderCopy(renderer, texture, NULL, &rect);
//提交渲染
SDL_RenderPresent(renderer);
//休眠16.6毫秒
SDL_Delay(16.6);
}
return 0;
}
//初始化
void init() {
//初始化SDL為視頻顯示
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
//創(chuàng)建窗口
window = SDL_CreateWindow("Hello Skia", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
//創(chuàng)建渲染器
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
//清理渲染器
SDL_RenderClear(renderer);
//獲取窗口表面
surface = SDL_GetWindowSurface(window);
//通過SDL_Surface創(chuàng)建矩形
rect = create_rect(surface);
}
//程序的入口點
int main(int args, char *argv[]) {
//初始化
init();
//創(chuàng)建并啟動線程
SDL_Thread *thread = SDL_CreateThread(update, "update", (void *)NULL);
//事件隊列
SDL_Event e;
//事件處理
while (!quit) {
//輪詢事件
while (SDL_PollEvent(&e) != 0) {
//用戶退出事件
if (e.type == SDL_QUIT) {
//設置循環(huán)標記
quit = true;
}
}
}
//判斷表面是否為空
if (surface != NULL) {
//釋放表面
SDL_FreeSurface(surface);
}
//判斷紋理是否為空
if (texture != NULL) {
//釋放紋理
SDL_DestroyTexture(texture);
}
//判斷渲染器是否為空
if (renderer != NULL) {
//釋放渲染器
SDL_DestroyRenderer(renderer);
}
//釋放窗口
SDL_DestroyWindow(window);
//結束SDL
SDL_Quit();
//程序退出
return 0;
}
然后運行程序試試?是不是想怎么玩就怎么玩啦?沒錯,就是這樣,為了更直觀的查看FPS,我們需要增加一點代碼,這里我就不詳細介紹啦,直接貼代碼吧,反正你們也不會仔細的看我的文章 (*  ̄︿ ̄)
之后,貼出增加FPS顯示后的代碼
#include <SkBitmap.h>
#include <core/SkCanvas.h>
#include <core/SkTypeface.h>
#include <string.h>
#ifdef _WIN32
#pragma warning(disable:4996)
#include <SDL.h>
#include <SDL_thread.h>
#else
#include <SDL2/SDL.h>
#endif
//聲明窗口
SDL_Window *window;
//聲明繪圖表面
SDL_Surface *surface;
//聲明渲染器
SDL_Renderer *renderer;
//聲明紋理
SDL_Texture *texture;
//聲明Bitmap
SkBitmap bitmap;
//聲明矩形
SDL_Rect rect;
//聲明窗口的寬高
int width = 800;
int height = 480;
//線程循環(huán)標記
bool quit = false;
//幀數(shù)
int fps;
//待繪制的FPS數(shù)據(jù)
char chars[15];
//創(chuàng)建RGBA結構體
struct RGBA {
//設置Red
Uint32 rmask = 0x00ff0000;
//設置Green
Uint32 gmask = 0x0000ff00;
//設置Blue
Uint32 bmask = 0x000000ff;
//設置Alpha
Uint32 amask = 0xff000000;
}RGBA;
//創(chuàng)建SkBitmap對象并在Bitmap上繪制
SkBitmap draw(int w, int h) {
//聲明
SkBitmap bitmap;
//設置Bitmap的配置信息
bitmap.setInfo(SkImageInfo::Make(w, h, kBGRA_8888_SkColorType, kOpaque_SkAlphaType));
//轉換為像素填充
bitmap.allocPixels();
//創(chuàng)建畫布
SkCanvas canvas(bitmap);
//創(chuàng)建畫筆
SkPaint paint;
//設置畫布顏色
canvas.clear(SK_ColorWHITE);
//設置畫筆抗鋸齒
paint.setAntiAlias(true);
//設置畫筆顏色(此處為紅色)
paint.setARGB(255, 255, 0, 0);
//繪制圓形
canvas.drawCircle(80, 80, 40, paint);
//繪制線段
canvas.drawLine(0, 280, w, 280, paint);
//設置字體大小
paint.setTextSize(60);
//繪制字體
canvas.drawString("Hello Skia", 300, 150, paint);
//設置字體大小
paint.setTextSize(20);
//繪制FPS
canvas.drawText(chars, sizeof((char*)chars) - 1, 10, 20, paint);
//返回SkBitmap對象
return bitmap;
}
//通過SDL_Surface創(chuàng)建SDL_Rect
SDL_Rect create_rect(SDL_Surface *surface) {
//創(chuàng)建SDL_Rect對象
SDL_Rect src = { 0, 0, surface->w, surface->h };
//返回SDL_Rect對象
return src;
}
//SDL線程調用的方法
int update(void *data) {
while (!quit) {
//判斷表面是否為空
if (surface != NULL) {
//釋放表面
SDL_FreeSurface(surface);
}
//判斷紋理是否為空
if (texture != NULL) {
//釋放紋理
SDL_DestroyTexture(texture);
}
//繪制位圖
bitmap = draw(rect.w, rect.h);
//創(chuàng)建紋理
surface = SDL_CreateRGBSurfaceFrom(bitmap.getPixels(), rect.w, rect.h, 32, rect.w * 4, RGBA.rmask, RGBA.gmask,
RGBA.bmask, RGBA.amask);
//創(chuàng)建紋理
texture = SDL_CreateTextureFromSurface(renderer, surface);
//復制紋理
SDL_RenderCopy(renderer, texture, NULL, &rect);
//提交渲染
SDL_RenderPresent(renderer);
//休眠16.6毫秒
SDL_Delay(16.6);
//FPS自增長
fps++;
}
return 0;
}
//FPS更新線程方法
int updateFPS(void *data) {
while (!quit){
//拼接字符串
sprintf(chars, "FPS: %d", fps);
//重置FPS
fps = 0;
//每秒獲取一次刷新速率
SDL_Delay(1000);
}
return 0;
}
//初始化
void init() {
//初始化SDL為視頻顯示
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
//創(chuàng)建窗口
window = SDL_CreateWindow("Hello Skia", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
//創(chuàng)建渲染器
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
//清理渲染器
SDL_RenderClear(renderer);
//獲取窗口表面
surface = SDL_GetWindowSurface(window);
//通過SDL_Surface創(chuàng)建矩形
rect = create_rect(surface);
}
//程序的入口點
int main(int args, char *argv[]) {
//初始化
init();
//創(chuàng)建并啟動線程
SDL_Thread *thread = SDL_CreateThread(update, "update", (void *)NULL);
//創(chuàng)建并啟動FPS記錄線程
SDL_Thread *fpsThread = SDL_CreateThread(updateFPS, "fps", (void *)NULL);
//事件隊列
SDL_Event e;
//事件處理
while (!quit) {
//輪詢事件
while (SDL_PollEvent(&e) != 0) {
//用戶退出事件
if (e.type == SDL_QUIT) {
//設置循環(huán)標記
quit = true;
}
}
}
//判斷表面是否為空
if (surface != NULL) {
//釋放表面
SDL_FreeSurface(surface);
}
//判斷紋理是否為空
if (texture != NULL) {
//釋放紋理
SDL_DestroyTexture(texture);
}
//判斷渲染器是否為空
if (renderer != NULL) {
//釋放渲染器
SDL_DestroyRenderer(renderer);
}
//釋放窗口
SDL_DestroyWindow(window);
//結束SDL
SDL_Quit();
//程序退出
return 0;
}
然后嘛,附上一張圖吧
skia_run_on_windows_with_fps.png
擴展知識
關于SDL的 垂直同步 和 硬件加速
硬件加速
開啟SDL的硬件加速只需要在創(chuàng)建SDL的渲染器的時候傳入 SDL_RENDERER_ACCELERATED 字段
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
同理,換成軟件渲染只需要換成 SDL_RENDERER_SOFTWARE 即可
垂直同步
開啟垂直同步只需要在創(chuàng)建SDL的渲染器的時候傳入 SDL_RENDERER_PRESENTVSYNC 字段即可,這樣程序在運行的時候會以最大限度保持在每秒60次的重繪速度
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
當然,通常我們會把硬件加速和垂直同步一起使用,所以我們通常會這么寫
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
好啦,小伙伴們可以隨便玩啦,可以試著測試一下最大的FPS哦~~ 只需要把 SDL_Delay(16.6); 這句注釋掉就可以啦~~
最后放幾張圖吧,我這老爺車跑Visual Studio 2017都吃力
FPS就湊合著看吧(# ̄~ ̄#)使用軟件加速的最大FPS
sdl_sofware_render_fps.png使用硬件加速的最大FPS
sdl_hardware_render_fps.png開啟垂直同步的FPS
sdl_sync_render_fps.png
不知道為什么,在Ubuntu上跑軟加速都能上 800FPS ,硬加速能上 1400FPS
在Windows下咋就不管用了呢? (# ̄~ ̄#)森氣~~




