若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
Qt开发专栏:三方库开发技术(点击传送门)
上一篇:《SDL开发笔记(二):音频基础介绍、使用SDL播放音频》
下一篇:敬请期待
前言
对于Qt应用来说,为了更大的跨平台通用性,使用SDL播放音频,同样也流行使用SDL渲染视频,基本上很大一部分市面上的sdk播放器都是基于sdl的,传入窗口句柄使用sdl渲染。
Demo
循环渲染颜色:
按键渲染颜色:
按键渲染图片:
SDL渲染流程解析
基本流程如下:
步骤一:初始化子系统
SDL_Init()初始化视频系统,其他多余的系统不用初始化。
步骤二:创建窗口
SDL_CreateWindow()创建windows窗口,设置一些常用属性。
步骤三:创建渲染器(与窗口绑定)
SDL_CreateRenderer()创建渲染器,该渲染器创建时已经与显示的窗口进行了绑定。
步骤四:渲染颜色/渲染图片步骤
本篇有3个demo,分别为渲染了简单的颜色,同构按键时间渲染不同的颜色,通过按键渲染不同的图片。
渲染简单的颜色:设置渲染颜色->清空->渲染
// 步骤四:开始渲染-渲染简单的颜色
for(int index = 0; index < 100000; index++)
{
SDL_SetRenderDrawColor(pSDLRenderer,
index/255%255,
index/10%255,
index/20%255,
128);
SDL_RenderClear(pSDLRenderer);
SDL_RenderPresent(pSDLRenderer);
SDL_PollEvent(&event);
}
按键渲染简单的颜色:设置渲染颜色->清空->渲染->按键不同的颜色
// 步骤四:开始渲染-渲染简答的颜色,接受按键输入0~9对应不同的颜色,
// 对键盘事件进行处理
bool out = false;
int r = 0;
int g = 0;
int b = 0;
while(true)
{
SDL_SetRenderDrawColor(pSDLRenderer, r, g, b, 255);
SDL_RenderClear(pSDLRenderer);
SDL_RenderPresent(pSDLRenderer);
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
out = true;
break;
case SDLK_1:
r = 255; g = 0; b = 0;
break;
case SDLK_2:
r = 0; g = 255; b = 0;
break;
case SDLK_3:
r = 0; g = 0; b = 255;
break;
case SDLK_4:
r = 255; g = 255; b = 0;
break;
case SDLK_5:
r = 0; g = 255; b = 255;
break;
case SDLK_6:
r = 255; g = 0; b = 255;
break;
case SDLK_7:
r = 255; g = 255; b = 255;
break;
case SDLK_8:
r = 255; g = 140; b = 0;
break;
case SDLK_9:
r = 0; g = 191; b = 255;
break;
case SDLK_0:
r = 255; g = 215; b = 0;
break;
default:
break;
}
break;
case SDL_QUIT:
out = true;
break;
default:
break;
}
if(out)
{
break;
}
}
渲染图片:加载图片->创建纹理->清空->复制纹理到渲染->渲染。
// 步骤四:开始渲染-渲染bmp图片,1-2两张图片
SDL_Surface *pSDLSurface = 0;
SDL_Texture *pSDLTexture = 0;
SDL_Surface *pSDLSurface2 = 0;
SDL_Texture *pSDLTexture2 = 0;
SDL_Texture *pSDLTextureTemp = 0; // 用于临时存放
bool out = false;
pSDLSurface = SDL_LoadBMP("testBMP/1.bmp");
pSDLTexture = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface);
pSDLSurface2 = SDL_LoadBMP("testBMP/2.bmp");
pSDLTexture2 = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface2);
pSDLTextureTemp = pSDLTexture;
while(true)
{
// 清空渲染器
SDL_RenderClear(pSDLRenderer);
// 将问题copy到渲染器上
SDL_RenderCopy(pSDLRenderer, pSDLTextureTemp, 0, 0);
// 显示渲染器内容
SDL_RenderPresent(pSDLRenderer);
// 事件处理
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
out = true;
break;
case SDLK_1:
pSDLTextureTemp = pSDLTexture;
break;
case SDLK_2:
pSDLTextureTemp = pSDLTexture2;
break;
default:
break;
}
break;
case SDL_QUIT:
out = true;
break;
default:
break;
}
if(out)
{
break;
}
}
步骤五:销毁渲染器
SDL_DestroyRenderer();
步骤六:销毁窗口
SDL_DestroyWindow();
步骤七:退出SDL系统
SDL_Quit();
SDL渲染相关变量
SDL_Window
用于标识窗口。
SDL_Renderer
表示呈现状态的结构。
typedef struct SDL_Surface
{
Uint32 flags; /**< Read-only */
SDL_PixelFormat *format; /**< Read-only */
int w, h; /**< Read-only */
int pitch; /**< Read-only */
void *pixels; /**< Read-write */
/** Application data associated with the surface */
void *userdata; /**< Read-write */
/** information needed for surfaces requiring locks */
int locked; /**< Read-only */
void *lock_data; /**< Read-only */
/** clipping information */
SDL_Rect clip_rect; /**< Read-only */
/** info for fast blit mapping to other surfaces */
struct SDL_BlitMap *map; /**< Private */
/** Reference count -- used when freeing surface */
int refcount; /**< Read-mostly */
} SDL_Surface;
SDL_Event
SDL的事件系统结构体,博大精深,以后兴趣可以仔细研究,按键主要用到了其type,然后键值用到的是其key.keysym.sym。
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
out = true;
break;
default:
;
}
}
SDL_Surface
在软件blitting中使用的像素集合,此结构应被视为只读,但像素除外,如果不为空,则包含表面的原始像素数据。
typedef struct SDL_Surface
{
Uint32 flags; /**< Read-only */
SDL_PixelFormat *format; /**< Read-only */
int w, h; /**< Read-only */
int pitch; /**< Read-only */
void *pixels; /**< Read-write */
/** Application data associated with the surface */
void *userdata; /**< Read-write */
/** information needed for surfaces requiring locks */
int locked; /**< Read-only */
void *lock_data; /**< Read-only */
/** clipping information */
SDL_Rect clip_rect; /**< Read-only */
/** info for fast blit mapping to other surfaces */
struct SDL_BlitMap *map; /**< Private */
/** Reference count -- used when freeing surface */
int refcount; /**< Read-mostly */
} SDL_Surface;
SDL_Texture
纹理,像素数据的一种高效的特定表示。
SDL渲染相关函数原型
SDL_Init()
int SDLCALL SDL_Init(Uint32 flags);
使用此函数初始化SDL库,必须在使用大多数其他SDL函数之前调用它,初始化的时候尽量做到“够用就好”,而不要用SDL_INIT_EVERYTHING。会出现一些不可预知的问题。
- 参数一:输入初始化的设备
SDL_CreateWindow()
SDL_Window * SDL_CreateWindow(const char *title,
int x,
int y,
int w,
int h,
Uint32 flags);
使用指定的位置、尺寸和标志创建一个窗口。
前面5个参数都是常用的,第六个参数是窗口的属性,如是否可改变大小等等.
SDL_CreateRenderer()
SDL_Renderer * SDL_CreateRenderer(SDL_Window * window,
int index,
Uint32 flags);
为窗口创建二维渲染上下文,参数一为我们之前需要渲染的窗口。
SDL_SetRenderDrawColor()
int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer,
Uint8 r,
Uint8 g,
Uint8 b,
Uint8 a);
设置用于绘图操作的颜色(矩形、直线和清除)。
SDL_RenderClear()
int SDL_RenderClear(SDL_Renderer * renderer);
使用绘图颜色清除当前渲染目标。
SDL_RenderPresent()
void SDL_RenderPresent(SDL_Renderer * renderer);
使用已执行的渲染更新屏幕。
SDL_PollEvent()
int SDL_PollEvent(SDL_Event * event);
当前挂起事件的轮询。
SDL_LoadBMP()
#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)
SDL_Surface * SDL_LoadBMP_RW(SDL_RWops * src,
int freesrc);
从可查找的SDL数据流(内存或文件)加载表面数据。
SDL_CreateTextureFromSurface()
SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer * renderer,
SDL_Surface * surface);
从现有表面创建纹理。
- 参数一:绑定窗口的渲染器。
- 参数二:加载文件后的表面数据(加载的图片)。
SDL_RenderCopy()
int SDL_RenderCopy(SDL_Renderer * renderer,
SDL_Texture * texture,
const SDL_Rect * srcrect,
const SDL_Rect * dstrect);
将纹理的一部分复制到当前渲染目标。
- 参数一:应该复制纹理部分的渲染器。
- 参数二:源纹理
- 参数三:指向源矩形的指针,设置为0则全部。
- 参数四:指向目标矩形的指针,设置为0则全部。
SDL_DestroyRenderer()
void SDL_DestroyRenderer(SDL_Renderer * renderer);
销毁渲染器。
SDL_DestroyWindow()
void SDL_DestroyWindow(SDL_Window * window);
销毁窗口。
SDL_Quit()
void SDL_Quit(void);
此函数用于清除所有初始化的子系统。在所有退出条件后调用它。
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694
Demo源码
void SDLManager::testRenderWindow()
{
int ret = 0;
SDL_Window *pSDLWindow = 0;
SDL_Renderer *pSDLRenderer = 0;
SDL_Event event;
// 步骤一:初始化视频子系统
ret = SDL_Init(SDL_INIT_VIDEO);
if(ret)
{
LOG << "Failed";
return;
}
// 步骤二:创建窗口,支持opengl、大小可变
pSDLWindow = SDL_CreateWindow("SDL Widget",
0,
0,
800,
480,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if(!pSDLWindow)
{
LOG << "Failed";
return;
}
// 步骤三:基于窗口创建渲染器
pSDLRenderer = SDL_CreateRenderer(pSDLWindow, -1, 0);
if(!pSDLRenderer)
{
LOG << "Failed";
return;
}
#if 0
// 步骤四:开始渲染-渲染简单的颜色
for(int index = 0; index < 100000; index++)
{
SDL_SetRenderDrawColor(pSDLRenderer,
index/255%255,
index/10%255,
index/20%255, 128);
SDL_RenderClear(pSDLRenderer);
SDL_RenderPresent(pSDLRenderer);
SDL_PollEvent(&event);
}
#endif
#if 0
// 步骤四:开始渲染-渲染简答的颜色,接受按键输入0~9对应不同的颜色,
// 对键盘事件进行处理
bool out = false;
int r = 0;
int g = 0;
int b = 0;
while(true)
{
SDL_SetRenderDrawColor(pSDLRenderer, r, g, b, 255);
SDL_RenderClear(pSDLRenderer);
SDL_RenderPresent(pSDLRenderer);
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
out = true;
break;
case SDLK_1:
r = 255; g = 0; b = 0;
break;
case SDLK_2:
r = 0; g = 255; b = 0;
break;
case SDLK_3:
r = 0; g = 0; b = 255;
break;
case SDLK_4:
r = 255; g = 255; b = 0;
break;
case SDLK_5:
r = 0; g = 255; b = 255;
break;
case SDLK_6:
r = 255; g = 0; b = 255;
break;
case SDLK_7:
r = 255; g = 255; b = 255;
break;
case SDLK_8:
r = 255; g = 140; b = 0;
break;
case SDLK_9:
r = 0; g = 191; b = 255;
break;
case SDLK_0:
r = 255; g = 215; b = 0;
break;
default:
break;
}
break;
case SDL_QUIT:
out = true;
break;
default:
break;
}
if(out)
{
break;
}
}
#endif
#if 1
// 步骤四:开始渲染-渲染bmp图片,1-2两张图片
SDL_Surface *pSDLSurface = 0;
SDL_Texture *pSDLTexture = 0;
SDL_Surface *pSDLSurface2 = 0;
SDL_Texture *pSDLTexture2 = 0;
SDL_Texture *pSDLTextureTemp = 0; // 用于临时存放
bool out = false;
pSDLSurface = SDL_LoadBMP("testBMP/1.bmp");
pSDLTexture = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface);
pSDLSurface2 = SDL_LoadBMP("testBMP/2.bmp");
pSDLTexture2 = SDL_CreateTextureFromSurface(pSDLRenderer, pSDLSurface2);
pSDLTextureTemp = pSDLTexture;
while(true)
{
// 清空渲染器
SDL_RenderClear(pSDLRenderer);
// 将问题copy到渲染器上
SDL_RenderCopy(pSDLRenderer, pSDLTextureTemp, 0, 0);
// 显示渲染器内容
SDL_RenderPresent(pSDLRenderer);
// 事件处理
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
out = true;
break;
case SDLK_1:
pSDLTextureTemp = pSDLTexture;
break;
case SDLK_2:
pSDLTextureTemp = pSDLTexture2;
break;
default:
break;
}
break;
case SDL_QUIT:
out = true;
break;
default:
break;
}
if(out)
{
break;
}
}
#endif
// 步骤五:销毁渲染器
SDL_DestroyRenderer(pSDLRenderer);
// 步骤六:销毁窗口
SDL_DestroyWindow(pSDLWindow);
// 步骤七:退出SDL
SDL_Quit();
}
工程模板:对应版本号v1.2.0
对应版本号v1.2.0:按键渲染颜色和BMP图片
上一篇:《SDL开发笔记(二):音频基础介绍、使用SDL播放音频》
下一篇:敬请期待
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/108602694