SDL入门操练

概述

本文使用SDL作为图形库,实现了在一个界面上, 隔一会就出来一个方块,算是学习SDL图形库的入门, 为了方便, 使用了Qt IDE, 而不是在Linux上构建。对于新手来说,对各个函数的名称, 参数, 作用, 返回值都不熟悉, 借用IDE能显著降低入门难度, 就不要逞能直接在vim里写项目了。

项目实现

逻辑流程

在这里插入图片描述

重要控制原语

PS:鉴于其他的函数看名字就知道是啥玩意, 在这里就不赘述,只把不太明显的讲解一下, 大家自己手动敲一遍, 就什么都明白了
SDL_SetRenderTarget把一个纹理设置为渲染目标。接下来的所有对render的操作其实都是操作了纹理。

/**
 * \brief Set a texture as the current rendering target.
 *
 * \param renderer The renderer.
 * \param texture The targeted texture, which must be created with the SDL_TEXTUREACCESS_TARGET flag, or NULL for the default render target
 *
 * \return 0 on success, or -1 on error
 *
 *  \sa SDL_GetRenderTarget()
 */
extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer,
                                                SDL_Texture *texture);

SDL_SetRenderDrawColor这里是以RGB的形式, 定义了一种颜色, 此颜色将被用来在render上画各种图形

/**
 *  \brief Set the color used for drawing operations (Rect, Line and Clear).
 *
 *  \param renderer The renderer for which drawing color should be set.
 *  \param r The red value used to draw on the rendering target.
 *  \param g The green value used to draw on the rendering target.
 *  \param b The blue value used to draw on the rendering target.
 *  \param a The alpha value used to draw on the rendering target, usually
 *           ::SDL_ALPHA_OPAQUE (255).
 *
 *  \return 0 on success, or -1 on error
 */
extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer,
                                           Uint8 r, Uint8 g, Uint8 b,
                                           Uint8 a);

SDL_RenderClear用预设的颜色, 清空render: 说是清空, 其实就是用上一步预设的颜色把整个render都糊上。 这里的clear有很强的迷惑性, 从源码看, 就是把renderer结构体里的r、g、b、a参数, 赋值到了一个SDL_RenderCommand 中相应的变量中,然后就是一系列的回调函数了, 再次要感叹一下SDL的团队了, 把C语言函数指针用的炉火纯青。

/**
 *  \brief Clear the current rendering target with the drawing color
 *
 *  This function clears the entire rendering target, ignoring the viewport and
 *  the clip rectangle.
 *
 *  \return 0 on success, or -1 on error
 */
extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer);

SDL_RenderDrawRect在render上画一个矩形, 大家有心里有数, 这里的render 究竟是真的render还是texture冒充的

/**
 *  \brief Draw a rectangle on the current rendering target.
 *
 *  \param renderer The renderer which should draw a rectangle.
 *  \param rect A pointer to the destination rectangle, or NULL to outline the entire rendering target.
 *
 *  \return 0 on success, or -1 on error
 */
extern DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer * renderer,
                                               const SDL_Rect * rect);

SDL_RenderFillRect使用预设的颜色, 填充当前render上的一个矩形

/**
 *  \brief Fill a rectangle on the current rendering target with the drawing color.
 *
 *  \param renderer The renderer which should fill a rectangle.
 *  \param rect A pointer to the destination rectangle, or NULL for the entire
 *              rendering target.
 *
 *  \return 0 on success, or -1 on error
 */
extern DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer * renderer,
                                               const SDL_Rect * rect);

SDL_RenderCopy把texture上srcrect 的内容 拷贝到 renderer上的dstrect上, 如果srcrect/dstrect为null, 则代表整个。

/**
 *  \brief Copy a portion of the texture to the current rendering target.
 *
 *  \param renderer The renderer which should copy parts of a texture.
 *  \param texture The source texture.
 *  \param srcrect   A pointer to the source rectangle, or NULL for the entire
 *                   texture.
 *  \param dstrect   A pointer to the destination rectangle, or NULL for the
 *                   entire rendering target.
 *
 *  \return 0 on success, or -1 on error
 */
extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer,
                                           SDL_Texture * texture,
                                           const SDL_Rect * srcrect,
                                           const SDL_Rect * dstrect);

代码实现

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

#undef main
using namespace std;
int main()
{
    SDL_Window      *window = nullptr;
    SDL_Renderer    *render = nullptr;
    SDL_Texture     *texture = nullptr;
    SDL_Rect        rect;
    SDL_Event       event;

    SDL_Init(SDL_INIT_VIDEO);
    window = SDL_CreateWindow("sdl window", 30, 30, 700, 400, SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
    if (window == nullptr) {
        SDL_Log("create window failed\n");
        goto _EXIT;
    }
    render = SDL_CreateRenderer(window, -1, 0);
    if (render == nullptr) {
        SDL_Log("create render failed\n");
        goto _FREE_WINDOW;
    }

    texture =  SDL_CreateTexture(render, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_TARGET, 700, 400);
    if (!texture) {
        SDL_Log("create Texture failed\n");
        goto _FREE_RENDER;
    }

    rect.w = 10;
    rect.h = 10;
    while (1) {
        SDL_WaitEventTimeout(&event, 100);
        SDL_Log("event type = %d", event.type);
        if (event.type == SDL_QUIT) {
            SDL_Log("it will quit\n");
            break;
        }

        rect.x = rand() % 700;
        rect.y = rand() % 400;

        //Set a texture as the current rendering target.
        SDL_SetRenderTarget(render, texture);
        //Set the color used for drawing operations (Rect, Line and Clear)
        SDL_SetRenderDrawColor(render, 255, 155, 55, 255);
        //Clear the current rendering target with the drawing color
        SDL_RenderClear(render);

        //Draw a rectangle on the current rendering target
        SDL_RenderDrawRect(render, &rect);
        SDL_SetRenderDrawColor(render, 200, 50, 200, 150);
        //Fill a rectangle on the current rendering target with the drawing color
        SDL_RenderFillRect(render, &rect);

        SDL_SetRenderTarget(render, nullptr);
        //Copy a portion of the texture to the current rendering target.
        SDL_RenderCopy(render, texture, nullptr, nullptr);

        SDL_RenderPresent(render);
    }

    SDL_DestroyTexture(texture);
_FREE_RENDER:
    SDL_DestroyRenderer(render);
_FREE_WINDOW:
    SDL_DestroyWindow(window);
_EXIT:
    SDL_Quit();
    return 0;
}

因为结果是一个动态的, 本人也比较懒惰, 请大家自己运行, 看一下效果!

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值