美文网首页
SDL开发笔记(初级)

SDL开发笔记(初级)

作者: pengxiaochao | 来源:发表于2020-09-30 10:18 被阅读0次

SDL窗口渲染

SDL(Simple DirectMedia Layer)

由C语言实现的跨平台的媒体开源库

用于游戏开发、模拟器、媒体播放器等多媒体应用领域

注意: 安装步骤

1.下载SDK源代码 (http://www.libsdl.org/index.php)

2.解压源码 tar -zvxf SDL2-2.0.12.tar.gz

3. 编译与安装 ./configure --prefix=/usr/local (后面的路径表示安装路径)

4.安装 sudo make -j 8 && make install

5.安装完毕

xxxx.png

SDL简单用法

SDL_Init() //

SDL_CreateWindow() //

SDL_DestoryWindow() //

SDL_Quit() //

SDL_CreateRender/SDL_DestoryRenderer () //SDL 渲染器创建/销毁

SDL_RenderClear //清空上一次的render数据

SDL_RenderPresent //将数据显示出来

程序内容:

#include<SDL.h>
#include<stdio.h>

int main(int argc, char * argv[]){
    SDL_Window *window = NULL;
    SDL_Renderer *render = NULL;
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
    /*SDL日志输出*/
    SDL_Log("hello SDL");
    
    /*title、坐标x、坐标y、宽、高、 参数*/
    window = SDL_CreateWindow("SDL2 Window",
                                200,
                                400,
                                640,
                                680,
                                SDL_WINDOW_SHOWN);
    if(!window){
        SDL_Log("Fail to create SDL window\n");
        goto __EXIT;
    }

    render = SDL_CreateRenderer(window,-1,0);
    if(!render){
        SDL_Log("Failed to create render\n");
        goto __DESTORYWINDOW;
    }
   
    /* 渲染器、(255,0,0)红色、255 表示透明度*/
    
    SDL_RenderClear(render);
    SDL_SetRenderDrawColor(render,255,0,0,255);
    SDL_RenderPresent(render);
    SDL_Delay(30000);
    
__DESTORYWINDOW:
    SDL_DestroyWindow(window);
   
__EXIT:
    SDL_Quit();
    return 0;
}

使用命令编译: clang -g -o firstsdl firstsdl.c pkg-config --cflags --libs sdl2

运行程序: ./firstsdl

SDL 处理事件

SDL_WindowEvent: //窗口事件

SDL_KeyboardEvent: //键盘事件

SDL_MouseMotionEvent: //鼠标事件

SDL_PollEvent //轮循触发机制

SDL_WaitEvent //事件触发机制

程序内容:

#include<SDL.h>
#include<stdio.h>

int main(int argc, char * argv[]){
    int quit = 1;
    SDL_Event event;
    SDL_Window *window = NULL;
    SDL_Renderer *render = NULL;
    SDL_Init(SDL_INIT_VIDEO);
    /*SDL日志输出*/
    SDL_Log("hello SDL");

    /*title、坐标x、坐标y、宽、高、 参数*/
    window = SDL_CreateWindow("SDL2 Window",
                                SDL_WINDOWPOS_UNDEFINED,
                                SDL_WINDOWPOS_UNDEFINED,
                                640,
                                480,
                                SDL_WINDOW_OPENGL);
    if(!window){
        SDL_Log("Fail to create SDL window\n");
        goto __EXIT;
    }

    render = SDL_CreateRenderer(window,-1,0);
    if(!render){
        SDL_Log("Failed to create render\n");
        goto __DESTORYWINDOW;
    }
   
    /* 渲染器、(255,0,0)红色、255 表示透明度*/
    SDL_SetRenderDrawColor(render,255,0,0,255);
    SDL_RenderClear(render);
    SDL_RenderPresent(render);
    //SDL_Delay(10000);
    
    do {
        
        SDL_WaitEvent(&event);
        switch(event.type){
            case SDL_QUIT:
                quit =0;
                break;
            default:
            SDL_Log("event type is %d",event.type);
        }

    }while(quit);

__DESTORYWINDOW:
    SDL_DestroyWindow(window);
   
__EXIT:
    SDL_Quit();
    return 0;
}

使用命令编译: clang -g -o firstsdl firstsdl.c pkg-config --cflags --libs sdl2

运行程序: ./firstsdl

SDL理解纹理渲染

SDL_CreateTexture(format,access) //format:YUV,RGB 、access:Texture类型、Traget,Stream

SDL_DestoryTexture() //销毁

SDL_SetRenderTarget() //设置渲染的targe

SDL_RenderClear() //清屏

SDL_renderCopy() //将纹理数据copy

SDL_RenderPresent() //将计算好的图形投影到显示器上

程序内容:

#include<SDL.h>
#include<stdio.h>

int main(int argc, char * argv[]){
    int quit = 1;
    SDL_Event event;
    SDL_Window *window = NULL;
    SDL_Renderer *render = NULL;
    SDL_Init(SDL_INIT_VIDEO);
    /*SDL日志输出*/
    SDL_Log("hello SDL");

    /*title、坐标x、坐标y、宽、高、 参数*/
    window = SDL_CreateWindow("SDL2 Window",
                                SDL_WINDOWPOS_UNDEFINED,
                                SDL_WINDOWPOS_UNDEFINED,
                                640,
                                480,
                                SDL_WINDOW_OPENGL);
    if(!window){
        SDL_Log("Fail to create SDL window\n");
        goto __EXIT;
    }

    render = SDL_CreateRenderer(window,-1,0);
    if(!render){
        SDL_Log("Failed to create render\n");
        goto __DESTORYWINDOW;
    }
   
    /* 渲染器、(255,0,0)红色、255 表示透明度*/
    SDL_SetRenderDrawColor(render,255,0,0,255);
    SDL_RenderClear(render);
    SDL_RenderPresent(render);
    //SDL_Delay(10000);

    SDL_Texture *texture = SDL_CreateTexture(render,
                                                SDL_PIXELFORMAT_RGBA8888,
                                                SDL_TEXTUREACCESS_TARGET,
                                                640,480);
    if(!texture){
        SDL_Log("Failed to create texture");
        goto __RENDER;
    }                                                
    do {
        
        SDL_WaitEvent(&event);
        switch(event.type){
            case SDL_QUIT:
                quit =0;
                break;
            default:
            SDL_Log("event type is %d",event.type);
        }

        /* 画一个随机小方块在画布中随机出现*/
        SDL_Rect rect;
        rect.w = 40;
        rect.h = 40;
        rect.x = rand()%640;
        rect.y = rand()%480;

        SDL_SetRenderTarget(render,texture);
        SDL_SetRenderDrawColor(render,0,0,0,0);
        SDL_RenderClear(render);

        SDL_RenderDrawRect(render,&rect);
        SDL_SetRenderDrawColor(render,255,0,0,0);
        SDL_RenderFillRect(render,&rect);

        SDL_SetRenderTarget(render,NULL);
        SDL_RenderCopy(render,texture,NULL,NULL);
        SDL_RenderPresent(render);

    }while(quit);

__RENDER:
SDL_DestroyTexture(texture);

__DESTORYWINDOW:
    SDL_DestroyWindow(window);
   
__EXIT:
    SDL_Quit();
    return 0;
}

使用命令编译: clang -g -o firstsdl firstsdl.c pkg-config --cflags --libs sdl2

运行程序: ./firstsdl

SDL 实现YUV播放器

SDL_CreateThread(fn,name,data) //fn:线程执行参数 name:线程名称,data:执行线程所需的参数

SDL_UpdateTexture() //更新SDL纹理

SDL_UpdateYUVTexture() //更新SDL的YUV纹理(效率更高)

程序内容:(程序有错误,需要调试)

#include <stdio.h>
#include <string.h>
#include <SDL.h>

const int bpp=12;


#define BLOCK_SIZE 4096000

//event message
#define REFRESH_EVENT  (SDL_USEREVENT + 1)
#define QUIT_EVENT  (SDL_USEREVENT + 2)

int thread_exit=0;

int refresh_video_timer(void *udata){

    thread_exit=0;

    while (!thread_exit) {
        SDL_Event event;
        event.type = REFRESH_EVENT;
        SDL_PushEvent(&event);
        SDL_Delay(40);
    }

    thread_exit=0;

    //push quit event
    SDL_Event event;
    event.type = QUIT_EVENT;
    SDL_PushEvent(&event);

    return 0;
}

int main(int argc, char* argv[])
{

    FILE *video_fd = NULL;

    SDL_Event event;
    SDL_Rect rect;

    Uint32 pixformat = 0;

    SDL_Window *win = NULL;
    SDL_Renderer *renderer = NULL;
    SDL_Texture *texture = NULL;
    SDL_Thread *timer_thread = NULL;

    Uint8 *video_buf = NULL;

    int w_width = 640;
    int w_height = 480;
    const int video_width = 320, video_height = 180;

    Uint8 *video_pos = NULL;
    Uint8 *video_end = NULL;

    unsigned int remain_len = 0;
    unsigned int video_buff_len = 0;
    unsigned int blank_space_len = 0;
    Uint8 *video_buf[BLOCK_SIZE];

    const char *path = "test_yuv420p_320x180.yuv";

    /* 定义一个YUV数据包的缓冲区大小
    YUV 表示 4:2:0 、4:0:2*/
    const unsigned int yuv_frame_len = video_width * video_height * 12 / 8;

    //initialize SDL
    if(SDL_Init(SDL_INIT_VIDEO)) {
        fprintf( stderr, "Could not initialize SDL - %s\n", SDL_GetError());
        return -1;
    }

    //creat window from SDL
    win = SDL_CreateWindow("YUV Player",
                           SDL_WINDOWPOS_UNDEFINED,
                           SDL_WINDOWPOS_UNDEFINED,
                           w_width, w_height,
                           SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
    if(!win) {
        fprintf(stderr, "Failed to create window, %s\n",SDL_GetError());
        goto __FAIL;
    }

    renderer = SDL_CreateRenderer(video_width, -1, 0);

    //IYUV: Y + U + V  (3 planes)s
    //YV12: Y + V + U  (3 planes)
    pixformat= SDL_PIXELFORMAT_IYUV;

    //create texture for render
    texture = SDL_CreateTexture(renderer,
                                pixformat,
                                SDL_TEXTUREACCESS_STREAMING,
                                video_width,
                                video_height);

    //open yuv file
    video_fd = fopen(path, "r");
    if( !video_fd ){
        fprintf(stderr, "Failed to open yuv file\n");
        goto __FAIL;
    }

    //read block data
    video_buff_len = fread(video_buf, 1, BLOCK_SIZE, video_fd);
    if(video_buff_len <= 0){
        fprintf(stderr, "Failed to read data from yuv file!\n");
        goto __FAIL;
    }

    /* 视频起始位*/ 
    video_pos = video_buf;
    video_end = video_buf + video_buff_len;
    /* */
    blank_space_len = BLOCK_SIZE - video_buff_len;

    timer_thread = SDL_CreateThread(refresh_video_timer,
                                    NULL,
                                    NULL);

    do {
        //Wait
        SDL_WaitEvent(&event);
        if(event.type==REFRESH_EVENT){
            //not enought data to render
            if((video_pos + yuv_frame_len) > video_end){

                //have remain data, but there isn't space
                remain_len = video_end - video_pos;
                if(remain_len && !black_space_len) {
                    //copy data to header of buffer
                    memcpy(video_buf, video_pos, remain_len);

                    blank_space_len = BLOCK_SIZE - remain_len;
                    video_pos = video_buf;
                    video_end = video_buf + remain_len;
                }

                //at the end of buffer, so rotate to header of buffer
                if(video_end == (video_buf + BLOCK_SIZE)){
                    video_pos = video_buf;
                    video_end = video_buf;
                    blank_space_len = BLOCK_SIZE;
                }

                //read data from yuv file to buffer
                if(video_buff_len = fread(video_end, 1, blank_space_len, video_fd) <= 0){
                    fprintf(stderr, "eof, exit thread!");
                    thread_exit = 1;
                    continue;// to wait event for exiting
                }

                //reset video_end
                video_end += video_buff_len;
            }

            SDL_UpdateTexture( texture, NULL, video_pos, video_width);

            //FIX: If window is resize
            rect.x = 0;
            rect.y = 0;
            rect.w = w_width;
            rect.h = w_height;

            SDL_RenderClear( renderer );
            SDL_RenderCopy( renderer, texture, NULL, &rect);
            SDL_RenderPresent( renderer );

        }else if(event.type==SDL_WINDOWEVENT){
            //If Resize
            SDL_GetWindowSize(win, &w_width, &w_height);
        }else if(event.type==SDL_QUIT){
            thread_exit=1;
        }else if(event.type==QUIT_EVENT){
            break;
        }
    }while ( 1 );

__FAIL:

    //close file
    if(video_fd){
        fclose(video_fd);
    }

    SDL_Quit();

    return 0;
}


使用命令编译: clang -g -o yuv_player yuv_player.c pkg-config --cflags --libs sdl2

运行程序:./yuv_player

SDL 实现音频播放器

SDL_CreateThread() //创建线程

SDL_WaitThread() //等待线程结束

SDL_CreateMutex/SDL_DestroyMutex() //创建互斥锁/销毁互斥锁

SDL_LockMutex/SDL_UnlockMutex() //锁住互斥量/打开互斥量

SDL_CreateCond/SDL_DestroyCond() //创建信号量/销毁信号量

SDL_CondWait/SDL_CondSignal() //等待信号/发送信号

程序内容:

使用命令编译:

运行程序:

相关文章

  • SDL开发笔记(初级)

    SDL窗口渲染 SDL(Simple DirectMedia Layer) 由C语言实现的跨平台的媒体开源库 用于...

  • FFmpeg编程开发笔记 —— Android FFmpeg +

    在前一篇文章FFmpeg编程开发笔记 —— Android 移植 FFmpeg + SDL2.0 库中,我们介绍了...

  • SDL初识

    1、SDL是什么? SDL(Security Development Lifecycle)安全开发生命周期。是微软...

  • SDL安全开发周期

    SDL介绍 安全开发生命周期(SDL)即Security Development Lifecycle,是一个帮助开...

  • SDL简介和使用

    SDL 跨平台硬件访问 Simple DirectMedia(SDL)Layer 是一个跨平台开发库,旨在通过 O...

  • SDL入门

    SDL是什么 SDL的全称是Simple DirectMedia Layer。是一套开源的跨平台多媒体开发库,用C...

  • ffmpeg 、SDL

    目录:1、视频的显示知识;2、SDL简介3、vc下sdl的开发搭建【在mac上应该如何搭建、linux上】4、示例...

  • SDL渲染窗口

    SDL_Init/SDL_Quit() SDL_CreateWindow() / SDL_DestoryWindo...

  • SDL音频API

    SDL_OpenAudio/SDL_CloseAudio SDL_PauseAudio SDL_MixAudio

  • SDL2常用函数

    SDL2常用函数&结构分析:SDL_BlitSurface&SDL_UpdateWindowSurface SDL...

网友评论

      本文标题:SDL开发笔记(初级)

      本文链接:https://www.haomeiwen.com/subject/bmruuktx.html