SDL渲染一幅图像

环境配置

下载源码:http://www.libsdl.org/download-2.0.php

进入到 SDL2-2.0.14\VisualC 用visual studio 2019 打开 SDL.sln

将工程升级到vs2019选择对的,debug|release x64|x86进行编译生成相应的.dll.pdb.lib

然后将对应的.dll.pdb.lib放到对应目录中,并配置值相应的工程目录

API介绍

1.使用SDL_init初始化SDL video库

#define SDL_INIT_TIMER          0x00000001u  //定时器
#define SDL_INIT_AUDIO          0x00000010u  //音频
#define SDL_INIT_VIDEO          0x00000020u  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */  //视频
#define SDL_INIT_JOYSTICK       0x00000200u  /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ //摇杆
#define SDL_INIT_HAPTIC         0x00001000u  //触摸屏
#define SDL_INIT_GAMECONTROLLER 0x00002000u  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ //游戏控制
#define SDL_INIT_EVENTS         0x00004000u //事件
#define SDL_INIT_SENSOR         0x00008000u //传感器
#define SDL_INIT_NOPARACHUTE    0x00100000u  /**< compatibility; this flag is ignored. */  //屏蔽所有信号
#define SDL_INIT_EVERYTHING ( \
                SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \
            ) //接受所有信号


/**
 *  This function initializes  the subsystems specified by \c flags
 */
extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags);

//-----------------------------------------------------------------------------//

SDL_Init(SDL_INIT_VIDEO);

2.使用SDL_CreateWindow创建窗口

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

//title 窗体名称
//x     窗体位置
//y     窗体位置
//w     窗体宽 
//h     窗体高
//flags  窗体属性
typedef enum
{
    SDL_WINDOW_FULLSCREEN = 0x00000001,         /**< fullscreen window */
    SDL_WINDOW_OPENGL = 0x00000002,             /**< window usable with OpenGL context */
    SDL_WINDOW_SHOWN = 0x00000004,              /**< window is visible */
    SDL_WINDOW_HIDDEN = 0x00000008,             /**< window is not visible */
    SDL_WINDOW_BORDERLESS = 0x00000010,         /**< no window decoration */
    SDL_WINDOW_RESIZABLE = 0x00000020,          /**< window can be resized */
    SDL_WINDOW_MINIMIZED = 0x00000040,          /**< window is minimized */
    SDL_WINDOW_MAXIMIZED = 0x00000080,          /**< window is maximized */
    SDL_WINDOW_INPUT_GRABBED = 0x00000100,      /**< window has grabbed input focus */
    SDL_WINDOW_INPUT_FOCUS = 0x00000200,        /**< window has input focus */
    SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */
    SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
    SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */
    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported.
                                                     On macOS NSHighResolutionCapable must be set true in the
                                                     application's Info.plist for this to have any effect. */
    SDL_WINDOW_MOUSE_CAPTURE = 0x00004000,      /**< window has mouse captured (unrelated to INPUT_GRABBED) */
    SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000,      /**< window should always be above others */
    SDL_WINDOW_SKIP_TASKBAR  = 0x00010000,      /**< window should not be added to the taskbar */
    SDL_WINDOW_UTILITY       = 0x00020000,      /**< window should be treated as a utility window */
    SDL_WINDOW_TOOLTIP       = 0x00040000,      /**< window should be treated as a tooltip */
    SDL_WINDOW_POPUP_MENU    = 0x00080000,      /**< window should be treated as a popup menu */
    SDL_WINDOW_VULKAN        = 0x10000000,      /**< window usable for Vulkan surface */
    SDL_WINDOW_METAL         = 0x20000000       /**< window usable for Metal view */
} SDL_WindowFlags;


//------------------------------------------------------------------------------------//

int w = 800;
int h = 600; 

//用auto类型接受,窗口句柄

auto screen = SDL_CreateWindow("test sdl ffmpeg"    // 窗体名称
        , SDL_WINDOWPOS_CENTERED    //宏定义的屏幕位置参数,窗体位置
        , SDL_WINDOWPOS_CENTERED    //宏定义的屏幕位置参数,窗体位置
        , w, h                      // 窗体宽高
        , SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE  //窗体属性,使用OpenGL渲染,且大小可变
    );

3.使用SDL_CreateRenderer创建渲染器

