2024-07-13 22:55:36 -03:00
|
|
|
|
#include "xna/xna-dx.hpp"
|
2024-03-30 14:25:08 -03:00
|
|
|
|
|
|
|
|
|
namespace xna {
|
2024-07-30 09:41:31 -03:00
|
|
|
|
static bool IsWindowOnAdapter(intptr_t windowHandle, GraphicsAdapter const& adapter);
|
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
GraphicsDeviceManager::GraphicsDeviceManager(sptr<Game> const& game) : game(game)
|
2024-05-24 14:42:12 -03:00
|
|
|
|
{
|
|
|
|
|
sptr<GraphicsAdapter> adp = GraphicsAdapter::DefaultAdapter();
|
2024-05-24 12:31:24 -03:00
|
|
|
|
_information.Adapter = adp;
|
|
|
|
|
_information.Profile = xna::GraphicsProfile::HiDef;
|
|
|
|
|
|
|
|
|
|
auto parameters = snew<PresentationParameters>();
|
2024-07-28 17:03:13 -03:00
|
|
|
|
parameters->BackBufferWidth = backBufferWidth;
|
|
|
|
|
parameters->BackBufferHeight = backBufferHeight;
|
2024-05-24 12:31:24 -03:00
|
|
|
|
parameters->BackBufferFormat = SurfaceFormat::Color;
|
2024-07-30 10:43:39 -03:00
|
|
|
|
parameters->IsFullscreen = false;
|
|
|
|
|
_information.PresentParameters = parameters;
|
2024-05-24 12:31:24 -03:00
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
if (game)
|
|
|
|
|
_information.Window = game->Window();
|
2024-05-24 14:42:12 -03:00
|
|
|
|
}
|
2024-04-01 11:29:32 -03:00
|
|
|
|
|
2024-04-26 10:13:00 -03:00
|
|
|
|
bool GraphicsDeviceManager::Initialize() {
|
2024-07-28 17:03:13 -03:00
|
|
|
|
if (!game)
|
2024-04-26 10:13:00 -03:00
|
|
|
|
return false;
|
2024-04-16 16:13:36 -03:00
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
CreateDevice();
|
|
|
|
|
|
|
|
|
|
return true;
|
2024-04-01 11:29:32 -03:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 14:25:08 -03:00
|
|
|
|
void GraphicsDeviceManager::ApplyChanges() {
|
2024-07-28 17:03:13 -03:00
|
|
|
|
if (device && !isDeviceDirty)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ChangeDevice(false);
|
2024-03-30 14:25:08 -03:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-26 10:13:00 -03:00
|
|
|
|
bool GraphicsDeviceManager::ToggleFullScreen() {
|
2024-07-28 17:03:13 -03:00
|
|
|
|
if (!game || !game->graphicsDevice || !game->graphicsDevice->impl->_swapChain)
|
2024-04-26 10:13:00 -03:00
|
|
|
|
return false;
|
2024-04-22 16:14:55 -03:00
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
auto& swap = game->graphicsDevice->impl->_swapChain;
|
2024-04-22 16:14:55 -03:00
|
|
|
|
|
|
|
|
|
BOOL state = false;
|
2024-05-22 20:05:52 -03:00
|
|
|
|
auto hr = swap->impl->dxSwapChain->GetFullscreenState(&state, nullptr);
|
2024-04-23 16:11:17 -03:00
|
|
|
|
|
2024-04-26 10:37:49 -03:00
|
|
|
|
if (FAILED(hr)) return false;
|
2024-04-23 16:11:17 -03:00
|
|
|
|
|
2024-05-22 20:05:52 -03:00
|
|
|
|
hr = swap->impl->dxSwapChain->SetFullscreenState(!state, nullptr);
|
2024-04-23 16:11:17 -03:00
|
|
|
|
|
2024-04-26 10:37:49 -03:00
|
|
|
|
if (FAILED(hr)) return false;
|
2024-04-23 16:11:17 -03:00
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
isFullScreen = !state;
|
2024-04-26 10:37:49 -03:00
|
|
|
|
|
|
|
|
|
return true;
|
2024-07-28 17:03:13 -03:00
|
|
|
|
}
|
2024-05-24 14:42:12 -03:00
|
|
|
|
|
|
|
|
|
bool initWindow(GraphicsDeviceInformation& info, Game& game, int backWidth, int backHeight)
|
2024-04-26 10:13:00 -03:00
|
|
|
|
{
|
2024-05-24 14:42:12 -03:00
|
|
|
|
auto window = info.Window;
|
2024-04-26 10:13:00 -03:00
|
|
|
|
|
|
|
|
|
if (!window) {
|
2024-05-24 14:42:12 -03:00
|
|
|
|
window = game.Window();
|
|
|
|
|
info.Window = window;
|
2024-04-26 10:13:00 -03:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-24 14:42:12 -03:00
|
|
|
|
window->impl->Size(backWidth, backHeight);
|
2024-04-26 10:13:00 -03:00
|
|
|
|
|
2024-05-24 12:31:24 -03:00
|
|
|
|
if (!window->impl->Create()) {
|
2024-04-26 10:13:00 -03:00
|
|
|
|
MessageBox(nullptr, "Falha na cria<69><61>o da janela", "XN65", MB_OK);
|
|
|
|
|
return false;
|
2024-04-01 11:29:32 -03:00
|
|
|
|
}
|
|
|
|
|
|
2024-07-30 10:43:39 -03:00
|
|
|
|
info.PresentParameters->DeviceWindowHandle = reinterpret_cast<intptr_t>(window->impl->WindowHandle());
|
2024-04-26 10:13:00 -03:00
|
|
|
|
|
|
|
|
|
return true;
|
2024-03-30 14:25:08 -03:00
|
|
|
|
}
|
|
|
|
|
|
2024-05-24 14:42:12 -03:00
|
|
|
|
bool initDevice(GraphicsDeviceInformation& info, Game& game, sptr<GraphicsDevice>& device)
|
2024-06-05 09:26:33 -03:00
|
|
|
|
{
|
2024-06-22 11:52:21 -03:00
|
|
|
|
device = snew<GraphicsDevice>(info);
|
2024-04-26 10:13:00 -03:00
|
|
|
|
|
2024-06-05 09:26:33 -03:00
|
|
|
|
if (!device->Initialize()) {
|
|
|
|
|
MessageBox(info.Window->impl->WindowHandle(), "Falha na inicializa<7A><61>o do dispositivo gr<67>fico", "XN65", MB_OK);
|
2024-05-24 14:42:12 -03:00
|
|
|
|
device = nullptr;
|
2024-04-26 10:13:00 -03:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-24 14:42:12 -03:00
|
|
|
|
game.graphicsDevice = device;
|
2024-04-26 10:37:49 -03:00
|
|
|
|
|
|
|
|
|
return true;
|
2024-03-30 14:25:08 -03:00
|
|
|
|
}
|
2024-05-24 14:42:12 -03:00
|
|
|
|
|
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
void GraphicsDeviceManager::CreateDevice() {
|
|
|
|
|
if (isDeviceDirty) {
|
2024-07-30 10:43:39 -03:00
|
|
|
|
_information.PresentParameters->BackBufferWidth = backBufferWidth;
|
|
|
|
|
_information.PresentParameters->BackBufferHeight = backBufferHeight;
|
2024-05-24 14:42:12 -03:00
|
|
|
|
}
|
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
auto result = initWindow(_information, *game, backBufferWidth, backBufferHeight);
|
2024-05-24 14:42:12 -03:00
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
//if (!result) return false;
|
2024-05-24 14:42:12 -03:00
|
|
|
|
|
2024-07-28 17:03:13 -03:00
|
|
|
|
initDevice(_information, *game, device);
|
2024-05-24 14:42:12 -03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GraphicsDeviceManager::ChangeDevice() {
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-30 10:43:39 -03:00
|
|
|
|
void GraphicsDeviceManager::AddDevices(bool anySuitableDevice, std::vector<sptr<GraphicsDeviceInformation>>& foundDevices) {
|
2024-07-28 17:03:13 -03:00
|
|
|
|
const auto handle = game->Window()->Handle();
|
|
|
|
|
|
|
|
|
|
std::vector<uptr<GraphicsAdapter>> adapters;
|
|
|
|
|
GraphicsAdapter::Adapters(adapters);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; adapters.size(); ++i) {
|
|
|
|
|
auto& adapter = adapters[i];
|
|
|
|
|
|
2024-07-30 09:41:31 -03:00
|
|
|
|
if (!anySuitableDevice) {
|
|
|
|
|
if (!IsWindowOnAdapter(handle, *adapter))
|
|
|
|
|
continue;
|
2024-07-28 17:03:13 -03:00
|
|
|
|
}
|
2024-07-30 10:43:39 -03:00
|
|
|
|
|
|
|
|
|
if (adapter->IsProfileSupported(graphicsProfile)) {
|
|
|
|
|
auto baseDeviceInfo = snew<GraphicsDeviceInformation>();
|
|
|
|
|
baseDeviceInfo->Adapter = std::move(adapter);
|
|
|
|
|
baseDeviceInfo->Profile = graphicsProfile;
|
|
|
|
|
baseDeviceInfo->PresentParameters = snew<PresentationParameters>();
|
|
|
|
|
baseDeviceInfo->PresentParameters->DeviceWindowHandle = handle;
|
|
|
|
|
baseDeviceInfo->PresentParameters->MultiSampleCount = 0;
|
|
|
|
|
baseDeviceInfo->PresentParameters->IsFullscreen = isFullScreen;
|
|
|
|
|
baseDeviceInfo->PresentParameters->PresentationInterval = synchronizeWithVerticalRetrace ? PresentInterval::One : PresentInterval::Immediate;
|
|
|
|
|
|
|
|
|
|
const auto& currentDisplayMode = baseDeviceInfo->Adapter->CurrentDisplayMode();
|
|
|
|
|
AddDevices(*baseDeviceInfo->Adapter, *currentDisplayMode, baseDeviceInfo, foundDevices);
|
|
|
|
|
|
|
|
|
|
if (isFullScreen) {
|
2024-07-30 11:02:18 -03:00
|
|
|
|
const auto& supportedDisplayModes = adapter->SupportedDisplayModes();
|
|
|
|
|
const auto count = supportedDisplayModes->Count();
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < count; ++i) {
|
|
|
|
|
auto& supportedDisplayMode = supportedDisplayModes->DisplayModes[i];
|
|
|
|
|
|
|
|
|
|
if (supportedDisplayMode->Width() >= 640 && supportedDisplayMode->Height() >= 480) {
|
|
|
|
|
AddDevices(*baseDeviceInfo->Adapter, *supportedDisplayMode, baseDeviceInfo, foundDevices);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-07-30 10:43:39 -03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-30 11:02:18 -03:00
|
|
|
|
void GraphicsDeviceManager::AddDevices(GraphicsAdapter const& adapter, DisplayMode const& mode, sptr<GraphicsDeviceInformation>& baseDeviceInfo, std::vector<sptr<GraphicsDeviceInformation>>& foundDevices) const {
|
2024-07-30 10:43:39 -03:00
|
|
|
|
auto deviceInformation = snew<GraphicsDeviceInformation>(*baseDeviceInfo);
|
|
|
|
|
|
|
|
|
|
if (isFullScreen)
|
|
|
|
|
{
|
|
|
|
|
deviceInformation->PresentParameters->BackBufferWidth = mode.Width();
|
|
|
|
|
deviceInformation->PresentParameters->BackBufferHeight = mode.Height();
|
|
|
|
|
}
|
|
|
|
|
else if (useResizedBackBuffer) {
|
|
|
|
|
deviceInformation->PresentParameters->BackBufferWidth = resizedBackBufferWidth;
|
|
|
|
|
deviceInformation->PresentParameters->BackBufferHeight = resizedBackBufferHeight;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
deviceInformation->PresentParameters->BackBufferWidth = backBufferWidth;
|
|
|
|
|
deviceInformation->PresentParameters->BackBufferHeight = backBufferHeight;
|
2024-07-28 17:03:13 -03:00
|
|
|
|
}
|
2024-07-30 10:43:39 -03:00
|
|
|
|
|
|
|
|
|
SurfaceFormat selectedFormat;
|
|
|
|
|
DepthFormat selectedDepthFormat;
|
|
|
|
|
int selectedMultiSampleCount;
|
|
|
|
|
|
|
|
|
|
adapter.QueryBackBufferFormat(deviceInformation->Profile, mode.Format(), depthStencilFormat, allowMultiSampling ? 16 : 0, selectedFormat, selectedDepthFormat, selectedMultiSampleCount);
|
|
|
|
|
|
|
|
|
|
deviceInformation->PresentParameters->BackBufferFormat = selectedFormat;
|
|
|
|
|
deviceInformation->PresentParameters->DepthStencilFormat = selectedDepthFormat;
|
|
|
|
|
deviceInformation->PresentParameters->MultiSampleCount = selectedMultiSampleCount;
|
|
|
|
|
|
|
|
|
|
if (std::find(foundDevices.begin(), foundDevices.end(), deviceInformation) != foundDevices.end())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
foundDevices.push_back(deviceInformation);
|
2024-07-28 17:03:13 -03:00
|
|
|
|
}
|
2024-07-30 09:41:31 -03:00
|
|
|
|
|
|
|
|
|
bool IsWindowOnAdapter(intptr_t windowHandle, GraphicsAdapter const& adapter) {
|
|
|
|
|
return GameWindow::ScreenFromAdapter(adapter) == GameWindow::ScreenFromHandle(windowHandle);
|
|
|
|
|
}
|
2024-03-30 14:25:08 -03:00
|
|
|
|
}
|