SDL2第三篇。git
SDL2入門github
SDL2事件處理函數
接下來就看下如何使用SDL如何經過SDL_Texture在窗口繪製圖像。post
先了解幾個紋理渲染相關API:ui
SDL_Texture* SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h);
複製代碼
format: 像素格式,YUV或RGBspa
access: 指明Texture的類型。能夠是 Stream(視頻),也能夠是Target通常的類型。code
void SDL_DestroyTexture(SDL_Texture* texture) 複製代碼
//將渲染目標定爲紋理
int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture);
複製代碼
//會將紋理拷貝到顯卡上去,顯卡會計算出最終圖形並渲染到窗口中
int SDL_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srcrect, const SDL_Rect* dstrect) 複製代碼
srcrect: 指定 Texture 中要渲染的一部分。若是將 Texture所有輸出,能夠設置它爲 NULL。orm
dstrect: 指定輸出的空間大小。視頻
在前面Demo的基礎上作了必定修改,簡單實現一個正方形在界面中隨機顯示。事件
#include <stdio.h>
#include <SDL2/SDL.h>
int WinMain() {
int quit = 1;
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *sdlTexture = NULL;
SDL_Event event;
SDL_Rect rect; // 長方形,原點在左上角
rect.w = 50;
rect.h = 50;
SDL_Init(SDL_INIT_VIDEO);//初始化函數,能夠肯定但願激活的子系統
window = SDL_CreateWindow("My First Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);// 建立窗口
if (!window) {
return -1;
}
renderer = SDL_CreateRenderer(window, -1, 0);//基於窗口建立渲染器
if (!renderer) {
return -1;
}
// SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); //設置渲染器顏色
// SDL_RenderClear(renderer); //用指定的顏色清空緩衝區
// SDL_RenderPresent(renderer); //將緩衝區中的內容輸出到目標窗口上
sdlTexture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET,
640,
480); //建立紋理
if (!sdlTexture) {
return -1;
}
while (quit) {
SDL_PollEvent(&event); // SDL_WaitEvent在這裏就不太適合,只有在事件發生時纔會觸發,其他時間都是阻塞狀態
switch (event.type) {
case SDL_QUIT:
SDL_Log("quit");
quit = 0;
break;
default:
SDL_Log("event type:%d", event.type);
}
rect.x = rand() % 600;
rect.y = rand() % 400;
SDL_SetRenderTarget(renderer, sdlTexture); // 設置渲染目標爲紋理
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); // 紋理背景爲黑色
SDL_RenderClear(renderer); //清屏
SDL_RenderDrawRect(renderer, &rect); //繪製一個長方形
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); //長方形爲白色
SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderTarget(renderer, NULL); //恢復默認,渲染目標爲窗口
SDL_RenderCopy(renderer, sdlTexture, NULL, NULL); //拷貝紋理到CPU
SDL_RenderPresent(renderer); //輸出到目標窗口上
}
SDL_DestroyTexture(sdlTexture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window); //銷燬窗口
SDL_Quit();
return 0;
}
複製代碼
上面這個Demo就是最簡單的紋理渲染流程。
接下來再認識兩個API:
//兩個API功能相同,可是SDL_UpdateYUVTexture直接將Y、U、V份量傳入,能夠減小CPU計算量,更快一些
int SDL_UpdateTexture(SDL_Texture * texture, //想要更新的紋理 const SDL_Rect * rect, //更新的像素矩形,傳NULL則表示爲整個紋理 const void *pixels, //像素數據 int pitch);//一行像素數據的字節數
int SDL_UpdateYUVTexture(SDL_Texture * texture, const SDL_Rect * rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch);
複製代碼
這兩個API將會在視頻播放中發揮重要做用,下一篇博客將會結合FFmpeg實現一個簡易的視頻播放器。