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;
}