SDL Development Notes: using SDL to render window colors and pictures

If the article is original, it cannot be reproduced without permission
Original blogger's blog address: https://blog.csdn.net/qq21497936
Original blogger's blog navigation: https://blog.csdn.net/qq21497936/article/details/102478062
This blog address: https://blog.csdn.net/qq21497936/article/details/108602694

The complete blog of red fat man (red imitation): the collection of development technologies (including Qt practical technology, raspberry pie, 3D, OpenCV, OpenGL, ffmpeg, OSG, single chip microcomputer, combination of software and hardware, etc.) is continuously updated... (click the portal)

Qt development column: tripartite library development technology (click the portal)

Previous:< SDL Development Notes (II): introduction to basic audio and playing audio with SDL>
Next: stay tuned


preface

   for Qt applications, for greater cross platform versatility, SDL is used to play audio, and SDL is also popular to render video. Basically, a large number of sdk players on the market are based on SDL, and the incoming window handle is rendered using SDL.


Demo

   cycle render colors:
  

  key rendering color:
  
  press the key to render the picture:
  


SDL rendering process analysis

  the basic process is as follows:
  

Step 1: initialize the subsystem

  SDL_Init() initializes the video system, and other redundant systems do not need to be initialized.

Step 2: create a window

  SDL_CreateWindow() creates a windows window and sets some common properties.

Step 3: create a renderer (bound to the window)

  SDL_CreateRenderer() creates a renderer that is already bound to the displayed window when it is created.

Step 4: color rendering / picture rendering

   this article has three demo s, which are to render simple colors, isomorphic key time to render different colors, and key to render different pictures.
  render simple colors: set render color - > empty - > render

// Step 4: start rendering - render simple colors
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);
}

   press the key to render simple colors: set the rendering color - > empty - > render - > press the key to different colors

// Step 4: start rendering - render the color of the short answer, and accept the key input 0 ~ 9 corresponding to different colors,
// Handle keyboard events
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;
    }
}

   render picture: load picture - > create texture - > empty - > copy texture to rendering - > render.

// Step 4: start rendering - render bmp pictures, 1-2 pictures
SDL_Surface *pSDLSurface = 0;
SDL_Texture *pSDLTexture = 0;
SDL_Surface *pSDLSurface2 = 0;
SDL_Texture *pSDLTexture2 = 0;

SDL_Texture *pSDLTextureTemp = 0;       // For temporary storage

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)
{

    // Empty renderer
    SDL_RenderClear(pSDLRenderer);
    // copy the problem to the renderer
    SDL_RenderCopy(pSDLRenderer, pSDLTextureTemp, 0, 0);
    // Show renderer content
    SDL_RenderPresent(pSDLRenderer);
    // event processing 
    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;
    }
} 

Step 5: destroy the renderer

  SDL_DestroyRenderer();

Step 6: destroy the window

  SDL_DestroyWindow();

Step 7: exit SDL system

  SDL_Quit();


SDL rendering related variables

SDL_Window

  used to identify the window.

SDL_Renderer

   represents a structure that presents a state.

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

   the event system structure of SDL is broad and profound. You can study it carefully in the future. The key mainly uses its type, and then the key value uses its key keysym. sym.

switch (event.type)
{
case SDL_KEYDOWN:
    switch (event.key.keysym.sym)
    {
    case SDLK_ESCAPE:
        out = true;
        break;
    default:
        ;
    }
}

SDL_Surface

   for the pixel set used in the software blitting, this structure shall be regarded as read-only, except for pixels. If it is not empty, it contains the original pixel data of the surface.

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

   texture is an efficient specific representation of pixel data.


SDL rendering correlation function prototype

SDL_Init()

int SDLCALL SDL_Init(Uint32 flags);

   when using this function to initialize the SDL library, you must call it before using most other SDL functions. During initialization, try to be "enough" instead of SDL_INIT_EVERYTHING. There will be some unpredictable problems.

  • Parameter 1: input the initialized device

  

SDL_CreateWindow()

SDL_Window * SDL_CreateWindow(const char *title,
                              int x,
                              int y,
                              int w,
                              int h,
                              Uint32 flags);

  create a window with the specified location, size, and logo.
   the first five parameters are commonly used, and the sixth parameter is the attribute of the window, such as whether the size can be changed, etc

SDL_CreateRenderer()

SDL_Renderer * SDL_CreateRenderer(SDL_Window * window,
                                  int index,
                                  Uint32 flags);

   create a 2d rendering context for the window. Parameter 1 is the window we need to render before.

SDL_SetRenderDrawColor()

