SDL创建视频窗口图像

一、创建流程

1.SDL初始化
flags可以填:
SDL_INIT_TIMER:定时器
SDL_INIT_AUDIO:音频
SDL_INIT_VIDEO:视频
SDL_INIT_JOYSTICK:摇杆
SDL_INIT_HAPTIC:触摸屏
SDL_INIT_GAMECONTROLLER:游戏控制器
SDL_INIT_EVENTS:事件
SDL_INIT_EVERYTHING:包含上述所有选项
SDL_INIT_NOPARACHUTE:不捕获关键信号

extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags);

2.创建窗口
title : 窗口名字
x : 在显示屏上的位置
y : 在显示屏上的位置
w : 窗口宽度
h : 窗口高度
flags :窗口的属性 可以填:

    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 */
extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title,
                                                      int x, int y, int w,
                                                      int h, Uint32 flags);

3.生成渲染器
window:第二步生成的窗口
index :-1
flags:渲染时使用硬件还是软件

    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 */
extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window,
                                               int index, Uint32 flags);

4.生成材质
renderer : 第三步的渲染器
format: 材质的像素格式
access:是否可以加锁
w: 宽
h: 高

extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer,
                                                        Uint32 format,
                                                        int access, int w,
                                                        int h);

5.内存数据写入材质
texture:第四步材质
rect:
pixels:内存数据
pitch:一行多长按字节算

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

6.清理屏幕

extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer);

7.复制材质到渲染
renderer : 渲染
texture :材质
srcrect : 原图位置和尺寸
dstrect : 目标位置和尺寸

extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer,
                                           SDL_Texture * texture,
                                           const SDL_Rect * srcrect,
                                           const SDL_Rect * dstrect);

8.渲染

extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer);

二、完整代码

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

