SDL2缩放窗口in MFC

SDL2窗口缩放大坑

没有使用SDL的消息响应的一个解决方案
  • 关键点:
    如果不采用sdl的消息机制,就让改变窗口的操作放在SDL的播放函数中

  • 操作
    改变MFC 播放窗口大小----->改变SDL窗口大小,SDL_SetWindowSize(…)----->释放SDL绘图内容(SDL_WINDOW不要释放!!)----->重建SDL绘图内容

  • 代码

//SDL初始化代码,我采用的是获取mfc创建的窗口的句柄的方式
void sdl::init()
{
		SDL_Init(SDL_INIT_VIDEO);
		if (win == NULL)
			exit(1);
		screen = SDL_CreateWindowFrom(win);
		char szPrint[255];
		sdlRenderer = SDL_CreateRenderer(screen,-1,0);
		if (sdlRenderer == NULL)
		{
			AfxMessageBox(_T("SDL渲染器创建失败!"));
			exit(1);
		}
		//先创建init随后才设置的回调,所以就先打开引擎吧
		//if(sdl_draw_text!=NULL)
		//打开ttf字体引擎
		if(ttf_err=TTF_Init())
			AfxMessageBox(_T("TTF引擎打开失败!"));
}
//SDL_ttf引擎不支持多线程安全,采取互斥量,串行化的方式播放
int status = 0;
CMutex g_sdl_mutex;
//播放线程
void sdl::play(unsigned char*buffer,int buffSize,int&_frameWidth,int&_frameHeight)
{
	while (status == 1)
		Sleep(10);
	if (buffSize == 0)
		return;
	g_sdl_mutex.Lock();
		status = 1;
	//myMutex.Lock();
	if (this->isNotFirst== false)
	{
		//自适应图像分辨率
		sdlTexture = SDL_CreateTexture(sdlRenderer,SDL_PIXELFORMAT_IYUV,SDL_TEXTUREACCESS_STREAMING,_frameWidth,_frameHeight);
		isNotFirst = true;
	}
	//获取窗口大小,自适应
	CWnd *myPic=CWnd::FromHandle((HWND)win);
	CRect myPicRect;
	myPic->GetClientRect(&myPicRect);
	sdlrect.x=0;
	sdlrect.y=0;
	sdlrect.w=myPicRect.Width();
	sdlrect.h=myPicRect.Height();

//如果你想直接使用这句话就想实现缩放的话,那就跟我一样入坑了
//我先改变了,窗口大小,后调用SDL_SetWindowSize()
//在复制Texture时返回,resize() invalide错误
//期间,想通过,把SDL释放后重新建立,这个思路是对的,但我对SDL的思想理解不到位,
//我把SDL_WINDOWS也释放了,这就是我失败的地方,
//其实是SDL_WINDOWS不要释放,其余的 SDL_Texture SDL_Surface...等关于绘图的内容释放,重建就ok了
//SDL_SetWindowSize(screen, sdlrect.w , sdlrect.h );
	if (change !=0)
	{
//《------------------------------------窗口缩放在这------------------------------------------》
		if (change == 1)
		{
			sdlrect.w *= 2;
			sdlrect.h *= 2;
		}
		else
		{
			sdlrect.w /= 2;
			sdlrect.h /= 2;
		}
		//在播放函数中改变窗口大小,这也就确保了,绘图的时候实在合适的窗口上画的
		//在外部改变窗口时,绘图可能正在工作,也就导致了resize失败
		//改变MFC picture窗口大小
		myPic->SetWindowPos(NULL, 0, 0,sdlrect.w, sdlrect.h, SWP_NOMOVE);
		//设置SDL windows大小
		SDL_SetWindowSize(screen, sdlrect.w , sdlrect.h );
		//SDL绘图内容释放
		SDL_DestroyTexture(sdlTexture);
		SDL_DestroyRenderer(sdlRenderer);
		//已经说了,千万不是释放窗口,不然就什么也看不到了,就是重建也不行
		//SDL_DestroyWindow(screen);
		Sleep(10);
		//重新初始化绘图内容
		init();
		isNotFirst = false;
		//sdlTexture = SDL_CreateTexture(sdlRenderer,SDL_PIXELFORMAT_IYUV,SDL_TEXTUREACCESS_STREAMING,_frameWidth,_frameHeight);
		status = 0;
		g_sdl_mutex.Unlock();
		change = 0;
		return;

	}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答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都是强大的图形库,彼此之间的使用存在一定的复杂性和潜在的冲突。在嵌入过程中可能会遇到一些问题,如窗口大小和信号传递等方面的兼容性问题。因此,在实际应用中需要仔细评估项目需求和技术复杂度,并进行充分的测试和调试,以确保嵌入的正确性和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值