SDL渲染RGB图像

发布于:2025-06-30 ⋅ 阅读:(23) ⋅ 点赞:(0)

一什么是SDL

在 FFmpeg 中,使用 SDL 来初始化视频和音频播放器,并将音频和视频数据从 FFmpeg 解码器中读取出来,再通过 SDL 进行处理和显示。

二SDL渲染图像的步骤

先要进行初始化接口,第二部创建一个窗口或者绑定一个窗口句柄,第三步创建一个渲染器,第四步是在这个渲染器中创建一个材质,创建完材质之后需要显示,显示涉及四个步骤,首先就是清屏,更新材质,把内存中的数据传进来,再把材质数值复制到我们的渲染区,最后进行渲染显示。

  1. srcrect:
    • 类型:const SDL_Rect *
    • 描述:指向源矩形的指针,指定从纹理中复制的区域。如果为 NULL,则使用整个纹理作为源区域。
  1. dstrect:
    • 类型:const SDL_Rect *
    • 描述:指向目标矩形的指针,指定将纹理渲染到的目标区域。如果为 NULL,则纹理会被渲染到整个渲染目标(通常是整个窗口)。

 实际设置了20ms间隔发生一次,那么一秒就是50帧,设置了帧率,1s=1000ms,那么20ms发生一次,那么1000/20=50次,发生了50次,那么对应到视频图片就是50帧(但是只是理想情况下)

#include <iostream>
#include <sdl/SDL.h>
using namespace std;
#pragma comment(lib,"SDL2.lib")
#undef main

int main(int argc, char* argv[])
{
    int w = 800;
    int h = 600;
    //1 初始化SDL video库
    if (SDL_Init(SDL_INIT_VIDEO))
    {
        cout << SDL_GetError() << endl;
        return -1;
    }
    //2 生成SDL 窗口
    auto screen = SDL_CreateWindow("test sdl ffmpeg",
        SDL_WINDOWPOS_CENTERED,//窗口位置
        SDL_WINDOWPOS_CENTERED,
        w,h,
        SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE
    );
    if (!screen)
    {
        cout << SDL_GetError() << endl;
        return -2;
    }

    //3 生成渲染器
    auto render = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
    if (!render)
    {
        cout << SDL_GetError() << endl;
        return -3;
    }
    //4 生成材质
    auto texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_ARGB8888,
        SDL_TEXTUREACCESS_STREAMING,// 可加锁
        w, h
    );
    if (!texture)
    {
        cout << SDL_GetError() << endl;
        return -4;
    }

    // 存放图像的数据
    //智能指针分配和管理内存
    shared_ptr<unsigned char> rgb(new unsigned char[w * h * 4]);//使用智能指针,不用释放对象
    auto r = rgb.get();//返回原始指针

    unsigned char tmp = 255;
    for (;;)
    {
        //判断退出
        SDL_Event ev;
        SDL_WaitEventTimeout(&ev, 10);//增加时间控制帧率 100帧每秒
        if (ev.type == SDL_QUIT)
        {
            SDL_DestroyWindow(screen);
            break;
        }
        tmp--;
    
        for (int j = 0; j < h; j++)
        {
            int b = j * w * 4;
            for (int i = 0; i < w*4; i += 4)
            {
                //r指针相当于顺序存储在一维数组中
                r[b + i] = 0;           //B
                r[b + i + 1] = 0;       //G
                r[b + i + 2] = tmp;     //R
                r[b + i + 3] = 0;       //A
            }
        }
        //5 内存数据写入材质
        SDL_UpdateTexture(texture, NULL, r, w * 4);//NULL表示整幅图 

        //6 清理屏幕
        SDL_RenderClear(render);
        
        SDL_Rect sdl_rect;
        sdl_rect.x = 0;
        sdl_rect.y = 0;
        sdl_rect.w = w;
        sdl_rect.h = h;
    
        //7 复制材质到渲染器
        SDL_RenderCopy(render, texture,
            NULL,//原图位置和尺寸
            &sdl_rect//目标位置和尺寸
        );
        //8 渲染
        SDL_RenderPresent(render);
    }
    getchar();
    return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到