mirror of https://github.com/AxioDL/boo.git
More D3D12 work
This commit is contained in:
parent
4f650ce5f5
commit
facacd4e95
|
@ -24,6 +24,7 @@ if(WIN32)
|
|||
list(APPEND PLAT_SRCS
|
||||
lib/win/ApplicationWin32.cpp
|
||||
lib/win/WindowWin32.cpp
|
||||
lib/win/Win32Common.hpp
|
||||
lib/inputdev/HIDListenerWinUSB.cpp
|
||||
lib/inputdev/HIDDeviceWinUSB.cpp
|
||||
lib/graphicsdev/D3D11.cpp
|
||||
|
@ -33,6 +34,8 @@ if(WIN32)
|
|||
include/boo/graphicsdev/D3D11.hpp
|
||||
include/boo/graphicsdev/D3D12.hpp)
|
||||
|
||||
list(APPEND _BOO_SYS_DEFINES -DUNICODE=1)
|
||||
|
||||
list(APPEND _BOO_SYS_LIBS Winusb)
|
||||
elseif(APPLE)
|
||||
list(APPEND PLAT_SRCS
|
||||
|
@ -116,7 +119,9 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|||
endif()
|
||||
|
||||
set(BOO_SYS_LIBS ${_BOO_SYS_LIBS} CACHE PATH "Boo System Libraries" FORCE)
|
||||
set(BOO_SYS_DEFINES ${_BOO_SYS_DEFINES} CACHE PATH "Boo System Defines" FORCE)
|
||||
|
||||
add_definitions(${_BOO_SYS_DEFINES})
|
||||
include_directories(include)
|
||||
|
||||
add_library(Boo
|
||||
|
|
|
@ -7,89 +7,89 @@ namespace boo
|
|||
{
|
||||
struct IGraphicsCommandQueue;
|
||||
struct IGraphicsDataFactory;
|
||||
|
||||
enum EMouseButton
|
||||
{
|
||||
BUTTON_NONE = 0,
|
||||
BUTTON_PRIMARY = 1,
|
||||
BUTTON_SECONDARY = 2,
|
||||
BUTTON_MIDDLE = 3,
|
||||
BUTTON_AUX1 = 4,
|
||||
BUTTON_AUX2 = 5
|
||||
};
|
||||
|
||||
struct SWindowRect
|
||||
{
|
||||
int location[2];
|
||||
int size[2];
|
||||
};
|
||||
|
||||
struct SWindowCoord
|
||||
{
|
||||
unsigned pixel[2];
|
||||
unsigned virtualPixel[2];
|
||||
float norm[2];
|
||||
};
|
||||
|
||||
struct STouchCoord
|
||||
{
|
||||
double coord[2];
|
||||
};
|
||||
|
||||
struct SScrollDelta
|
||||
{
|
||||
double delta[2];
|
||||
bool isFine; /* Use system-scale fine-scroll (for scrollable-trackpads) */
|
||||
|
||||
SScrollDelta operator+(const SScrollDelta& other)
|
||||
{return {{delta[0] + other.delta[0], delta[1] + other.delta[1]}, isFine || other.isFine};}
|
||||
SScrollDelta& operator+=(const SScrollDelta& other)
|
||||
{delta[0] += other.delta[0]; delta[1] += other.delta[1]; isFine |= other.isFine; return *this;}
|
||||
void zeroOut() {delta[0] = 0.0; delta[1] = 0.0;}
|
||||
};
|
||||
|
||||
enum ESpecialKey
|
||||
{
|
||||
KEY_NONE = 0,
|
||||
KEY_F1 = 1,
|
||||
KEY_F2 = 2,
|
||||
KEY_F3 = 3,
|
||||
KEY_F4 = 4,
|
||||
KEY_F5 = 5,
|
||||
KEY_F6 = 6,
|
||||
KEY_F7 = 7,
|
||||
KEY_F8 = 8,
|
||||
KEY_F9 = 9,
|
||||
KEY_F10 = 10,
|
||||
KEY_F11 = 11,
|
||||
KEY_F12 = 12,
|
||||
KEY_ESC = 13,
|
||||
KEY_ENTER = 14,
|
||||
KEY_BACKSPACE = 15,
|
||||
KEY_INSERT = 16,
|
||||
KEY_DELETE = 17,
|
||||
KEY_HOME = 18,
|
||||
KEY_END = 19,
|
||||
KEY_PGUP = 20,
|
||||
KEY_PGDOWN = 21,
|
||||
KEY_LEFT = 22,
|
||||
KEY_RIGHT = 23,
|
||||
KEY_UP = 24,
|
||||
KEY_DOWN = 25
|
||||
};
|
||||
|
||||
enum EModifierKey
|
||||
{
|
||||
MKEY_NONE = 0,
|
||||
MKEY_CTRL = 1<<0,
|
||||
MKEY_ALT = 1<<2,
|
||||
MKEY_SHIFT = 1<<3,
|
||||
MKEY_COMMAND = 1<<4
|
||||
};
|
||||
|
||||
class IWindowCallback
|
||||
{
|
||||
public:
|
||||
enum EMouseButton
|
||||
{
|
||||
BUTTON_NONE = 0,
|
||||
BUTTON_PRIMARY = 1,
|
||||
BUTTON_SECONDARY = 2,
|
||||
BUTTON_MIDDLE = 3,
|
||||
BUTTON_AUX1 = 4,
|
||||
BUTTON_AUX2 = 5
|
||||
};
|
||||
|
||||
struct SWindowRect
|
||||
{
|
||||
int location[2];
|
||||
int size[2];
|
||||
};
|
||||
|
||||
struct SWindowCoord
|
||||
{
|
||||
unsigned pixel[2];
|
||||
unsigned virtualPixel[2];
|
||||
float norm[2];
|
||||
};
|
||||
|
||||
struct STouchCoord
|
||||
{
|
||||
double coord[2];
|
||||
};
|
||||
|
||||
struct SScrollDelta
|
||||
{
|
||||
double delta[2];
|
||||
bool isFine; /* Use system-scale fine-scroll (for scrollable-trackpads) */
|
||||
|
||||
SScrollDelta operator+(const SScrollDelta& other)
|
||||
{return {{delta[0] + other.delta[0], delta[1] + other.delta[1]}, isFine || other.isFine};}
|
||||
SScrollDelta& operator+=(const SScrollDelta& other)
|
||||
{delta[0] += other.delta[0]; delta[1] += other.delta[1]; isFine |= other.isFine; return *this;}
|
||||
void zeroOut() {delta[0] = 0.0; delta[1] = 0.0;}
|
||||
};
|
||||
|
||||
enum ESpecialKey
|
||||
{
|
||||
KEY_NONE = 0,
|
||||
KEY_F1 = 1,
|
||||
KEY_F2 = 2,
|
||||
KEY_F3 = 3,
|
||||
KEY_F4 = 4,
|
||||
KEY_F5 = 5,
|
||||
KEY_F6 = 6,
|
||||
KEY_F7 = 7,
|
||||
KEY_F8 = 8,
|
||||
KEY_F9 = 9,
|
||||
KEY_F10 = 10,
|
||||
KEY_F11 = 11,
|
||||
KEY_F12 = 12,
|
||||
KEY_ESC = 13,
|
||||
KEY_ENTER = 14,
|
||||
KEY_BACKSPACE = 15,
|
||||
KEY_INSERT = 16,
|
||||
KEY_DELETE = 17,
|
||||
KEY_HOME = 18,
|
||||
KEY_END = 19,
|
||||
KEY_PGUP = 20,
|
||||
KEY_PGDOWN = 21,
|
||||
KEY_LEFT = 22,
|
||||
KEY_RIGHT = 23,
|
||||
KEY_UP = 24,
|
||||
KEY_DOWN = 25
|
||||
};
|
||||
|
||||
enum EModifierKey
|
||||
{
|
||||
MKEY_NONE = 0,
|
||||
MKEY_CTRL = 1<<0,
|
||||
MKEY_ALT = 1<<2,
|
||||
MKEY_SHIFT = 1<<3,
|
||||
MKEY_COMMAND = 1<<4
|
||||
};
|
||||
|
||||
public:
|
||||
virtual void resized(const SWindowRect& rect)
|
||||
{(void)rect;}
|
||||
virtual void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
|
||||
|
@ -122,6 +122,13 @@ public:
|
|||
|
||||
};
|
||||
|
||||
enum ETouchType
|
||||
{
|
||||
TOUCH_NONE = 0,
|
||||
TOUCH_DISPLAY = 1,
|
||||
TOUCH_TRACKPAD = 2
|
||||
};
|
||||
|
||||
class IWindow
|
||||
{
|
||||
public:
|
||||
|
@ -149,12 +156,6 @@ public:
|
|||
virtual uintptr_t getPlatformHandle() const=0;
|
||||
virtual void _incomingEvent(void* event) {(void)event;}
|
||||
|
||||
enum ETouchType
|
||||
{
|
||||
TOUCH_NONE = 0,
|
||||
TOUCH_DISPLAY = 1,
|
||||
TOUCH_TRACKPAD = 2
|
||||
};
|
||||
virtual ETouchType getTouchType() const=0;
|
||||
|
||||
virtual IGraphicsCommandQueue* getCommandQueue()=0;
|
||||
|
|
|
@ -22,4 +22,10 @@ namespace boo
|
|||
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wrl/client.h>
|
||||
template <class T>
|
||||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef GDEV_D3D11_HPP
|
||||
#define GDEV_D3D11_HPP
|
||||
|
||||
#if _WIN32
|
||||
#include <sdkddkver.h>
|
||||
#if _WIN32_WINNT_WIN7
|
||||
|
||||
#include "IGraphicsDataFactory.hpp"
|
||||
|
||||
namespace boo
|
||||
|
@ -47,4 +51,6 @@ public:
|
|||
|
||||
}
|
||||
|
||||
#endif // _WIN32_WINNT_WIN7
|
||||
#endif // _WIN32
|
||||
#endif // GDEV_D3D11_HPP
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
#ifndef GDEV_D3D12_HPP
|
||||
#define GDEV_D3D12_HPP
|
||||
|
||||
#if _WIN32
|
||||
#include <sdkddkver.h>
|
||||
#if _WIN32_WINNT_WIN10
|
||||
|
||||
#include "IGraphicsDataFactory.hpp"
|
||||
#include "IGraphicsCommandQueue.hpp"
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
#include "boo/System.hpp"
|
||||
#include <d3d12.h>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <wrl/client.h>
|
||||
template <class T>
|
||||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||
|
||||
namespace boo
|
||||
{
|
||||
|
||||
|
@ -32,16 +33,16 @@ public:
|
|||
IGraphicsBufferD* newDynamicBuffer(BufferUse use, size_t stride, size_t count);
|
||||
|
||||
ITextureS* newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||
const void* data, size_t sz);
|
||||
const void* data, size_t sz);
|
||||
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
|
||||
|
||||
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);
|
||||
|
||||
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,
|
||||
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
|
||||
const IVertexFormat* vtxFmt,
|
||||
BlendFactor srcFac, BlendFactor dstFac,
|
||||
bool depthTest, bool depthWrite, bool backfaceCulling);
|
||||
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
|
||||
IVertexFormat* vtxFmt,
|
||||
BlendFactor srcFac, BlendFactor dstFac,
|
||||
bool depthTest, bool depthWrite, bool backfaceCulling);
|
||||
|
||||
IShaderDataBinding*
|
||||
newShaderDataBinding(IShaderPipeline* pipeline,
|
||||
|
@ -58,4 +59,6 @@ public:
|
|||
|
||||
}
|
||||
|
||||
#endif // _WIN32_WINNT_WIN10
|
||||
#endif // _WIN32
|
||||
#endif // GDEV_D3D12_HPP
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define IGFXCOMMANDQUEUE_HPP
|
||||
|
||||
#include "IGraphicsDataFactory.hpp"
|
||||
#include "boo/IWindow.hpp"
|
||||
|
||||
namespace boo
|
||||
{
|
||||
|
@ -19,8 +20,10 @@ struct IGraphicsCommandQueue
|
|||
virtual Platform platform() const=0;
|
||||
virtual const char* platformName() const=0;
|
||||
|
||||
virtual void setShaderDataBinding(const IShaderDataBinding* binding)=0;
|
||||
virtual void setRenderTarget(const ITextureD* target)=0;
|
||||
virtual void setShaderDataBinding(IShaderDataBinding* binding)=0;
|
||||
virtual void setRenderTarget(IWindow* window)=0;
|
||||
virtual void setRenderTarget(ITextureD* target)=0;
|
||||
virtual void setViewport(const SWindowRect& rect)=0;
|
||||
|
||||
virtual void setClearColor(const float rgba[4])=0;
|
||||
virtual void clearTarget(bool render=true, bool depth=true)=0;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "boo/graphicsdev/D3D12.hpp"
|
||||
#include "../win/Win32Common.hpp"
|
||||
#include "boo/IGraphicsContext.hpp"
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
@ -29,22 +30,6 @@ static inline UINT64 NextHeapOffset(UINT64 offset, const D3D12_RESOURCE_ALLOCATI
|
|||
return (offset + info.Alignment - 1) & ~(info.Alignment - 1);
|
||||
}
|
||||
|
||||
struct D3D12Context
|
||||
{
|
||||
ComPtr<ID3D12Device> m_dev;
|
||||
ComPtr<ID3D12CommandAllocator> m_qalloc;
|
||||
ComPtr<ID3D12CommandQueue> m_q;
|
||||
ComPtr<ID3D12CommandAllocator> m_loadqalloc;
|
||||
ComPtr<ID3D12CommandQueue> m_loadq;
|
||||
ComPtr<ID3D12Fence> m_frameFence;
|
||||
ComPtr<ID3D12RootSignature> m_rs;
|
||||
struct Window
|
||||
{
|
||||
ComPtr<ID3D12Resource> m_fbs[3];
|
||||
};
|
||||
std::vector<Window> m_windows;
|
||||
};
|
||||
|
||||
struct D3D12Data : IGraphicsData
|
||||
{
|
||||
std::vector<std::unique_ptr<class D3D12ShaderPipeline>> m_SPs;
|
||||
|
@ -212,6 +197,8 @@ class D3D12TextureD : public ITextureD
|
|||
public:
|
||||
ComPtr<ID3D12Resource> m_texs[2];
|
||||
ComPtr<ID3D12Resource> m_gpuTexs[2];
|
||||
ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
|
||||
ComPtr<ID3D12DescriptorHeap> m_dsvHeap;
|
||||
~D3D12TextureD() = default;
|
||||
|
||||
void load(const void* data, size_t sz)
|
||||
|
@ -238,10 +225,21 @@ public:
|
|||
{
|
||||
D3D12_RESOURCE_DESC desc = m_texs[i]->GetDesc();
|
||||
ThrowIfFailed(ctx->m_dev->CreatePlacedResource(gpuHeap, offset, &desc,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
i ? D3D12_RESOURCE_STATE_DEPTH_WRITE : D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
nullptr, __uuidof(ID3D12Resource), &m_gpuTexs[i]));
|
||||
offset = NextHeapOffset(offset, ctx->m_dev->GetResourceAllocationInfo(0, 1, &desc));
|
||||
}
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtvdesc = {D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1};
|
||||
ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&rtvdesc, __uuidof(ID3D12DescriptorHeap), &m_rtvHeap));
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvvdesc = {DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RTV_DIMENSION_TEXTURE2D};
|
||||
ctx->m_dev->CreateRenderTargetView(m_gpuTexs[0].Get(), &rtvvdesc, m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC dsvdesc = {D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1};
|
||||
ThrowIfFailed(ctx->m_dev->CreateDescriptorHeap(&dsvdesc, __uuidof(ID3D12DescriptorHeap), &m_dsvHeap));
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsvvdesc = {DXGI_FORMAT_D24_UNORM_S8_UINT, D3D12_DSV_DIMENSION_TEXTURE2D};
|
||||
ctx->m_dev->CreateDepthStencilView(m_gpuTexs[1].Get(), &dsvvdesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
|
||||
|
||||
return offset;
|
||||
}
|
||||
};
|
||||
|
@ -363,8 +361,7 @@ public:
|
|||
IShaderPipeline* D3D12DataFactory::newShaderPipeline
|
||||
(const char* vertSource, const char* fragSource,
|
||||
ComPtr<ID3DBlob>& vertBlobOut, ComPtr<ID3DBlob>& fragBlobOut,
|
||||
const IVertexFormat* vtxFmt,
|
||||
BlendFactor srcFac, BlendFactor dstFac,
|
||||
IVertexFormat* vtxFmt, BlendFactor srcFac, BlendFactor dstFac,
|
||||
bool depthTest, bool depthWrite, bool backfaceCulling)
|
||||
{
|
||||
ComPtr<ID3DBlob> errBlob;
|
||||
|
@ -666,78 +663,92 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
|||
m_cmdList->SetGraphicsRootSignature(m_ctx->m_rs.Get());
|
||||
}
|
||||
|
||||
void setShaderDataBinding(const IShaderDataBinding* binding)
|
||||
void setShaderDataBinding(IShaderDataBinding* binding)
|
||||
{
|
||||
const D3D12ShaderDataBinding* cbind = static_cast<const D3D12ShaderDataBinding*>(binding);
|
||||
D3D12ShaderDataBinding* cbind = static_cast<D3D12ShaderDataBinding*>(binding);
|
||||
ID3D12DescriptorHeap* descHeap = cbind->m_descHeap[m_fillBuf].Get();
|
||||
m_cmdList->SetDescriptorHeaps(1, &descHeap);
|
||||
m_cmdList->SetPipelineState(cbind->m_pipeline->m_state.Get());
|
||||
}
|
||||
void setRenderTarget(const ITextureD* target)
|
||||
|
||||
D3D12TextureD* m_boundTarget = nullptr;
|
||||
|
||||
void setRenderTarget(IWindow* window)
|
||||
{
|
||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||
cmds.emplace_back(Command::OpSetRenderTarget);
|
||||
cmds.back().target = target;
|
||||
|
||||
}
|
||||
|
||||
void setRenderTarget(ITextureD* target)
|
||||
{
|
||||
D3D12TextureD* ctarget = static_cast<D3D12TextureD*>(target);
|
||||
|
||||
if (m_boundTarget)
|
||||
m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_boundTarget->m_gpuTexs[0].Get(),
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
||||
|
||||
m_cmdList->OMSetRenderTargets(1, &ctarget->m_rtvHeap->GetCPUDescriptorHandleForHeapStart(),
|
||||
false, &ctarget->m_dsvHeap->GetCPUDescriptorHandleForHeapStart());
|
||||
|
||||
m_cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ctarget->m_gpuTexs[0].Get(),
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET));
|
||||
|
||||
m_boundTarget = ctarget;
|
||||
}
|
||||
|
||||
void setViewport(const SWindowRect& rect)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
|
||||
void setClearColor(const float rgba[4])
|
||||
{
|
||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||
cmds.emplace_back(Command::OpSetClearColor);
|
||||
cmds.back().rgba[0] = rgba[0];
|
||||
cmds.back().rgba[1] = rgba[1];
|
||||
cmds.back().rgba[2] = rgba[2];
|
||||
cmds.back().rgba[3] = rgba[3];
|
||||
m_clearColor[0] = rgba[0];
|
||||
m_clearColor[1] = rgba[1];
|
||||
m_clearColor[2] = rgba[2];
|
||||
m_clearColor[3] = rgba[3];
|
||||
}
|
||||
|
||||
void clearTarget(bool render=true, bool depth=true)
|
||||
{
|
||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||
cmds.emplace_back(Command::OpClearTarget);
|
||||
cmds.back().flags = 0;
|
||||
if (render)
|
||||
cmds.back().flags |= GL_COLOR_BUFFER_BIT;
|
||||
{
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE handle;
|
||||
m_cmdList->ClearRenderTargetView(handle, m_clearColor, 0, nullptr);
|
||||
}
|
||||
if (depth)
|
||||
cmds.back().flags |= GL_DEPTH_BUFFER_BIT;
|
||||
{
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE handle;
|
||||
m_cmdList->ClearDepthStencilView(handle, D3D12_CLEAR_FLAG_DEPTH, 1.0, 0, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void setDrawPrimitive(Primitive prim)
|
||||
{
|
||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||
cmds.emplace_back(Command::OpSetDrawPrimitive);
|
||||
if (prim == PrimitiveTriangles)
|
||||
cmds.back().prim = GL_TRIANGLES;
|
||||
m_cmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
else if (prim == PrimitiveTriStrips)
|
||||
cmds.back().prim = GL_TRIANGLE_STRIP;
|
||||
m_cmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
}
|
||||
|
||||
void draw(size_t start, size_t count)
|
||||
{
|
||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||
cmds.emplace_back(Command::OpDraw);
|
||||
cmds.back().start = start;
|
||||
cmds.back().count = count;
|
||||
m_cmdList->DrawInstanced(count, 1, start, 0);
|
||||
}
|
||||
|
||||
void drawIndexed(size_t start, size_t count)
|
||||
{
|
||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||
cmds.emplace_back(Command::OpDrawIndexed);
|
||||
cmds.back().start = start;
|
||||
cmds.back().count = count;
|
||||
m_cmdList->DrawIndexedInstanced(count, 1, start, 0, 0);
|
||||
}
|
||||
|
||||
void drawInstances(size_t start, size_t count, size_t instCount)
|
||||
{
|
||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||
cmds.emplace_back(Command::OpDrawInstances);
|
||||
cmds.back().start = start;
|
||||
cmds.back().count = count;
|
||||
cmds.back().instCount = instCount;
|
||||
m_cmdList->DrawInstanced(count, instCount, start, 0);
|
||||
}
|
||||
|
||||
void drawInstancesIndexed(size_t start, size_t count, size_t instCount)
|
||||
{
|
||||
std::vector<Command>& cmds = m_cmdBufs[m_fillBuf];
|
||||
cmds.emplace_back(Command::OpDrawInstancesIndexed);
|
||||
cmds.back().start = start;
|
||||
cmds.back().count = count;
|
||||
cmds.back().instCount = instCount;
|
||||
m_cmdList->DrawIndexedInstanced(count, instCount, start, 0, 0);
|
||||
}
|
||||
|
||||
void present()
|
||||
|
@ -747,7 +758,6 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
|||
|
||||
void execute()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mt);
|
||||
m_completeBuf = m_fillBuf;
|
||||
for (size_t i=0 ; i<3 ; ++i)
|
||||
{
|
||||
|
@ -756,37 +766,35 @@ struct D3D12CommandQueue : IGraphicsCommandQueue
|
|||
m_fillBuf = i;
|
||||
break;
|
||||
}
|
||||
lk.unlock();
|
||||
m_cv.notify_one();
|
||||
m_cmdBufs[m_fillBuf].clear();
|
||||
}
|
||||
};
|
||||
|
||||
void D3D12GraphicsBufferD::load(const void* data, size_t sz)
|
||||
{
|
||||
glBindBuffer(m_target, m_bufs[m_q->m_fillBuf]);
|
||||
glBufferData(m_target, sz, data, GL_DYNAMIC_DRAW);
|
||||
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
|
||||
void* d;
|
||||
res->Map(0, nullptr, &d);
|
||||
memcpy(d, data, sz);
|
||||
res->Unmap(0, nullptr);
|
||||
}
|
||||
void* D3D12GraphicsBufferD::map(size_t sz)
|
||||
{
|
||||
if (m_mappedBuf)
|
||||
free(m_mappedBuf);
|
||||
m_mappedBuf = malloc(sz);
|
||||
m_mappedSize = sz;
|
||||
return m_mappedBuf;
|
||||
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
|
||||
void* d;
|
||||
res->Map(0, nullptr, &d);
|
||||
return d;
|
||||
}
|
||||
void D3D12GraphicsBufferD::unmap()
|
||||
{
|
||||
glBindBuffer(m_target, m_bufs[m_q->m_fillBuf]);
|
||||
glBufferData(m_target, m_mappedSize, m_mappedBuf, GL_DYNAMIC_DRAW);
|
||||
free(m_mappedBuf);
|
||||
m_mappedBuf = nullptr;
|
||||
ID3D12Resource* res = m_bufs[m_q->m_fillBuf].Get();
|
||||
res->Unmap(0, nullptr);
|
||||
}
|
||||
|
||||
IGraphicsBufferD*
|
||||
D3D12DataFactory::newDynamicBuffer(BufferUse use, size_t stride, size_t count)
|
||||
{
|
||||
D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(use, stride, count);
|
||||
D3D12CommandQueue* q = static_cast<D3D12CommandQueue*>(m_parent->getCommandQueue());
|
||||
D3D12GraphicsBufferD* retval = new D3D12GraphicsBufferD(q, use, m_ctx, stride, count);
|
||||
static_cast<D3D12Data*>(m_deferredData)->m_DBufs.emplace_back(retval);
|
||||
return retval;
|
||||
}
|
||||
|
@ -809,9 +817,9 @@ IVertexFormat* D3D12DataFactory::newVertexFormat
|
|||
return retval;
|
||||
}
|
||||
|
||||
IGraphicsCommandQueue* _NewD3D12CommandQueue(IGraphicsContext* parent)
|
||||
IGraphicsCommandQueue* _NewD3D12CommandQueue(D3D12Context* ctx, IGraphicsContext* parent)
|
||||
{
|
||||
return new struct D3D12CommandQueue(parent);
|
||||
return new struct D3D12CommandQueue(ctx, parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,32 +1,41 @@
|
|||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include "Win32Common.hpp"
|
||||
#include <shellapi.h>
|
||||
#include <initguid.h>
|
||||
#include <Usbiodef.h>
|
||||
|
||||
#if _DEBUG
|
||||
#define DXGI_FACTORY2_FLAGS DXGI_CREATE_FACTORY_DEBUG
|
||||
#define D3D11_CREATE_DEVICE_FLAGS D3D11_CREATE_DEVICE_DEBUG
|
||||
#else
|
||||
#define DXGI_FACTORY2_FLAGS 0
|
||||
#define D3D11_CREATE_DEVICE_FLAGS 0
|
||||
#endif
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "boo/System.hpp"
|
||||
#include "boo/IApplication.hpp"
|
||||
#include "boo/inputdev/DeviceFinder.hpp"
|
||||
#include <LogVisor/LogVisor.hpp>
|
||||
|
||||
namespace boo
|
||||
{
|
||||
static LogVisor::LogModule Log("ApplicationWin32");
|
||||
|
||||
IWindow* _WindowWin32New(const SystemString& title);
|
||||
IWindow* _WindowWin32New(const SystemString& title, D3DAppContext& d3dCtx);
|
||||
|
||||
class ApplicationWin32 final : public IApplication
|
||||
{
|
||||
const IApplicationCallback& m_callback;
|
||||
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, IWindow*> m_allWindows;
|
||||
bool m_singleInstance;
|
||||
|
||||
|
||||
D3DAppContext m_d3dCtx;
|
||||
|
||||
void _deletedWindow(IWindow* window)
|
||||
{
|
||||
m_allWindows.erase(HWND(window->getPlatformHandle()));
|
||||
|
@ -34,7 +43,7 @@ class ApplicationWin32 final : public IApplication
|
|||
|
||||
public:
|
||||
|
||||
ApplicationWin32(const IApplicationCallback& callback,
|
||||
ApplicationWin32(IApplicationCallback& callback,
|
||||
const SystemString& uniqueName,
|
||||
const SystemString& friendlyName,
|
||||
const SystemString& pname,
|
||||
|
@ -46,7 +55,55 @@ public:
|
|||
m_pname(pname),
|
||||
m_args(args),
|
||||
m_singleInstance(singleInstance)
|
||||
{}
|
||||
{
|
||||
HMODULE dxgilib = LoadLibraryW(L"dxgi.dll");
|
||||
if (!dxgilib)
|
||||
Log.report(LogVisor::FatalError, "unable to load dxgi.dll");
|
||||
|
||||
typedef HRESULT(WINAPI*CreateDXGIFactory2PROC)(UINT Flags, REFIID riid, _COM_Outptr_ void **ppFactory);
|
||||
CreateDXGIFactory2PROC MyCreateDXGIFactory2 = (CreateDXGIFactory2PROC)GetProcAddress(dxgilib, "CreateDXGIFactory2");
|
||||
if (!MyCreateDXGIFactory2)
|
||||
Log.report(LogVisor::FatalError, "unable to find CreateDXGIFactory2 in DXGI.dll\n"
|
||||
"Windows 7 users should install \"Platform Update for Windows 7\" from Microsoft");
|
||||
if (FAILED(MyCreateDXGIFactory2(DXGI_FACTORY2_FLAGS, __uuidof(IDXGIFactory2), &m_d3dCtx.m_dxFactory)))
|
||||
Log.report(LogVisor::FatalError, "unable to create DXGI factory");
|
||||
|
||||
#if WINVER >= _WIN32_WINNT_WIN10
|
||||
HMODULE d3d12lib = LoadLibraryW(L"D3D12.dll");
|
||||
if (d3d12lib)
|
||||
{
|
||||
PFN_D3D12_CREATE_DEVICE MyD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(d3d12lib, "D3D12CreateDevice");
|
||||
if (!MyD3D12CreateDevice)
|
||||
Log.report(LogVisor::FatalError, "unable to find D3D12CreateDevice in D3D12.dll");
|
||||
if (FAILED(MyD3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_12_0, __uuidof(ID3D12Device), &m_d3dCtx.m_ctx12.m_dev)))
|
||||
Log.report(LogVisor::FatalError, "unable to create D3D12 device");
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
HMODULE d3d11lib = LoadLibraryW(L"D3D11.dll");
|
||||
if (d3d11lib)
|
||||
{
|
||||
/* Create device proc */
|
||||
PFN_D3D11_CREATE_DEVICE MyD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11lib, "D3D11CreateDevice");
|
||||
if (!MyD3D11CreateDevice)
|
||||
Log.report(LogVisor::FatalError, "unable to find D3D11CreateDevice in D3D11.dll");
|
||||
|
||||
/* Create device */
|
||||
D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_1;
|
||||
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::FatalError, "unable to create D3D11.1 device");
|
||||
tempDev.As<ID3D11Device1>(&m_d3dCtx.m_ctx11.m_dev);
|
||||
tempCtx.As<ID3D11DeviceContext1>(&m_d3dCtx.m_ctx11.m_devCtx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Log.report(LogVisor::FatalError, "system doesn't support D3D11.1 or D3D12");
|
||||
}
|
||||
|
||||
EPlatformType getPlatformType() const
|
||||
{
|
||||
|
@ -65,13 +122,32 @@ public:
|
|||
case WM_DEVICECHANGE:
|
||||
return DeviceFinder::winDevChangedHandler(wParam, lParam);
|
||||
|
||||
case WM_SIZE:
|
||||
case WM_KEYDOWN:
|
||||
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:
|
||||
window->_incomingEvent(&HWNDEvent(uMsg, wParam, lParam));
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
void pump()
|
||||
int run()
|
||||
{
|
||||
/* Spawn client thread */
|
||||
int clientReturn = 0;
|
||||
std::thread clientThread([&]()
|
||||
{clientReturn = m_callback.appMain(this);});
|
||||
|
||||
/* Pump messages */
|
||||
MSG msg = {0};
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
|
@ -79,6 +155,10 @@ public:
|
|||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
m_callback.appQuitting(this);
|
||||
clientThread.join();
|
||||
return clientReturn;
|
||||
}
|
||||
|
||||
const SystemString& getUniqueName() const
|
||||
|
@ -103,7 +183,7 @@ public:
|
|||
|
||||
IWindow* newWindow(const SystemString& title)
|
||||
{
|
||||
IWindow* window = _WindowWin32New(title);
|
||||
IWindow* window = _WindowWin32New(title, m_d3dCtx);
|
||||
HWND hwnd = HWND(window->getPlatformHandle());
|
||||
m_allWindows[hwnd] = window;
|
||||
return window;
|
||||
|
@ -111,23 +191,21 @@ public:
|
|||
};
|
||||
|
||||
IApplication* APP = NULL;
|
||||
std::unique_ptr<IApplication>
|
||||
ApplicationBootstrap(IApplication::EPlatformType platform,
|
||||
IApplicationCallback& cb,
|
||||
const SystemString& uniqueName,
|
||||
const SystemString& friendlyName,
|
||||
const SystemString& pname,
|
||||
const std::vector<SystemString>& args,
|
||||
bool singleInstance)
|
||||
int ApplicationRun(IApplication::EPlatformType platform,
|
||||
IApplicationCallback& cb,
|
||||
const SystemString& uniqueName,
|
||||
const SystemString& friendlyName,
|
||||
const SystemString& pname,
|
||||
const std::vector<SystemString>& args,
|
||||
bool singleInstance)
|
||||
{
|
||||
if (!APP)
|
||||
{
|
||||
if (platform != IApplication::PLAT_WIN32 &&
|
||||
platform != IApplication::PLAT_AUTO)
|
||||
return NULL;
|
||||
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args, singleInstance);
|
||||
}
|
||||
return std::unique_ptr<IApplication>(APP);
|
||||
if (APP)
|
||||
return 1;
|
||||
if (platform != IApplication::PLAT_WIN32 &&
|
||||
platform != IApplication::PLAT_AUTO)
|
||||
return 1;
|
||||
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args, singleInstance);
|
||||
return APP->run();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -154,7 +232,7 @@ static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||
int wmain(int argc, wchar_t** argv);
|
||||
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
||||
{
|
||||
#if DEBUG
|
||||
#if _DEBUG
|
||||
/* Debug console */
|
||||
AllocConsole();
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef BOO_WIN32COMMON_HPP
|
||||
#define BOO_WIN32COMMON_HPP
|
||||
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||
#endif
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#if _WIN32_WINNT_WIN10
|
||||
#include <dxgi1_4.h>
|
||||
#include <d3d12.h>
|
||||
#include <d3d11_1.h>
|
||||
|
||||
struct D3D12Context
|
||||
{
|
||||
ComPtr<ID3D12Device> m_dev;
|
||||
ComPtr<ID3D12CommandAllocator> m_qalloc;
|
||||
ComPtr<ID3D12CommandQueue> m_q;
|
||||
ComPtr<ID3D12CommandAllocator> m_loadqalloc;
|
||||
ComPtr<ID3D12CommandQueue> m_loadq;
|
||||
ComPtr<ID3D12Fence> m_frameFence;
|
||||
ComPtr<ID3D12RootSignature> m_rs;
|
||||
};
|
||||
|
||||
#elif _WIN32_WINNT_WIN7
|
||||
#include <dxgi1_2.h>
|
||||
#include <d3d11_1.h>
|
||||
#else
|
||||
#error Unsupported Windows target
|
||||
#endif
|
||||
|
||||
struct D3D11Context
|
||||
{
|
||||
ComPtr<ID3D11Device1> m_dev;
|
||||
ComPtr<ID3D11DeviceContext1> m_devCtx;
|
||||
};
|
||||
|
||||
#include "boo/System.hpp"
|
||||
|
||||
struct D3DAppContext
|
||||
{
|
||||
D3D11Context m_ctx11;
|
||||
#if _WIN32_WINNT_WIN10
|
||||
D3D12Context m_ctx12;
|
||||
#endif
|
||||
ComPtr<IDXGIFactory2> m_dxFactory;
|
||||
};
|
||||
|
||||
struct HWNDEvent
|
||||
{
|
||||
UINT uMsg;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
HWNDEvent(UINT m, WPARAM w, LPARAM l)
|
||||
: uMsg(m), wParam(w), lParam(l) {}
|
||||
};
|
||||
|
||||
#endif // BOO_WIN32COMMON_HPP
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
add_executable(booTest main.cpp)
|
||||
add_executable(booTest WIN32 main.cpp)
|
||||
target_link_libraries(booTest Boo LogVisor ${BOO_SYS_LIBS})
|
||||
|
|
Loading…
Reference in New Issue