int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer,
                                   Uint8 r,
                                   Uint8 g,
                                   Uint8 b,
                                   Uint8 a);

   sets the colors used for drawing operations (rectangle, line, and clear).

SDL_RenderClear()

int SDL_RenderClear(SDL_Renderer * renderer);

  use the drawing color to clear the current rendering target.

SDL_RenderPresent()

void SDL_RenderPresent(SDL_Renderer * renderer);

  update the screen with the executed rendering.

SDL_PollEvent()

int SDL_PollEvent(SDL_Event * event);

  polling of currently pending events.

SDL_LoadBMP()

#define SDL_LoadBMP(file)   SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)
SDL_Surface * SDL_LoadBMP_RW(SDL_RWops * src,
                             int freesrc);

  load surface data from a searchable SDL data stream (memory or file).

SDL_CreateTextureFromSurface()

SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer * renderer,
                                           SDL_Surface * surface);

  create a texture from an existing surface.

  • Parameter 1: bind the renderer of the window.
  • Parameter 2: surface data after loading the file (loaded picture).

SDL_RenderCopy()

int SDL_RenderCopy(SDL_Renderer * renderer,
                   SDL_Texture * texture,
                   const SDL_Rect * srcrect,
                   const SDL_Rect * dstrect);

  copies a portion of the texture to the current render target.

  • Parameter 1: the renderer that should copy the texture part.
  • Parameter 2: source texture
  • Parameter 3: pointer to the source rectangle. If it is set to 0, it will be all.
  • Parameter 4: pointer to the target rectangle. If it is set to 0, it will be all.

SDL_DestroyRenderer()

void SDL_DestroyRenderer(SDL_Renderer * renderer);

  destroy the renderer.

SDL_DestroyWindow()

void SDL_DestroyWindow(SDL_Window * window);

  destroy window.

SDL_Quit()

void SDL_Quit(void);

  this function is used to clear all initialized subsystems. Call it after all exit conditions.


This blog address: https://blog.csdn.net/qq21497936/article/details/108602694

Demo source code

void SDLManager::testRenderWindow()
{
    int ret = 0;
    SDL_Window *pSDLWindow = 0;
    SDL_Renderer *pSDLRenderer = 0;
    SDL_Event event;

    // Step 1: initialize the video subsystem
    ret = SDL_Init(SDL_INIT_VIDEO);
    if(ret)
    {
        LOG << "Failed";
        return;
    }
    // Step 2: create a window that supports opengl and variable size
    pSDLWindow = SDL_CreateWindow("SDL Widget", 
                                   0, 
                                   0, 
                                   800,
                                    480, 
                                   SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    if(!pSDLWindow)
    {
        LOG << "Failed";
        return;
    }
    // Step 3: create a renderer based on the window
    pSDLRenderer = SDL_CreateRenderer(pSDLWindow, -1, 0);
    if(!pSDLRenderer)
    {
        LOG << "Failed";
        return;
    }

#if 0
    // Step 4: start rendering - render simple colors
    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
    // Step 4: start rendering - render the color of the short answer, and accept the key input 0 ~ 9 corresponding to different colors,
    // Handle keyboard events
    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
    // Step 4: start rendering - render bmp pictures, 1-2 pictures
    SDL_Surface *pSDLSurface = 0;
    SDL_Texture *pSDLTexture = 0;
    SDL_Surface *pSDLSurface2 = 0;
    SDL_Texture *pSDLTexture2 = 0;

    SDL_Texture *pSDLTextureTemp = 0;       // For temporary storage

    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)
    {

        // Empty renderer
        SDL_RenderClear(pSDLRenderer);
        // copy the problem to the renderer
        SDL_RenderCopy(pSDLRenderer, pSDLTextureTemp, 0, 0);
        // Show renderer content
        SDL_RenderPresent(pSDLRenderer);
        // event processing 
        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
    // Step 5: destroy the renderer
    SDL_DestroyRenderer(pSDLRenderer);
    // Step 6: destroy the window
    SDL_DestroyWindow(pSDLWindow);
    // Step 7: exit SDL
    SDL_Quit();
}


Project template: corresponding version number v1 two

  corresponding version number v1 2.0: key rendering color and BMP picture


Previous:< SDL Development Notes (II): introduction to basic audio and playing audio with SDL>
Next: stay tuned


Original blogger's blog address: https://blog.csdn.net/qq21497936
Original blogger's blog navigation: https://blog.csdn.net/qq21497936/article/details/102478062
This blog address: https://blog.csdn.net/qq21497936/article/details/108602694

Tags: ffmpeg

Posted by sander_ESP on Mon, 16 May 2022 16:20:06 +0300