mirror of
https://github.com/AxioDL/boo.git
synced 2025-12-09 13:37:48 +00:00
New code style refactor
This commit is contained in:
@@ -25,294 +25,234 @@ PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignaturePROC = nullptr;
|
||||
pD3DCompile D3DCompilePROC = nullptr;
|
||||
pD3DCreateBlob D3DCreateBlobPROC = nullptr;
|
||||
|
||||
static bool FindBestD3DCompile()
|
||||
{
|
||||
D3DCompilePROC = D3DCompile;
|
||||
D3DCreateBlobPROC = D3DCreateBlob;
|
||||
return D3DCompilePROC != nullptr && D3DCreateBlobPROC != nullptr;
|
||||
static bool FindBestD3DCompile() {
|
||||
D3DCompilePROC = D3DCompile;
|
||||
D3DCreateBlobPROC = D3DCreateBlob;
|
||||
return D3DCompilePROC != nullptr && D3DCreateBlobPROC != nullptr;
|
||||
}
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
static logvisor::Module Log("boo::ApplicationUWP");
|
||||
|
||||
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx);
|
||||
|
||||
class ApplicationUWP final : public IApplication
|
||||
{
|
||||
friend ref class AppView;
|
||||
IApplicationCallback& m_callback;
|
||||
const SystemString m_uniqueName;
|
||||
const SystemString m_friendlyName;
|
||||
const SystemString m_pname;
|
||||
const std::vector<SystemString> m_args;
|
||||
std::shared_ptr<IWindow> m_window;
|
||||
bool m_singleInstance;
|
||||
bool m_issuedWindow = false;
|
||||
class ApplicationUWP final : public IApplication {
|
||||
friend ref class AppView;
|
||||
IApplicationCallback& m_callback;
|
||||
const SystemString m_uniqueName;
|
||||
const SystemString m_friendlyName;
|
||||
const SystemString m_pname;
|
||||
const std::vector<SystemString> m_args;
|
||||
std::shared_ptr<IWindow> m_window;
|
||||
bool m_singleInstance;
|
||||
bool m_issuedWindow = false;
|
||||
|
||||
Boo3DAppContextUWP m_3dCtx;
|
||||
Boo3DAppContextUWP m_3dCtx;
|
||||
|
||||
void _deletedWindow(IWindow* window)
|
||||
{
|
||||
}
|
||||
void _deletedWindow(IWindow* window) {}
|
||||
|
||||
public:
|
||||
ApplicationUWP(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
|
||||
SystemStringView pname, const std::vector<SystemString>& args, bool singleInstance)
|
||||
: m_callback(callback)
|
||||
, m_uniqueName(uniqueName)
|
||||
, m_friendlyName(friendlyName)
|
||||
, m_pname(pname)
|
||||
, m_args(args)
|
||||
, m_singleInstance(singleInstance) {
|
||||
typedef HRESULT(WINAPI * CreateDXGIFactory1PROC)(REFIID riid, _COM_Outptr_ void** ppFactory);
|
||||
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = CreateDXGIFactory1;
|
||||
|
||||
ApplicationUWP(IApplicationCallback& callback,
|
||||
SystemStringView uniqueName,
|
||||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
bool singleInstance)
|
||||
: m_callback(callback),
|
||||
m_uniqueName(uniqueName),
|
||||
m_friendlyName(friendlyName),
|
||||
m_pname(pname),
|
||||
m_args(args),
|
||||
m_singleInstance(singleInstance)
|
||||
{
|
||||
typedef HRESULT(WINAPI*CreateDXGIFactory1PROC)(REFIID riid, _COM_Outptr_ void **ppFactory);
|
||||
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = CreateDXGIFactory1;
|
||||
|
||||
bool no12 = true;
|
||||
for (const SystemString& arg : args)
|
||||
if (!arg.compare(L"--d3d12"))
|
||||
no12 = false;
|
||||
bool no12 = true;
|
||||
for (const SystemString& arg : args)
|
||||
if (!arg.compare(L"--d3d12"))
|
||||
no12 = false;
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
if (!no12)
|
||||
{
|
||||
if (!FindBestD3DCompile())
|
||||
Log.report(logvisor::Fatal, "unable to find D3DCompile_[43-47].dll");
|
||||
if (!no12) {
|
||||
if (!FindBestD3DCompile())
|
||||
Log.report(logvisor::Fatal, "unable to find D3DCompile_[43-47].dll");
|
||||
|
||||
D3D12SerializeRootSignaturePROC = D3D12SerializeRootSignature;
|
||||
D3D12SerializeRootSignaturePROC = D3D12SerializeRootSignature;
|
||||
|
||||
/* Create device */
|
||||
PFN_D3D12_CREATE_DEVICE MyD3D12CreateDevice = D3D12CreateDevice;
|
||||
/* Create device */
|
||||
PFN_D3D12_CREATE_DEVICE MyD3D12CreateDevice = D3D12CreateDevice;
|
||||
|
||||
/* Obtain DXGI Factory */
|
||||
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx12.m_dxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create DXGI factory");
|
||||
/* Obtain DXGI Factory */
|
||||
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx12.m_dxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create DXGI factory");
|
||||
|
||||
/* Adapter */
|
||||
ComPtr<IDXGIAdapter1> ppAdapter;
|
||||
for (UINT adapterIndex = 0; ; ++adapterIndex)
|
||||
{
|
||||
ComPtr<IDXGIAdapter1> pAdapter;
|
||||
if (DXGI_ERROR_NOT_FOUND == m_3dCtx.m_ctx12.m_dxFactory->EnumAdapters1(adapterIndex, &pAdapter))
|
||||
break;
|
||||
/* Adapter */
|
||||
ComPtr<IDXGIAdapter1> ppAdapter;
|
||||
for (UINT adapterIndex = 0;; ++adapterIndex) {
|
||||
ComPtr<IDXGIAdapter1> pAdapter;
|
||||
if (DXGI_ERROR_NOT_FOUND == m_3dCtx.m_ctx12.m_dxFactory->EnumAdapters1(adapterIndex, &pAdapter))
|
||||
break;
|
||||
|
||||
// Check to see if the adapter supports Direct3D 12, but don't create the
|
||||
// actual device yet.
|
||||
if (SUCCEEDED(MyD3D12CreateDevice(pAdapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
|
||||
{
|
||||
ppAdapter = std::move(pAdapter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create device */
|
||||
hr = ppAdapter ? MyD3D12CreateDevice(ppAdapter.Get(), D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), &m_3dCtx.m_ctx12.m_dev) : E_FAIL;
|
||||
if (!FAILED(hr))
|
||||
{
|
||||
/* Establish loader objects */
|
||||
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
__uuidof(ID3D12CommandAllocator), &m_3dCtx.m_ctx12.m_loadqalloc)))
|
||||
Log.report(logvisor::Fatal, "unable to create loader allocator");
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC desc =
|
||||
{
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
||||
D3D12_COMMAND_QUEUE_FLAG_NONE
|
||||
};
|
||||
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue), &m_3dCtx.m_ctx12.m_loadq)))
|
||||
Log.report(logvisor::Fatal, "unable to create loader queue");
|
||||
|
||||
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), &m_3dCtx.m_ctx12.m_loadfence)))
|
||||
Log.report(logvisor::Fatal, "unable to create loader fence");
|
||||
|
||||
m_3dCtx.m_ctx12.m_loadfencehandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
|
||||
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_3dCtx.m_ctx12.m_loadqalloc.Get(),
|
||||
nullptr, __uuidof(ID3D12GraphicsCommandList), &m_3dCtx.m_ctx12.m_loadlist)))
|
||||
Log.report(logvisor::Fatal, "unable to create loader list");
|
||||
|
||||
Log.report(logvisor::Info, "initialized D3D12 renderer");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Some Win10 client HW doesn't support D3D12 (despite being supposedly HW-agnostic) */
|
||||
m_3dCtx.m_ctx12.m_dev.Reset();
|
||||
m_3dCtx.m_ctx12.m_dxFactory.Reset();
|
||||
}
|
||||
// Check to see if the adapter supports Direct3D 12, but don't create the
|
||||
// actual device yet.
|
||||
if (SUCCEEDED(MyD3D12CreateDevice(pAdapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) {
|
||||
ppAdapter = std::move(pAdapter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create device */
|
||||
hr = ppAdapter ? MyD3D12CreateDevice(ppAdapter.Get(), D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device),
|
||||
&m_3dCtx.m_ctx12.m_dev)
|
||||
: E_FAIL;
|
||||
if (!FAILED(hr)) {
|
||||
/* Establish loader objects */
|
||||
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandAllocator(
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), &m_3dCtx.m_ctx12.m_loadqalloc)))
|
||||
Log.report(logvisor::Fatal, "unable to create loader allocator");
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC desc = {D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
||||
D3D12_COMMAND_QUEUE_FLAG_NONE};
|
||||
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandQueue(&desc, __uuidof(ID3D12CommandQueue),
|
||||
&m_3dCtx.m_ctx12.m_loadq)))
|
||||
Log.report(logvisor::Fatal, "unable to create loader queue");
|
||||
|
||||
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence),
|
||||
&m_3dCtx.m_ctx12.m_loadfence)))
|
||||
Log.report(logvisor::Fatal, "unable to create loader fence");
|
||||
|
||||
m_3dCtx.m_ctx12.m_loadfencehandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
|
||||
if (FAILED(m_3dCtx.m_ctx12.m_dev->CreateCommandList(
|
||||
0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_3dCtx.m_ctx12.m_loadqalloc.Get(), nullptr,
|
||||
__uuidof(ID3D12GraphicsCommandList), &m_3dCtx.m_ctx12.m_loadlist)))
|
||||
Log.report(logvisor::Fatal, "unable to create loader list");
|
||||
|
||||
Log.report(logvisor::Info, "initialized D3D12 renderer");
|
||||
return;
|
||||
} else {
|
||||
/* Some Win10 client HW doesn't support D3D12 (despite being supposedly HW-agnostic) */
|
||||
m_3dCtx.m_ctx12.m_dev.Reset();
|
||||
m_3dCtx.m_ctx12.m_dxFactory.Reset();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
{
|
||||
if (!FindBestD3DCompile())
|
||||
Log.report(logvisor::Fatal, "unable to find D3DCompile_[43-47].dll");
|
||||
|
||||
/* Create device proc */
|
||||
PFN_D3D11_CREATE_DEVICE MyD3D11CreateDevice = D3D11CreateDevice;
|
||||
|
||||
/* Create device */
|
||||
D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;
|
||||
ComPtr<ID3D11Device> tempDev;
|
||||
ComPtr<ID3D11DeviceContext> tempCtx;
|
||||
if (FAILED(MyD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_FLAGS, &level,
|
||||
1, D3D11_SDK_VERSION, &tempDev, nullptr, &tempCtx)))
|
||||
Log.report(logvisor::Fatal, "unable to create D3D11 device");
|
||||
|
||||
ComPtr<IDXGIDevice2> device;
|
||||
if (FAILED(tempDev.As<ID3D11Device1>(&m_3dCtx.m_ctx11.m_dev)) || !m_3dCtx.m_ctx11.m_dev ||
|
||||
FAILED(tempCtx.As<ID3D11DeviceContext1>(&m_3dCtx.m_ctx11.m_devCtx)) || !m_3dCtx.m_ctx11.m_devCtx ||
|
||||
FAILED(m_3dCtx.m_ctx11.m_dev.As<IDXGIDevice2>(&device)) || !device)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Obtain DXGI Factory */
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx11.m_dxFactory);
|
||||
|
||||
/* Build default sampler here */
|
||||
CD3D11_SAMPLER_DESC sampDesc(D3D11_DEFAULT);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[0]);
|
||||
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[1]);
|
||||
|
||||
Log.report(logvisor::Info, "initialized D3D11 renderer");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.report(logvisor::Fatal, "system doesn't support D3D11 or D3D12");
|
||||
}
|
||||
|
||||
EPlatformType getPlatformType() const
|
||||
{
|
||||
return EPlatformType::UWP;
|
||||
if (!FindBestD3DCompile())
|
||||
Log.report(logvisor::Fatal, "unable to find D3DCompile_[43-47].dll");
|
||||
|
||||
/* Create device proc */
|
||||
PFN_D3D11_CREATE_DEVICE MyD3D11CreateDevice = D3D11CreateDevice;
|
||||
|
||||
/* Create device */
|
||||
D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;
|
||||
ComPtr<ID3D11Device> tempDev;
|
||||
ComPtr<ID3D11DeviceContext> tempCtx;
|
||||
if (FAILED(MyD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_FLAGS, &level, 1,
|
||||
D3D11_SDK_VERSION, &tempDev, nullptr, &tempCtx)))
|
||||
Log.report(logvisor::Fatal, "unable to create D3D11 device");
|
||||
|
||||
ComPtr<IDXGIDevice2> device;
|
||||
if (FAILED(tempDev.As<ID3D11Device1>(&m_3dCtx.m_ctx11.m_dev)) || !m_3dCtx.m_ctx11.m_dev ||
|
||||
FAILED(tempCtx.As<ID3D11DeviceContext1>(&m_3dCtx.m_ctx11.m_devCtx)) || !m_3dCtx.m_ctx11.m_devCtx ||
|
||||
FAILED(m_3dCtx.m_ctx11.m_dev.As<IDXGIDevice2>(&device)) || !device) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Obtain DXGI Factory */
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx11.m_dxFactory);
|
||||
|
||||
/* Build default sampler here */
|
||||
CD3D11_SAMPLER_DESC sampDesc(D3D11_DEFAULT);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[0]);
|
||||
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[1]);
|
||||
|
||||
Log.report(logvisor::Info, "initialized D3D11 renderer");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.report(logvisor::Fatal, "system doesn't support D3D11 or D3D12");
|
||||
}
|
||||
|
||||
std::thread m_clientThread;
|
||||
int run()
|
||||
{
|
||||
/* Spawn client thread */
|
||||
int clientReturn = 0;
|
||||
m_clientThread = std::thread([&]()
|
||||
{
|
||||
std::string thrName = WCSTMBS(getFriendlyName().data()) + " Client Thread";
|
||||
logvisor::RegisterThreadName(thrName.c_str());
|
||||
clientReturn = m_callback.appMain(this);
|
||||
});
|
||||
EPlatformType getPlatformType() const { return EPlatformType::UWP; }
|
||||
|
||||
CoreWindow::GetForCurrentThread()->Activate();
|
||||
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
|
||||
return 0;
|
||||
std::thread m_clientThread;
|
||||
int run() {
|
||||
/* Spawn client thread */
|
||||
int clientReturn = 0;
|
||||
m_clientThread = std::thread([&]() {
|
||||
std::string thrName = WCSTMBS(getFriendlyName().data()) + " Client Thread";
|
||||
logvisor::RegisterThreadName(thrName.c_str());
|
||||
clientReturn = m_callback.appMain(this);
|
||||
});
|
||||
|
||||
CoreWindow::GetForCurrentThread()->Activate();
|
||||
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void quit() {
|
||||
m_callback.appQuitting(this);
|
||||
if (m_clientThread.joinable())
|
||||
m_clientThread.join();
|
||||
}
|
||||
|
||||
SystemStringView getUniqueName() const { return m_uniqueName; }
|
||||
|
||||
SystemStringView getFriendlyName() const { return m_friendlyName; }
|
||||
|
||||
SystemStringView getProcessName() const { return m_pname; }
|
||||
|
||||
const std::vector<SystemString>& getArgs() const { return m_args; }
|
||||
|
||||
std::shared_ptr<IWindow> newWindow(SystemStringView title, uint32_t sampleCount) {
|
||||
if (!m_issuedWindow) {
|
||||
m_issuedWindow = true;
|
||||
return m_window;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void quit()
|
||||
{
|
||||
m_callback.appQuitting(this);
|
||||
if (m_clientThread.joinable())
|
||||
m_clientThread.join();
|
||||
}
|
||||
|
||||
SystemStringView getUniqueName() const
|
||||
{
|
||||
return m_uniqueName;
|
||||
}
|
||||
|
||||
SystemStringView getFriendlyName() const
|
||||
{
|
||||
return m_friendlyName;
|
||||
}
|
||||
|
||||
SystemStringView getProcessName() const
|
||||
{
|
||||
return m_pname;
|
||||
}
|
||||
|
||||
const std::vector<SystemString>& getArgs() const
|
||||
{
|
||||
return m_args;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWindow> newWindow(SystemStringView title, uint32_t sampleCount)
|
||||
{
|
||||
if (!m_issuedWindow)
|
||||
{
|
||||
m_issuedWindow = true;
|
||||
return m_window;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void _setWindow(CoreWindow^ window)
|
||||
{
|
||||
m_window = _WindowUWPNew(m_friendlyName, m_3dCtx);
|
||||
}
|
||||
void _setWindow(CoreWindow ^ window) { m_window = _WindowUWPNew(m_friendlyName, m_3dCtx); }
|
||||
};
|
||||
|
||||
IApplication* APP = NULL;
|
||||
ref class AppView sealed : public IFrameworkView
|
||||
{
|
||||
ApplicationUWP m_app;
|
||||
ref class AppView sealed : public IFrameworkView {
|
||||
ApplicationUWP m_app;
|
||||
|
||||
internal:
|
||||
AppView(IApplicationCallback& callback,
|
||||
SystemStringView uniqueName,
|
||||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
bool singleInstance)
|
||||
: m_app(callback, uniqueName, friendlyName, pname, args, singleInstance) { APP = &m_app; }
|
||||
internal : AppView(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
|
||||
SystemStringView pname, const std::vector<SystemString>& args, bool singleInstance)
|
||||
: m_app(callback, uniqueName, friendlyName, pname, args, singleInstance) {
|
||||
APP = &m_app;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void Initialize(CoreApplicationView^ applicationView)
|
||||
{
|
||||
applicationView->Activated += ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &AppView::OnActivated);
|
||||
}
|
||||
virtual void Initialize(CoreApplicationView ^ applicationView) {
|
||||
applicationView->Activated +=
|
||||
ref new TypedEventHandler<CoreApplicationView ^, IActivatedEventArgs ^>(this, &AppView::OnActivated);
|
||||
}
|
||||
|
||||
virtual void SetWindow(CoreWindow^ window)
|
||||
{
|
||||
m_app._setWindow(window);
|
||||
}
|
||||
virtual void SetWindow(CoreWindow ^ window) { m_app._setWindow(window); }
|
||||
|
||||
virtual void Load(String^ entryPoint)
|
||||
{
|
||||
virtual void Load(String ^ entryPoint) {}
|
||||
|
||||
}
|
||||
virtual void Run() { m_app.run(); }
|
||||
|
||||
virtual void Run()
|
||||
{
|
||||
m_app.run();
|
||||
}
|
||||
virtual void Uninitialize() { m_app.quit(); }
|
||||
|
||||
virtual void Uninitialize()
|
||||
{
|
||||
m_app.quit();
|
||||
}
|
||||
|
||||
void OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
|
||||
{
|
||||
CoreWindow::GetForCurrentThread()->Activate();
|
||||
}
|
||||
void OnActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args) {
|
||||
CoreWindow::GetForCurrentThread()->Activate();
|
||||
}
|
||||
};
|
||||
|
||||
IFrameworkView^ ViewProvider::CreateView()
|
||||
{
|
||||
return ref new AppView(m_appCb, m_uniqueName, m_friendlyName, m_pname, m_args, m_singleInstance);
|
||||
}
|
||||
|
||||
IFrameworkView ^ ViewProvider::CreateView() {
|
||||
return ref new AppView(m_appCb, m_uniqueName, m_friendlyName, m_pname, m_args, m_singleInstance);
|
||||
}
|
||||
|
||||
} // namespace boo
|
||||
|
||||
@@ -33,565 +33,467 @@ static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
|
||||
pD3DCompile D3DCompilePROC = nullptr;
|
||||
pD3DCreateBlob D3DCreateBlobPROC = nullptr;
|
||||
|
||||
static bool FindBestD3DCompile()
|
||||
{
|
||||
HMODULE d3dCompilelib = LoadLibraryW(L"D3DCompiler_47.dll");
|
||||
if (!d3dCompilelib)
|
||||
{
|
||||
d3dCompilelib = LoadLibraryW(L"D3DCompiler_46.dll");
|
||||
if (!d3dCompilelib)
|
||||
{
|
||||
d3dCompilelib = LoadLibraryW(L"D3DCompiler_45.dll");
|
||||
if (!d3dCompilelib)
|
||||
{
|
||||
d3dCompilelib = LoadLibraryW(L"D3DCompiler_44.dll");
|
||||
if (!d3dCompilelib)
|
||||
{
|
||||
d3dCompilelib = LoadLibraryW(L"D3DCompiler_43.dll");
|
||||
}
|
||||
}
|
||||
static bool FindBestD3DCompile() {
|
||||
HMODULE d3dCompilelib = LoadLibraryW(L"D3DCompiler_47.dll");
|
||||
if (!d3dCompilelib) {
|
||||
d3dCompilelib = LoadLibraryW(L"D3DCompiler_46.dll");
|
||||
if (!d3dCompilelib) {
|
||||
d3dCompilelib = LoadLibraryW(L"D3DCompiler_45.dll");
|
||||
if (!d3dCompilelib) {
|
||||
d3dCompilelib = LoadLibraryW(L"D3DCompiler_44.dll");
|
||||
if (!d3dCompilelib) {
|
||||
d3dCompilelib = LoadLibraryW(L"D3DCompiler_43.dll");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d3dCompilelib)
|
||||
{
|
||||
D3DCompilePROC = (pD3DCompile)GetProcAddress(d3dCompilelib, "D3DCompile");
|
||||
D3DCreateBlobPROC = (pD3DCreateBlob)GetProcAddress(d3dCompilelib, "D3DCreateBlob");
|
||||
return D3DCompilePROC != nullptr && D3DCreateBlobPROC != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (d3dCompilelib) {
|
||||
D3DCompilePROC = (pD3DCompile)GetProcAddress(d3dCompilelib, "D3DCompile");
|
||||
D3DCreateBlobPROC = (pD3DCreateBlob)GetProcAddress(d3dCompilelib, "D3DCreateBlob");
|
||||
return D3DCompilePROC != nullptr && D3DCreateBlobPROC != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
static logvisor::Module Log("boo::ApplicationWin32");
|
||||
Win32Cursors WIN32_CURSORS;
|
||||
|
||||
std::shared_ptr<IWindow> _WindowWin32New(SystemStringView title, Boo3DAppContextWin32& d3dCtx);
|
||||
|
||||
class ApplicationWin32 final : public IApplication
|
||||
{
|
||||
IApplicationCallback& m_callback;
|
||||
const SystemString m_uniqueName;
|
||||
const SystemString m_friendlyName;
|
||||
const SystemString m_pname;
|
||||
const std::vector<SystemString> m_args;
|
||||
std::unordered_map<HWND, std::weak_ptr<IWindow>> m_allWindows;
|
||||
class ApplicationWin32 final : public IApplication {
|
||||
IApplicationCallback& m_callback;
|
||||
const SystemString m_uniqueName;
|
||||
const SystemString m_friendlyName;
|
||||
const SystemString m_pname;
|
||||
const std::vector<SystemString> m_args;
|
||||
std::unordered_map<HWND, std::weak_ptr<IWindow>> m_allWindows;
|
||||
|
||||
Boo3DAppContextWin32 m_3dCtx;
|
||||
Boo3DAppContextWin32 m_3dCtx;
|
||||
#if BOO_HAS_VULKAN
|
||||
PFN_vkGetInstanceProcAddr m_getVkProc = nullptr;
|
||||
PFN_vkGetInstanceProcAddr m_getVkProc = nullptr;
|
||||
#endif
|
||||
|
||||
void _deletedWindow(IWindow* window)
|
||||
{
|
||||
m_allWindows.erase(HWND(window->getPlatformHandle()));
|
||||
}
|
||||
void _deletedWindow(IWindow* window) { m_allWindows.erase(HWND(window->getPlatformHandle())); }
|
||||
|
||||
public:
|
||||
|
||||
ApplicationWin32(IApplicationCallback& callback,
|
||||
SystemStringView uniqueName,
|
||||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi,
|
||||
uint32_t samples,
|
||||
uint32_t anisotropy,
|
||||
bool deepColor,
|
||||
bool singleInstance)
|
||||
: m_callback(callback),
|
||||
m_uniqueName(uniqueName),
|
||||
m_friendlyName(friendlyName),
|
||||
m_pname(pname),
|
||||
m_args(args)
|
||||
{
|
||||
m_3dCtx.m_ctx11.m_sampleCount = samples;
|
||||
m_3dCtx.m_ctx11.m_anisotropy = anisotropy;
|
||||
m_3dCtx.m_ctx11.m_fbFormat = deepColor ? DXGI_FORMAT_R16G16B16A16_FLOAT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
m_3dCtx.m_ctxOgl.m_glCtx.m_sampleCount = samples;
|
||||
m_3dCtx.m_ctxOgl.m_glCtx.m_anisotropy = anisotropy;
|
||||
m_3dCtx.m_ctxOgl.m_glCtx.m_deepColor = deepColor;
|
||||
ApplicationWin32(IApplicationCallback& callback, SystemStringView uniqueName, SystemStringView friendlyName,
|
||||
SystemStringView pname, const std::vector<SystemString>& args, std::string_view gfxApi,
|
||||
uint32_t samples, uint32_t anisotropy, bool deepColor, bool singleInstance)
|
||||
: m_callback(callback), m_uniqueName(uniqueName), m_friendlyName(friendlyName), m_pname(pname), m_args(args) {
|
||||
m_3dCtx.m_ctx11.m_sampleCount = samples;
|
||||
m_3dCtx.m_ctx11.m_anisotropy = anisotropy;
|
||||
m_3dCtx.m_ctx11.m_fbFormat = deepColor ? DXGI_FORMAT_R16G16B16A16_FLOAT : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
m_3dCtx.m_ctxOgl.m_glCtx.m_sampleCount = samples;
|
||||
m_3dCtx.m_ctxOgl.m_glCtx.m_anisotropy = anisotropy;
|
||||
m_3dCtx.m_ctxOgl.m_glCtx.m_deepColor = deepColor;
|
||||
#if BOO_HAS_VULKAN
|
||||
g_VulkanContext.m_sampleCountColor = samples;
|
||||
g_VulkanContext.m_sampleCountDepth = samples;
|
||||
g_VulkanContext.m_anisotropy = anisotropy;
|
||||
g_VulkanContext.m_deepColor = deepColor;
|
||||
g_VulkanContext.m_sampleCountColor = samples;
|
||||
g_VulkanContext.m_sampleCountDepth = samples;
|
||||
g_VulkanContext.m_anisotropy = anisotropy;
|
||||
g_VulkanContext.m_deepColor = deepColor;
|
||||
#endif
|
||||
|
||||
HMODULE dxgilib = LoadLibraryW(L"dxgi.dll");
|
||||
if (!dxgilib)
|
||||
Log.report(logvisor::Fatal, "unable to load dxgi.dll");
|
||||
HMODULE dxgilib = LoadLibraryW(L"dxgi.dll");
|
||||
if (!dxgilib)
|
||||
Log.report(logvisor::Fatal, "unable to load dxgi.dll");
|
||||
|
||||
typedef HRESULT(WINAPI*CreateDXGIFactory1PROC)(REFIID riid, _COM_Outptr_ void **ppFactory);
|
||||
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = (CreateDXGIFactory1PROC)GetProcAddress(dxgilib, "CreateDXGIFactory1");
|
||||
if (!MyCreateDXGIFactory1)
|
||||
Log.report(logvisor::Fatal, "unable to find CreateDXGIFactory1 in DXGI.dll\n");
|
||||
typedef HRESULT(WINAPI * CreateDXGIFactory1PROC)(REFIID riid, _COM_Outptr_ void** ppFactory);
|
||||
CreateDXGIFactory1PROC MyCreateDXGIFactory1 = (CreateDXGIFactory1PROC)GetProcAddress(dxgilib, "CreateDXGIFactory1");
|
||||
if (!MyCreateDXGIFactory1)
|
||||
Log.report(logvisor::Fatal, "unable to find CreateDXGIFactory1 in DXGI.dll\n");
|
||||
|
||||
bool noD3d = false;
|
||||
bool noD3d = false;
|
||||
#if BOO_HAS_VULKAN
|
||||
bool useVulkan = false;
|
||||
bool useVulkan = false;
|
||||
#endif
|
||||
if (!gfxApi.empty())
|
||||
{
|
||||
if (!gfxApi.empty()) {
|
||||
#if BOO_HAS_VULKAN
|
||||
if (!gfxApi.compare("Vulkan"))
|
||||
{
|
||||
noD3d = true;
|
||||
useVulkan = true;
|
||||
}
|
||||
if (!gfxApi.compare("OpenGL"))
|
||||
{
|
||||
noD3d = true;
|
||||
useVulkan = false;
|
||||
}
|
||||
if (!gfxApi.compare("Vulkan")) {
|
||||
noD3d = true;
|
||||
useVulkan = true;
|
||||
}
|
||||
if (!gfxApi.compare("OpenGL")) {
|
||||
noD3d = true;
|
||||
useVulkan = false;
|
||||
}
|
||||
#else
|
||||
if (!gfxApi.compare("OpenGL"))
|
||||
noD3d = true;
|
||||
if (!gfxApi.compare("OpenGL"))
|
||||
noD3d = true;
|
||||
#endif
|
||||
}
|
||||
for (const SystemString& arg : args)
|
||||
{
|
||||
}
|
||||
for (const SystemString& arg : args) {
|
||||
#if BOO_HAS_VULKAN
|
||||
if (!arg.compare(L"--d3d11"))
|
||||
{
|
||||
useVulkan = false;
|
||||
noD3d = false;
|
||||
}
|
||||
if (!arg.compare(L"--vulkan"))
|
||||
{
|
||||
noD3d = true;
|
||||
useVulkan = true;
|
||||
}
|
||||
if (!arg.compare(L"--gl"))
|
||||
{
|
||||
noD3d = true;
|
||||
useVulkan = false;
|
||||
}
|
||||
if (!arg.compare(L"--d3d11")) {
|
||||
useVulkan = false;
|
||||
noD3d = false;
|
||||
}
|
||||
if (!arg.compare(L"--vulkan")) {
|
||||
noD3d = true;
|
||||
useVulkan = true;
|
||||
}
|
||||
if (!arg.compare(L"--gl")) {
|
||||
noD3d = true;
|
||||
useVulkan = false;
|
||||
}
|
||||
#else
|
||||
if (!arg.compare(L"--d3d11"))
|
||||
noD3d = false;
|
||||
if (!arg.compare(L"--gl"))
|
||||
noD3d = true;
|
||||
if (!arg.compare(L"--d3d11"))
|
||||
noD3d = false;
|
||||
if (!arg.compare(L"--gl"))
|
||||
noD3d = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
HMODULE d3d11lib = nullptr;
|
||||
if (!noD3d)
|
||||
d3d11lib = LoadLibraryW(L"D3D11.dll");
|
||||
if (d3d11lib)
|
||||
{
|
||||
if (!FindBestD3DCompile())
|
||||
Log.report(logvisor::Fatal, "unable to find D3DCompile_[43-47].dll");
|
||||
HMODULE d3d11lib = nullptr;
|
||||
if (!noD3d)
|
||||
d3d11lib = LoadLibraryW(L"D3D11.dll");
|
||||
if (d3d11lib) {
|
||||
if (!FindBestD3DCompile())
|
||||
Log.report(logvisor::Fatal, "unable to find D3DCompile_[43-47].dll");
|
||||
|
||||
/* Create device proc */
|
||||
PFN_D3D11_CREATE_DEVICE MyD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11lib, "D3D11CreateDevice");
|
||||
if (!MyD3D11CreateDevice)
|
||||
Log.report(logvisor::Fatal, "unable to find D3D11CreateDevice in D3D11.dll");
|
||||
/* Create device proc */
|
||||
PFN_D3D11_CREATE_DEVICE MyD3D11CreateDevice =
|
||||
(PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11lib, "D3D11CreateDevice");
|
||||
if (!MyD3D11CreateDevice)
|
||||
Log.report(logvisor::Fatal, "unable to find D3D11CreateDevice in D3D11.dll");
|
||||
|
||||
/* Create device */
|
||||
D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;
|
||||
ComPtr<ID3D11Device> tempDev;
|
||||
ComPtr<ID3D11DeviceContext> tempCtx;
|
||||
if (FAILED(MyD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_FLAGS, &level,
|
||||
1, D3D11_SDK_VERSION, &tempDev, nullptr, &tempCtx)))
|
||||
Log.report(logvisor::Fatal, "unable to create D3D11 device");
|
||||
/* Create device */
|
||||
D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0;
|
||||
ComPtr<ID3D11Device> tempDev;
|
||||
ComPtr<ID3D11DeviceContext> tempCtx;
|
||||
if (FAILED(MyD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_FLAGS, &level, 1,
|
||||
D3D11_SDK_VERSION, &tempDev, nullptr, &tempCtx)))
|
||||
Log.report(logvisor::Fatal, "unable to create D3D11 device");
|
||||
|
||||
ComPtr<IDXGIDevice2> device;
|
||||
if (FAILED(tempDev.As<ID3D11Device1>(&m_3dCtx.m_ctx11.m_dev)) || !m_3dCtx.m_ctx11.m_dev ||
|
||||
FAILED(tempCtx.As<ID3D11DeviceContext1>(&m_3dCtx.m_ctx11.m_devCtx)) || !m_3dCtx.m_ctx11.m_devCtx ||
|
||||
FAILED(m_3dCtx.m_ctx11.m_dev.As<IDXGIDevice2>(&device)) || !device)
|
||||
{
|
||||
MessageBoxW(nullptr, L"Windows 7 users should install 'Platform Update for Windows 7':\n"
|
||||
L"https://www.microsoft.com/en-us/download/details.aspx?id=36805",
|
||||
L"IDXGIDevice2 interface error", MB_OK | MB_ICONERROR);
|
||||
exit(1);
|
||||
}
|
||||
ComPtr<IDXGIDevice2> device;
|
||||
if (FAILED(tempDev.As<ID3D11Device1>(&m_3dCtx.m_ctx11.m_dev)) || !m_3dCtx.m_ctx11.m_dev ||
|
||||
FAILED(tempCtx.As<ID3D11DeviceContext1>(&m_3dCtx.m_ctx11.m_devCtx)) || !m_3dCtx.m_ctx11.m_devCtx ||
|
||||
FAILED(m_3dCtx.m_ctx11.m_dev.As<IDXGIDevice2>(&device)) || !device) {
|
||||
MessageBoxW(nullptr,
|
||||
L"Windows 7 users should install 'Platform Update for Windows 7':\n"
|
||||
L"https://www.microsoft.com/en-us/download/details.aspx?id=36805",
|
||||
L"IDXGIDevice2 interface error", MB_OK | MB_ICONERROR);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Obtain DXGI Factory */
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx11.m_dxFactory);
|
||||
/* Obtain DXGI Factory */
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
device->GetParent(__uuidof(IDXGIAdapter), &adapter);
|
||||
adapter->GetParent(__uuidof(IDXGIFactory2), &m_3dCtx.m_ctx11.m_dxFactory);
|
||||
|
||||
m_3dCtx.m_ctx11.m_anisotropy = std::min(m_3dCtx.m_ctx11.m_anisotropy, uint32_t(16));
|
||||
m_3dCtx.m_ctx11.m_anisotropy = std::min(m_3dCtx.m_ctx11.m_anisotropy, uint32_t(16));
|
||||
|
||||
/* Build default sampler here */
|
||||
CD3D11_SAMPLER_DESC sampDesc(D3D11_DEFAULT);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.Filter = D3D11_FILTER_ANISOTROPIC;
|
||||
sampDesc.MaxAnisotropy = m_3dCtx.m_ctx11.m_anisotropy;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[0]);
|
||||
/* Build default sampler here */
|
||||
CD3D11_SAMPLER_DESC sampDesc(D3D11_DEFAULT);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampDesc.Filter = D3D11_FILTER_ANISOTROPIC;
|
||||
sampDesc.MaxAnisotropy = m_3dCtx.m_ctx11.m_anisotropy;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[0]);
|
||||
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[1]);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[1]);
|
||||
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
std::fill(std::begin(sampDesc.BorderColor), std::end(sampDesc.BorderColor), 0.f);
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[2]);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
std::fill(std::begin(sampDesc.BorderColor), std::end(sampDesc.BorderColor), 0.f);
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[2]);
|
||||
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[3]);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[3]);
|
||||
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[4]);
|
||||
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
m_3dCtx.m_ctx11.m_dev->CreateSamplerState(&sampDesc, &m_3dCtx.m_ctx11.m_ss[4]);
|
||||
|
||||
Log.report(logvisor::Info, "initialized D3D11 renderer");
|
||||
return;
|
||||
}
|
||||
Log.report(logvisor::Info, "initialized D3D11 renderer");
|
||||
return;
|
||||
}
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
if (useVulkan)
|
||||
{
|
||||
HMODULE vulkanLib = LoadLibraryW(L"vulkan-1.dll");
|
||||
if (vulkanLib)
|
||||
{
|
||||
m_getVkProc = (PFN_vkGetInstanceProcAddr)GetProcAddress(vulkanLib, "vkGetInstanceProcAddr");
|
||||
if (m_getVkProc)
|
||||
{
|
||||
/* Check device support for vulkan */
|
||||
if (g_VulkanContext.m_instance == VK_NULL_HANDLE)
|
||||
{
|
||||
auto appName = getUniqueName();
|
||||
if (g_VulkanContext.initVulkan(WCSTMBS(appName.data()).c_str(), m_getVkProc))
|
||||
{
|
||||
if (g_VulkanContext.enumerateDevices())
|
||||
{
|
||||
/* Obtain DXGI Factory */
|
||||
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_vulkanDxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create DXGI factory");
|
||||
if (useVulkan) {
|
||||
HMODULE vulkanLib = LoadLibraryW(L"vulkan-1.dll");
|
||||
if (vulkanLib) {
|
||||
m_getVkProc = (PFN_vkGetInstanceProcAddr)GetProcAddress(vulkanLib, "vkGetInstanceProcAddr");
|
||||
if (m_getVkProc) {
|
||||
/* Check device support for vulkan */
|
||||
if (g_VulkanContext.m_instance == VK_NULL_HANDLE) {
|
||||
auto appName = getUniqueName();
|
||||
if (g_VulkanContext.initVulkan(WCSTMBS(appName.data()).c_str(), m_getVkProc)) {
|
||||
if (g_VulkanContext.enumerateDevices()) {
|
||||
/* Obtain DXGI Factory */
|
||||
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_vulkanDxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create DXGI factory");
|
||||
|
||||
Log.report(logvisor::Info, "initialized Vulkan renderer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.report(logvisor::Info, "initialized Vulkan renderer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Finally try OpenGL */
|
||||
{
|
||||
/* Obtain DXGI Factory */
|
||||
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_ctxOgl.m_dxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create DXGI factory");
|
||||
/* Finally try OpenGL */
|
||||
{
|
||||
/* Obtain DXGI Factory */
|
||||
HRESULT hr = MyCreateDXGIFactory1(__uuidof(IDXGIFactory1), &m_3dCtx.m_ctxOgl.m_dxFactory);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create DXGI factory");
|
||||
|
||||
Log.report(logvisor::Info, "initialized OpenGL renderer");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.report(logvisor::Fatal, "system doesn't support Vulkan, D3D11, or OpenGL");
|
||||
Log.report(logvisor::Info, "initialized OpenGL renderer");
|
||||
return;
|
||||
}
|
||||
|
||||
EPlatformType getPlatformType() const
|
||||
{
|
||||
return EPlatformType::Win32;
|
||||
Log.report(logvisor::Fatal, "system doesn't support Vulkan, D3D11, or OpenGL");
|
||||
}
|
||||
|
||||
EPlatformType getPlatformType() const { return EPlatformType::Win32; }
|
||||
|
||||
LRESULT winHwndHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
/* Lookup boo window instance */
|
||||
auto search = m_allWindows.find(hwnd);
|
||||
if (search == m_allWindows.end())
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
;
|
||||
|
||||
std::shared_ptr<IWindow> window = search->second.lock();
|
||||
if (!window)
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
|
||||
switch (uMsg) {
|
||||
case WM_CREATE:
|
||||
return 0;
|
||||
|
||||
case WM_DEVICECHANGE:
|
||||
return DeviceFinder::winDevChangedHandler(wParam, lParam);
|
||||
|
||||
case WM_CLOSE:
|
||||
case WM_SIZE:
|
||||
case WM_MOVING:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_XBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSELEAVE:
|
||||
case WM_NCMOUSELEAVE:
|
||||
case WM_MOUSEHOVER:
|
||||
case WM_NCMOUSEHOVER:
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
case WM_CHAR:
|
||||
case WM_UNICHAR: {
|
||||
HWNDEvent eventData(uMsg, wParam, lParam);
|
||||
window->_incomingEvent(&eventData);
|
||||
}
|
||||
|
||||
LRESULT winHwndHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
/* Lookup boo window instance */
|
||||
auto search = m_allWindows.find(hwnd);
|
||||
if (search == m_allWindows.end())
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);;
|
||||
|
||||
std::shared_ptr<IWindow> window = search->second.lock();
|
||||
if (!window)
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
return 0;
|
||||
|
||||
case WM_DEVICECHANGE:
|
||||
return DeviceFinder::winDevChangedHandler(wParam, lParam);
|
||||
|
||||
case WM_CLOSE:
|
||||
case WM_SIZE:
|
||||
case WM_MOVING:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_XBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSELEAVE:
|
||||
case WM_NCMOUSELEAVE:
|
||||
case WM_MOUSEHOVER:
|
||||
case WM_NCMOUSEHOVER:
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
case WM_CHAR:
|
||||
case WM_UNICHAR:
|
||||
{
|
||||
HWNDEvent eventData(uMsg, wParam, lParam);
|
||||
window->_incomingEvent(&eventData);
|
||||
}
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
default:
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
template <class W>
|
||||
static void DoSetFullscreen(W& win, bool fs)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(g_nwmt);
|
||||
if (fs)
|
||||
{
|
||||
win.m_fsStyle = GetWindowLong(win.m_hwnd, GWL_STYLE);
|
||||
win.m_fsExStyle = GetWindowLong(win.m_hwnd, GWL_EXSTYLE);
|
||||
GetWindowRect(win.m_hwnd, &win.m_fsRect);
|
||||
template <class W>
|
||||
static void DoSetFullscreen(W& win, bool fs) {
|
||||
std::lock_guard<std::mutex> lk(g_nwmt);
|
||||
if (fs) {
|
||||
win.m_fsStyle = GetWindowLong(win.m_hwnd, GWL_STYLE);
|
||||
win.m_fsExStyle = GetWindowLong(win.m_hwnd, GWL_EXSTYLE);
|
||||
GetWindowRect(win.m_hwnd, &win.m_fsRect);
|
||||
|
||||
SetWindowLong(win.m_hwnd, GWL_STYLE,
|
||||
win.m_fsStyle & ~(WS_CAPTION | WS_THICKFRAME));
|
||||
SetWindowLong(win.m_hwnd, GWL_EXSTYLE,
|
||||
win.m_fsExStyle & ~(WS_EX_DLGMODALFRAME |
|
||||
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
|
||||
SetWindowLong(win.m_hwnd, GWL_STYLE, win.m_fsStyle & ~(WS_CAPTION | WS_THICKFRAME));
|
||||
SetWindowLong(win.m_hwnd, GWL_EXSTYLE,
|
||||
win.m_fsExStyle & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
|
||||
|
||||
MONITORINFO monitor_info;
|
||||
monitor_info.cbSize = sizeof(monitor_info);
|
||||
GetMonitorInfo(MonitorFromWindow(win.m_hwnd, MONITOR_DEFAULTTONEAREST),
|
||||
&monitor_info);
|
||||
SetWindowPos(win.m_hwnd, NULL, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top,
|
||||
monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
|
||||
monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
MONITORINFO monitor_info;
|
||||
monitor_info.cbSize = sizeof(monitor_info);
|
||||
GetMonitorInfo(MonitorFromWindow(win.m_hwnd, MONITOR_DEFAULTTONEAREST), &monitor_info);
|
||||
SetWindowPos(win.m_hwnd, NULL, monitor_info.rcMonitor.left, monitor_info.rcMonitor.top,
|
||||
monitor_info.rcMonitor.right - monitor_info.rcMonitor.left,
|
||||
monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
|
||||
win.m_fs = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowLong(win.m_hwnd, GWL_STYLE, win.m_fsStyle);
|
||||
SetWindowLong(win.m_hwnd, GWL_EXSTYLE, win.m_fsExStyle);
|
||||
win.m_fs = true;
|
||||
} else {
|
||||
SetWindowLong(win.m_hwnd, GWL_STYLE, win.m_fsStyle);
|
||||
SetWindowLong(win.m_hwnd, GWL_EXSTYLE, win.m_fsExStyle);
|
||||
|
||||
SetWindowPos(win.m_hwnd, NULL, win.m_fsRect.left, win.m_fsRect.top,
|
||||
win.m_fsRect.right - win.m_fsRect.left, win.m_fsRect.bottom - win.m_fsRect.top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
SetWindowPos(win.m_hwnd, NULL, win.m_fsRect.left, win.m_fsRect.top, win.m_fsRect.right - win.m_fsRect.left,
|
||||
win.m_fsRect.bottom - win.m_fsRect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
|
||||
win.m_fs = false;
|
||||
}
|
||||
g_nwcv.notify_one();
|
||||
win.m_fs = false;
|
||||
}
|
||||
g_nwcv.notify_one();
|
||||
}
|
||||
|
||||
int run()
|
||||
{
|
||||
g_mainThreadId = GetCurrentThreadId();
|
||||
int run() {
|
||||
g_mainThreadId = GetCurrentThreadId();
|
||||
|
||||
/* Spawn client thread */
|
||||
int clientReturn = 0;
|
||||
std::thread clientThread([&]()
|
||||
{
|
||||
std::string thrName = WCSTMBS(getFriendlyName().data()) + " Client Thread";
|
||||
logvisor::RegisterThreadName(thrName.c_str());
|
||||
CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
clientReturn = m_callback.appMain(this);
|
||||
PostThreadMessageW(g_mainThreadId, WM_USER+1, 0, 0);
|
||||
});
|
||||
/* Spawn client thread */
|
||||
int clientReturn = 0;
|
||||
std::thread clientThread([&]() {
|
||||
std::string thrName = WCSTMBS(getFriendlyName().data()) + " Client Thread";
|
||||
logvisor::RegisterThreadName(thrName.c_str());
|
||||
CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
clientReturn = m_callback.appMain(this);
|
||||
PostThreadMessageW(g_mainThreadId, WM_USER + 1, 0, 0);
|
||||
});
|
||||
|
||||
/* Pump messages */
|
||||
MSG msg = {0};
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
if (!msg.hwnd)
|
||||
{
|
||||
/* PostThreadMessage events */
|
||||
switch (msg.message)
|
||||
{
|
||||
case WM_USER:
|
||||
{
|
||||
/* New-window message (coalesced onto main thread) */
|
||||
std::lock_guard<std::mutex> lk(g_nwmt);
|
||||
SystemStringView* title = reinterpret_cast<SystemStringView*>(msg.wParam);
|
||||
m_mwret = newWindow(*title);
|
||||
g_nwcv.notify_one();
|
||||
continue;
|
||||
}
|
||||
case WM_USER+1:
|
||||
/* Quit message from client thread */
|
||||
PostQuitMessage(0);
|
||||
continue;
|
||||
case WM_USER+2:
|
||||
/* SetCursor call from client thread */
|
||||
SetCursor(HCURSOR(msg.wParam));
|
||||
continue;
|
||||
case WM_USER+3:
|
||||
/* ImmSetOpenStatus call from client thread */
|
||||
ImmSetOpenStatus(HIMC(msg.wParam), BOOL(msg.lParam));
|
||||
continue;
|
||||
case WM_USER+4:
|
||||
/* ImmSetCompositionWindow call from client thread */
|
||||
ImmSetCompositionWindow(HIMC(msg.wParam), LPCOMPOSITIONFORM(msg.lParam));
|
||||
continue;
|
||||
case WM_USER+5:
|
||||
/* SetFullscreen call for OpenGL window */
|
||||
DoSetFullscreen(*reinterpret_cast<OGLContext::Window*>(msg.wParam), msg.lParam);
|
||||
continue;
|
||||
/* Pump messages */
|
||||
MSG msg = {0};
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
if (!msg.hwnd) {
|
||||
/* PostThreadMessage events */
|
||||
switch (msg.message) {
|
||||
case WM_USER: {
|
||||
/* New-window message (coalesced onto main thread) */
|
||||
std::lock_guard<std::mutex> lk(g_nwmt);
|
||||
SystemStringView* title = reinterpret_cast<SystemStringView*>(msg.wParam);
|
||||
m_mwret = newWindow(*title);
|
||||
g_nwcv.notify_one();
|
||||
continue;
|
||||
}
|
||||
case WM_USER + 1:
|
||||
/* Quit message from client thread */
|
||||
PostQuitMessage(0);
|
||||
continue;
|
||||
case WM_USER + 2:
|
||||
/* SetCursor call from client thread */
|
||||
SetCursor(HCURSOR(msg.wParam));
|
||||
continue;
|
||||
case WM_USER + 3:
|
||||
/* ImmSetOpenStatus call from client thread */
|
||||
ImmSetOpenStatus(HIMC(msg.wParam), BOOL(msg.lParam));
|
||||
continue;
|
||||
case WM_USER + 4:
|
||||
/* ImmSetCompositionWindow call from client thread */
|
||||
ImmSetCompositionWindow(HIMC(msg.wParam), LPCOMPOSITIONFORM(msg.lParam));
|
||||
continue;
|
||||
case WM_USER + 5:
|
||||
/* SetFullscreen call for OpenGL window */
|
||||
DoSetFullscreen(*reinterpret_cast<OGLContext::Window*>(msg.wParam), msg.lParam);
|
||||
continue;
|
||||
#if BOO_HAS_VULKAN
|
||||
case WM_USER+6:
|
||||
/* SetFullscreen call for Vulkan window */
|
||||
DoSetFullscreen(*reinterpret_cast<boo::VulkanContext::Window*>(msg.wParam), msg.lParam);
|
||||
continue;
|
||||
case WM_USER + 6:
|
||||
/* SetFullscreen call for Vulkan window */
|
||||
DoSetFullscreen(*reinterpret_cast<boo::VulkanContext::Window*>(msg.wParam), msg.lParam);
|
||||
continue;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_callback.appQuitting(this);
|
||||
clientThread.join();
|
||||
return clientReturn;
|
||||
}
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
~ApplicationWin32()
|
||||
{
|
||||
for (auto& p : m_allWindows)
|
||||
if (auto w = p.second.lock())
|
||||
w->_cleanup();
|
||||
m_callback.appQuitting(this);
|
||||
clientThread.join();
|
||||
return clientReturn;
|
||||
}
|
||||
|
||||
~ApplicationWin32() {
|
||||
for (auto& p : m_allWindows)
|
||||
if (auto w = p.second.lock())
|
||||
w->_cleanup();
|
||||
}
|
||||
|
||||
SystemStringView getUniqueName() const { return m_uniqueName; }
|
||||
|
||||
SystemStringView getFriendlyName() const { return m_friendlyName; }
|
||||
|
||||
SystemStringView getProcessName() const { return m_pname; }
|
||||
|
||||
const std::vector<SystemString>& getArgs() const { return m_args; }
|
||||
|
||||
std::shared_ptr<IWindow> m_mwret;
|
||||
std::shared_ptr<IWindow> newWindow(SystemStringView title) {
|
||||
if (GetCurrentThreadId() != g_mainThreadId) {
|
||||
std::unique_lock<std::mutex> lk(g_nwmt);
|
||||
if (!PostThreadMessageW(g_mainThreadId, WM_USER, WPARAM(&title), 0))
|
||||
Log.report(logvisor::Fatal, "PostThreadMessage error");
|
||||
g_nwcv.wait(lk);
|
||||
std::shared_ptr<IWindow> ret = std::move(m_mwret);
|
||||
m_mwret.reset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
SystemStringView getUniqueName() const
|
||||
{
|
||||
return m_uniqueName;
|
||||
}
|
||||
|
||||
SystemStringView getFriendlyName() const
|
||||
{
|
||||
return m_friendlyName;
|
||||
}
|
||||
|
||||
SystemStringView getProcessName() const
|
||||
{
|
||||
return m_pname;
|
||||
}
|
||||
|
||||
const std::vector<SystemString>& getArgs() const
|
||||
{
|
||||
return m_args;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWindow> m_mwret;
|
||||
std::shared_ptr<IWindow> newWindow(SystemStringView title)
|
||||
{
|
||||
if (GetCurrentThreadId() != g_mainThreadId)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(g_nwmt);
|
||||
if (!PostThreadMessageW(g_mainThreadId, WM_USER, WPARAM(&title), 0))
|
||||
Log.report(logvisor::Fatal, "PostThreadMessage error");
|
||||
g_nwcv.wait(lk);
|
||||
std::shared_ptr<IWindow> ret = std::move(m_mwret);
|
||||
m_mwret.reset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<IWindow> window = _WindowWin32New(title, m_3dCtx);
|
||||
HWND hwnd = HWND(window->getPlatformHandle());
|
||||
m_allWindows[hwnd] = window;
|
||||
return window;
|
||||
}
|
||||
std::shared_ptr<IWindow> window = _WindowWin32New(title, m_3dCtx);
|
||||
HWND hwnd = HWND(window->getPlatformHandle());
|
||||
m_allWindows[hwnd] = window;
|
||||
return window;
|
||||
}
|
||||
};
|
||||
|
||||
IApplication* APP = NULL;
|
||||
int ApplicationRun(IApplication::EPlatformType platform,
|
||||
IApplicationCallback& cb,
|
||||
SystemStringView uniqueName,
|
||||
SystemStringView friendlyName,
|
||||
SystemStringView pname,
|
||||
const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi,
|
||||
uint32_t samples,
|
||||
uint32_t anisotropy,
|
||||
bool deepColor,
|
||||
bool singleInstance)
|
||||
{
|
||||
std::string thrName = WCSTMBS(friendlyName.data()) + " Main Thread";
|
||||
logvisor::RegisterThreadName(thrName.c_str());
|
||||
if (APP)
|
||||
return 1;
|
||||
if (platform != IApplication::EPlatformType::Win32 &&
|
||||
platform != IApplication::EPlatformType::Auto)
|
||||
return 1;
|
||||
int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, SystemStringView uniqueName,
|
||||
SystemStringView friendlyName, SystemStringView pname, const std::vector<SystemString>& args,
|
||||
std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool deepColor,
|
||||
bool singleInstance) {
|
||||
std::string thrName = WCSTMBS(friendlyName.data()) + " Main Thread";
|
||||
logvisor::RegisterThreadName(thrName.c_str());
|
||||
if (APP)
|
||||
return 1;
|
||||
if (platform != IApplication::EPlatformType::Win32 && platform != IApplication::EPlatformType::Auto)
|
||||
return 1;
|
||||
|
||||
#if _WIN32_WINNT_WINBLUE
|
||||
/* HI-DPI support */
|
||||
HMODULE shcoreLib = LoadLibraryW(L"Shcore.dll");
|
||||
if (shcoreLib)
|
||||
MyGetScaleFactorForMonitor =
|
||||
(PFN_GetScaleFactorForMonitor)GetProcAddress(shcoreLib, "GetScaleFactorForMonitor");
|
||||
/* HI-DPI support */
|
||||
HMODULE shcoreLib = LoadLibraryW(L"Shcore.dll");
|
||||
if (shcoreLib)
|
||||
MyGetScaleFactorForMonitor = (PFN_GetScaleFactorForMonitor)GetProcAddress(shcoreLib, "GetScaleFactorForMonitor");
|
||||
#endif
|
||||
|
||||
WIN32_CURSORS.m_arrow = LoadCursor(nullptr, IDC_ARROW);
|
||||
WIN32_CURSORS.m_hResize = LoadCursor(nullptr, IDC_SIZEWE);
|
||||
WIN32_CURSORS.m_vResize = LoadCursor(nullptr, IDC_SIZENS);
|
||||
WIN32_CURSORS.m_ibeam = LoadCursor(nullptr, IDC_IBEAM);
|
||||
WIN32_CURSORS.m_crosshairs = LoadCursor(nullptr, IDC_CROSS);
|
||||
WIN32_CURSORS.m_wait = LoadCursor(nullptr, IDC_WAIT);
|
||||
WIN32_CURSORS.m_arrow = LoadCursor(nullptr, IDC_ARROW);
|
||||
WIN32_CURSORS.m_hResize = LoadCursor(nullptr, IDC_SIZEWE);
|
||||
WIN32_CURSORS.m_vResize = LoadCursor(nullptr, IDC_SIZENS);
|
||||
WIN32_CURSORS.m_ibeam = LoadCursor(nullptr, IDC_IBEAM);
|
||||
WIN32_CURSORS.m_crosshairs = LoadCursor(nullptr, IDC_CROSS);
|
||||
WIN32_CURSORS.m_wait = LoadCursor(nullptr, IDC_WAIT);
|
||||
|
||||
/* One class for *all* boo windows */
|
||||
WNDCLASS wndClass =
|
||||
{
|
||||
0,
|
||||
WindowProc,
|
||||
0,
|
||||
0,
|
||||
GetModuleHandle(nullptr),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
L"BooWindow"
|
||||
};
|
||||
wndClass.hIcon = LoadIconW(wndClass.hInstance, MAKEINTRESOURCEW(101));
|
||||
wndClass.hCursor = WIN32_CURSORS.m_arrow;
|
||||
RegisterClassW(&wndClass);
|
||||
/* One class for *all* boo windows */
|
||||
WNDCLASS wndClass = {0, WindowProc, 0, 0, GetModuleHandle(nullptr), 0, 0, 0, 0, L"BooWindow"};
|
||||
wndClass.hIcon = LoadIconW(wndClass.hInstance, MAKEINTRESOURCEW(101));
|
||||
wndClass.hCursor = WIN32_CURSORS.m_arrow;
|
||||
RegisterClassW(&wndClass);
|
||||
|
||||
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args,
|
||||
gfxApi, samples, anisotropy, deepColor, singleInstance);
|
||||
int ret = APP->run();
|
||||
delete APP;
|
||||
APP = nullptr;
|
||||
return ret;
|
||||
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args, gfxApi, samples, anisotropy, deepColor,
|
||||
singleInstance);
|
||||
int ret = APP->run();
|
||||
delete APP;
|
||||
APP = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace boo
|
||||
|
||||
static const DEV_BROADCAST_DEVICEINTERFACE HOTPLUG_CONF =
|
||||
{
|
||||
sizeof(DEV_BROADCAST_DEVICEINTERFACE),
|
||||
DBT_DEVTYP_DEVICEINTERFACE
|
||||
};
|
||||
static const DEV_BROADCAST_DEVICEINTERFACE HOTPLUG_CONF = {sizeof(DEV_BROADCAST_DEVICEINTERFACE),
|
||||
DBT_DEVTYP_DEVICEINTERFACE};
|
||||
static bool HOTPLUG_REGISTERED = false;
|
||||
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!HOTPLUG_REGISTERED && uMsg == WM_CREATE)
|
||||
{
|
||||
/* Register hotplug notification with windows */
|
||||
RegisterDeviceNotification(hwnd, (LPVOID)&HOTPLUG_CONF,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
|
||||
HOTPLUG_REGISTERED = true;
|
||||
}
|
||||
return static_cast<boo::ApplicationWin32*>(boo::APP)->winHwndHandler(hwnd, uMsg, wParam, lParam);
|
||||
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
if (!HOTPLUG_REGISTERED && uMsg == WM_CREATE) {
|
||||
/* Register hotplug notification with windows */
|
||||
RegisterDeviceNotification(hwnd, (LPVOID)&HOTPLUG_CONF,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
|
||||
HOTPLUG_REGISTERED = true;
|
||||
}
|
||||
return static_cast<boo::ApplicationWin32*>(boo::APP)->winHwndHandler(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,84 +2,73 @@
|
||||
|
||||
#include "WinCommon.hpp"
|
||||
|
||||
struct Boo3DAppContextUWP : Boo3DAppContext
|
||||
{
|
||||
bool isFullscreen(const boo::IWindow* window)
|
||||
{
|
||||
struct Boo3DAppContextUWP : Boo3DAppContext {
|
||||
bool isFullscreen(const boo::IWindow* window) {
|
||||
#if _WIN32_WINNT_WIN10
|
||||
if (m_ctx12.m_dev)
|
||||
{
|
||||
D3D12Context::Window& win = m_ctx12.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
return isFScr != 0;
|
||||
}
|
||||
#endif
|
||||
if (m_ctx11.m_dev)
|
||||
{
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
return isFScr != 0;
|
||||
}
|
||||
return false;
|
||||
if (m_ctx12.m_dev) {
|
||||
D3D12Context::Window& win = m_ctx12.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
return isFScr != 0;
|
||||
}
|
||||
#endif
|
||||
if (m_ctx11.m_dev) {
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
return isFScr != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool setFullscreen(boo::IWindow* window, bool fs)
|
||||
{
|
||||
bool setFullscreen(boo::IWindow* window, bool fs) {
|
||||
#if _WIN32_WINNT_WIN10
|
||||
if (m_ctx12.m_dev)
|
||||
{
|
||||
D3D12Context::Window& win = m_ctx12.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
if (fs && isFScr)
|
||||
return false;
|
||||
else if (!fs && !isFScr)
|
||||
return false;
|
||||
|
||||
if (fs)
|
||||
{
|
||||
ComPtr<IDXGIOutput> out;
|
||||
win.m_swapChain->GetContainingOutput(&out);
|
||||
DXGI_OUTPUT_DESC outDesc;
|
||||
out->GetDesc(&outDesc);
|
||||
|
||||
win.m_swapChain->SetFullscreenState(true, nullptr);
|
||||
DXGI_MODE_DESC mdesc = {UINT(outDesc.DesktopCoordinates.right - outDesc.DesktopCoordinates.left),
|
||||
UINT(outDesc.DesktopCoordinates.bottom - outDesc.DesktopCoordinates.top)};
|
||||
win.m_swapChain->ResizeTarget(&mdesc);
|
||||
}
|
||||
else
|
||||
win.m_swapChain->SetFullscreenState(false, nullptr);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
if (m_ctx11.m_dev)
|
||||
{
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
if (fs && isFScr)
|
||||
return false;
|
||||
else if (!fs && !isFScr)
|
||||
return false;
|
||||
|
||||
if (fs)
|
||||
{
|
||||
ComPtr<IDXGIOutput> out;
|
||||
win.m_swapChain->GetContainingOutput(&out);
|
||||
DXGI_OUTPUT_DESC outDesc;
|
||||
out->GetDesc(&outDesc);
|
||||
|
||||
win.m_fsdesc.Width = outDesc.DesktopCoordinates.right;
|
||||
win.m_fsdesc.Height = outDesc.DesktopCoordinates.bottom;
|
||||
}
|
||||
win.m_fs = fs;
|
||||
win.m_needsFSTransition = true;
|
||||
return true;
|
||||
}
|
||||
if (m_ctx12.m_dev) {
|
||||
D3D12Context::Window& win = m_ctx12.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
if (fs && isFScr)
|
||||
return false;
|
||||
else if (!fs && !isFScr)
|
||||
return false;
|
||||
|
||||
if (fs) {
|
||||
ComPtr<IDXGIOutput> out;
|
||||
win.m_swapChain->GetContainingOutput(&out);
|
||||
DXGI_OUTPUT_DESC outDesc;
|
||||
out->GetDesc(&outDesc);
|
||||
|
||||
win.m_swapChain->SetFullscreenState(true, nullptr);
|
||||
DXGI_MODE_DESC mdesc = {UINT(outDesc.DesktopCoordinates.right - outDesc.DesktopCoordinates.left),
|
||||
UINT(outDesc.DesktopCoordinates.bottom - outDesc.DesktopCoordinates.top)};
|
||||
win.m_swapChain->ResizeTarget(&mdesc);
|
||||
} else
|
||||
win.m_swapChain->SetFullscreenState(false, nullptr);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
if (m_ctx11.m_dev) {
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
if (fs && isFScr)
|
||||
return false;
|
||||
else if (!fs && !isFScr)
|
||||
return false;
|
||||
|
||||
if (fs) {
|
||||
ComPtr<IDXGIOutput> out;
|
||||
win.m_swapChain->GetContainingOutput(&out);
|
||||
DXGI_OUTPUT_DESC outDesc;
|
||||
out->GetDesc(&outDesc);
|
||||
|
||||
win.m_fsdesc.Width = outDesc.DesktopCoordinates.right;
|
||||
win.m_fsdesc.Height = outDesc.DesktopCoordinates.bottom;
|
||||
}
|
||||
win.m_fs = fs;
|
||||
win.m_needsFSTransition = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,150 +20,133 @@ extern std::condition_variable g_nwcv;
|
||||
|
||||
#if _WIN32_WINNT_WINBLUE && !WINDOWS_STORE
|
||||
#include <ShellScalingApi.h>
|
||||
typedef HRESULT (WINAPI* PFN_GetScaleFactorForMonitor)( _In_ HMONITOR, _Out_ DEVICE_SCALE_FACTOR *);
|
||||
typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(_In_ HMONITOR, _Out_ DEVICE_SCALE_FACTOR*);
|
||||
extern PFN_GetScaleFactorForMonitor MyGetScaleFactorForMonitor;
|
||||
#endif
|
||||
|
||||
struct OGLContext
|
||||
{
|
||||
ComPtr<IDXGIFactory1> m_dxFactory;
|
||||
HGLRC m_lastContext = 0;
|
||||
struct Window
|
||||
{
|
||||
HWND m_hwnd;
|
||||
HDC m_deviceContext;
|
||||
HGLRC m_mainContext;
|
||||
HGLRC m_renderContext;
|
||||
bool m_needsResize = false;
|
||||
size_t width, height;
|
||||
struct OGLContext {
|
||||
ComPtr<IDXGIFactory1> m_dxFactory;
|
||||
HGLRC m_lastContext = 0;
|
||||
struct Window {
|
||||
HWND m_hwnd;
|
||||
HDC m_deviceContext;
|
||||
HGLRC m_mainContext;
|
||||
HGLRC m_renderContext;
|
||||
bool m_needsResize = false;
|
||||
size_t width, height;
|
||||
|
||||
bool m_fs = false;
|
||||
LONG m_fsStyle;
|
||||
LONG m_fsExStyle;
|
||||
RECT m_fsRect;
|
||||
int m_fsCountDown = 0;
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
bool m_fs = false;
|
||||
LONG m_fsStyle;
|
||||
LONG m_fsExStyle;
|
||||
RECT m_fsRect;
|
||||
int m_fsCountDown = 0;
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
|
||||
boo::GLContext m_glCtx;
|
||||
boo::GLContext m_glCtx;
|
||||
};
|
||||
|
||||
#if !WINDOWS_STORE
|
||||
static inline void SetFullscreen(OGLContext::Window& win, bool fs)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(g_nwmt);
|
||||
PostThreadMessageW(g_mainThreadId, WM_USER+5, WPARAM(&win), LPARAM(fs));
|
||||
g_nwcv.wait(lk);
|
||||
static inline void SetFullscreen(OGLContext::Window& win, bool fs) {
|
||||
std::unique_lock<std::mutex> lk(g_nwmt);
|
||||
PostThreadMessageW(g_mainThreadId, WM_USER + 5, WPARAM(&win), LPARAM(fs));
|
||||
g_nwcv.wait(lk);
|
||||
}
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
static inline void SetFullscreen(boo::VulkanContext::Window& win, bool fs)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(g_nwmt);
|
||||
PostThreadMessageW(g_mainThreadId, WM_USER+6, WPARAM(&win), LPARAM(fs));
|
||||
g_nwcv.wait(lk);
|
||||
static inline void SetFullscreen(boo::VulkanContext::Window& win, bool fs) {
|
||||
std::unique_lock<std::mutex> lk(g_nwmt);
|
||||
PostThreadMessageW(g_mainThreadId, WM_USER + 6, WPARAM(&win), LPARAM(fs));
|
||||
g_nwcv.wait(lk);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct Boo3DAppContextWin32 : Boo3DAppContext
|
||||
{
|
||||
OGLContext m_ctxOgl;
|
||||
ComPtr<IDXGIFactory1> m_vulkanDxFactory;
|
||||
struct Boo3DAppContextWin32 : Boo3DAppContext {
|
||||
OGLContext m_ctxOgl;
|
||||
ComPtr<IDXGIFactory1> m_vulkanDxFactory;
|
||||
|
||||
bool isFullscreen(const boo::IWindow* window)
|
||||
{
|
||||
bool isFullscreen(const boo::IWindow* window) {
|
||||
#if BOO_HAS_VULKAN
|
||||
if (m_vulkanDxFactory)
|
||||
{
|
||||
boo::VulkanContext::Window& win = *boo::g_VulkanContext.m_windows[window];
|
||||
return win.m_fs;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_ctx11.m_dev)
|
||||
{
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
return isFScr != 0;
|
||||
}
|
||||
OGLContext::Window& win = m_ctxOgl.m_windows[window];
|
||||
return win.m_fs;
|
||||
if (m_vulkanDxFactory) {
|
||||
boo::VulkanContext::Window& win = *boo::g_VulkanContext.m_windows[window];
|
||||
return win.m_fs;
|
||||
}
|
||||
|
||||
bool setFullscreen(boo::IWindow* window, bool fs)
|
||||
{
|
||||
#if BOO_HAS_VULKAN
|
||||
if (m_vulkanDxFactory)
|
||||
{
|
||||
boo::VulkanContext::Window& win = *boo::g_VulkanContext.m_windows[window];
|
||||
if (fs && win.m_fs)
|
||||
return false;
|
||||
else if (!fs && !win.m_fs)
|
||||
return false;
|
||||
SetFullscreen(win, fs);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_ctx11.m_dev)
|
||||
{
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
if (fs && isFScr)
|
||||
return false;
|
||||
else if (!fs && !isFScr)
|
||||
return false;
|
||||
if (m_ctx11.m_dev) {
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
return isFScr != 0;
|
||||
}
|
||||
OGLContext::Window& win = m_ctxOgl.m_windows[window];
|
||||
return win.m_fs;
|
||||
}
|
||||
|
||||
if (fs)
|
||||
{
|
||||
ComPtr<IDXGIOutput> out;
|
||||
win.m_swapChain->GetContainingOutput(&out);
|
||||
DXGI_OUTPUT_DESC outDesc;
|
||||
out->GetDesc(&outDesc);
|
||||
bool setFullscreen(boo::IWindow* window, bool fs) {
|
||||
#if BOO_HAS_VULKAN
|
||||
if (m_vulkanDxFactory) {
|
||||
boo::VulkanContext::Window& win = *boo::g_VulkanContext.m_windows[window];
|
||||
if (fs && win.m_fs)
|
||||
return false;
|
||||
else if (!fs && !win.m_fs)
|
||||
return false;
|
||||
SetFullscreen(win, fs);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
win.m_fsdesc.Width = outDesc.DesktopCoordinates.right;
|
||||
win.m_fsdesc.Height = outDesc.DesktopCoordinates.bottom;
|
||||
}
|
||||
win.m_fs = fs;
|
||||
win.m_needsFSTransition = true;
|
||||
return true;
|
||||
}
|
||||
if (m_ctx11.m_dev) {
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
BOOL isFScr;
|
||||
win.m_swapChain->GetFullscreenState(&isFScr, nullptr);
|
||||
if (fs && isFScr)
|
||||
return false;
|
||||
else if (!fs && !isFScr)
|
||||
return false;
|
||||
|
||||
if (fs) {
|
||||
ComPtr<IDXGIOutput> out;
|
||||
win.m_swapChain->GetContainingOutput(&out);
|
||||
DXGI_OUTPUT_DESC outDesc;
|
||||
out->GetDesc(&outDesc);
|
||||
|
||||
win.m_fsdesc.Width = outDesc.DesktopCoordinates.right;
|
||||
win.m_fsdesc.Height = outDesc.DesktopCoordinates.bottom;
|
||||
}
|
||||
win.m_fs = fs;
|
||||
win.m_needsFSTransition = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !WINDOWS_STORE
|
||||
OGLContext::Window& win = m_ctxOgl.m_windows[window];
|
||||
if (fs && win.m_fs)
|
||||
return false;
|
||||
else if (!fs && !win.m_fs)
|
||||
return false;
|
||||
SetFullscreen(win, fs);
|
||||
OGLContext::Window& win = m_ctxOgl.m_windows[window];
|
||||
if (fs && win.m_fs)
|
||||
return false;
|
||||
else if (!fs && !win.m_fs)
|
||||
return false;
|
||||
SetFullscreen(win, fs);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct HWNDEvent
|
||||
{
|
||||
UINT uMsg;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
HWNDEvent(UINT m, WPARAM w, LPARAM l)
|
||||
: uMsg(m), wParam(w), lParam(l) {}
|
||||
struct HWNDEvent {
|
||||
UINT uMsg;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
HWNDEvent(UINT m, WPARAM w, LPARAM l) : uMsg(m), wParam(w), lParam(l) {}
|
||||
};
|
||||
|
||||
struct Win32Cursors
|
||||
{
|
||||
HCURSOR m_arrow;
|
||||
HCURSOR m_hResize;
|
||||
HCURSOR m_vResize;
|
||||
HCURSOR m_ibeam;
|
||||
HCURSOR m_crosshairs;
|
||||
HCURSOR m_wait;
|
||||
struct Win32Cursors {
|
||||
HCURSOR m_arrow;
|
||||
HCURSOR m_hResize;
|
||||
HCURSOR m_vResize;
|
||||
HCURSOR m_ibeam;
|
||||
HCURSOR m_crosshairs;
|
||||
HCURSOR m_wait;
|
||||
};
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
extern Win32Cursors WIN32_CURSORS;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
#include <unordered_map>
|
||||
#include "boo/IWindow.hpp"
|
||||
|
||||
namespace boo {class IWindow;}
|
||||
namespace boo {
|
||||
class IWindow;
|
||||
}
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
#include <dxgi1_4.h>
|
||||
@@ -12,7 +14,6 @@ namespace boo {class IWindow;}
|
||||
#include <d3dcompiler.h>
|
||||
#include <wingdi.h>
|
||||
|
||||
|
||||
#elif _WIN32_WINNT_WIN7
|
||||
#include <dxgi1_2.h>
|
||||
#include <d3d11_1.h>
|
||||
@@ -22,113 +23,100 @@ namespace boo {class IWindow;}
|
||||
#error Unsupported Windows target
|
||||
#endif
|
||||
|
||||
struct D3D12Context
|
||||
{
|
||||
ComPtr<IDXGIFactory2> m_dxFactory;
|
||||
ComPtr<ID3D12Device> m_dev;
|
||||
ComPtr<ID3D12CommandAllocator> m_qalloc[2];
|
||||
ComPtr<ID3D12CommandQueue> m_q;
|
||||
ComPtr<ID3D12CommandAllocator> m_loadqalloc;
|
||||
ComPtr<ID3D12CommandQueue> m_loadq;
|
||||
ComPtr<ID3D12Fence> m_loadfence;
|
||||
UINT64 m_loadfenceval = 0;
|
||||
HANDLE m_loadfencehandle;
|
||||
ComPtr<ID3D12GraphicsCommandList> m_loadlist;
|
||||
ComPtr<ID3D12RootSignature> m_rs;
|
||||
struct Window
|
||||
{
|
||||
ComPtr<IDXGISwapChain3> m_swapChain;
|
||||
std::unordered_map<ID3D12Resource*, ComPtr<ID3D12DescriptorHeap>> m_rtvHeaps;
|
||||
UINT m_backBuf = 0;
|
||||
bool m_needsResize = false;
|
||||
size_t width, height;
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
struct D3D12Context {
|
||||
ComPtr<IDXGIFactory2> m_dxFactory;
|
||||
ComPtr<ID3D12Device> m_dev;
|
||||
ComPtr<ID3D12CommandAllocator> m_qalloc[2];
|
||||
ComPtr<ID3D12CommandQueue> m_q;
|
||||
ComPtr<ID3D12CommandAllocator> m_loadqalloc;
|
||||
ComPtr<ID3D12CommandQueue> m_loadq;
|
||||
ComPtr<ID3D12Fence> m_loadfence;
|
||||
UINT64 m_loadfenceval = 0;
|
||||
HANDLE m_loadfencehandle;
|
||||
ComPtr<ID3D12GraphicsCommandList> m_loadlist;
|
||||
ComPtr<ID3D12RootSignature> m_rs;
|
||||
struct Window {
|
||||
ComPtr<IDXGISwapChain3> m_swapChain;
|
||||
std::unordered_map<ID3D12Resource*, ComPtr<ID3D12DescriptorHeap>> m_rtvHeaps;
|
||||
UINT m_backBuf = 0;
|
||||
bool m_needsResize = false;
|
||||
size_t width, height;
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
|
||||
uint32_t m_sampleCount = 1;
|
||||
uint32_t m_anisotropy = 1;
|
||||
uint32_t m_sampleCount = 1;
|
||||
uint32_t m_anisotropy = 1;
|
||||
|
||||
struct RGBATex2DFBViewDesc : D3D12_SHADER_RESOURCE_VIEW_DESC
|
||||
{
|
||||
RGBATex2DFBViewDesc()
|
||||
{
|
||||
Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
Texture2D = {UINT(0), UINT(1), UINT(0), 0.0f};
|
||||
}
|
||||
} RGBATex2DFBViewDesc;
|
||||
};
|
||||
|
||||
struct D3D11Context
|
||||
{
|
||||
ComPtr<IDXGIFactory2> m_dxFactory;
|
||||
ComPtr<ID3D11Device1> m_dev;
|
||||
ComPtr<ID3D11DeviceContext1> m_devCtx;
|
||||
ComPtr<ID3D11SamplerState> m_ss[5];
|
||||
struct Window
|
||||
{
|
||||
ComPtr<IDXGISwapChain1> m_swapChain;
|
||||
ComPtr<ID3D11Texture2D> m_swapChainTex;
|
||||
ComPtr<ID3D11RenderTargetView> m_swapChainRTV;
|
||||
bool m_needsResize = false;
|
||||
size_t width, height;
|
||||
|
||||
bool m_needsFSTransition = false;
|
||||
bool m_fs = false;
|
||||
DXGI_MODE_DESC m_fsdesc = {};
|
||||
|
||||
void clearRTV()
|
||||
{
|
||||
m_swapChainTex.Reset();
|
||||
m_swapChainRTV.Reset();
|
||||
}
|
||||
|
||||
void setupRTV(ComPtr<IDXGISwapChain1>& sc, ID3D11Device* dev)
|
||||
{
|
||||
m_swapChain = sc;
|
||||
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &m_swapChainTex);
|
||||
D3D11_TEXTURE2D_DESC resDesc;
|
||||
m_swapChainTex->GetDesc(&resDesc);
|
||||
width = resDesc.Width;
|
||||
height = resDesc.Height;
|
||||
CD3D11_RENDER_TARGET_VIEW_DESC rtvDesc(D3D11_RTV_DIMENSION_TEXTURE2D, resDesc.Format);
|
||||
dev->CreateRenderTargetView(m_swapChainTex.Get(), &rtvDesc, &m_swapChainRTV);
|
||||
}
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
|
||||
uint32_t m_sampleCount = 1;
|
||||
uint32_t m_anisotropy = 1;
|
||||
DXGI_FORMAT m_fbFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
};
|
||||
|
||||
struct Boo3DAppContext
|
||||
{
|
||||
D3D11Context m_ctx11;
|
||||
|
||||
void resize(boo::IWindow* window, size_t width, size_t height)
|
||||
{
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
win.width = width;
|
||||
win.height = height;
|
||||
win.m_needsResize = true;
|
||||
struct RGBATex2DFBViewDesc : D3D12_SHADER_RESOURCE_VIEW_DESC {
|
||||
RGBATex2DFBViewDesc() {
|
||||
Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
Texture2D = {UINT(0), UINT(1), UINT(0), 0.0f};
|
||||
}
|
||||
} RGBATex2DFBViewDesc;
|
||||
};
|
||||
|
||||
static inline std::string WCSTMBS(const wchar_t* wstr)
|
||||
{
|
||||
int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr) - 1;
|
||||
std::string strTo(sizeNeeded, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &strTo[0], sizeNeeded, nullptr, nullptr);
|
||||
return strTo;
|
||||
struct D3D11Context {
|
||||
ComPtr<IDXGIFactory2> m_dxFactory;
|
||||
ComPtr<ID3D11Device1> m_dev;
|
||||
ComPtr<ID3D11DeviceContext1> m_devCtx;
|
||||
ComPtr<ID3D11SamplerState> m_ss[5];
|
||||
struct Window {
|
||||
ComPtr<IDXGISwapChain1> m_swapChain;
|
||||
ComPtr<ID3D11Texture2D> m_swapChainTex;
|
||||
ComPtr<ID3D11RenderTargetView> m_swapChainRTV;
|
||||
bool m_needsResize = false;
|
||||
size_t width, height;
|
||||
|
||||
bool m_needsFSTransition = false;
|
||||
bool m_fs = false;
|
||||
DXGI_MODE_DESC m_fsdesc = {};
|
||||
|
||||
void clearRTV() {
|
||||
m_swapChainTex.Reset();
|
||||
m_swapChainRTV.Reset();
|
||||
}
|
||||
|
||||
void setupRTV(ComPtr<IDXGISwapChain1>& sc, ID3D11Device* dev) {
|
||||
m_swapChain = sc;
|
||||
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &m_swapChainTex);
|
||||
D3D11_TEXTURE2D_DESC resDesc;
|
||||
m_swapChainTex->GetDesc(&resDesc);
|
||||
width = resDesc.Width;
|
||||
height = resDesc.Height;
|
||||
CD3D11_RENDER_TARGET_VIEW_DESC rtvDesc(D3D11_RTV_DIMENSION_TEXTURE2D, resDesc.Format);
|
||||
dev->CreateRenderTargetView(m_swapChainTex.Get(), &rtvDesc, &m_swapChainRTV);
|
||||
}
|
||||
};
|
||||
std::unordered_map<const boo::IWindow*, Window> m_windows;
|
||||
|
||||
uint32_t m_sampleCount = 1;
|
||||
uint32_t m_anisotropy = 1;
|
||||
DXGI_FORMAT m_fbFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
};
|
||||
|
||||
struct Boo3DAppContext {
|
||||
D3D11Context m_ctx11;
|
||||
|
||||
void resize(boo::IWindow* window, size_t width, size_t height) {
|
||||
D3D11Context::Window& win = m_ctx11.m_windows[window];
|
||||
win.width = width;
|
||||
win.height = height;
|
||||
win.m_needsResize = true;
|
||||
}
|
||||
};
|
||||
|
||||
static inline std::string WCSTMBS(const wchar_t* wstr) {
|
||||
int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr) - 1;
|
||||
std::string strTo(sizeNeeded, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &strTo[0], sizeNeeded, nullptr, nullptr);
|
||||
return strTo;
|
||||
}
|
||||
|
||||
static inline std::wstring MBSTWCS(const char* str)
|
||||
{
|
||||
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0) - 1;
|
||||
std::wstring strTo(sizeNeeded, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, str, -1, &strTo[0], sizeNeeded);
|
||||
return strTo;
|
||||
static inline std::wstring MBSTWCS(const char* str) {
|
||||
int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0) - 1;
|
||||
std::wstring strTo(sizeNeeded, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, str, -1, &strTo[0], sizeNeeded);
|
||||
return strTo;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,621 +17,473 @@ using namespace Platform;
|
||||
|
||||
#include <agile.h>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
namespace boo {
|
||||
static logvisor::Module Log("boo::WindowWin32");
|
||||
#if _WIN32_WINNT_WIN10
|
||||
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx, IGraphicsContext* parent,
|
||||
ID3D12CommandQueue** cmdQueueOut);
|
||||
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, D3D12Context::Window* windowCtx,
|
||||
IGraphicsContext* parent, ID3D12CommandQueue** cmdQueueOut);
|
||||
IGraphicsDataFactory* _NewD3D12DataFactory(D3D12Context* ctx, IGraphicsContext* parent, uint32_t sampleCount);
|
||||
#endif
|
||||
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx, IGraphicsContext* parent);
|
||||
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, D3D11Context::Window* windowCtx,
|
||||
IGraphicsContext* parent);
|
||||
IGraphicsDataFactory* _NewD3D11DataFactory(D3D11Context* ctx, IGraphicsContext* parent, uint32_t sampleCount);
|
||||
|
||||
struct GraphicsContextUWP : IGraphicsContext
|
||||
{
|
||||
EGraphicsAPI m_api;
|
||||
EPixelFormat m_pf;
|
||||
IWindow* m_parentWindow;
|
||||
Boo3DAppContextUWP& m_3dCtx;
|
||||
ComPtr<IDXGIOutput> m_output;
|
||||
GraphicsContextUWP(EGraphicsAPI api, IWindow* parentWindow, Boo3DAppContextUWP& b3dCtx)
|
||||
: m_api(api),
|
||||
m_pf(EPixelFormat::RGBA8),
|
||||
m_parentWindow(parentWindow),
|
||||
m_3dCtx(b3dCtx) {}
|
||||
struct GraphicsContextUWP : IGraphicsContext {
|
||||
EGraphicsAPI m_api;
|
||||
EPixelFormat m_pf;
|
||||
IWindow* m_parentWindow;
|
||||
Boo3DAppContextUWP& m_3dCtx;
|
||||
ComPtr<IDXGIOutput> m_output;
|
||||
GraphicsContextUWP(EGraphicsAPI api, IWindow* parentWindow, Boo3DAppContextUWP& b3dCtx)
|
||||
: m_api(api), m_pf(EPixelFormat::RGBA8), m_parentWindow(parentWindow), m_3dCtx(b3dCtx) {}
|
||||
|
||||
virtual void resized(const SWindowRect& rect)
|
||||
{
|
||||
m_3dCtx.resize(m_parentWindow, rect.size[0], rect.size[1]);
|
||||
}
|
||||
virtual void resized(const SWindowRect& rect) { m_3dCtx.resize(m_parentWindow, rect.size[0], rect.size[1]); }
|
||||
};
|
||||
|
||||
struct GraphicsContextUWPD3D : GraphicsContextUWP
|
||||
{
|
||||
ComPtr<IDXGISwapChain1> m_swapChain;
|
||||
struct GraphicsContextUWPD3D : GraphicsContextUWP {
|
||||
ComPtr<IDXGISwapChain1> m_swapChain;
|
||||
|
||||
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||
|
||||
public:
|
||||
IWindowCallback* m_callback;
|
||||
IWindowCallback* m_callback;
|
||||
|
||||
GraphicsContextUWPD3D(EGraphicsAPI api, IWindow* parentWindow, Agile<CoreWindow>& coreWindow,
|
||||
Boo3DAppContextUWP& b3dCtx)
|
||||
: GraphicsContextUWP(api, parentWindow, b3dCtx)
|
||||
{
|
||||
/* Create Swap Chain */
|
||||
DXGI_SWAP_CHAIN_DESC1 scDesc = {};
|
||||
scDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
scDesc.SampleDesc.Count = 1;
|
||||
scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
scDesc.BufferCount = 2;
|
||||
GraphicsContextUWPD3D(EGraphicsAPI api, IWindow* parentWindow, Agile<CoreWindow>& coreWindow,
|
||||
Boo3DAppContextUWP& b3dCtx)
|
||||
: GraphicsContextUWP(api, parentWindow, b3dCtx) {
|
||||
/* Create Swap Chain */
|
||||
DXGI_SWAP_CHAIN_DESC1 scDesc = {};
|
||||
scDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
scDesc.SampleDesc.Count = 1;
|
||||
scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
scDesc.BufferCount = 2;
|
||||
#if !WINDOWS_STORE
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
#else
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
#endif
|
||||
scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
|
||||
IUnknown* cw = reinterpret_cast<IUnknown*>(coreWindow.Get());
|
||||
IUnknown* cw = reinterpret_cast<IUnknown*>(coreWindow.Get());
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
if (b3dCtx.m_ctx12.m_dev)
|
||||
{
|
||||
auto insIt = b3dCtx.m_ctx12.m_windows.emplace(std::make_pair(parentWindow, D3D12Context::Window()));
|
||||
D3D12Context::Window& w = insIt.first->second;
|
||||
if (b3dCtx.m_ctx12.m_dev) {
|
||||
auto insIt = b3dCtx.m_ctx12.m_windows.emplace(std::make_pair(parentWindow, D3D12Context::Window()));
|
||||
D3D12Context::Window& w = insIt.first->second;
|
||||
|
||||
ID3D12CommandQueue* cmdQueue;
|
||||
m_dataFactory = _NewD3D12DataFactory(&b3dCtx.m_ctx12, this);
|
||||
m_commandQueue = _NewD3D12CommandQueue(&b3dCtx.m_ctx12, &w, this, &cmdQueue);
|
||||
ID3D12CommandQueue* cmdQueue;
|
||||
m_dataFactory = _NewD3D12DataFactory(&b3dCtx.m_ctx12, this);
|
||||
m_commandQueue = _NewD3D12CommandQueue(&b3dCtx.m_ctx12, &w, this, &cmdQueue);
|
||||
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
HRESULT hr = b3dCtx.m_ctx12.m_dxFactory->CreateSwapChainForCoreWindow(cmdQueue,
|
||||
cw, &scDesc, nullptr, &m_swapChain);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create swap chain");
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
HRESULT hr =
|
||||
b3dCtx.m_ctx12.m_dxFactory->CreateSwapChainForCoreWindow(cmdQueue, cw, &scDesc, nullptr, &m_swapChain);
|
||||
if (FAILED(hr))
|
||||
Log.report(logvisor::Fatal, "unable to create swap chain");
|
||||
|
||||
m_swapChain.As<IDXGISwapChain3>(&w.m_swapChain);
|
||||
ComPtr<ID3D12Resource> fb;
|
||||
m_swapChain->GetBuffer(0, __uuidof(ID3D12Resource), &fb);
|
||||
w.m_backBuf = w.m_swapChain->GetCurrentBackBufferIndex();
|
||||
D3D12_RESOURCE_DESC resDesc = fb->GetDesc();
|
||||
w.width = resDesc.Width;
|
||||
w.height = resDesc.Height;
|
||||
m_swapChain.As<IDXGISwapChain3>(&w.m_swapChain);
|
||||
ComPtr<ID3D12Resource> fb;
|
||||
m_swapChain->GetBuffer(0, __uuidof(ID3D12Resource), &fb);
|
||||
w.m_backBuf = w.m_swapChain->GetCurrentBackBufferIndex();
|
||||
D3D12_RESOURCE_DESC resDesc = fb->GetDesc();
|
||||
w.width = resDesc.Width;
|
||||
w.height = resDesc.Height;
|
||||
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
Log.report(logvisor::Fatal, "unable to get DXGI output");
|
||||
}
|
||||
else
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
Log.report(logvisor::Fatal, "unable to get DXGI output");
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (FAILED(b3dCtx.m_ctx11.m_dxFactory->CreateSwapChainForCoreWindow(b3dCtx.m_ctx11.m_dev.Get(),
|
||||
cw, &scDesc, nullptr, &m_swapChain)))
|
||||
Log.report(logvisor::Fatal, "unable to create swap chain");
|
||||
|
||||
auto insIt = b3dCtx.m_ctx11.m_windows.emplace(std::make_pair(parentWindow, D3D11Context::Window()));
|
||||
D3D11Context::Window& w = insIt.first->second;
|
||||
|
||||
m_swapChain.As<IDXGISwapChain1>(&w.m_swapChain);
|
||||
ComPtr<ID3D11Texture2D> fbRes;
|
||||
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &fbRes);
|
||||
D3D11_TEXTURE2D_DESC resDesc;
|
||||
fbRes->GetDesc(&resDesc);
|
||||
w.width = resDesc.Width;
|
||||
w.height = resDesc.Height;
|
||||
m_dataFactory = _NewD3D11DataFactory(&b3dCtx.m_ctx11, this);
|
||||
m_commandQueue = _NewD3D11CommandQueue(&b3dCtx.m_ctx11, &insIt.first->second, this);
|
||||
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
Log.report(logvisor::Fatal, "unable to get DXGI output");
|
||||
}
|
||||
}
|
||||
|
||||
~GraphicsContextUWPD3D()
|
||||
{
|
||||
if (FAILED(b3dCtx.m_ctx11.m_dxFactory->CreateSwapChainForCoreWindow(b3dCtx.m_ctx11.m_dev.Get(), cw, &scDesc,
|
||||
nullptr, &m_swapChain)))
|
||||
Log.report(logvisor::Fatal, "unable to create swap chain");
|
||||
|
||||
auto insIt = b3dCtx.m_ctx11.m_windows.emplace(std::make_pair(parentWindow, D3D11Context::Window()));
|
||||
D3D11Context::Window& w = insIt.first->second;
|
||||
|
||||
m_swapChain.As<IDXGISwapChain1>(&w.m_swapChain);
|
||||
ComPtr<ID3D11Texture2D> fbRes;
|
||||
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &fbRes);
|
||||
D3D11_TEXTURE2D_DESC resDesc;
|
||||
fbRes->GetDesc(&resDesc);
|
||||
w.width = resDesc.Width;
|
||||
w.height = resDesc.Height;
|
||||
m_dataFactory = _NewD3D11DataFactory(&b3dCtx.m_ctx11, this);
|
||||
m_commandQueue = _NewD3D11CommandQueue(&b3dCtx.m_ctx11, &insIt.first->second, this);
|
||||
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
Log.report(logvisor::Fatal, "unable to get DXGI output");
|
||||
}
|
||||
}
|
||||
|
||||
~GraphicsContextUWPD3D() {
|
||||
#if _WIN32_WINNT_WIN10
|
||||
if (m_3dCtx.m_ctx12.m_dev)
|
||||
m_3dCtx.m_ctx12.m_windows.erase(m_parentWindow);
|
||||
else
|
||||
if (m_3dCtx.m_ctx12.m_dev)
|
||||
m_3dCtx.m_ctx12.m_windows.erase(m_parentWindow);
|
||||
else
|
||||
#endif
|
||||
m_3dCtx.m_ctx11.m_windows.erase(m_parentWindow);
|
||||
}
|
||||
m_3dCtx.m_ctx11.m_windows.erase(m_parentWindow);
|
||||
}
|
||||
|
||||
void _setCallback(IWindowCallback* cb)
|
||||
{
|
||||
m_callback = cb;
|
||||
}
|
||||
void _setCallback(IWindowCallback* cb) { m_callback = cb; }
|
||||
|
||||
EGraphicsAPI getAPI() const
|
||||
{
|
||||
return m_api;
|
||||
}
|
||||
EGraphicsAPI getAPI() const { return m_api; }
|
||||
|
||||
EPixelFormat getPixelFormat() const
|
||||
{
|
||||
return m_pf;
|
||||
}
|
||||
EPixelFormat getPixelFormat() const { return m_pf; }
|
||||
|
||||
void setPixelFormat(EPixelFormat pf)
|
||||
{
|
||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||
return;
|
||||
m_pf = pf;
|
||||
}
|
||||
void setPixelFormat(EPixelFormat pf) {
|
||||
if (pf > EPixelFormat::RGBAF32_Z24)
|
||||
return;
|
||||
m_pf = pf;
|
||||
}
|
||||
|
||||
bool initializeContext(void*) {return true;}
|
||||
bool initializeContext(void*) { return true; }
|
||||
|
||||
void makeCurrent() {}
|
||||
void makeCurrent() {}
|
||||
|
||||
void postInit() {}
|
||||
void postInit() {}
|
||||
|
||||
void present() {}
|
||||
void present() {}
|
||||
|
||||
IGraphicsCommandQueue* getCommandQueue()
|
||||
{
|
||||
return m_commandQueue;
|
||||
}
|
||||
IGraphicsCommandQueue* getCommandQueue() { return m_commandQueue; }
|
||||
|
||||
IGraphicsDataFactory* getDataFactory()
|
||||
{
|
||||
return m_dataFactory;
|
||||
}
|
||||
IGraphicsDataFactory* getDataFactory() { return m_dataFactory; }
|
||||
|
||||
IGraphicsDataFactory* getMainContextDataFactory()
|
||||
{
|
||||
return m_dataFactory;
|
||||
}
|
||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_dataFactory; }
|
||||
|
||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||
{
|
||||
return m_dataFactory;
|
||||
}
|
||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_dataFactory; }
|
||||
};
|
||||
|
||||
static uint32_t translateKeysym(CoreWindow^ window, VirtualKey sym,
|
||||
ESpecialKey& specialSym, EModifierKey& modifierSym)
|
||||
{
|
||||
specialSym = ESpecialKey::None;
|
||||
modifierSym = EModifierKey::None;
|
||||
if (sym >= VirtualKey::F1 && sym <= VirtualKey::F12)
|
||||
specialSym = ESpecialKey(uint32_t(ESpecialKey::F1) + uint32_t(sym - VirtualKey::F1));
|
||||
else if (sym == VirtualKey::Escape)
|
||||
specialSym = ESpecialKey::Esc;
|
||||
else if (sym == VirtualKey::Enter)
|
||||
specialSym = ESpecialKey::Enter;
|
||||
else if (sym == VirtualKey::Back)
|
||||
specialSym = ESpecialKey::Backspace;
|
||||
else if (sym == VirtualKey::Insert)
|
||||
specialSym = ESpecialKey::Insert;
|
||||
else if (sym == VirtualKey::Delete)
|
||||
specialSym = ESpecialKey::Delete;
|
||||
else if (sym == VirtualKey::Home)
|
||||
specialSym = ESpecialKey::Home;
|
||||
else if (sym == VirtualKey::End)
|
||||
specialSym = ESpecialKey::End;
|
||||
else if (sym == VirtualKey::PageUp)
|
||||
specialSym = ESpecialKey::PgUp;
|
||||
else if (sym == VirtualKey::PageDown)
|
||||
specialSym = ESpecialKey::PgDown;
|
||||
else if (sym == VirtualKey::Left)
|
||||
specialSym = ESpecialKey::Left;
|
||||
else if (sym == VirtualKey::Right)
|
||||
specialSym = ESpecialKey::Right;
|
||||
else if (sym == VirtualKey::Up)
|
||||
specialSym = ESpecialKey::Up;
|
||||
else if (sym == VirtualKey::Down)
|
||||
specialSym = ESpecialKey::Down;
|
||||
else if (sym == VirtualKey::Shift)
|
||||
modifierSym = EModifierKey::Shift;
|
||||
else if (sym == VirtualKey::Control)
|
||||
modifierSym = EModifierKey::Ctrl;
|
||||
else if (sym == VirtualKey::Menu)
|
||||
modifierSym = EModifierKey::Alt;
|
||||
else if (sym >= VirtualKey::A && sym <= VirtualKey::Z)
|
||||
return uint32_t(sym - VirtualKey::A) +
|
||||
(window->GetKeyState(VirtualKey::Shift) != CoreVirtualKeyStates::None) ? 'A' : 'a';
|
||||
return 0;
|
||||
static uint32_t translateKeysym(CoreWindow ^ window, VirtualKey sym, ESpecialKey& specialSym,
|
||||
EModifierKey& modifierSym) {
|
||||
specialSym = ESpecialKey::None;
|
||||
modifierSym = EModifierKey::None;
|
||||
if (sym >= VirtualKey::F1 && sym <= VirtualKey::F12)
|
||||
specialSym = ESpecialKey(uint32_t(ESpecialKey::F1) + uint32_t(sym - VirtualKey::F1));
|
||||
else if (sym == VirtualKey::Escape)
|
||||
specialSym = ESpecialKey::Esc;
|
||||
else if (sym == VirtualKey::Enter)
|
||||
specialSym = ESpecialKey::Enter;
|
||||
else if (sym == VirtualKey::Back)
|
||||
specialSym = ESpecialKey::Backspace;
|
||||
else if (sym == VirtualKey::Insert)
|
||||
specialSym = ESpecialKey::Insert;
|
||||
else if (sym == VirtualKey::Delete)
|
||||
specialSym = ESpecialKey::Delete;
|
||||
else if (sym == VirtualKey::Home)
|
||||
specialSym = ESpecialKey::Home;
|
||||
else if (sym == VirtualKey::End)
|
||||
specialSym = ESpecialKey::End;
|
||||
else if (sym == VirtualKey::PageUp)
|
||||
specialSym = ESpecialKey::PgUp;
|
||||
else if (sym == VirtualKey::PageDown)
|
||||
specialSym = ESpecialKey::PgDown;
|
||||
else if (sym == VirtualKey::Left)
|
||||
specialSym = ESpecialKey::Left;
|
||||
else if (sym == VirtualKey::Right)
|
||||
specialSym = ESpecialKey::Right;
|
||||
else if (sym == VirtualKey::Up)
|
||||
specialSym = ESpecialKey::Up;
|
||||
else if (sym == VirtualKey::Down)
|
||||
specialSym = ESpecialKey::Down;
|
||||
else if (sym == VirtualKey::Shift)
|
||||
modifierSym = EModifierKey::Shift;
|
||||
else if (sym == VirtualKey::Control)
|
||||
modifierSym = EModifierKey::Ctrl;
|
||||
else if (sym == VirtualKey::Menu)
|
||||
modifierSym = EModifierKey::Alt;
|
||||
else if (sym >= VirtualKey::A && sym <= VirtualKey::Z)
|
||||
return uint32_t(sym - VirtualKey::A) + (window->GetKeyState(VirtualKey::Shift) != CoreVirtualKeyStates::None) ? 'A'
|
||||
: 'a';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EModifierKey translateModifiers(CoreWindow^ window)
|
||||
{
|
||||
EModifierKey retval = EModifierKey::None;
|
||||
if (window->GetKeyState(VirtualKey::Shift) != CoreVirtualKeyStates::None)
|
||||
retval |= EModifierKey::Shift;
|
||||
if (window->GetKeyState(VirtualKey::Control) != CoreVirtualKeyStates::None)
|
||||
retval |= EModifierKey::Ctrl;
|
||||
if (window->GetKeyState(VirtualKey::Menu) != CoreVirtualKeyStates::None)
|
||||
retval |= EModifierKey::Alt;
|
||||
return retval;
|
||||
static EModifierKey translateModifiers(CoreWindow ^ window) {
|
||||
EModifierKey retval = EModifierKey::None;
|
||||
if (window->GetKeyState(VirtualKey::Shift) != CoreVirtualKeyStates::None)
|
||||
retval |= EModifierKey::Shift;
|
||||
if (window->GetKeyState(VirtualKey::Control) != CoreVirtualKeyStates::None)
|
||||
retval |= EModifierKey::Ctrl;
|
||||
if (window->GetKeyState(VirtualKey::Menu) != CoreVirtualKeyStates::None)
|
||||
retval |= EModifierKey::Alt;
|
||||
return retval;
|
||||
}
|
||||
|
||||
class WindowUWP : public IWindow
|
||||
{
|
||||
friend struct GraphicsContextUWP;
|
||||
ApplicationView^ m_appView = ApplicationView::GetForCurrentView();
|
||||
Platform::Agile<CoreWindow> m_coreWindow;
|
||||
Rect m_bounds;
|
||||
float m_dispInfoDpiFactor = 1.f;
|
||||
std::unique_ptr<GraphicsContextUWP> m_gfxCtx;
|
||||
IWindowCallback* m_callback = nullptr;
|
||||
class WindowUWP : public IWindow {
|
||||
friend struct GraphicsContextUWP;
|
||||
ApplicationView ^ m_appView = ApplicationView::GetForCurrentView();
|
||||
Platform::Agile<CoreWindow> m_coreWindow;
|
||||
Rect m_bounds;
|
||||
float m_dispInfoDpiFactor = 1.f;
|
||||
std::unique_ptr<GraphicsContextUWP> m_gfxCtx;
|
||||
IWindowCallback* m_callback = nullptr;
|
||||
|
||||
public:
|
||||
ref struct EventReceiver sealed {
|
||||
void OnKeyDown(CoreWindow ^ window, KeyEventArgs ^ keyEventArgs) { w.OnKeyDown(window, keyEventArgs); }
|
||||
|
||||
ref struct EventReceiver sealed
|
||||
{
|
||||
void OnKeyDown(CoreWindow^ window, KeyEventArgs^ keyEventArgs)
|
||||
{
|
||||
w.OnKeyDown(window, keyEventArgs);
|
||||
}
|
||||
void OnKeyUp(CoreWindow ^ window, KeyEventArgs ^ keyEventArgs) { w.OnKeyUp(window, keyEventArgs); }
|
||||
|
||||
void OnKeyUp(CoreWindow^ window, KeyEventArgs^ keyEventArgs)
|
||||
{
|
||||
w.OnKeyUp(window, keyEventArgs);
|
||||
}
|
||||
void OnPointerEntered(CoreWindow ^ window, PointerEventArgs ^ args) { w.OnPointerEntered(window, args); }
|
||||
|
||||
void OnPointerEntered(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
w.OnPointerEntered(window, args);
|
||||
}
|
||||
void OnPointerExited(CoreWindow ^ window, PointerEventArgs ^ args) { w.OnPointerExited(window, args); }
|
||||
|
||||
void OnPointerExited(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
w.OnPointerExited(window, args);
|
||||
}
|
||||
void OnPointerMoved(CoreWindow ^ window, PointerEventArgs ^ args) { w.OnPointerMoved(window, args); }
|
||||
|
||||
void OnPointerMoved(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
w.OnPointerMoved(window, args);
|
||||
}
|
||||
void OnPointerPressed(CoreWindow ^ window, PointerEventArgs ^ args) { w.OnPointerPressed(window, args); }
|
||||
|
||||
void OnPointerPressed(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
w.OnPointerPressed(window, args);
|
||||
}
|
||||
void OnPointerReleased(CoreWindow ^ window, PointerEventArgs ^ args) { w.OnPointerReleased(window, args); }
|
||||
|
||||
void OnPointerReleased(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
w.OnPointerReleased(window, args);
|
||||
}
|
||||
void OnPointerWheelChanged(CoreWindow ^ window, PointerEventArgs ^ args) { w.OnPointerWheelChanged(window, args); }
|
||||
|
||||
void OnPointerWheelChanged(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
w.OnPointerWheelChanged(window, args);
|
||||
}
|
||||
void OnClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ args) { w.OnClosed(sender, args); }
|
||||
|
||||
void OnClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
|
||||
{
|
||||
w.OnClosed(sender, args);
|
||||
}
|
||||
void SizeChanged(CoreWindow ^ window, WindowSizeChangedEventArgs ^) {
|
||||
w.m_bounds = window->Bounds;
|
||||
w._resized();
|
||||
}
|
||||
|
||||
void SizeChanged(CoreWindow^ window, WindowSizeChangedEventArgs^)
|
||||
{
|
||||
w.m_bounds = window->Bounds;
|
||||
w._resized();
|
||||
}
|
||||
void DisplayInfoChanged(DisplayInformation ^ di, Object ^) {
|
||||
w.m_dispInfoDpiFactor = di->LogicalDpi / 96.f;
|
||||
w._resized();
|
||||
}
|
||||
|
||||
void DisplayInfoChanged(DisplayInformation^ di, Object^)
|
||||
{
|
||||
w.m_dispInfoDpiFactor = di->LogicalDpi / 96.f;
|
||||
w._resized();
|
||||
}
|
||||
internal : WindowUWP& w;
|
||||
EventReceiver(WindowUWP& w) : w(w) {
|
||||
w.m_coreWindow->KeyDown +=
|
||||
ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &EventReceiver::OnKeyDown);
|
||||
w.m_coreWindow->KeyUp += ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &EventReceiver::OnKeyUp);
|
||||
w.m_coreWindow->PointerEntered +=
|
||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &EventReceiver::OnPointerEntered);
|
||||
w.m_coreWindow->PointerExited +=
|
||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &EventReceiver::OnPointerExited);
|
||||
w.m_coreWindow->PointerMoved +=
|
||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &EventReceiver::OnPointerMoved);
|
||||
w.m_coreWindow->PointerPressed +=
|
||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &EventReceiver::OnPointerPressed);
|
||||
w.m_coreWindow->PointerReleased +=
|
||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &EventReceiver::OnPointerReleased);
|
||||
w.m_coreWindow->PointerWheelChanged +=
|
||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &EventReceiver::OnPointerWheelChanged);
|
||||
w.m_coreWindow->Closed +=
|
||||
ref new TypedEventHandler<CoreWindow ^, CoreWindowEventArgs ^>(this, &EventReceiver::OnClosed);
|
||||
w.m_coreWindow->SizeChanged +=
|
||||
ref new TypedEventHandler<CoreWindow ^, WindowSizeChangedEventArgs ^>(this, &EventReceiver::SizeChanged);
|
||||
DisplayInformation::GetForCurrentView()->DpiChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation ^, Object ^>(this, &EventReceiver::DisplayInfoChanged);
|
||||
}
|
||||
};
|
||||
EventReceiver ^ m_eventReceiver;
|
||||
|
||||
internal:
|
||||
WindowUWP& w;
|
||||
EventReceiver(WindowUWP& w) : w(w)
|
||||
{
|
||||
w.m_coreWindow->KeyDown += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &EventReceiver::OnKeyDown);
|
||||
w.m_coreWindow->KeyUp += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &EventReceiver::OnKeyUp);
|
||||
w.m_coreWindow->PointerEntered += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &EventReceiver::OnPointerEntered);
|
||||
w.m_coreWindow->PointerExited += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &EventReceiver::OnPointerExited);
|
||||
w.m_coreWindow->PointerMoved += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &EventReceiver::OnPointerMoved);
|
||||
w.m_coreWindow->PointerPressed += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &EventReceiver::OnPointerPressed);
|
||||
w.m_coreWindow->PointerReleased += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &EventReceiver::OnPointerReleased);
|
||||
w.m_coreWindow->PointerWheelChanged += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &EventReceiver::OnPointerWheelChanged);
|
||||
w.m_coreWindow->Closed += ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &EventReceiver::OnClosed);
|
||||
w.m_coreWindow->SizeChanged += ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &EventReceiver::SizeChanged);
|
||||
DisplayInformation::GetForCurrentView()->DpiChanged +=
|
||||
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &EventReceiver::DisplayInfoChanged);
|
||||
}
|
||||
};
|
||||
EventReceiver^ m_eventReceiver;
|
||||
|
||||
WindowUWP(SystemStringView title, Boo3DAppContextUWP& b3dCtx)
|
||||
: m_coreWindow(CoreWindow::GetForCurrentThread()),
|
||||
m_eventReceiver(ref new EventReceiver(*this))
|
||||
{
|
||||
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11;
|
||||
WindowUWP(SystemStringView title, Boo3DAppContextUWP& b3dCtx)
|
||||
: m_coreWindow(CoreWindow::GetForCurrentThread()), m_eventReceiver(ref new EventReceiver(*this)) {
|
||||
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::EGraphicsAPI::D3D11;
|
||||
#if _WIN32_WINNT_WIN10
|
||||
if (b3dCtx.m_ctx12.m_dev)
|
||||
api = IGraphicsContext::EGraphicsAPI::D3D12;
|
||||
if (b3dCtx.m_ctx12.m_dev)
|
||||
api = IGraphicsContext::EGraphicsAPI::D3D12;
|
||||
#endif
|
||||
m_gfxCtx.reset(new GraphicsContextUWPD3D(api, this, m_coreWindow, b3dCtx));
|
||||
m_gfxCtx.reset(new GraphicsContextUWPD3D(api, this, m_coreWindow, b3dCtx));
|
||||
|
||||
setTitle(title);
|
||||
m_bounds = m_coreWindow->Bounds;
|
||||
m_dispInfoDpiFactor = DisplayInformation::GetForCurrentView()->LogicalDpi / 96.f;
|
||||
if (auto titleBar = ApplicationView::GetForCurrentView()->TitleBar)
|
||||
{
|
||||
Color grey = { 0xFF, 0x33, 0x33, 0x33 };
|
||||
Color transWhite = { 0xFF, 0x88, 0x88, 0x88 };
|
||||
setTitle(title);
|
||||
m_bounds = m_coreWindow->Bounds;
|
||||
m_dispInfoDpiFactor = DisplayInformation::GetForCurrentView()->LogicalDpi / 96.f;
|
||||
if (auto titleBar = ApplicationView::GetForCurrentView()->TitleBar) {
|
||||
Color grey = {0xFF, 0x33, 0x33, 0x33};
|
||||
Color transWhite = {0xFF, 0x88, 0x88, 0x88};
|
||||
|
||||
titleBar->ButtonBackgroundColor = grey;
|
||||
titleBar->ButtonForegroundColor = Colors::White;
|
||||
titleBar->BackgroundColor = grey;
|
||||
titleBar->ForegroundColor = Colors::White;
|
||||
titleBar->ButtonBackgroundColor = grey;
|
||||
titleBar->ButtonForegroundColor = Colors::White;
|
||||
titleBar->BackgroundColor = grey;
|
||||
titleBar->ForegroundColor = Colors::White;
|
||||
|
||||
titleBar->ButtonInactiveBackgroundColor = grey;
|
||||
titleBar->ButtonInactiveForegroundColor = transWhite;
|
||||
titleBar->InactiveBackgroundColor = grey;
|
||||
titleBar->InactiveForegroundColor = transWhite;
|
||||
}
|
||||
titleBar->ButtonInactiveBackgroundColor = grey;
|
||||
titleBar->ButtonInactiveForegroundColor = transWhite;
|
||||
titleBar->InactiveBackgroundColor = grey;
|
||||
titleBar->InactiveForegroundColor = transWhite;
|
||||
}
|
||||
}
|
||||
|
||||
~WindowUWP()
|
||||
{
|
||||
~WindowUWP() {}
|
||||
|
||||
}
|
||||
void setCallback(IWindowCallback* cb) { m_callback = cb; }
|
||||
|
||||
void setCallback(IWindowCallback* cb)
|
||||
{
|
||||
m_callback = cb;
|
||||
}
|
||||
void closeWindow() { m_coreWindow->Close(); }
|
||||
|
||||
void closeWindow()
|
||||
{
|
||||
m_coreWindow->Close();
|
||||
}
|
||||
void showWindow() {}
|
||||
|
||||
void showWindow()
|
||||
{
|
||||
}
|
||||
void hideWindow() {}
|
||||
|
||||
void hideWindow()
|
||||
{
|
||||
}
|
||||
SystemString getTitle() { return SystemString(m_appView->Title->Data()); }
|
||||
|
||||
SystemString getTitle()
|
||||
{
|
||||
return SystemString(m_appView->Title->Data());
|
||||
}
|
||||
void setTitle(SystemStringView title) { m_appView->Title = ref new Platform::String(title.data()); }
|
||||
|
||||
void setTitle(SystemStringView title)
|
||||
{
|
||||
m_appView->Title = ref new Platform::String(title.data());
|
||||
}
|
||||
void setCursor(EMouseCursor cursor) {}
|
||||
|
||||
void setCursor(EMouseCursor cursor)
|
||||
{
|
||||
}
|
||||
void setWaitCursor(bool wait) {}
|
||||
|
||||
void setWaitCursor(bool wait)
|
||||
{
|
||||
}
|
||||
void setWindowFrameDefault() {}
|
||||
|
||||
void setWindowFrameDefault()
|
||||
{
|
||||
}
|
||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const {
|
||||
xOut = m_bounds.X * m_dispInfoDpiFactor;
|
||||
yOut = m_bounds.Y * m_dispInfoDpiFactor;
|
||||
wOut = m_bounds.Width * m_dispInfoDpiFactor;
|
||||
hOut = m_bounds.Height * m_dispInfoDpiFactor;
|
||||
}
|
||||
|
||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const
|
||||
{
|
||||
xOut = m_bounds.X * m_dispInfoDpiFactor;
|
||||
yOut = m_bounds.Y * m_dispInfoDpiFactor;
|
||||
wOut = m_bounds.Width * m_dispInfoDpiFactor;
|
||||
hOut = m_bounds.Height * m_dispInfoDpiFactor;
|
||||
}
|
||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const {
|
||||
xOut = m_bounds.X * m_dispInfoDpiFactor;
|
||||
yOut = m_bounds.Y * m_dispInfoDpiFactor;
|
||||
wOut = m_bounds.Width * m_dispInfoDpiFactor;
|
||||
hOut = m_bounds.Height * m_dispInfoDpiFactor;
|
||||
}
|
||||
|
||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const
|
||||
{
|
||||
xOut = m_bounds.X * m_dispInfoDpiFactor;
|
||||
yOut = m_bounds.Y * m_dispInfoDpiFactor;
|
||||
wOut = m_bounds.Width * m_dispInfoDpiFactor;
|
||||
hOut = m_bounds.Height * m_dispInfoDpiFactor;
|
||||
}
|
||||
void setWindowFrame(float x, float y, float w, float h) {}
|
||||
|
||||
void setWindowFrame(float x, float y, float w, float h)
|
||||
{
|
||||
}
|
||||
void setWindowFrame(int x, int y, int w, int h) {}
|
||||
|
||||
void setWindowFrame(int x, int y, int w, int h)
|
||||
{
|
||||
}
|
||||
float getVirtualPixelFactor() const { return m_dispInfoDpiFactor; }
|
||||
|
||||
float getVirtualPixelFactor() const
|
||||
{
|
||||
return m_dispInfoDpiFactor;
|
||||
}
|
||||
bool isFullscreen() const { return ApplicationView::GetForCurrentView()->IsFullScreenMode; }
|
||||
|
||||
bool isFullscreen() const
|
||||
{
|
||||
return ApplicationView::GetForCurrentView()->IsFullScreenMode;
|
||||
}
|
||||
void setFullscreen(bool fs) {
|
||||
if (fs)
|
||||
ApplicationView::GetForCurrentView()->TryEnterFullScreenMode();
|
||||
else
|
||||
ApplicationView::GetForCurrentView()->ExitFullScreenMode();
|
||||
}
|
||||
|
||||
void setFullscreen(bool fs)
|
||||
{
|
||||
if (fs)
|
||||
ApplicationView::GetForCurrentView()->TryEnterFullScreenMode();
|
||||
else
|
||||
ApplicationView::GetForCurrentView()->ExitFullScreenMode();
|
||||
}
|
||||
void claimKeyboardFocus(const int coord[2]) {}
|
||||
|
||||
void claimKeyboardFocus(const int coord[2])
|
||||
{
|
||||
}
|
||||
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) { return false; }
|
||||
|
||||
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz) { return std::unique_ptr<uint8_t[]>(); }
|
||||
|
||||
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz)
|
||||
{
|
||||
return std::unique_ptr<uint8_t[]>();
|
||||
}
|
||||
void waitForRetrace(IAudioVoiceEngine* engine) {
|
||||
if (engine)
|
||||
engine->pumpAndMixVoices();
|
||||
m_gfxCtx->m_output->WaitForVBlank();
|
||||
}
|
||||
|
||||
void waitForRetrace(IAudioVoiceEngine* engine)
|
||||
{
|
||||
if (engine)
|
||||
engine->pumpAndMixVoices();
|
||||
m_gfxCtx->m_output->WaitForVBlank();
|
||||
}
|
||||
uintptr_t getPlatformHandle() const { return 0; }
|
||||
|
||||
uintptr_t getPlatformHandle() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bool _incomingEvent(void* ev) { return false; }
|
||||
|
||||
bool _incomingEvent(void* ev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void OnKeyDown(CoreWindow ^ window, KeyEventArgs ^ keyEventArgs) {
|
||||
ESpecialKey specialKey;
|
||||
EModifierKey modifierKey;
|
||||
uint32_t charCode = translateKeysym(m_coreWindow.Get(), keyEventArgs->VirtualKey, specialKey, modifierKey);
|
||||
EModifierKey modifierMask = translateModifiers(window);
|
||||
bool repeat = keyEventArgs->KeyStatus.RepeatCount > 1;
|
||||
if (charCode)
|
||||
m_callback->charKeyDown(charCode, modifierMask, repeat);
|
||||
else if (specialKey != ESpecialKey::None)
|
||||
m_callback->specialKeyDown(specialKey, modifierMask, repeat);
|
||||
else if (modifierKey != EModifierKey::None)
|
||||
m_callback->modKeyDown(modifierKey, repeat);
|
||||
}
|
||||
|
||||
void OnKeyDown(CoreWindow^ window, KeyEventArgs^ keyEventArgs)
|
||||
{
|
||||
ESpecialKey specialKey;
|
||||
EModifierKey modifierKey;
|
||||
uint32_t charCode = translateKeysym(m_coreWindow.Get(), keyEventArgs->VirtualKey, specialKey, modifierKey);
|
||||
EModifierKey modifierMask = translateModifiers(window);
|
||||
bool repeat = keyEventArgs->KeyStatus.RepeatCount > 1;
|
||||
if (charCode)
|
||||
m_callback->charKeyDown(charCode, modifierMask, repeat);
|
||||
else if (specialKey != ESpecialKey::None)
|
||||
m_callback->specialKeyDown(specialKey, modifierMask, repeat);
|
||||
else if (modifierKey != EModifierKey::None)
|
||||
m_callback->modKeyDown(modifierKey, repeat);
|
||||
}
|
||||
void OnKeyUp(CoreWindow ^ window, KeyEventArgs ^ keyEventArgs) {
|
||||
ESpecialKey specialKey;
|
||||
EModifierKey modifierKey;
|
||||
uint32_t charCode = translateKeysym(m_coreWindow.Get(), keyEventArgs->VirtualKey, specialKey, modifierKey);
|
||||
EModifierKey modifierMask = translateModifiers(window);
|
||||
if (charCode)
|
||||
m_callback->charKeyUp(charCode, modifierMask);
|
||||
else if (specialKey != ESpecialKey::None)
|
||||
m_callback->specialKeyUp(specialKey, modifierMask);
|
||||
else if (modifierKey != EModifierKey::None)
|
||||
m_callback->modKeyUp(modifierKey);
|
||||
}
|
||||
|
||||
void OnKeyUp(CoreWindow^ window, KeyEventArgs^ keyEventArgs)
|
||||
{
|
||||
ESpecialKey specialKey;
|
||||
EModifierKey modifierKey;
|
||||
uint32_t charCode = translateKeysym(m_coreWindow.Get(), keyEventArgs->VirtualKey, specialKey, modifierKey);
|
||||
EModifierKey modifierMask = translateModifiers(window);
|
||||
if (charCode)
|
||||
m_callback->charKeyUp(charCode, modifierMask);
|
||||
else if (specialKey != ESpecialKey::None)
|
||||
m_callback->specialKeyUp(specialKey, modifierMask);
|
||||
else if (modifierKey != EModifierKey::None)
|
||||
m_callback->modKeyUp(modifierKey);
|
||||
}
|
||||
SWindowCoord GetCursorCoords(const Point& point) {
|
||||
SWindowCoord coord = {point.X * m_dispInfoDpiFactor,
|
||||
(m_bounds.Height - point.Y) * m_dispInfoDpiFactor,
|
||||
point.X,
|
||||
m_bounds.Height - point.Y,
|
||||
point.X / m_bounds.Width,
|
||||
(m_bounds.Height - point.Y) / m_bounds.Height};
|
||||
return coord;
|
||||
}
|
||||
|
||||
SWindowCoord GetCursorCoords(const Point& point)
|
||||
{
|
||||
SWindowCoord coord = {
|
||||
point.X * m_dispInfoDpiFactor, (m_bounds.Height - point.Y) * m_dispInfoDpiFactor,
|
||||
point.X, m_bounds.Height - point.Y, point.X / m_bounds.Width,
|
||||
(m_bounds.Height - point.Y) / m_bounds.Height
|
||||
};
|
||||
return coord;
|
||||
}
|
||||
void OnPointerEntered(CoreWindow ^ window, PointerEventArgs ^ args) {
|
||||
m_callback->mouseEnter(GetCursorCoords(args->CurrentPoint->Position));
|
||||
}
|
||||
|
||||
void OnPointerEntered(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
m_callback->mouseEnter(GetCursorCoords(args->CurrentPoint->Position));
|
||||
}
|
||||
void OnPointerExited(CoreWindow ^ window, PointerEventArgs ^ args) {
|
||||
m_callback->mouseLeave(GetCursorCoords(args->CurrentPoint->Position));
|
||||
}
|
||||
|
||||
void OnPointerExited(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
m_callback->mouseLeave(GetCursorCoords(args->CurrentPoint->Position));
|
||||
}
|
||||
void OnPointerMoved(CoreWindow ^ window, PointerEventArgs ^ args) {
|
||||
m_callback->mouseMove(GetCursorCoords(args->CurrentPoint->Position));
|
||||
}
|
||||
|
||||
void OnPointerMoved(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
m_callback->mouseMove(GetCursorCoords(args->CurrentPoint->Position));
|
||||
}
|
||||
boo::EMouseButton m_pressedButton = boo::EMouseButton::None;
|
||||
void OnPointerPressed(CoreWindow ^ window, PointerEventArgs ^ args) {
|
||||
auto properties = args->CurrentPoint->Properties;
|
||||
boo::EMouseButton button = boo::EMouseButton::None;
|
||||
if (properties->IsLeftButtonPressed)
|
||||
button = boo::EMouseButton::Primary;
|
||||
else if (properties->IsMiddleButtonPressed)
|
||||
button = boo::EMouseButton::Middle;
|
||||
else if (properties->IsRightButtonPressed)
|
||||
button = boo::EMouseButton::Secondary;
|
||||
else if (properties->IsXButton1Pressed)
|
||||
button = boo::EMouseButton::Aux1;
|
||||
else if (properties->IsXButton2Pressed)
|
||||
button = boo::EMouseButton::Aux2;
|
||||
m_callback->mouseDown(GetCursorCoords(args->CurrentPoint->Position), button,
|
||||
translateModifiers(m_coreWindow.Get()));
|
||||
m_pressedButton = button;
|
||||
}
|
||||
|
||||
boo::EMouseButton m_pressedButton = boo::EMouseButton::None;
|
||||
void OnPointerPressed(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
auto properties = args->CurrentPoint->Properties;
|
||||
boo::EMouseButton button = boo::EMouseButton::None;
|
||||
if (properties->IsLeftButtonPressed)
|
||||
button = boo::EMouseButton::Primary;
|
||||
else if (properties->IsMiddleButtonPressed)
|
||||
button = boo::EMouseButton::Middle;
|
||||
else if (properties->IsRightButtonPressed)
|
||||
button = boo::EMouseButton::Secondary;
|
||||
else if (properties->IsXButton1Pressed)
|
||||
button = boo::EMouseButton::Aux1;
|
||||
else if (properties->IsXButton2Pressed)
|
||||
button = boo::EMouseButton::Aux2;
|
||||
m_callback->mouseDown(GetCursorCoords(args->CurrentPoint->Position),
|
||||
button, translateModifiers(m_coreWindow.Get()));
|
||||
m_pressedButton = button;
|
||||
}
|
||||
void OnPointerReleased(CoreWindow ^ window, PointerEventArgs ^ args) {
|
||||
auto properties = args->CurrentPoint->Properties;
|
||||
m_callback->mouseUp(GetCursorCoords(args->CurrentPoint->Position), m_pressedButton,
|
||||
translateModifiers(m_coreWindow.Get()));
|
||||
}
|
||||
|
||||
void OnPointerReleased(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
auto properties = args->CurrentPoint->Properties;
|
||||
m_callback->mouseUp(GetCursorCoords(args->CurrentPoint->Position),
|
||||
m_pressedButton, translateModifiers(m_coreWindow.Get()));
|
||||
}
|
||||
void OnPointerWheelChanged(CoreWindow ^ window, PointerEventArgs ^ args) {
|
||||
auto properties = args->CurrentPoint->Properties;
|
||||
SScrollDelta scroll = {};
|
||||
scroll.delta[1] = properties->MouseWheelDelta / double(WHEEL_DELTA);
|
||||
m_callback->scroll(GetCursorCoords(args->CurrentPoint->Position), scroll);
|
||||
}
|
||||
|
||||
void OnPointerWheelChanged(CoreWindow^ window, PointerEventArgs^ args)
|
||||
{
|
||||
auto properties = args->CurrentPoint->Properties;
|
||||
SScrollDelta scroll = {};
|
||||
scroll.delta[1] = properties->MouseWheelDelta / double(WHEEL_DELTA);
|
||||
m_callback->scroll(GetCursorCoords(args->CurrentPoint->Position), scroll);
|
||||
}
|
||||
void OnClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ args) {
|
||||
if (m_callback)
|
||||
m_callback->destroyed();
|
||||
}
|
||||
|
||||
void OnClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
|
||||
{
|
||||
if (m_callback)
|
||||
m_callback->destroyed();
|
||||
}
|
||||
void _resized() {
|
||||
boo::SWindowRect rect(m_bounds.X * m_dispInfoDpiFactor, m_bounds.Y * m_dispInfoDpiFactor,
|
||||
m_bounds.Width * m_dispInfoDpiFactor, m_bounds.Height * m_dispInfoDpiFactor);
|
||||
m_gfxCtx->resized(rect);
|
||||
if (m_callback)
|
||||
m_callback->resized(rect, false);
|
||||
}
|
||||
|
||||
void _resized()
|
||||
{
|
||||
boo::SWindowRect rect(
|
||||
m_bounds.X * m_dispInfoDpiFactor, m_bounds.Y * m_dispInfoDpiFactor,
|
||||
m_bounds.Width * m_dispInfoDpiFactor, m_bounds.Height * m_dispInfoDpiFactor);
|
||||
m_gfxCtx->resized(rect);
|
||||
if (m_callback)
|
||||
m_callback->resized(rect, false);
|
||||
}
|
||||
ETouchType getTouchType() const { return ETouchType::None; }
|
||||
|
||||
ETouchType getTouchType() const
|
||||
{
|
||||
return ETouchType::None;
|
||||
}
|
||||
void setStyle(EWindowStyle style) {}
|
||||
|
||||
void setStyle(EWindowStyle style)
|
||||
{
|
||||
}
|
||||
EWindowStyle getStyle() const {
|
||||
EWindowStyle retval = EWindowStyle::None;
|
||||
return retval;
|
||||
}
|
||||
|
||||
EWindowStyle getStyle() const
|
||||
{
|
||||
EWindowStyle retval = EWindowStyle::None;
|
||||
return retval;
|
||||
}
|
||||
IGraphicsCommandQueue* getCommandQueue() { return m_gfxCtx->getCommandQueue(); }
|
||||
IGraphicsDataFactory* getDataFactory() { return m_gfxCtx->getDataFactory(); }
|
||||
|
||||
IGraphicsCommandQueue* getCommandQueue()
|
||||
{
|
||||
return m_gfxCtx->getCommandQueue();
|
||||
}
|
||||
IGraphicsDataFactory* getDataFactory()
|
||||
{
|
||||
return m_gfxCtx->getDataFactory();
|
||||
}
|
||||
|
||||
/* Creates a new context on current thread!! Call from main client thread */
|
||||
IGraphicsDataFactory* getMainContextDataFactory()
|
||||
{
|
||||
return m_gfxCtx->getMainContextDataFactory();
|
||||
}
|
||||
|
||||
/* Creates a new context on current thread!! Call from client loading thread */
|
||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||
{
|
||||
return m_gfxCtx->getLoadContextDataFactory();
|
||||
}
|
||||
/* Creates a new context on current thread!! Call from main client thread */
|
||||
IGraphicsDataFactory* getMainContextDataFactory() { return m_gfxCtx->getMainContextDataFactory(); }
|
||||
|
||||
/* Creates a new context on current thread!! Call from client loading thread */
|
||||
IGraphicsDataFactory* getLoadContextDataFactory() { return m_gfxCtx->getLoadContextDataFactory(); }
|
||||
};
|
||||
|
||||
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx)
|
||||
{
|
||||
return std::make_shared<WindowUWP>(title, d3dCtx);
|
||||
std::shared_ptr<IWindow> _WindowUWPNew(SystemStringView title, Boo3DAppContextUWP& d3dCtx) {
|
||||
return std::make_shared<WindowUWP>(title, d3dCtx);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace boo
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user