#undef main
int sdl_flush_rgb_windows(int argc, char* argv[]) 
{
	int width  = 800;
	int height = 900;

	/* 初始化sdl */
	if (SDL_Init(SDL_INIT_VIDEO)) 
	{
		cout << SDL_GetError() << endl;
		return -1;
	}

	/**
	    para 1 窗口名字
		para 2 窗口在界面中的位置
        para 3 窗口在界面中的位置
		para 4 窗口自身宽
		para 5 窗口自身高
		para 6 允许做哪些操作?
	*/
	auto screen = SDL_CreateWindow("SDL_Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height,
		SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
	if (!screen) 
	{
		cout << SDL_GetError() << endl;
		return -1;
	}

	/* 生成渲染器 */
	/**
		para 1 渲染的窗口
		para 2 
		para 3 使用硬件渲染还是软件渲染
	*/
	auto render = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
	if (!render) 
	{
		cout << SDL_GetError() << endl;
		return -1;
	}

	/* 生成材质 */
	auto texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, //可以加锁
	    width, height);
	if (!texture)
	{
		cout << SDL_GetError() << endl;
		return -1;
	}

	/* 存放图像数据 */
	shared_ptr<unsigned char> rgb(new unsigned char[width * height * 4]);
	auto r = rgb.get();
	unsigned char tmp = 255;
	while (1)
	{
		SDL_Event ev;
		SDL_WaitEventTimeout(&ev, 10);
		if (ev.type == SDL_QUIT)
		{
			SDL_DestroyWindow(screen);
			break;
		}
		tmp--;
		for (int i = 0; i < height; i++)
		{
			int b = i * width * 4;
			for (int j = 0; j < width * 4; j += 4)
			{
				r[b + j] = 255;       // B
				r[b + j + 1] = tmp; // G
				r[b + j + 2] = 255;   // R
				r[b + j + 3] = 255;   // A
			}
		}

		/* 内存数据写入材质 */
		SDL_UpdateTexture(texture, NULL, r, width * 4);

		/* 清理屏幕 */
		SDL_RenderClear(render);

		/* 复制材质到渲染 */
		SDL_Rect sdl_rect;
		sdl_rect.x = 0;
		sdl_rect.y = 0;
		sdl_rect.w = width;
		sdl_rect.h = height;

		SDL_RenderCopy(render, texture,
			NULL,   //原图位置和尺寸
			&sdl_rect); //目标位置和尺寸

		/* 具体渲染 */
		SDL_RenderPresent(render);
	}

	getchar();
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在Qt中嵌入SDL2窗口,首先需要进行一些准备工作。首先,确保已经安装了Qt和SDL2,并且你的项目是一个Qt项目。 在Qt项目中,创建一个新的Qt窗口类,例如“MainWindow”,并在该类的构造函数中进行初始化。如下所示: ``` MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { // 设置窗口标题等 // 创建一个QWidget,作为SDL2窗口的父容器 QWidget *sdlContainer = new QWidget(this); setCentralWidget(sdlContainer); // 获取SDL窗口的句柄 SDL_Window *sdlWindow = SDL_CreateWindowFrom((void *)sdlContainer->winId()); } ``` 在上面的代码中,我们首先创建一个QWidget作为SDL2窗口的父容器,并将其设置为主窗口的中心窗口。然后,我们使用Qt的winId()函数获取sdlContainer的窗口句柄,并将其传递给SDL_CreateWindowFrom函数,从而创建一个SDL窗口。 接下来,我们可以将SDL渲染器渲染到这个窗口中。我们需要在主窗口类中添加一个paintEvent事件,用于处理窗口重绘。如下所示: ``` void MainWindow::paintEvent(QPaintEvent *event) { // 在窗口重绘时,将SDL渲染器绘制到窗口SDL_Renderer *sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, 0); SDL_RenderClear(sdlRenderer); // 在这里进行SDL渲染器的渲染操作,例如绘制图形、绘制图片等 SDL_RenderPresent(sdlRenderer); // 调用父类的绘图事件处理函数 QMainWindow::paintEvent(event); } ``` 在上面的代码中,我们创建一个SDL渲染器,并在paintEvent事件中进行渲染操作。请注意,在窗口重绘之前,需要先清除渲染器,然后再进行绘制操作,最后调用SDL_RenderPresent函数将渲染结果显示到窗口上。 通过以上步骤,你可以在Qt中成功嵌入SDL2窗口并进行渲染操作。记得在程序结束时要释放SDL的资源,以避免内存泄漏。 ### 回答2: 将Qt框架与SDL2窗口嵌入可以通过以下步骤实现: 首先,在Qt应用程序中创建一个QWidget对象。例如,可以使用QMainWindow或QDialog来创建一个窗口。 接下来,使用QNativeWindow类将QWidget转换为原生的窗口句柄。可以通过调用QWidget的winId()函数来获取窗口的原生句柄。 然后,使用SDL_CreateWindowFrom函数将窗口的原生句柄传递给SDL2库以创建一个与Qt窗口相关联的SDL窗口。这样,SDL窗口就会嵌入到Qt窗口中。 在创建SDL窗口后,我们可以使用SDL_Renderer以及其他SDL函数来在SDL窗口中绘制图形、处理输入事件等操作。 最后,需要在Qt应用程序的事件循环中处理SDL2窗口的事件。通过使用QObject::startTimer()函数,我们可以将SDL2窗口的事件与Qt应用程序的事件循环相集成,以确保正确地处理事件。 在嵌入SDL2窗口时,还要注意一些限制。由于SDL2和Qt的事件处理机制不同,需要进行一些额外的处理,以确保事件正确传递和处理。另外,还需要注意窗口尺寸、位置等方面的调整,以确保SDL2窗口正确地嵌入到Qt窗口中。 总之,通过以上步骤,我们可以成功地在Qt应用程序中嵌入SDL2窗口,并实现与SDL2相关的图形和输入处理。这种嵌入方式可以帮助我们在使用Qt框架的同时,获得SDL2库强大的图形和输入能力,以满足特定应用需求。 ### 回答3: 要将Qt嵌入SDL2窗口,需要进行以下步骤: 1. 首先,确保已安装好Qt和SDL2,并准备好Qt项目开发环境。 2. 创建一个Qt窗口应用程序项目,选择“Widgets应用程序”类型。 3. 在Qt的主窗口设计界面中,添加一个QWidget小部件作为SDL2窗口的容器。 4. 将SDL2窗口嵌入到QWidget容器中,可以通过使用SDL_CreateWindowFrom函数或者SDL2函数来实现。 5. 创建一个QTimer对象,在定时器的槽函数中通过SDL_RenderPresent函数或者SDL2函数来绘制SDL2窗口。 6. 编写Qt程序的其他逻辑,包括处理用户输入、更新SDL2窗口内的内容等。 7. 构建和运行Qt程序,即可看到SDL2窗口嵌入到Qt窗口中的效果。 需要注意的是,SDL2和Qt都是强大的图形库,彼此之间的使用存在一定的复杂性和潜在的冲突。在嵌入过程中可能会遇到一些问题,如窗口大小和信号传递等方面的兼容性问题。因此,在实际应用中需要仔细评估项目需求和技术复杂度,并进行充分的测试和调试,以确保嵌入的正确性和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值