Beginning SDL 2.0(3) SDL介绍及BMP渲染
2015-08-19 21:34
323 查看
SDL是一个跨平台的多媒体库。为了实现跨平台,SDL提供了一个简单的界面库抽象,比如提供了SDL_Window用于表示窗口句柄,SDL_Surface、SDL_Texture、SDL_Renderer用于处理画面刷新及基本的图形绘制,提供各种事件(鼠标、键盘、游戏手柄等)输入事件、窗口消息事件用于模拟基于消息的事件处理机制。同时也提供了线程创建、销毁以及同步的机制,在此基础上上也提供了文件访问、字体渲染、多格式图片加载、混音器等扩展功能。
正是由于SDL的跨平台特性,如果你仅仅是希望知道SDL的功能,并能够应用SDL做简单的开发,那这篇文件不适合你,建议去SDL官网上看看Lazy Foo的教程或者Beginning SDL 2.0(1) SDL功能简介。
撰写本文的主要目的在于,我希望可以在window框架下使用SDL渲染YUV数据,仅仅调用视频渲染有关的函数,其他跨平台的机制不需要,windows平台下都提供了对应的机制。或者你现有基于window框架的程序,希望使用SDL渲染视频,这也是一篇不错的介绍文章。
同时创建一个Win32的工程,命名为0_Win32_bmp_render。
编译并运行,会有如下窗口显示:
View Code
Init函数添加了Bmp文件加载到SDL_Surface的代码。Deinit中添加了销毁SDL_Surface的代码。其实现如下:
Render给出了如何将SDL_Surface渲染到SDL_Window上的机制。
原理很简单,先获取窗口的surface,直接通过SDL_BlitScaled函数将BMP位图Surface渲染到我们事先指定的区域。
以win32的测试程序为例(第一步vs自动生成的代码)。
首先在0_Win32_bmp_render.cpp文件开头添加
并在_tWinMain的主消息循环之前添加:(注意InvalidateRect是必须的,否则你可以去掉试试。)
在消息循环结束的时候添加:
在InitInstance中添加
最后在WndProc消息处理函数的WM_PAINT的EndPaint函数之后添加
编译运行,就会得到下面效果图:(我们将图片缩放到客户区的左上角的1/4的区域)
这里说明一点,据SDL官网介绍,SDL_Surface的实现是纯软件实现的,不支持硬件加速。如果对性能要求比较苛刻,建议不要过多依赖SDL_Surface。
相关代码可以从我的git下载,url如下:https://git.oschina.net/Tocy/SampleCode.git,位于TocySDL2VisualTutorial目录下。
----------------------------------------------------------------------------------------------------------------------------
本文作者:Tocy e-mail: zyvj@qq.com
版权所有@2015,请勿用于商业用途,转载请注明原文地址。本人保留所有权利
正是由于SDL的跨平台特性,如果你仅仅是希望知道SDL的功能,并能够应用SDL做简单的开发,那这篇文件不适合你,建议去SDL官网上看看Lazy Foo的教程或者Beginning SDL 2.0(1) SDL功能简介。
撰写本文的主要目的在于,我希望可以在window框架下使用SDL渲染YUV数据,仅仅调用视频渲染有关的函数,其他跨平台的机制不需要,windows平台下都提供了对应的机制。或者你现有基于window框架的程序,希望使用SDL渲染视频,这也是一篇不错的介绍文章。
一、准备工作
我使用的开发环境是VS2010,SDL使用V2.0.0.3的发布版本,并且安装在C:\dev-tools\SDL2-2.0.3目录下。请按照其他任何SDL的开发环境配置号vs的包含路径和库路径。同时创建一个Win32的工程,命名为0_Win32_bmp_render。
编译并运行,会有如下窗口显示:
class BmpVideoRender: SDLVideoRender { public: BmpVideoRender(); ~BmpVideoRender(); bool Init(HWND show_wnd, RECT show_rect); void Deinit(); // width x height resolution // data[] for Y\U\V, stride is linesize of each raw void Update(int width, int height, unsigned char *data[3], int stride[3]){} bool Render(); private: SDL_Surface * m_bmp_surface; };
View Code
Init函数添加了Bmp文件加载到SDL_Surface的代码。Deinit中添加了销毁SDL_Surface的代码。其实现如下:
bool BmpVideoRender::Init(HWND show_wnd, RECT show_rect) { if (!SDLVideoRender::Init(show_wnd, show_rect)) { return false; } m_bmp_surface = SDL_LoadBMP("hello_world.bmp"); if (nullptr == m_bmp_surface) { return false; } return true; } void BmpVideoRender::Deinit() { if (nullptr != m_bmp_surface) { SDL_FreeSurface(m_bmp_surface); m_bmp_surface = nullptr; } SDLVideoRender::Deinit(); }
Render给出了如何将SDL_Surface渲染到SDL_Window上的机制。
bool BmpVideoRender::Render() { if (nullptr != m_bmp_surface) { SDL_Surface * window_surface = SDL_GetWindowSurface(m_sdl_window); SDL_BlitScaled(m_bmp_surface, NULL, window_surface, &m_show_rect); SDL_UpdateWindowSurfaceRects(m_sdl_window, &m_show_rect, 1); } return true; }
原理很简单,先获取窗口的surface,直接通过SDL_BlitScaled函数将BMP位图Surface渲染到我们事先指定的区域。
四、集成到window程序中
既然BmpRender已经完成了,那么怎么在Window程序中调用呢?以win32的测试程序为例(第一步vs自动生成的代码)。
首先在0_Win32_bmp_render.cpp文件开头添加
HWND hMainWnd; BmpVideoRender bmpRender;
并在_tWinMain的主消息循环之前添加:(注意InvalidateRect是必须的,否则你可以去掉试试。)
if (0 != SDL_Init(SDL_INIT_VIDEO)) { return FALSE; } RECT show_rect = {0}; GetClientRect(hMainWnd, &show_rect); show_rect.right/=2; show_rect.bottom/=2; bmpRender.Init(hMainWnd, show_rect); InvalidateRect(hMainWnd, &show_rect, TRUE);
在消息循环结束的时候添加:
bmpRender.Deinit(); SDL_Quit();
在InitInstance中添加
hMainWnd = hWnd;
最后在WndProc消息处理函数的WM_PAINT的EndPaint函数之后添加
bmpRender.Render();
编译运行,就会得到下面效果图:(我们将图片缩放到客户区的左上角的1/4的区域)
总结
这是一篇很简单的SDL绘制位图的demo。基本概念涉及到SDL_Window、SDL_Rect、SDL_Surface、BMP位图加载、Surface缩放、窗口绘制区域获取和刷新。这里说明一点,据SDL官网介绍,SDL_Surface的实现是纯软件实现的,不支持硬件加速。如果对性能要求比较苛刻,建议不要过多依赖SDL_Surface。
相关代码可以从我的git下载,url如下:https://git.oschina.net/Tocy/SampleCode.git,位于TocySDL2VisualTutorial目录下。
----------------------------------------------------------------------------------------------------------------------------
本文作者:Tocy e-mail: zyvj@qq.com
版权所有@2015,请勿用于商业用途,转载请注明原文地址。本人保留所有权利
相关文章推荐
- 夜· 启程
- 夜· 启程
- 严格模式和混杂模式
- Codeforces Round #244 (Div. 2) B. Prison Transfer
- JAVA的简单计算器设计
- 从B 树、B+ 树、B* 树
- 编写高质量代码改善C#程序的157个建议——建议89:在并行方法体中谨慎使用锁
- [rxjs] Async, handle data over time
- struts2 学习之 redirectAction初步认识
- C语言字符串库函数的实现也是笔试题常考的题目,以下代码没有严格测试,只是简单的实现:
- hdu1599(floyd算法讲解)
- 技术路线
- ubuntu自动挂载smba服务器
- hdoj 1312 Red and Black
- uva 1324 Bring Them There (最大流)
- iOS网络开发编程之NSURLConnection详解 iOS网络层常用的库如ASIHTTPRequest,AFNetworking,MKNetworkKit等知名的第三方库。随着ASI不再更新,楼主
- laravel队列-让守护进程处理耗时任务
- jquery实现简单轮播
- OC中定义了一个结构体(struct),设置结构体的值
- AndroidStudio启动时发生The environment variable JAVA_HOMExxxdoes not point to a valid jvm installation的错误