SDL入门
本篇主要用于记录SDL2.0.22的基本用法,参考别人的代码,并加了注释方便理解这些api
以下两个demo可以在VS中编译并运行,代码参考 SDL视频显示_奋斗吧!骚年!的博客-CSDN博客
1、SimpleSDL
这个demo使用SDL api来播放yuv视频,运行可以发现窗口并不能移动或者缩放
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> extern "C"
{
#include "SDL.h"
} int main(int argc, char* argv[]) {
// 窗口大小
int screen_w = 1000;
int screen_h = 1000; // 视频大小
const int pixel_w = 352, pixel_h = 288;
const int bpp = 12; // 这里buffer大小为 1 帧数据 width * height * 3 / 2,主要是因为YUV420这种采样方式
unsigned char buffer[pixel_w * pixel_h * bpp / 8]; // 初始化SDL
if (SDL_Init(SDL_INIT_VIDEO))
{
printf("could not initialize SDL: %s\n", SDL_GetError());
return -1;
} // 创建一个SDL_Window
// 第二个参数、第三个参数是相对于显示器左上角的坐标
// 第四个参数、第五个参数是窗口大小
// 最后一个参数为窗口选项
SDL_Window *screen = SDL_CreateWindow("SimpleSDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (!screen)
{
printf("could not create window: %s\n", SDL_GetError());
return -1;
} // 创建一个SDL_Render对象,第一个参数为SDL_Window,第二个参数为图层序号、第三个参数为flags
SDL_Renderer *sdlRenderer = SDL_CreateRenderer(screen, -1, 0); // 数据的存储格式
Uint32 pixformat = SDL_PIXELFORMAT_IYUV; // 创建一个SDL_Texture对象
// 第一个参数为SDL_Render
// 第二个参数为数据格式
//
// 第四第五个为视频的宽高
SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer, pixformat, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h); FILE *fp = fopen("E:\\Videos\\YUV\\352_288.yuv", "rb+");
if (fp == NULL) {
printf("cannot open this file\n");
return -1;
} // 这个sdlRect表示渲染的视频相对窗口的位置
SDL_Rect sdlRect;
sdlRect.x = 20;
sdlRect.y = 50;
sdlRect.w = screen_w;
sdlRect.h = screen_h; int i = 0; while (1) {
if (fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp) != pixel_w * pixel_h * bpp / 8) {
// Loop
fseek(fp, 0, SEEK_SET);
fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp);
} // 更新SDL_Texture
// 最后一个参数为 pitch
SDL_UpdateTexture(sdlTexture, NULL, buffer, pixel_w); // 清除Render中的数据
SDL_RenderClear(sdlRenderer);
// 将sdltexture中的数据拷贝给render
// 第三个参数SDL_Rect表示拷贝的数据范围
// 第四个参数SDL_Rect表示渲染的大小以及相对渲染窗口的位置
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect);
// 渲染
SDL_RenderPresent(sdlRenderer);
//Delay 40ms
SDL_Delay(40); }
SDL_Quit();
return 0;
}
2、advanced SDL
主要用了消息事件机制来做视频播放,这时候窗口可以自由移动并且缩放
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> extern "C"
{
#include "SDL.h"
} // 自定义事件
//Refresh Event
#define REFRESH_EVENT (SDL_USEREVENT + 1)
//Break
#define BREAK_EVENT (SDL_USEREVENT + 2) int thread_exit = 0; int refresh_video(void* opaque) {
thread_exit = 0;
while (thread_exit == 0) {
// 每隔40ms发送一个Refresh
SDL_Event event;
event.type = REFRESH_EVENT;
SDL_PushEvent(&event);
SDL_Delay(4000);
}
thread_exit = 0;
//Break
SDL_Event event;
event.type = BREAK_EVENT;
SDL_PushEvent(&event);
return 0;
} int main(int argc, char* argv[])
{
const int bpp = 12; int screen_w = 500, screen_h = 500;
const int pixel_w = 352, pixel_h = 288; unsigned char buffer[pixel_w * pixel_h * bpp / 8]; if (SDL_Init(SDL_INIT_VIDEO)) {
printf("Could not initialize SDL - %s\n", SDL_GetError());
return -1;
} SDL_Window* screen = SDL_CreateWindow("Advanced SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (!screen) {
printf("SDL: could not create window - exiting:%s\n", SDL_GetError());
return -1;
} SDL_Renderer* sdlRenderer = SDL_CreateRenderer(screen, -1, 0); Uint32 pixformat = SDL_PIXELFORMAT_IYUV; SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer, pixformat, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h); FILE *fp = fopen("E:\\Videos\\YUV\\352_288.yuv", "rb+");
if (fp == NULL) {
printf("cannot open this file\n");
return -1;
} SDL_Rect sdlRect; // 创建一个SDL线程
SDL_Thread* refresh_thread = SDL_CreateThread(refresh_video, NULL, NULL);
SDL_Event event;
while (1) {
// Wait 阻塞等待事件
SDL_WaitEvent(&event);
if (event.type == REFRESH_EVENT) { //如果是刷新事件
if (fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp) != pixel_w * pixel_h * bpp / 8) {
// Loop
fseek(fp, 0, SEEK_SET);
fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp);
} SDL_UpdateTexture(sdlTexture, NULL, buffer, pixel_w); //FIX: If window is resize
// 重新设置渲染区域
sdlRect.x = 0;
sdlRect.y = 0;
sdlRect.w = screen_w;
sdlRect.h = screen_h; SDL_RenderClear(sdlRenderer);
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent(sdlRenderer); }
else if (event.type == SDL_WINDOWEVENT) {
//If Resize
// 如果窗口发生改变,那么就获取窗口大小
SDL_GetWindowSize(screen, &screen_w, &screen_h);
}
else if (event.type == SDL_QUIT) {//如果退出
thread_exit = 1; //让线程安全退出
}
else if (event.type == BREAK_EVENT) {
break;
}
}
SDL_Quit();
return 0;
}
SDL入门的更多相关文章
- SDL入门教程(一):3、MinGW 下的安装与设置
作者:龙飞 3.1:MinGW 是什么? MinGW 提供了一套简单方便的Windows下的基于GCC 程序开发环境.MinGW 收集了一系列免费的Windows 使用的头文件和库文件:同时整合了GN ...
- SDL相关资料
SDL(Simple DirectMedia Layer)是一个自由的跨平台的多媒体开发包,适用于 游戏.游戏SDK.演示软件.模拟器.MPEG播放器和其他应用软件.目前支持windows,linux ...
- SDL 简单入门学习
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie 讨论新闻组及文件 概要 实际学习使用SDL创建窗体,并绘制图形. 前言 今天想要做一个简单的demo ...
- linux之x86裁剪移植---字符界面sdl开发入门
linux下有没有TurboC2.0那样的画点.线.圆的图形函数库,有没有grapihcs.h,或者与之相对应或相似的函数库是什么?有没有DirectX这样的游戏开发库?SDL就是其中之一. SDL( ...
- SDL 威胁建模工具入门 threat modeling tool
http://msdn.microsoft.com/zh-cn/magazine/dd347831.aspx threat modeling tool 威胁建模工具 minifuzz 文件模糊工具 c ...
- Maven学习总结(一)——Maven入门——转载
一.Maven的基本概念 Maven(翻译为"专家","内行")是跨平台的项目管理工具.主要服务于基于Java平台的项目构建,依赖管理和项目信息管理. 1.1. ...
- Windows下FFmpeg快速入门
本系列文章导航 Windows下FFmpeg快速入门 ffmpeg参数解释 mencoder和ffmpeg参数详解(Java处理视频) Java 生成视频缩略图(ffmpeg) 使用ffmpeg进行视 ...
- Windows下FFmpeg高速入门
本系列文章导航 Windows下FFmpeg高速入门 ffmpeg參数解释 mencoder和ffmpeg參数具体解释(Java处理视频) Java 生成视频缩略图(ffmpeg) 使用ffmpeg进 ...
- 【Lucene3.6.2入门系列】第14节_SolrJ操作索引和搜索文档以及整合中文分词
package com.jadyer.solrj; import java.util.ArrayList; import java.util.List; import org.apache.solr. ...
- Windows下FFmpeg快速入门 <第二篇>
FFmpeg简介 FFmpeg是什么? FFmpeg是用于录制.转换和流化音频和视频的完整解决方案, 包括 libavcodec ,一套领先的音/视频编解码类库.FFmpeg 在Linux上开发,当可 ...
随机推荐
- 【Java面试指北】单例模式
单线程下的单例模式: public class Singleton { private static Singleton instance; private Singleton() {} public ...
- WAF 原理入门
WAF 入门 WAF 功能 WAF 全称叫 Web Application Firewall,和传统防火墙的区别是,它是工作在应用层的防火墙,主要对 web 请求/响应进行防护.那么 WAF 有什么功 ...
- docker 应用篇————具名挂载和匿名挂载[十三]
前言 简单整理一下具名挂载和匿名挂载. 正文 来看一下匿名挂载. 这里-v指定了容器内部的路径,但是没有指定容器外部的路径,那么挂载到了什么地方. 用inspect 查看一下. 挂载到这个位置了. 然 ...
- json文件读取并转换成为字典python
# JSON到字典转化 f2 = open('info.json', 'r') info_data = json.load(f2) print(info_data) # 显示数据类型 print(ty ...
- 牛客网-SQL专项训练16
①在book表中,将工具书类型(tool)的书的书架序号都减少2,下列语句正确的是(C) 解析: 题目要求的批量更改,insert 是更改数据,排除B,update与set搭配使用,排除选项D,whe ...
- 阿里云消息队列 Kafka-消息检索实践
简介: 本文章主要介绍消息队列使用过程中所遇到的消息丢失.重复消费等痛点问题的排查办法,以及消息队列 Kafka「检索组件」的场景实践,并对其关键技术进行解读.旨在帮助大家对消息队列 Kafka「检索 ...
- Quick Audience组织和工作空间功能解读
近期,Quick Audience完成了权限系统全面升级,可以解决集团企业不同品牌.不同运营组织,不同消费者运营的诉求,精细化保障企业数据访问安全,提升管控的灵活度. Quick Audience整 ...
- 谁来拯救存量SGX1平台?又一个内核特性合并的血泪史
简介: 今天的故事主角,是一个被称为Flexible Launch Control的SGX平台特性. 前言 自从Intel内核开发人员Jarkko Sakkinen于2017年9月2日在inte ...
- [Nova] KeyValue Field 设置默认 key 的方式
1. 使用 withMeta: KeyValue::make('options') ->withMeta([ 'value' => $this->options ?? [ 'A' = ...
- WPF 更改 DrawingVisual 的 RenderOpen 用到的对象的内容将持续影响渲染效果
在 WPF 里面,可以通过 DrawingVisual 来进行使用底层的绘制方法,此方法需要调用 DrawingVisual 的 RenderOpen 拿到 DrawingContext 类型的对象, ...