SDL_CreateRenderer(SDL_Window * window,index, Uint32 flags);
//窗口句柄          之前创建的窗口句柄
//渲染器索引序号     表示渲染器的序号
//渲染器属性标志位   


typedef enum
{
    SDL_RENDERER_SOFTWARE = 0x00000001,         /**< The renderer is a software fallback */
    SDL_RENDERER_ACCELERATED = 0x00000002,      /**< The renderer uses hardware
                                                     acceleration */
    SDL_RENDERER_PRESENTVSYNC = 0x00000004,     /**< Present is synchronized
                                                     with the refresh rate */
    SDL_RENDERER_TARGETTEXTURE = 0x00000008     /**< The renderer supports
                                                     rendering to texture */
} SDL_RendererFlags;


//---------------------------------------------------------------------------//

auto render = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);  //渲染器使用硬件加速

4.使用SDL_CreateTexture创建纹理

SDL_CreateTexture(SDL_Renderer * renderer,Uint32 format,int access, int w,int h);
//SDL_Renderer 渲染器句柄
//format 纹理格式
//access 纹理访问属性
//w      纹理宽
//h      纹理高


typedef enum
{
    SDL_TEXTUREACCESS_STATIC,    /**< Changes rarely, not lockable */
    SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */
    SDL_TEXTUREACCESS_TARGET     /**< Texture can be used as a render target */
} SDL_TextureAccess;


//---------------------------------------------------------------------------------//

SDL_CreateTexture(render, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h);

5.使用SDL_UpdateTexture将数据更新到纹理中

SDL_UpdateTexture(SDL_Texture * texture,const SDL_Rect * rect,const void *pixels, int pitch);

//texture 纹理句柄
//rect    指向要更新的像素矩形的指针,或为NULL以更新整个纹理。
//pixels  像素的行
//pitch   像素的列,注意通道数统一到列里面放置,因此实际列数为宽度乘以通道数

//--------------------------------------------------------------------------------//

SDL_UpdateTexture(texture, NULL, r, w * 4);

6.使用SDL_RenderClear(render)清理渲染器

 SDL_RenderClear(render);

7.使用SDL_RenderCopy复制材质到渲染器中

SDL_RenderCopy(SDL_Renderer * renderer,SDL_Texture * texture,const SDL_Rect * srcrect,const SDL_Rect * dstrect);
//renderer 渲染器 
//texture  纹理
//srcrect 指向要更新的像素矩形的指针,或为NULL以更新整个纹理
//dstrect 指向目标矩形的指针,对于整个呈现目标为NULL

//-------------------------------------------------------------------------------//
SDL_RenderCopy(render, texture, NULL, &sdl_rect);

8.使用SDL_RenderPresent进行渲染

SDL_RenderPresent(render);   //执行渲染

 

代码样例

通过对以上API 接口的运用,将串到一起前,循环渲染显示一张图片

// first_sdl.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <sdl2/SDL.h>

using namespace std;
#pragma comment(lib,"SDL2.lib")
//lib代码中定义了一个main函数 与此处的main函数发生了冲突
//所以需要屏蔽掉main函数
#undef main

int main()
{
    //创建一个窗口 定义窗口高宽
    int w = 800;
    int h = 600; 

    //初始化SDL video库
    if (SDL_Init(SDL_INIT_VIDEO)) //成功返回零,失败返回非零
    {
        cout << SDL_GetError() << endl;
        return -1;
    }
    //生成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 -1;
    }

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

    

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

        if (ev.type == SDL_QUIT)
        {
            SDL_DestroyWindow(screen);
            break;
        }
        
        //动态更新矩阵中填充的内容
        for (int j = 0; j < h; j++)
        {
            int b = j * w * 4;
            for (int i = 0; i < w * 4; i += 4)
            {
                r[b + i] = 0;         //B
                r[b + i + 1] = 255-tmp;   //G
                r[b + i + 2] = 0;     //R
                r[b + i + 3] = 0;     //A
            }
        }
        tmp--;
        //5 将内容数据写入材质
        SDL_UpdateTexture(texture, NULL, r, w * 4);

        //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);             // 仅将渲染的位置控制到渲染器的rect范围中

        //8 渲染
        SDL_RenderPresent(render);
    }
    getchar();
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值