mirror of
https://github.com/AxioDL/boo.git
synced 2025-12-17 17:05:24 +00:00
More D3D12 work
This commit is contained in:
@@ -1,28 +1,78 @@
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include "Win32Common.hpp"
|
||||
#include <Windowsx.h>
|
||||
#include "boo/IWindow.hpp"
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
#include <LogVisor/LogVisor.hpp>
|
||||
|
||||
#include "boo/graphicsdev/D3D11.hpp"
|
||||
#include "boo/graphicsdev/D3D12.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
|
||||
static LogVisor::LogModule Log("WindowWin32");
|
||||
class WindowWin32;
|
||||
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, IGraphicsContext* parent);
|
||||
IGraphicsCommandQueue* _NewD3D11CommandQueue(D3D11Context* ctx, IGraphicsContext* parent);
|
||||
|
||||
struct GraphicsContextWin32 : IGraphicsContext
|
||||
{
|
||||
|
||||
EGraphicsAPI m_api;
|
||||
EPixelFormat m_pf;
|
||||
IWindow* m_parentWindow;
|
||||
WindowWin32* m_parentWindow;
|
||||
D3DAppContext& m_d3dCtx;
|
||||
|
||||
ComPtr<IDXGISwapChain1> m_swapChain;
|
||||
ComPtr<IDXGIOutput> m_output;
|
||||
|
||||
IGraphicsCommandQueue* m_commandQueue = nullptr;
|
||||
IGraphicsDataFactory* m_dataFactory = nullptr;
|
||||
|
||||
public:
|
||||
IWindowCallback* m_callback;
|
||||
|
||||
GraphicsContextWin32(EGraphicsAPI api, IWindow* parentWindow)
|
||||
: m_api(api),
|
||||
m_pf(PF_RGBA8),
|
||||
m_parentWindow(parentWindow)
|
||||
{}
|
||||
GraphicsContextWin32(EGraphicsAPI api, WindowWin32* parentWindow, D3DAppContext& d3dCtx)
|
||||
: m_api(api),
|
||||
m_pf(PF_RGBA8),
|
||||
m_parentWindow(parentWindow),
|
||||
m_d3dCtx(d3dCtx)
|
||||
{
|
||||
/* 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;
|
||||
scDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
IUnknown* dev = d3dCtx.m_ctx12.m_dev ?
|
||||
static_cast<IUnknown*>(d3dCtx.m_ctx12.m_dev.Get()) :
|
||||
static_cast<IUnknown*>(d3dCtx.m_ctx11.m_dev.Get());
|
||||
#else
|
||||
IUnknown* dev = static_cast<IUnknown*>(d3dCtx.m_ctx11.m_dev.Get());
|
||||
#endif
|
||||
if (FAILED(d3dCtx.m_dxFactory->CreateSwapChainForHwnd(dev,
|
||||
parentWindow->m_hwnd, &scDesc, nullptr, nullptr, &m_swapChain)))
|
||||
Log.report(LogVisor::FatalError, "unable to create swap chain");
|
||||
|
||||
if (FAILED(m_swapChain->GetContainingOutput(&m_output)))
|
||||
Log.report(LogVisor::FatalError, "unable to get DXGI output");
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
if (d3dCtx.m_ctx12.m_dev)
|
||||
{
|
||||
m_dataFactory = new D3D12DataFactory(this, &d3dCtx.m_ctx12);
|
||||
m_commandQueue = _NewD3D12CommandQueue(&d3dCtx.m_ctx12, this);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
m_dataFactory = new D3D11DataFactory(this, &d3dCtx.m_ctx11);
|
||||
m_commandQueue = _NewD3D11CommandQueue(&d3dCtx.m_ctx11, this);
|
||||
}
|
||||
}
|
||||
|
||||
~GraphicsContextWin32()
|
||||
{
|
||||
@@ -51,45 +101,111 @@ public:
|
||||
m_pf = pf;
|
||||
}
|
||||
|
||||
void initializeContext()
|
||||
void initializeContext() {}
|
||||
|
||||
void makeCurrent() {}
|
||||
|
||||
void postInit() {}
|
||||
|
||||
void present() {}
|
||||
|
||||
IGraphicsCommandQueue* getCommandQueue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IGraphicsContext* makeShareContext() const
|
||||
IGraphicsDataFactory* getDataFactory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void makeCurrent()
|
||||
/* Creates a new context on current thread!! Call from client loading thread */
|
||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void clearCurrent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void swapBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static void genFrameDefault(MONITORINFO* screen, int& xOut, int& yOut, int& wOut, int& hOut)
|
||||
{
|
||||
float width = screen->rcMonitor.right * 2.0 / 3.0;
|
||||
float height = screen->rcMonitor.bottom * 2.0 / 3.0;
|
||||
xOut = (screen->rcMonitor.right - width) / 2.0;
|
||||
yOut = (screen->rcMonitor.bottom - height) / 2.0;
|
||||
wOut = width;
|
||||
hOut = height;
|
||||
}
|
||||
|
||||
static uint32_t translateKeysym(WPARAM sym, int& specialSym, int& modifierSym)
|
||||
{
|
||||
specialSym = KEY_NONE;
|
||||
modifierSym = MKEY_NONE;
|
||||
if (sym >= VK_F1 && sym <= VK_F12)
|
||||
specialSym = KEY_F1 + sym - VK_F1;
|
||||
else if (sym == VK_ESCAPE)
|
||||
specialSym = KEY_ESC;
|
||||
else if (sym == VK_RETURN)
|
||||
specialSym = KEY_ENTER;
|
||||
else if (sym == VK_BACK)
|
||||
specialSym = KEY_BACKSPACE;
|
||||
else if (sym == VK_INSERT)
|
||||
specialSym = KEY_INSERT;
|
||||
else if (sym == VK_DELETE)
|
||||
specialSym = KEY_DELETE;
|
||||
else if (sym == VK_HOME)
|
||||
specialSym = KEY_HOME;
|
||||
else if (sym == VK_END)
|
||||
specialSym = KEY_END;
|
||||
else if (sym == VK_PRIOR)
|
||||
specialSym = KEY_PGUP;
|
||||
else if (sym == VK_NEXT)
|
||||
specialSym = KEY_PGDOWN;
|
||||
else if (sym == VK_LEFT)
|
||||
specialSym = KEY_LEFT;
|
||||
else if (sym == VK_RIGHT)
|
||||
specialSym = KEY_RIGHT;
|
||||
else if (sym == VK_UP)
|
||||
specialSym = KEY_UP;
|
||||
else if (sym == VK_DOWN)
|
||||
specialSym = KEY_DOWN;
|
||||
else if (sym == VK_LSHIFT || sym == VK_RSHIFT)
|
||||
modifierSym = MKEY_SHIFT;
|
||||
else if (sym == VK_LCONTROL || sym == VK_RCONTROL)
|
||||
modifierSym = MKEY_CTRL;
|
||||
else if (sym == VK_MENU)
|
||||
modifierSym = MKEY_ALT;
|
||||
else
|
||||
return MapVirtualKey(sym, MAPVK_VK_TO_CHAR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int translateModifiers()
|
||||
{
|
||||
int retval = 0;
|
||||
if (GetKeyState(VK_LSHIFT) & 0x8000 != 0 || GetKeyState(VK_RSHIFT) & 0x8000 != 0)
|
||||
retval |= MKEY_SHIFT;
|
||||
if (GetKeyState(VK_LCONTROL) & 0x8000 != 0 || GetKeyState(VK_RCONTROL) & 0x8000 != 0)
|
||||
retval |= MKEY_CTRL;
|
||||
if (GetKeyState(VK_MENU) & 0x8000 != 0)
|
||||
retval |= MKEY_ALT;
|
||||
return retval;
|
||||
}
|
||||
|
||||
class WindowWin32 : public IWindow
|
||||
{
|
||||
|
||||
friend GraphicsContextWin32;
|
||||
HWND m_hwnd;
|
||||
std::unique_ptr<GraphicsContextWin32> m_gfxCtx;
|
||||
IWindowCallback* m_callback = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
WindowWin32(const SystemString& title)
|
||||
WindowWin32(const SystemString& title, D3DAppContext& d3dCtx)
|
||||
{
|
||||
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
NULL, NULL, NULL, NULL);
|
||||
m_gfxCtx.reset(new GraphicsContextWin32(IGraphicsContext::API_D3D11, this, d3dCtx));
|
||||
}
|
||||
|
||||
~WindowWin32()
|
||||
@@ -99,17 +215,17 @@ public:
|
||||
|
||||
void setCallback(IWindowCallback* cb)
|
||||
{
|
||||
|
||||
m_callback = cb;
|
||||
}
|
||||
|
||||
void showWindow()
|
||||
{
|
||||
|
||||
ShowWindow(m_hwnd, SW_SHOW);
|
||||
}
|
||||
|
||||
void hideWindow()
|
||||
{
|
||||
|
||||
ShowWindow(m_hwnd, SW_HIDE);
|
||||
}
|
||||
|
||||
SystemString getTitle()
|
||||
@@ -126,17 +242,41 @@ public:
|
||||
|
||||
void setWindowFrameDefault()
|
||||
{
|
||||
|
||||
MONITORINFO monInfo;
|
||||
GetMonitorInfo(MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTOPRIMARY), &monInfo);
|
||||
int x, y, w, h;
|
||||
genFrameDefault(&monInfo, x, y, w, h);
|
||||
setWindowFrame(x, y, w, h);
|
||||
}
|
||||
|
||||
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const
|
||||
{
|
||||
|
||||
RECT rct;
|
||||
GetWindowRect(m_hwnd, &rct);
|
||||
xOut = rct.left;
|
||||
yOut = rct.top;
|
||||
wOut = rct.right;
|
||||
hOut = rct.bottom;
|
||||
}
|
||||
|
||||
void getWindowFrame(int& xOut, int& yOut, int& wOut, int& hOut) const
|
||||
{
|
||||
RECT rct;
|
||||
GetWindowRect(m_hwnd, &rct);
|
||||
xOut = rct.left;
|
||||
yOut = rct.top;
|
||||
wOut = rct.right;
|
||||
hOut = rct.bottom;
|
||||
}
|
||||
|
||||
void setWindowFrame(float x, float y, float w, float h)
|
||||
{
|
||||
|
||||
MoveWindow(m_hwnd, x, y, w, h, true);
|
||||
}
|
||||
|
||||
void setWindowFrame(int x, int y, int w, int h)
|
||||
{
|
||||
MoveWindow(m_hwnd, x, y, w, h, true);
|
||||
}
|
||||
|
||||
float getVirtualPixelFactor() const
|
||||
@@ -156,23 +296,193 @@ public:
|
||||
|
||||
void waitForRetrace()
|
||||
{
|
||||
m_gfxCtx->m_output->WaitForVBlank();
|
||||
}
|
||||
|
||||
uintptr_t getPlatformHandle() const
|
||||
{
|
||||
return uintptr_t(m_hwnd);
|
||||
}
|
||||
|
||||
void buttonDown(HWNDEvent& e, EMouseButton button)
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
int x, y, w, h;
|
||||
getWindowFrame(x, y, w, h);
|
||||
int modifierMask = translateModifiers();
|
||||
SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
||||
{float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)}
|
||||
};
|
||||
m_callback->mouseDown(coord, button, EModifierKey(modifierMask));
|
||||
}
|
||||
}
|
||||
|
||||
void buttonUp(HWNDEvent& e, EMouseButton button)
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
int x, y, w, h;
|
||||
getWindowFrame(x, y, w, h);
|
||||
int modifierMask = translateModifiers();
|
||||
SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
||||
{float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)}
|
||||
};
|
||||
m_callback->mouseUp(coord, button, EModifierKey(modifierMask));
|
||||
}
|
||||
}
|
||||
|
||||
void _incomingEvent(void* ev)
|
||||
{
|
||||
HWNDEvent& e = *static_cast<HWNDEvent*>(ev);
|
||||
switch (e.uMsg)
|
||||
{
|
||||
case WM_SIZE:
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
SWindowRect rect;
|
||||
int x, y, w, h;
|
||||
getWindowFrame(x, y, w, h);
|
||||
rect.location[0] = x;
|
||||
rect.location[1] = y;
|
||||
rect.size[0] = LOWORD(e.lParam);
|
||||
rect.size[1] = HIWORD(e.lParam);
|
||||
m_callback->resized(rect);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
int specialKey;
|
||||
int modifierKey;
|
||||
uint32_t charCode = translateKeysym(e.wParam, specialKey, modifierKey);
|
||||
int modifierMask = translateModifiers();
|
||||
if (charCode)
|
||||
m_callback->charKeyDown(charCode, EModifierKey(modifierMask), e.lParam & 0xffff != 0);
|
||||
else if (specialKey)
|
||||
m_callback->specialKeyDown(ESpecialKey(specialKey), EModifierKey(modifierMask), e.lParam & 0xffff != 0);
|
||||
else if (modifierKey)
|
||||
m_callback->modKeyDown(EModifierKey(modifierKey), e.lParam & 0xffff != 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case WM_KEYUP:
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
int specialKey;
|
||||
int modifierKey;
|
||||
uint32_t charCode = translateKeysym(e.wParam, specialKey, modifierKey);
|
||||
int modifierMask = translateModifiers();
|
||||
if (charCode)
|
||||
m_callback->charKeyUp(charCode, EModifierKey(modifierMask));
|
||||
else if (specialKey)
|
||||
m_callback->specialKeyUp(ESpecialKey(specialKey), EModifierKey(modifierMask));
|
||||
else if (modifierKey)
|
||||
m_callback->modKeyUp(EModifierKey(modifierKey));
|
||||
}
|
||||
return;
|
||||
}
|
||||
case WM_LBUTTONDOWN:
|
||||
{
|
||||
buttonDown(e, BUTTON_PRIMARY);
|
||||
return;
|
||||
}
|
||||
case WM_LBUTTONUP:
|
||||
{
|
||||
buttonUp(e, BUTTON_PRIMARY);
|
||||
return;
|
||||
}
|
||||
case WM_RBUTTONDOWN:
|
||||
{
|
||||
buttonDown(e, BUTTON_SECONDARY);
|
||||
return;
|
||||
}
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
buttonUp(e, BUTTON_SECONDARY);
|
||||
return;
|
||||
}
|
||||
case WM_MBUTTONDOWN:
|
||||
{
|
||||
buttonDown(e, BUTTON_MIDDLE);
|
||||
return;
|
||||
}
|
||||
case WM_MBUTTONUP:
|
||||
{
|
||||
buttonUp(e, BUTTON_MIDDLE);
|
||||
return;
|
||||
}
|
||||
case WM_XBUTTONDOWN:
|
||||
{
|
||||
if (HIWORD(e.wParam) == XBUTTON1)
|
||||
buttonDown(e, BUTTON_AUX1);
|
||||
else if (HIWORD(e.wParam) == XBUTTON2)
|
||||
buttonDown(e, BUTTON_AUX2);
|
||||
return;
|
||||
}
|
||||
case WM_XBUTTONUP:
|
||||
{
|
||||
if (HIWORD(e.wParam) == XBUTTON1)
|
||||
buttonUp(e, BUTTON_AUX1);
|
||||
else if (HIWORD(e.wParam) == XBUTTON2)
|
||||
buttonUp(e, BUTTON_AUX2);
|
||||
return;
|
||||
}
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
int x, y, w, h;
|
||||
getWindowFrame(x, y, w, h);
|
||||
SWindowCoord coord =
|
||||
{
|
||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
||||
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
|
||||
{float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)}
|
||||
};
|
||||
m_callback->mouseMove(coord);
|
||||
}
|
||||
return;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
ETouchType getTouchType() const
|
||||
{
|
||||
return TOUCH_NONE;
|
||||
}
|
||||
|
||||
IGraphicsCommandQueue* getCommandQueue()
|
||||
{
|
||||
return m_gfxCtx->getCommandQueue();
|
||||
}
|
||||
IGraphicsDataFactory* getDataFactory()
|
||||
{
|
||||
return m_gfxCtx->getDataFactory();
|
||||
}
|
||||
|
||||
/* Creates a new context on current thread!! Call from client loading thread */
|
||||
IGraphicsDataFactory* getLoadContextDataFactory()
|
||||
{
|
||||
return m_gfxCtx->getLoadContextDataFactory();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
IWindow* _WindowWin32New(const SystemString& title)
|
||||
IWindow* _WindowWin32New(const SystemString& title, D3DAppContext& d3dCtx)
|
||||
{
|
||||
return new WindowWin32(title);
|
||||
return new WindowWin32(title, d3dCtx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user