在DirectX程序中,我有一个算法来调整渲染目标的大小,以便在更改为全屏模式时(垂直于4:3,水平于16:9,创建信箱效果)适合屏幕。在全屏上它可以正常工作,但是每次我返回窗口模式时,窗口都会以某种方式变得越来越大。
该应用使用此值表示宽度和高度;它们在程序执行期间不会改变:
int winwidth=1280;
int winheight=720;
int screenwidth=GetSystemMetrics(SM_CXSCREEN);
int screenheight=GetSystemMetrics(SM_CYSCREEN);
在这里,我在消息循环中在ALT + ENTER上切换屏幕模式:
case WM_SYSKEYUP:
switch(wParam){
case VK_RETURN:
if(GetKeyState(VK_LMENU)<0){
if(!god->settings.fullscreen){
god->settings.fullscreen=true;
d2d->resize(hwnd,god->settings);
d2d->swapchain->SetFullscreenState(true, NULL);
god->saveSettings();
}
else{
god->settings.fullscreen=false;
d2d->resize(hwnd,god->settings);
d2d->swapchain->SetFullscreenState(false, NULL);
god->saveSettings();
}
}
break;
}
break;
这是我使用的调整大小的方法:
void D2DHandle::resize(HWND hwnd,GameSettings settings){
DXGI_MODE_DESC modedesc;
DXGI_RATIONAL rat;
rat.Denominator = 1;
rat.Numerator = 30;
modedesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
if(settings.fullscreen){
if(settings.aspect43){
modedesc.Width=(int)((settings.screenheight)*(4.f/3.f));
modedesc.Height=settings.screenheight;
}
else{
modedesc.Width=settings.screenwidth;
modedesc.Height=(int)((settings.screenwidth)*(9.f/16.f));
}
}
else{
modedesc.Width=settings.winwidth;
modedesc.Height=settings.winheight;
}
modedesc.RefreshRate = rat;
modedesc.Scaling=DXGI_MODE_SCALING_CENTERED;
modedesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
swapchain->ResizeTarget(&modedesc);
if(settings.fullscreen){
if(settings.aspect43){
swapchain->ResizeBuffers(0,(int)((settings.screenheight)*(4.f/3.f)),settings.screenheight,DXGI_FORMAT_R8G8B8A8_UNORM,0);
}
else{
swapchain->ResizeBuffers(0,settings.screenwidth,(int)((settings.screenwidth)*(9.f/16.f)),DXGI_FORMAT_R8G8B8A8_UNORM,0);
}
}
else{
swapchain->ResizeBuffers(0,settings.winwidth,settings.winheight,DXGI_FORMAT_R8G8B8A8_UNORM,0);
}
swapchain->GetBuffer(0,IID_PPV_ARGS(surface.ReleaseAndGetAddressOf()));
D2D1_RENDER_TARGET_PROPERTIES rtp;
rtp.dpiX=0.0f;
rtp.dpiY=0.0f;
rtp.minLevel=D2D1_FEATURE_LEVEL_10;
rtp.pixelFormat=PixelFormat(DXGI_FORMAT_R8G8B8A8_UNORM,D2D1_ALPHA_MODE_PREMULTIPLIED);
rtp.type=D2D1_RENDER_TARGET_TYPE_HARDWARE;
rtp.usage=D2D1_RENDER_TARGET_USAGE_NONE;
d2dfactory->CreateDxgiSurfaceRenderTarget(surface.Get(),rtp,target.ReleaseAndGetAddressOf());
}