DirectX11 Swapchain текстуры рендеринга проблема, когда окна?
Я программирую игровой фреймворк на основе DirectX11, но у меня проблема, мои текстуры плохо отображаются на экране, это скриншот:
Как вы можете видеть, изображение не идеальное, но я заметил, что это происходит только в том случае, если я инициализирую цепочку обмена для оконной, если я этого не делаю и инициализирую ее на весь экран, спрайт отображается правильно, даже если во время время выполнения я меняю с полного экрана на оконный, он по-прежнему отображается правильно, это изображение, показанное на экране:
Есть инициализация моего swapchain:
RECT dimensions;
GetClientRect(game->Window, &dimensions);
unsigned int width = dimensions.right - dimensions.left;
unsigned int height = dimensions.bottom - dimensions.top;
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
D3D_DRIVER_TYPE_SOFTWARE
};
unsigned int totalDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
unsigned int totalFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = DXGI_SWAP_EFFECT_SEQUENTIAL;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = game->Window;
swapChainDesc.Windowed = true;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
unsigned int creationFlags = 0;
#ifdef _DEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
HRESULT result;
unsigned int driver = 0;
pin_ptr<IDXGISwapChain*> swapChainPointer;
swapChainPointer = &swapChain_;
pin_ptr<ID3D11Device*> d3dDevicePointer;
d3dDevicePointer = &d3dDevice_;
pin_ptr<D3D_FEATURE_LEVEL> featureLevelPointer;
featureLevelPointer = &featureLevel_;
pin_ptr<ID3D11DeviceContext*> d3dContextPointer;
d3dContextPointer = &d3dContext_;
for (driver = 0; driver < totalDriverTypes; ++driver)
{
result = D3D11CreateDeviceAndSwapChain(0, driverTypes[driver], 0, creationFlags, featureLevels, totalFeatureLevels,
D3D11_SDK_VERSION, &swapChainDesc, swapChainPointer,
d3dDevicePointer, featureLevelPointer, d3dContextPointer);
if (SUCCEEDED(result))
{
driverType_ = driverTypes[driver];
break;
}
}
И это код для переключения на весь экран:
swapChain_->SetFullscreenState(isFullScreen, NULL);
Где IsFullScreen - логическое значение, передаваемое функции содержащей.
Может кто-нибудь мне помочь? Заранее спасибо!
РЕДАКТИРОВАТЬ:
Решено:
Я изменил параметр WS_OVERLAPPED при создании моего окна:
RECT rc = { 0, 0, WindowWidth, WindowHeight };
AdjustWindowRect(&rc, WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, FALSE);
LPCTSTR title = Utilities::StringToLPCSTR(Title);
HWND hwnd = CreateWindowA("BSGame", title, WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, windowHandler, NULL);
Для WS_OVERLAPPEDWINDOW
2 ответа
В моем случае проблема была при создании окна, это была моя ситуация:
RECT rc = { 0, 0, WindowWidth, WindowHeight };
AdjustWindowRect(&rc, WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, FALSE);
LPCTSTR title = Utilities::StringToLPCSTR(Title);
HWND hwnd = CreateWindowA("BSGame", title, WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, windowHandler, NULL);
Чтобы решить, я изменил WS_OVERLAPPED на WS_OVERLAPPEDWINDOW
Когда вы вызываете SetFullScreen на SwapChain, вы запрашиваете только изменение режима.
Обычно после звонка вы должны получить сообщение WM_SIZE из основной формы, после чего вам необходимо сделать следующее:
Освободите любой связанный ресурс, связанный с вашей цепочкой обмена (например, Texture и RenderTargetView). Убедитесь, что вы также вызываете ClearState для контекста устройства, поскольку, если вы SwapChain по-прежнему связаны с конвейером, у вас также возникнет проблема (среда выполнения не уничтожит ресурс, если он связан с трубопровод).
затем вы звоните изменить размер на swapchain, например:
HRESULT result = mSwapChain->ResizeBuffers(0,0,0,DXGI_FORMAT_UNKNOWN,0);
Наконец, вы можете снова запросить текстуру:
ID3D11Texture2D* texture;
mSwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(void**)(&texture));
//Get Buffer does an AddRef on top so we release
texture->Release();
И создайте новый RenderTargetView, а также обновите ваш ViewPort до нового размера (получите описание из текстуры).