SDL is a cross-platform multimedia library. To achieve cross-platform, SDL provides a simple interface library abstraction, such as the Sdl_window used to represent window handles, Sdl_surface, sdl_texture, sdl_renderer for processing screen refreshes and basic graphical drawing, Provides various events (mouse, keyboard, gamepad, etc.) Input events, window message events are used to simulate message-based event handling mechanisms. It also provides a mechanism for thread creation, destruction, and synchronization, which also provides file access, font rendering, multi-format picture loading, and audio mixer extension functions.
It is because of the cross-platform nature of SDL that if you just want to know the functionality of SDL and be able to apply SDL for simple development, then this document is not for you, so go to the SDL official website to see a tutorial on lazy foo or beginning SDL 2.0 (1) SDL feature brief.
The main purpose of this article is that I want to be able to render YUV data in the window frame using SDL, just call video rendering related functions, other cross-platform mechanisms are not required, and the corresponding mechanism is provided under the Windows platform. Or you have a window-based program that wants to use SDL to render video, which is a good introduction.
First, the preparatory work
The development environment I am using is a release version of VS2010,SDL using V2.0.0.3 and is installed in the C:\dev-tools\SDL2-2.0.3 directory. Please follow any other SDL development environment configuration number vs. include path and library path.
Create a Win32 project at the same time, named 0_win32_bmp_render.
Compile and run, the following window will appear:
Second, Sdlvideorender base class
In order to realize the concept of abstraction, we first set up the external interface of the SDL video rendering class, and give the basic framework.
#include <SDL.h>//#include <SDL_main.h>#pragmaComment (lib, "SDL2.lib")classsdlvideorender{ Public: Sdlvideorender (); Virtual~Sdlvideorender (); Virtual BOOLInit (HWND show_wnd, RECT show_rect); Virtual voidDeinit (); //width x Height Resolution//data[] For Y\u\v, stride are linesize of each raw Virtual voidUpdate (intWidthintHeight, unsignedChar*data[3],intstride[3]) =0; Virtual BOOLRender () =0;protected: Sdl_window*M_sdl_window; Sdl_rect M_show_rect;};
When you call the INIT function, you specify the window handle to draw and the display area (relative to the client area coordinates of the window).
If you need to refresh the window (given YUV) data, call the update interface.
The render interface is used to implement the display of the screen.
The M_sdl_window pointer is an abstract handle to the window provided by SDL.
Sdl_rect is a rectangular definition form given by SDL, which is defined as follows:
struct sdl_rect{ int x, y; int W, H;} Sdl_rect;
So what do you need to do to initialize the init function? Create the Sdl_window and save the display area with the following implementation code:
BOOLSdlvideorender::init (HWND show_wnd, RECT show_rect) {//the initialization window handle is empty or the display area is empty if(nullptr = = Show_wnd | | Isrectempty (&show_rect)) { return false; } if(Nullptr! =M_sdl_window) { return true; } if(Sdl_wasinit (Sdl_init_video)) {Sdl_initsubsystem (sdl_init_video); } M_sdl_window=Sdl_createwindowfrom (Show_wnd); if(nullptr = =M_sdl_window) { return false; } m_show_rect.x=Show_rect.left; M_show_rect.y=Show_rect.top; M_SHOW_RECT.W= Show_rect.right-Show_rect.left; M_show_rect.h= Show_rect.bottom-Show_rect.top; return true;}
The Deinit function is exactly the opposite, and the code is as follows:
void Sdlvideorender::D einit () { if (nullptr! = M_sdl_window) { Sdl_destroywindow (m_ Sdl_window); = nullptr; }}
View Code
OK, to this our Sdlvideorender base class function is basically perfect, any program that needs to draw the rendering video can be refreshed through this base class interface.
Third, BMP rendering implementation
The first feature we implemented might not be to load YUV data directly, but to simply understand the video rendering mechanism provided by SDL by loading BMP bitmaps and rendering the display.
Here we add a Bmprender class, inherit from Sdlvideorender, and rewrite the Init, Deinit, and render three functions. The class header file is as follows:
classbmpvideorender:sdlvideorender{ Public: Bmpvideorender (); ~Bmpvideorender (); BOOLInit (HWND show_wnd, RECT show_rect); voidDeinit (); //width x Height Resolution//data[] For Y\u\v, stride are linesize of each raw voidUpdate (intWidthintHeight, unsignedChar*data[3],intstride[3]){} BOOLRender ();Private: Sdl_surface*M_bmp_surface; };
View Code
The INIT function adds a BMP file loaded into the Sdl_surface code. The code to destroy the Sdl_surface is added to the deinit. The implementation is as follows:
BOOLBmpvideorender::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;}voidBmpvideorender::D einit () {if(Nullptr! =m_bmp_surface) {sdl_freesurface (m_bmp_surface); M_bmp_surface=nullptr; } Sdlvideorender::D einit ();}
Render gives a mechanism for how to render sdl_surface to Sdl_window.
BOOL Bmpvideorender::render () { if (nullptr! = m_bmp_surface ) {* window_surface = Sdl_getwindowsurface (M_sdl_window); Sdl_blitscaled (M_bmp_surface, NULL, Window_surface, &m_show_rect); 1 ); } return true ;}
The principle is simple, first get the window surface, directly through the sdl_blitscaled function to render BMP bitmap surface to our pre-specified area.
Iv. integration into the window program
Now that Bmprender is done, how do I invoke it in the window program?
Take the Win32 test program as an example (the first step vs auto-generated code).
First add at the beginning of the 0_win32_bmp_render.cpp file
HWND Hmainwnd; Bmpvideorender Bmprender;
and add it before the main message loop of the _tWinMain: (Note that InvalidateRect is a must, otherwise you can remove it and try it out.) )
if (0 ! = Sdl_init (sdl_init_video) ) {return FALSE ; } = {0}; &show_rect); Show_rect.right/=2; Show_rect.bottom/=2; Bmprender.init (Hmainwnd, show_rect); &show_rect, TRUE);
At the end of the message loop, add:
Bmprender.deinit (); Sdl_quit ();
Add in InitInstance
Hmainwnd = hWnd;
Finally, add the EndPaint function after the wm_paint of the WNDPROC message handler function.
Bmprender.render ();
Compile and run, you get the following: (we zoom the image to the 1/4 area in the upper-left corner of the customer area)
Summarize
This is a very simple demo of SDL drawing bitmaps. The basic concepts involve Sdl_window, Sdl_rect, Sdl_surface, BMP bitmap loading, Surface scaling, window drawing area acquisition, and refresh.
Here is a point, according to the SDL official website, the implementation of Sdl_surface is pure software implementation, does not support hardware acceleration. If the performance requirements are more stringent, it is recommended that you do not rely on sdl_surface too much.
The relevant code can be downloaded from my git URL as follows: Https://git.oschina.net/Tocy/SampleCode.git, located in the Tocysdl2visualtutorial directory.
--------------------------------------------------------------------------------------------------------------- -------------
This article Tocy e-mail: [Email protected]
Copyright @2015, do not use for commercial purposes, reprint please specify the original address. I reserve all rights
Beginning SDL 2.0 (3) SDL Introduction and BMP rendering