Initial directx example.
This commit is contained in:
parent
1dfbcc61c4
commit
92d1f24613
28 changed files with 683 additions and 212 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
.cproject
|
.cproject
|
||||||
.project
|
.project
|
||||||
.pydevproject
|
.pydevproject
|
||||||
|
.vscode
|
||||||
.settings/
|
.settings/
|
||||||
/Debug/
|
/Debug/
|
||||||
/build/
|
/build/
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
add_subdirectory(notes_tk)
|
add_subdirectory(notes_tk)
|
||||||
add_subdirectory(website-generator)
|
add_subdirectory(website-generator)
|
||||||
|
|
||||||
# Experimental Below
|
|
||||||
if(WIN32)
|
|
||||||
add_subdirectory(directx-practice)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Sample Console
|
# Sample Console
|
||||||
add_executable(notes_tk_console main.cpp)
|
add_executable(notes_tk_console main.cpp)
|
||||||
target_link_libraries(notes_tk_console PUBLIC console core network database geometry audio web)
|
target_link_libraries(notes_tk_console PUBLIC console core network database geometry audio web)
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
|
|
||||||
list(APPEND directx_practice_LIB_INCLUDES
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
add_executable(directx-practice WIN32 directx-practice.cpp ${directx_practice_LIB_INCLUDES})
|
|
||||||
|
|
||||||
target_include_directories(directx-practice PUBLIC
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(directx-practice PUBLIC core D3D12.lib DXGI.lib)
|
|
||||||
|
|
||||||
set_property(TARGET directx-practice PROPERTY FOLDER apps/directx-practice)
|
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
#include "loggers/FileLogger.h"
|
|
||||||
|
|
||||||
#include <DirectXMath.h>
|
|
||||||
#include <DirectXPackedVector.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <wrl.h>
|
|
||||||
|
|
||||||
#include <dxgi.h>
|
|
||||||
#include <dxgi1_6.h>
|
|
||||||
#include <d3d12.h>
|
|
||||||
#include <d3d12sdklayers.h>
|
|
||||||
|
|
||||||
|
|
||||||
void GetHardwareAdapter(IDXGIFactory7* pFactory, IDXGIAdapter1** ppAdapter)
|
|
||||||
{
|
|
||||||
*ppAdapter = nullptr;
|
|
||||||
for (UINT adapterIndex = 0; ; ++adapterIndex)
|
|
||||||
{
|
|
||||||
IDXGIAdapter1* pAdapter = nullptr;
|
|
||||||
if (DXGI_ERROR_NOT_FOUND == pFactory->EnumAdapters1(adapterIndex, &pAdapter))
|
|
||||||
{
|
|
||||||
// No more adapters to enumerate.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to see if the adapter supports Direct3D 12, but don't create the
|
|
||||||
// actual device yet.
|
|
||||||
if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
|
|
||||||
{
|
|
||||||
*ppAdapter = pAdapter;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pAdapter->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
|
|
||||||
{
|
|
||||||
FileLogger::GetInstance().Open();
|
|
||||||
MLOG_INFO("Test");
|
|
||||||
|
|
||||||
if (!DirectX::XMVerifyCPUSupport())
|
|
||||||
{
|
|
||||||
MLOG_ERROR("Directx math not supported");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto n = DirectX::XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f);
|
|
||||||
//auto u = DirectX::XMVectorSet(1.0f, 2.0f, 3.0f, 0.0f);
|
|
||||||
//auto v = DirectX::XMVectorSet(-2.0f, 1.0f, -3.0f, 0.0f);
|
|
||||||
//auto w = DirectX::XMVectorSet(0.707f, 0.707f, 0.0f, 0.0f);
|
|
||||||
|
|
||||||
auto p = DirectX::XMVectorZero();
|
|
||||||
auto q = DirectX::XMVectorSplatOne();
|
|
||||||
auto u = DirectX::XMVectorSet(1.0f, 2.0f, 3.0f, 0.0f);
|
|
||||||
auto v = DirectX::XMVectorReplicate(-2.0f);
|
|
||||||
auto w = DirectX::XMVectorSplatZ(u);
|
|
||||||
|
|
||||||
DirectX::XMMATRIX A(1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 2.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 4.0f, 0.0f,
|
|
||||||
1.0f, 2.0f, 3.0f, 1.0f);
|
|
||||||
DirectX::XMMATRIX B = DirectX::XMMatrixIdentity();
|
|
||||||
|
|
||||||
IDXGIAdapter* adapter = nullptr;
|
|
||||||
std::vector<IDXGIAdapter*> adapterList;
|
|
||||||
|
|
||||||
Microsoft::WRL::ComPtr<ID3D12CommandQueue> commandQueue;
|
|
||||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
|
||||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
|
||||||
|
|
||||||
#if defined(DEBUG) || defined(_DEBUG)
|
|
||||||
// Enable the D3D12 debug layer.
|
|
||||||
{
|
|
||||||
ID3D12Debug* debugController;
|
|
||||||
D3D12GetDebugInterface(IID_PPV_ARGS(&debugController));
|
|
||||||
debugController->EnableDebugLayer();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IDXGIFactory7* pFactory{ nullptr };
|
|
||||||
HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory7), (void**)(&pFactory));
|
|
||||||
if (hr == S_OK)
|
|
||||||
{
|
|
||||||
MLOG_INFO("FACTORY IS OK");
|
|
||||||
}
|
|
||||||
|
|
||||||
IDXGIAdapter1* pAdapter{ nullptr };
|
|
||||||
GetHardwareAdapter(pFactory, &pAdapter);
|
|
||||||
|
|
||||||
ID3D12Device* pDevice{ nullptr };
|
|
||||||
if (pAdapter)
|
|
||||||
{
|
|
||||||
MLOG_INFO("Found adapter");
|
|
||||||
if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&pDevice))))
|
|
||||||
{
|
|
||||||
MLOG_INFO("Got device");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MLOG_INFO("No adapter found");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -16,8 +16,8 @@
|
||||||
#include "DesktopManager.h"
|
#include "DesktopManager.h"
|
||||||
#include "MainApplication.h"
|
#include "MainApplication.h"
|
||||||
|
|
||||||
NotesTk::NotesTk(std::unique_ptr<CommandLineArgs> args)
|
NotesTk::NotesTk(std::unique_ptr<CommandLineArgs> args, std::unique_ptr<MainApplication> mainApp)
|
||||||
: GuiApplication(std::move(args))
|
: GuiApplication(std::move(args), std::move(mainApp))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
class NotesTk : public GuiApplication
|
class NotesTk : public GuiApplication
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NotesTk(std::unique_ptr<CommandLineArgs> args);
|
NotesTk(std::unique_ptr<CommandLineArgs> args = nullptr, std::unique_ptr<MainApplication> mainApp = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initializeViews() override;
|
void initializeViews() override;
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "MainApplication.h"
|
#include "MainApplication.h"
|
||||||
#include "GuiApplication.h"
|
#include "NotesTk.h"
|
||||||
#include "CommandLineArgs.h"
|
#include "CommandLineArgs.h"
|
||||||
#include "Win32WindowInterface.h"
|
#include "Win32WindowInterface.h"
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
|
||||||
|
@ -55,13 +56,11 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
|
||||||
MLOG_INFO("Creating GUI Application");
|
MLOG_INFO("Creating GUI Application");
|
||||||
|
|
||||||
// Start the gui application
|
// Start the gui application
|
||||||
auto gui_app = GuiApplication();
|
auto gui_app = NotesTk(nullptr, std::move(main_app));
|
||||||
//gui_app.setMainApplication(main_app);
|
|
||||||
|
|
||||||
MLOG_INFO("Running GUI Application");
|
MLOG_INFO("Running GUI Application");
|
||||||
gui_app.run();
|
gui_app.run();
|
||||||
|
|
||||||
main_app->shutDown();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ void WasapiInterface::play(AudioDevice* device, AudioSample* sample, unsigned du
|
||||||
// hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &deviceName);
|
// hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &deviceName);
|
||||||
hr = pPropertyStore->GetValue(PKEY_DeviceInterface_FriendlyName, &deviceName);
|
hr = pPropertyStore->GetValue(PKEY_DeviceInterface_FriendlyName, &deviceName);
|
||||||
//PKEY_Device_FriendlyName
|
//PKEY_Device_FriendlyName
|
||||||
std::cout << "Device name: " << deviceName.pwszVal << std::endl;
|
//std::cout << "Device name: " << deviceName.pwszVal << std::endl;
|
||||||
|
|
||||||
pPropertyStore->Release();
|
pPropertyStore->Release();
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,19 @@
|
||||||
|
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
|
|
||||||
GuiApplication::GuiApplication(std::unique_ptr<CommandLineArgs> args)
|
GuiApplication::GuiApplication(std::unique_ptr<CommandLineArgs> args, std::unique_ptr<MainApplication> mainApp)
|
||||||
: AbstractDesktopApp(),
|
: AbstractDesktopApp(),
|
||||||
mMainApplication(MainApplication::Create()),
|
|
||||||
mDesktopManager(DesktopManager::Create(this))
|
mDesktopManager(DesktopManager::Create(this))
|
||||||
{
|
{
|
||||||
mMainApplication->initialize(args ? std::move(args) : CommandLineArgs::Create());
|
if (mainApp)
|
||||||
|
{
|
||||||
|
mMainApplication = std::move(mainApp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMainApplication = MainApplication::Create();
|
||||||
|
mMainApplication->initialize(args ? std::move(args) : CommandLineArgs::Create());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GuiApplication::~GuiApplication()
|
GuiApplication::~GuiApplication()
|
||||||
|
|
|
@ -13,7 +13,7 @@ class AbstractUiInterface;
|
||||||
class GuiApplication : public AbstractDesktopApp
|
class GuiApplication : public AbstractDesktopApp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuiApplication(std::unique_ptr<CommandLineArgs> args = nullptr);
|
GuiApplication(std::unique_ptr<CommandLineArgs> args = nullptr, std::unique_ptr<MainApplication> mainApp = nullptr);
|
||||||
|
|
||||||
~GuiApplication();
|
~GuiApplication();
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ std::unique_ptr<SqliteInterface> SqliteInterface::Create()
|
||||||
|
|
||||||
void SqliteInterface::open(Database* db)
|
void SqliteInterface::open(Database* db)
|
||||||
{
|
{
|
||||||
int rc = sqlite3_open(db->getPath().c_str(), &mSqliteDb);
|
const auto path = db->getPath().string();
|
||||||
|
int rc = sqlite3_open(path.c_str(), &mSqliteDb);
|
||||||
if( rc )
|
if( rc )
|
||||||
{
|
{
|
||||||
MLOG_ERROR("Can't open database: %s\n" << sqlite3_errmsg(mSqliteDb));
|
MLOG_ERROR("Can't open database: %s\n" << sqlite3_errmsg(mSqliteDb));
|
||||||
|
|
|
@ -21,27 +21,32 @@ list(APPEND graphics_HEADERS
|
||||||
PainterFactory.h
|
PainterFactory.h
|
||||||
)
|
)
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
set(OpenGL_GL_PREFERENCE "GLVND")
|
set(OpenGL_GL_PREFERENCE "GLVND")
|
||||||
find_package(OpenGL QUIET)
|
find_package(OpenGL QUIET)
|
||||||
if (OpenGL_FOUND)
|
if (OpenGL_FOUND)
|
||||||
list(APPEND platform_LIBS OpenGL::GL OpenGL::GLU)
|
list(APPEND platform_LIBS OpenGL::GL OpenGL::GLU)
|
||||||
list(APPEND graphics_LIB_INCLUDES
|
list(APPEND graphics_LIB_INCLUDES
|
||||||
opengl/OpenGlPainter.cpp
|
opengl/OpenGlPainter.cpp
|
||||||
opengl/OpenGlTextPainter.cpp
|
opengl/OpenGlTextPainter.cpp
|
||||||
opengl/OpenGlMeshPainter.cpp
|
opengl/OpenGlMeshPainter.cpp
|
||||||
opengl/OpenGlFontTexture.cpp
|
opengl/OpenGlFontTexture.cpp
|
||||||
opengl/OpenGlShaderProgram.cpp
|
opengl/OpenGlShaderProgram.cpp
|
||||||
)
|
)
|
||||||
list(APPEND ${MODULE_NAME}
|
list(APPEND ${MODULE_NAME}
|
||||||
opengl/OpenGlPainter.h
|
opengl/OpenGlPainter.h
|
||||||
opengl/OpenGlTextPainter.h
|
opengl/OpenGlTextPainter.h
|
||||||
opengl/OpenGlMeshPainter.h
|
opengl/OpenGlMeshPainter.h
|
||||||
opengl/OpenGlFontTexture.h
|
opengl/OpenGlFontTexture.h
|
||||||
opengl/OpenGlShaderProgram.h)
|
opengl/OpenGlShaderProgram.h)
|
||||||
list(APPEND DEFINES "HAS_OPENGL")
|
list(APPEND DEFINES "HAS_OPENGL")
|
||||||
|
else()
|
||||||
|
message(STATUS "OpenGL not found - skipping support")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
message(STATUS "OpenGL not found - skipping support")
|
list(APPEND graphics_LIB_INCLUDES
|
||||||
endif()
|
directx/DirectXPainter.cpp)
|
||||||
|
list(APPEND graphics_HEADERS
|
||||||
|
directx/DirectXPainter.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(${MODULE_NAME} SHARED
|
add_library(${MODULE_NAME} SHARED
|
||||||
|
|
0
src/graphics/directx/DirectXPainter.cpp
Normal file
0
src/graphics/directx/DirectXPainter.cpp
Normal file
0
src/graphics/directx/DirectXPainter.h
Normal file
0
src/graphics/directx/DirectXPainter.h
Normal file
|
@ -34,7 +34,6 @@ public:
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
virtual void onResize(unsigned width, unsigned height) = 0;
|
virtual void onResize(unsigned width, unsigned height) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mt::Window* mWindow{nullptr};
|
mt::Window* mWindow{nullptr};
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,10 +58,20 @@ else()
|
||||||
ui_interfaces/win32/Win32WindowInterface.cpp
|
ui_interfaces/win32/Win32WindowInterface.cpp
|
||||||
ui_interfaces/win32/Win32Window.h
|
ui_interfaces/win32/Win32Window.h
|
||||||
ui_interfaces/win32/Win32Window.cpp
|
ui_interfaces/win32/Win32Window.cpp
|
||||||
|
ui_interfaces/win32/Win32DxInterface.h
|
||||||
|
ui_interfaces/win32/Win32DxInterface.cpp
|
||||||
|
ui_interfaces/win32/Win32DxWindowInterface.h
|
||||||
|
ui_interfaces/win32/Win32DxWindowInterface.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
list(APPEND platform_LIBS D3D12.lib D3DCompiler.lib DXGI.lib)
|
||||||
|
|
||||||
|
find_package(DirectX-Headers REQUIRED)
|
||||||
|
list(APPEND platform_LIBS Microsoft::DirectX-Headers)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND windows_LIB_INCLUDES
|
list(APPEND windows_LIB_INCLUDES
|
||||||
|
ui_interfaces/AbstractUiInterface.h
|
||||||
ui_interfaces/UiInterfaceFactory.cpp
|
ui_interfaces/UiInterfaceFactory.cpp
|
||||||
managers/WindowManager.cpp
|
managers/WindowManager.cpp
|
||||||
managers/DesktopManager.cpp
|
managers/DesktopManager.cpp
|
||||||
|
|
|
@ -45,6 +45,6 @@ std::unique_ptr<AbstractUIInterface> UiInterfaceFactory::create(DesktopManager*
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return std::make_unique<Win32UIInterface>(desktopManager, std::move(fonts_manager));
|
return std::make_unique<Win32UIInterface>(desktopManager, std::move(fonts_manager), true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
91
src/windows/ui_interfaces/win32/Win32DxInterface.cpp
Normal file
91
src/windows/ui_interfaces/win32/Win32DxInterface.cpp
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#include "Win32DxInterface.h"
|
||||||
|
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
#include <DirectXMath.h>
|
||||||
|
#include <DirectXPackedVector.h>
|
||||||
|
|
||||||
|
#include <dxgi.h>
|
||||||
|
#include <dxgi1_6.h>
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <d3d12sdklayers.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
void Win32DxInterface::getHardwareAdapter(IDXGIAdapter1** ppAdapter)
|
||||||
|
{
|
||||||
|
*ppAdapter = nullptr;
|
||||||
|
for (UINT adapterIndex = 0; ; ++adapterIndex)
|
||||||
|
{
|
||||||
|
IDXGIAdapter1* pAdapter = nullptr;
|
||||||
|
if (DXGI_ERROR_NOT_FOUND == mFactory->EnumAdapters1(adapterIndex, &pAdapter))
|
||||||
|
{
|
||||||
|
// No more adapters to enumerate.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if the adapter supports Direct3D 12, but don't create the actual device yet.
|
||||||
|
if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
|
||||||
|
{
|
||||||
|
*ppAdapter = pAdapter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pAdapter->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12Device* Win32DxInterface::getDevice() const
|
||||||
|
{
|
||||||
|
return mDevice.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
IDXGIFactory7* Win32DxInterface::getFactory() const
|
||||||
|
{
|
||||||
|
return mFactory.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32DxInterface::initialize()
|
||||||
|
{
|
||||||
|
if (!DirectX::XMVerifyCPUSupport())
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Directx math not supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG) || defined(_DEBUG)
|
||||||
|
// Enable the D3D12 debug layer.
|
||||||
|
{
|
||||||
|
ID3D12Debug* debugController;
|
||||||
|
D3D12GetDebugInterface(IID_PPV_ARGS(&debugController));
|
||||||
|
debugController->EnableDebugLayer();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory7), (void**)(&mFactory));
|
||||||
|
if (hr == S_OK)
|
||||||
|
{
|
||||||
|
MLOG_INFO("FACTORY IS OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
IDXGIAdapter1* pAdapter{ nullptr };
|
||||||
|
getHardwareAdapter(&pAdapter);
|
||||||
|
|
||||||
|
if (pAdapter)
|
||||||
|
{
|
||||||
|
MLOG_INFO("Found adapter");
|
||||||
|
if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&mDevice))))
|
||||||
|
{
|
||||||
|
MLOG_INFO("Got device");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MLOG_INFO("No adapter found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
24
src/windows/ui_interfaces/win32/Win32DxInterface.h
Normal file
24
src/windows/ui_interfaces/win32/Win32DxInterface.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
struct ID3D12Device;
|
||||||
|
struct IDXGIFactory7;
|
||||||
|
struct IDXGIAdapter1;
|
||||||
|
|
||||||
|
class Win32DxInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
ID3D12Device* getDevice() const;
|
||||||
|
|
||||||
|
IDXGIFactory7* getFactory() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void getHardwareAdapter(IDXGIAdapter1** ppAdapter);
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<IDXGIFactory7> mFactory;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12Device> mDevice;
|
||||||
|
};
|
304
src/windows/ui_interfaces/win32/Win32DxWindowInterface.cpp
Normal file
304
src/windows/ui_interfaces/win32/Win32DxWindowInterface.cpp
Normal file
|
@ -0,0 +1,304 @@
|
||||||
|
#include "Win32DxWindowInterface.h"
|
||||||
|
|
||||||
|
#include "Win32DxInterface.h"
|
||||||
|
#include "Win32Window.h"
|
||||||
|
#include "Window.h"
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
|
#include <dxgi.h>
|
||||||
|
#include <dxgi1_6.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#include <d3d12sdklayers.h>
|
||||||
|
|
||||||
|
Win32DxWindowInterface::Win32DxWindowInterface(Win32DxInterface* dxInterface)
|
||||||
|
: mDxInterface(dxInterface)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Win32DxWindowInterface::~Win32DxWindowInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32DxWindowInterface::destroyWindow()
|
||||||
|
{
|
||||||
|
waitForPreviousFrame();
|
||||||
|
|
||||||
|
::CloseHandle(mFenceEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32DxWindowInterface::onRender()
|
||||||
|
{
|
||||||
|
// Record all the commands we need to render the scene into the command list.
|
||||||
|
populateCommandList();
|
||||||
|
|
||||||
|
// Execute the command list.
|
||||||
|
ID3D12CommandList* ppCommandLists[] = { mCommandList.Get() };
|
||||||
|
mCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
|
||||||
|
|
||||||
|
// Present the frame.
|
||||||
|
mSwapChain->Present(1, 0);
|
||||||
|
|
||||||
|
waitForPreviousFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32DxWindowInterface::populateCommandList()
|
||||||
|
{
|
||||||
|
// Command list allocators can only be reset when the associated
|
||||||
|
// command lists have finished execution on the GPU; apps should use
|
||||||
|
// fences to determine GPU execution progress.
|
||||||
|
mCommandAllocator->Reset();
|
||||||
|
|
||||||
|
// However, when ExecuteCommandList() is called on a particular command
|
||||||
|
// list, that command list can then be reset at any time and must be before
|
||||||
|
// re-recording.
|
||||||
|
mCommandList->Reset(mCommandAllocator.Get(), mPipelineState.Get());
|
||||||
|
|
||||||
|
// Set necessary state.
|
||||||
|
mCommandList->SetGraphicsRootSignature(mRootSignature.Get());
|
||||||
|
mCommandList->RSSetViewports(1, &mViewport);
|
||||||
|
mCommandList->RSSetScissorRects(1, &mScissorRect);
|
||||||
|
|
||||||
|
// Indicate that the back buffer will be used as a render target.
|
||||||
|
auto barrier = CD3DX12_RESOURCE_BARRIER::Transition(mRenderTargets[mFrameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||||
|
mCommandList->ResourceBarrier(1, &barrier);
|
||||||
|
|
||||||
|
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(mRtvHeap->GetCPUDescriptorHandleForHeapStart(), static_cast<INT>(mFrameIndex), mRtvDescriptorSize);
|
||||||
|
mCommandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
|
||||||
|
|
||||||
|
// Record commands.
|
||||||
|
const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
|
||||||
|
mCommandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
|
||||||
|
mCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
mCommandList->IASetVertexBuffers(0, 1, &mVertexBufferView);
|
||||||
|
mCommandList->DrawInstanced(3, 1, 0, 0);
|
||||||
|
|
||||||
|
// Indicate that the back buffer will now be used to present.
|
||||||
|
barrier = CD3DX12_RESOURCE_BARRIER::Transition(mRenderTargets[mFrameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
||||||
|
mCommandList->ResourceBarrier(1, &barrier);
|
||||||
|
|
||||||
|
mCommandList->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32DxWindowInterface::initialize(mt::Window* window)
|
||||||
|
{
|
||||||
|
if (mInitialized)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto width = window->getWidth();
|
||||||
|
const auto height = window->getHeight();
|
||||||
|
mViewport = CD3DX12_VIEWPORT(0.0f, 0.0f, width, height);
|
||||||
|
mScissorRect = CD3DX12_RECT(0, 0, width, height);
|
||||||
|
|
||||||
|
loadPipeline(window);
|
||||||
|
|
||||||
|
loadAssets();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32DxWindowInterface::loadPipeline(mt::Window* window)
|
||||||
|
{
|
||||||
|
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||||
|
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||||
|
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||||
|
|
||||||
|
mDxInterface->getDevice()->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue));
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
|
||||||
|
swapChainDesc.BufferCount = FrameCount;
|
||||||
|
|
||||||
|
const auto width = window->getWidth();
|
||||||
|
const auto height = window->getHeight();
|
||||||
|
swapChainDesc.Width = width;
|
||||||
|
swapChainDesc.Height = height;
|
||||||
|
|
||||||
|
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
|
swapChainDesc.SampleDesc.Count = 1;
|
||||||
|
|
||||||
|
const auto hwnd = dynamic_cast<Win32Window*>(window->getPlatformWindow())->getHandle();
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain;
|
||||||
|
mDxInterface->getFactory()->CreateSwapChainForHwnd(
|
||||||
|
mCommandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it.
|
||||||
|
hwnd,
|
||||||
|
&swapChainDesc,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
&swapChain
|
||||||
|
);
|
||||||
|
mDxInterface->getFactory()->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
swapChain.As(&mSwapChain);
|
||||||
|
auto mFrameIndex = mSwapChain->GetCurrentBackBufferIndex();
|
||||||
|
|
||||||
|
// Create descriptor heaps.
|
||||||
|
{
|
||||||
|
// Describe and create a render target view (RTV) descriptor heap.
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
|
||||||
|
rtvHeapDesc.NumDescriptors = FrameCount;
|
||||||
|
rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||||
|
rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||||
|
mDxInterface->getDevice()->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&mRtvHeap));
|
||||||
|
|
||||||
|
mRtvDescriptorSize = mDxInterface->getDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create frame resources.
|
||||||
|
{
|
||||||
|
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(mRtvHeap->GetCPUDescriptorHandleForHeapStart());
|
||||||
|
|
||||||
|
// Create a RTV for each frame.
|
||||||
|
for (UINT n = 0; n < FrameCount; n++)
|
||||||
|
{
|
||||||
|
mSwapChain->GetBuffer(n, IID_PPV_ARGS(&mRenderTargets[n]));
|
||||||
|
mDxInterface->getDevice()->CreateRenderTargetView(mRenderTargets[n].Get(), nullptr, rtvHandle);
|
||||||
|
rtvHandle.Offset(1, mRtvDescriptorSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDxInterface->getDevice()->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCommandAllocator));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32DxWindowInterface::loadAssets()
|
||||||
|
{
|
||||||
|
// Create an empty root signature.
|
||||||
|
{
|
||||||
|
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
|
||||||
|
rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<ID3DBlob> signature;
|
||||||
|
Microsoft::WRL::ComPtr<ID3DBlob> error;
|
||||||
|
D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
|
||||||
|
mDxInterface->getDevice()->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&mRootSignature));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the pipeline state, which includes compiling and loading shaders.
|
||||||
|
{
|
||||||
|
Microsoft::WRL::ComPtr<ID3DBlob> vertexShader;
|
||||||
|
Microsoft::WRL::ComPtr<ID3DBlob> pixelShader;
|
||||||
|
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
// Enable better shader debugging with the graphics debugging tools.
|
||||||
|
// UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
|
||||||
|
UINT compileFlags = 0;
|
||||||
|
#else
|
||||||
|
UINT compileFlags = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders.hlsl";
|
||||||
|
|
||||||
|
D3DCompileFromFile(shader_path.c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr);
|
||||||
|
D3DCompileFromFile(shader_path.c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr);
|
||||||
|
|
||||||
|
// Define the vertex input layout.
|
||||||
|
D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
|
||||||
|
{
|
||||||
|
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Describe and create the graphics pipeline state object (PSO).
|
||||||
|
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
|
||||||
|
psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) };
|
||||||
|
psoDesc.pRootSignature = mRootSignature.Get();
|
||||||
|
psoDesc.VS = CD3DX12_SHADER_BYTECODE(vertexShader.Get());
|
||||||
|
psoDesc.PS = CD3DX12_SHADER_BYTECODE(pixelShader.Get());
|
||||||
|
psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
|
||||||
|
psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
|
||||||
|
psoDesc.DepthStencilState.DepthEnable = FALSE;
|
||||||
|
psoDesc.DepthStencilState.StencilEnable = FALSE;
|
||||||
|
psoDesc.SampleMask = UINT_MAX;
|
||||||
|
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||||
|
psoDesc.NumRenderTargets = 1;
|
||||||
|
psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
psoDesc.SampleDesc.Count = 1;
|
||||||
|
mDxInterface->getDevice()->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPipelineState));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the command list.
|
||||||
|
mDxInterface->getDevice()->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, mCommandAllocator.Get(), mPipelineState.Get(), IID_PPV_ARGS(&mCommandList));
|
||||||
|
|
||||||
|
// Command lists are created in the recording state, but there is nothing
|
||||||
|
// to record yet. The main loop expects it to be closed, so close it now.
|
||||||
|
mCommandList->Close();
|
||||||
|
|
||||||
|
// Create the vertex buffer.
|
||||||
|
{
|
||||||
|
// Define the geometry for a triangle.
|
||||||
|
const float aspectRatio = 1.0;
|
||||||
|
Vertex triangleVertices[] =
|
||||||
|
{
|
||||||
|
{ { 0.0f, 0.25f * aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
|
||||||
|
{ { 0.25f, -0.25f * aspectRatio, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
|
||||||
|
{ { -0.25f, -0.25f * aspectRatio, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } }
|
||||||
|
};
|
||||||
|
|
||||||
|
const UINT vertexBufferSize = sizeof(triangleVertices);
|
||||||
|
|
||||||
|
// Note: using upload heaps to transfer static data like vert buffers is not
|
||||||
|
// recommended. Every time the GPU needs it, the upload heap will be marshalled
|
||||||
|
// over. Please read up on Default Heap usage. An upload heap is used here for
|
||||||
|
// code simplicity and because there are very few verts to actually transfer.
|
||||||
|
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD);
|
||||||
|
auto desc = CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize);
|
||||||
|
mDxInterface->getDevice()->CreateCommittedResource(
|
||||||
|
&heapProps,
|
||||||
|
D3D12_HEAP_FLAG_NONE,
|
||||||
|
&desc,
|
||||||
|
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||||
|
nullptr,
|
||||||
|
IID_PPV_ARGS(&mVertexBuffer));
|
||||||
|
|
||||||
|
// Copy the triangle data to the vertex buffer.
|
||||||
|
UINT8* pVertexDataBegin;
|
||||||
|
CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU.
|
||||||
|
mVertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin));
|
||||||
|
memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices));
|
||||||
|
mVertexBuffer->Unmap(0, nullptr);
|
||||||
|
|
||||||
|
// Initialize the vertex buffer view.
|
||||||
|
mVertexBufferView.BufferLocation = mVertexBuffer->GetGPUVirtualAddress();
|
||||||
|
mVertexBufferView.StrideInBytes = sizeof(Vertex);
|
||||||
|
mVertexBufferView.SizeInBytes = vertexBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create synchronization objects and wait until assets have been uploaded to the GPU.
|
||||||
|
{
|
||||||
|
mDxInterface->getDevice()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence));
|
||||||
|
mFenceValue = 1;
|
||||||
|
|
||||||
|
// Create an event handle to use for frame synchronization.
|
||||||
|
mFenceEvent = ::CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||||
|
if (mFenceEvent == nullptr)
|
||||||
|
{
|
||||||
|
//ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the command list to execute; we are reusing the same command
|
||||||
|
// list in our main loop but for now, we just want to wait for setup to
|
||||||
|
// complete before continuing.
|
||||||
|
waitForPreviousFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32DxWindowInterface::waitForPreviousFrame()
|
||||||
|
{
|
||||||
|
// Signal and increment the fence value.
|
||||||
|
const UINT64 fence = mFenceValue;
|
||||||
|
mCommandQueue->Signal(mFence.Get(), fence);
|
||||||
|
mFenceValue++;
|
||||||
|
|
||||||
|
// Wait until the previous frame is finished.
|
||||||
|
if (mFence->GetCompletedValue() < fence)
|
||||||
|
{
|
||||||
|
mFence->SetEventOnCompletion(fence, mFenceEvent);
|
||||||
|
::WaitForSingleObject(mFenceEvent, INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
mFrameIndex = mSwapChain->GetCurrentBackBufferIndex();
|
||||||
|
}
|
87
src/windows/ui_interfaces/win32/Win32DxWindowInterface.h
Normal file
87
src/windows/ui_interfaces/win32/Win32DxWindowInterface.h
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <wrl.h>
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <directxmath.h>
|
||||||
|
#include <directx/d3dx12.h>
|
||||||
|
|
||||||
|
class Win32DxInterface;
|
||||||
|
namespace mt
|
||||||
|
{
|
||||||
|
class Window;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ID3D12CommandQueue;
|
||||||
|
struct ID3D12CommandAllocator;
|
||||||
|
struct ID3D12GraphicsCommandList;
|
||||||
|
struct IDXGISwapChain4;
|
||||||
|
struct ID3D12DescriptorHeap;
|
||||||
|
struct ID3D12Resource;
|
||||||
|
struct ID3D12Fence;
|
||||||
|
struct ID3D12RootSignature;
|
||||||
|
struct ID3D12PipelineState;
|
||||||
|
|
||||||
|
class Win32DxWindowInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Win32DxWindowInterface(Win32DxInterface* dxInterface);
|
||||||
|
|
||||||
|
~Win32DxWindowInterface();
|
||||||
|
|
||||||
|
bool initialize(mt::Window* window);
|
||||||
|
|
||||||
|
void onRender();
|
||||||
|
|
||||||
|
//void afterPaint();
|
||||||
|
|
||||||
|
//void resizeViewPort(unsigned width, unsigned height);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadPipeline(mt::Window* window);
|
||||||
|
void loadAssets();
|
||||||
|
|
||||||
|
void populateCommandList();
|
||||||
|
void waitForPreviousFrame();
|
||||||
|
void destroyWindow();
|
||||||
|
|
||||||
|
static const UINT FrameCount = 2;
|
||||||
|
Win32DxInterface* mDxInterface{ nullptr };
|
||||||
|
bool mInitialized{ false };
|
||||||
|
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
DirectX::XMFLOAT3 position;
|
||||||
|
DirectX::XMFLOAT4 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
CD3DX12_VIEWPORT mViewport;
|
||||||
|
CD3DX12_RECT mScissorRect;
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12CommandQueue> mCommandQueue;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12CommandAllocator> mCommandAllocator;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList> mCommandList;
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<IDXGISwapChain4> mSwapChain;
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12RootSignature> mRootSignature;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12PipelineState> mPipelineState;
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> mRtvHeap;
|
||||||
|
UINT mRtvDescriptorSize{ 0 };
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12Resource> mRenderTargets[FrameCount];
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12Resource> mVertexBuffer;
|
||||||
|
D3D12_VERTEX_BUFFER_VIEW mVertexBufferView{};
|
||||||
|
|
||||||
|
Microsoft::WRL::ComPtr<ID3D12Fence> mFence;
|
||||||
|
uint64_t mFenceValue = 0;
|
||||||
|
uint64_t mFrameFenceValues[FrameCount] = {};
|
||||||
|
HANDLE mFenceEvent{};
|
||||||
|
|
||||||
|
uint64_t mFrameIndex{ 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
using XcbGlWindowInterfacePtr = std::unique_ptr<Win32DxWindowInterface>;
|
|
@ -1,5 +1,12 @@
|
||||||
#include "Win32UIInterface.h"
|
#include "Win32UIInterface.h"
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
#include "DesktopManager.h"
|
||||||
|
#include "Win32DxInterface.h"
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <dxgi.h>
|
||||||
|
#include <dxgi1_6.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
Win32UIInterface::Win32UIInterface(DesktopManager* desktopManager, std::unique_ptr<FontsManager> fontsManager, bool useHardware)
|
Win32UIInterface::Win32UIInterface(DesktopManager* desktopManager, std::unique_ptr<FontsManager> fontsManager, bool useHardware)
|
||||||
|
@ -11,11 +18,23 @@ Win32UIInterface::Win32UIInterface(DesktopManager* desktopManager, std::unique_p
|
||||||
|
|
||||||
void Win32UIInterface::initialize()
|
void Win32UIInterface::initialize()
|
||||||
{
|
{
|
||||||
|
if (mUseHardwareRendering)
|
||||||
|
{
|
||||||
|
initializeHardwareRendering();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto num_windows = mDesktopManager->getWindowManager()->getNumWindows();
|
||||||
|
for (std::size_t idx = 0; idx < num_windows; idx++)
|
||||||
|
{
|
||||||
|
addWindow(mDesktopManager->getWindowManager()->getWindow(idx));
|
||||||
|
}
|
||||||
|
showWindow(mDesktopManager->getWindowManager()->getMainWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win32UIInterface::loop()
|
void Win32UIInterface::loop()
|
||||||
{
|
{
|
||||||
|
initialize();
|
||||||
|
|
||||||
// Run the message loop.
|
// Run the message loop.
|
||||||
MSG msg = { };
|
MSG msg = { };
|
||||||
while (::GetMessage(&msg, NULL, 0, 0))
|
while (::GetMessage(&msg, NULL, 0, 0))
|
||||||
|
@ -32,10 +51,16 @@ void Win32UIInterface::shutDown()
|
||||||
|
|
||||||
void Win32UIInterface::showWindow(mt::Window* window)
|
void Win32UIInterface::showWindow(mt::Window* window)
|
||||||
{
|
{
|
||||||
mWindowInterface->Show(window);
|
mWindowInterface->show(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win32UIInterface::addWindow(mt::Window* window)
|
void Win32UIInterface::addWindow(mt::Window* window)
|
||||||
{
|
{
|
||||||
mWindowInterface->Add(window, mDesktopManager);
|
mWindowInterface->add(window, mDesktopManager, mDxInterface.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UIInterface::initializeHardwareRendering()
|
||||||
|
{
|
||||||
|
mDxInterface = std::make_unique<Win32DxInterface>();
|
||||||
|
mDxInterface->initialize();
|
||||||
}
|
}
|
|
@ -7,6 +7,9 @@
|
||||||
|
|
||||||
class DesktopManager;
|
class DesktopManager;
|
||||||
|
|
||||||
|
class Win32DxInterface;
|
||||||
|
using Win32DxInterfacePtr = std::unique_ptr<Win32DxInterface>;
|
||||||
|
|
||||||
class Win32UIInterface : public AbstractUIInterface
|
class Win32UIInterface : public AbstractUIInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -14,6 +17,8 @@ public:
|
||||||
|
|
||||||
~Win32UIInterface() = default;
|
~Win32UIInterface() = default;
|
||||||
|
|
||||||
|
void addWindow(mt::Window* window) override;
|
||||||
|
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
|
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
@ -22,9 +27,8 @@ public:
|
||||||
|
|
||||||
void showWindow(mt::Window* window) override;
|
void showWindow(mt::Window* window) override;
|
||||||
|
|
||||||
void addWindow(mt::Window* window) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initializeHardwareRendering() override;
|
||||||
Win32WindowInterfacePtr mWindowInterface;
|
Win32WindowInterfacePtr mWindowInterface;
|
||||||
|
Win32DxInterfacePtr mDxInterface;
|
||||||
};
|
};
|
|
@ -1,33 +1,40 @@
|
||||||
#include "Win32Window.h"
|
#include "Win32Window.h"
|
||||||
|
|
||||||
#include "Win32WindowInterface.h"
|
#include "Win32WindowInterface.h"
|
||||||
|
#include "Win32DxInterface.h"
|
||||||
|
#include "Win32DxWindowInterface.h"
|
||||||
|
|
||||||
#include <WinUser.h>
|
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
#include "ui_events\KeyboardEvent.h"
|
#include "KeyboardEvent.h"
|
||||||
#include "DesktopManager.h"
|
#include "DesktopManager.h"
|
||||||
|
|
||||||
|
#include <WinUser.h>
|
||||||
|
|
||||||
LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
Win32Window::Win32Window(mt::Window* window)
|
Win32Window::Win32Window(mt::Window* window, Win32DxInterface* dxInterface)
|
||||||
: IPlatformWindow(window)
|
: IPlatformWindow(window)
|
||||||
{
|
{
|
||||||
|
if (dxInterface)
|
||||||
|
{
|
||||||
|
mDxInterface = std::make_unique<Win32DxWindowInterface>(dxInterface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Win32Window> Win32Window::Create(mt::Window* window)
|
std::unique_ptr<Win32Window> Win32Window::Create(mt::Window* window, Win32DxInterface* dxInterface)
|
||||||
{
|
{
|
||||||
return std::make_unique<Win32Window>(window);
|
return std::make_unique<Win32Window>(window, dxInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND Win32Window::GetHandle() const
|
HWND Win32Window::getHandle() const
|
||||||
{
|
{
|
||||||
return mHandle;
|
return mHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win32Window::CreateNative(Win32ApplicationContext* context, DesktopManager* desktopManager)
|
void Win32Window::createNative(Win32ApplicationContext* context, DesktopManager* desktopManager)
|
||||||
{
|
{
|
||||||
mDesktopManager = desktopManager;
|
mDesktopManager = desktopManager;
|
||||||
|
|
||||||
|
@ -45,7 +52,7 @@ void Win32Window::CreateNative(Win32ApplicationContext* context, DesktopManager*
|
||||||
mHandle = CreateWindowEx(
|
mHandle = CreateWindowEx(
|
||||||
0, // Optional window styles.
|
0, // Optional window styles.
|
||||||
CLASS_NAME, // Window class
|
CLASS_NAME, // Window class
|
||||||
"Media Tool", // Window text
|
"Notes TK", // Window text
|
||||||
WS_OVERLAPPEDWINDOW, // Window style
|
WS_OVERLAPPEDWINDOW, // Window style
|
||||||
|
|
||||||
// Size and position
|
// Size and position
|
||||||
|
@ -95,15 +102,22 @@ LRESULT CALLBACK Win32Window::WindowProc(UINT message, WPARAM wParam, LPARAM lPa
|
||||||
|
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
PAINTSTRUCT ps;
|
if (mDxInterface)
|
||||||
HDC hdc = BeginPaint(mHandle, &ps);
|
{
|
||||||
|
mDxInterface->onRender();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
HDC hdc = BeginPaint(mHandle, &ps);
|
||||||
|
|
||||||
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
|
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
|
||||||
|
|
||||||
auto text = L"Hello World";
|
auto text = L"Hello World";
|
||||||
auto val = DrawText(hdc, (LPCSTR)(&text[0]), -1, &ps.rcPaint, 0);
|
auto val = DrawText(hdc, (LPCSTR)(&text[0]), -1, &ps.rcPaint, 0);
|
||||||
|
|
||||||
EndPaint(mHandle, &ps);
|
EndPaint(mHandle, &ps);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DefWindowProc(mHandle, message, wParam, lParam);
|
return DefWindowProc(mHandle, message, wParam, lParam);
|
||||||
|
@ -132,9 +146,17 @@ static LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPAR
|
||||||
|
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
window->SetHandle(hwnd);
|
window->setHandle(hwnd);
|
||||||
return window->WindowProc(uMsg, wParam, lParam);
|
return window->WindowProc(uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32Window::beforePaint(mt::Screen* screen)
|
||||||
|
{
|
||||||
|
if (mDxInterface)
|
||||||
|
{
|
||||||
|
mDxInterface->initialize(mWindow);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -4,36 +4,38 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
class Win32ApplicationContext;
|
class Win32ApplicationContext;
|
||||||
|
class Win32DxInterface;
|
||||||
|
class Win32DxWindowInterface;
|
||||||
class DesktopManager;
|
class DesktopManager;
|
||||||
|
|
||||||
class Win32Window : public IPlatformWindow
|
class Win32Window : public IPlatformWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Win32Window(mt::Window* window);
|
Win32Window(mt::Window* window, Win32DxInterface* dxInterface = nullptr);
|
||||||
virtual ~Win32Window() = default;
|
virtual ~Win32Window() = default;
|
||||||
|
|
||||||
static std::unique_ptr<Win32Window> Create(mt::Window* window);
|
static std::unique_ptr<Win32Window> Create(mt::Window* window, Win32DxInterface* dxInterface = nullptr);
|
||||||
|
|
||||||
LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
HWND GetHandle() const;
|
HWND getHandle() const;
|
||||||
|
|
||||||
void SetHandle(HWND handle)
|
void setHandle(HWND handle)
|
||||||
{
|
{
|
||||||
mHandle = handle;
|
mHandle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetCmdShow() const
|
int getCmdShow() const
|
||||||
{
|
{
|
||||||
return mCmdShow;
|
return mCmdShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCmdShow(int cmdShow)
|
void setCmdShow(int cmdShow)
|
||||||
{
|
{
|
||||||
mCmdShow = cmdShow;
|
mCmdShow = cmdShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateNative(Win32ApplicationContext* context, DesktopManager* desktopManager);
|
void createNative(Win32ApplicationContext* context, DesktopManager* desktopManager);
|
||||||
|
|
||||||
void show() {};
|
void show() {};
|
||||||
|
|
||||||
|
@ -43,10 +45,7 @@ public:
|
||||||
|
|
||||||
void onResize(unsigned width, unsigned height) {};
|
void onResize(unsigned width, unsigned height) {};
|
||||||
|
|
||||||
void beforePaint(mt::Screen* screen)
|
void beforePaint(mt::Screen* screen);
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void afterPaint(mt::Screen* screen)
|
void afterPaint(mt::Screen* screen)
|
||||||
{
|
{
|
||||||
|
@ -56,5 +55,6 @@ public:
|
||||||
private:
|
private:
|
||||||
HWND mHandle{ 0 };
|
HWND mHandle{ 0 };
|
||||||
int mCmdShow{ 0 };
|
int mCmdShow{ 0 };
|
||||||
DesktopManager* mDesktopManager;
|
DesktopManager* mDesktopManager{ nullptr };
|
||||||
|
std::unique_ptr<Win32DxWindowInterface> mDxInterface;
|
||||||
};
|
};
|
|
@ -1,33 +1,36 @@
|
||||||
#include "Win32WindowInterface.h"
|
#include "Win32WindowInterface.h"
|
||||||
|
|
||||||
#include "Win32Window.h"
|
#include "Win32Window.h"
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#include "DesktopManager.h"
|
#include "DesktopManager.h"
|
||||||
#include "DrawingContext.h"
|
#include "DrawingContext.h"
|
||||||
|
#include "Win32DxInterface.h"
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
Win32WindowInterface::Win32WindowInterface()
|
Win32WindowInterface::Win32WindowInterface()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win32WindowInterface::Show(mt::Window* window)
|
void Win32WindowInterface::show(mt::Window* window)
|
||||||
{
|
{
|
||||||
auto platformWindow = dynamic_cast<Win32Window*>(window->getPlatformWindow());
|
auto platformWindow = dynamic_cast<Win32Window*>(window->getPlatformWindow());
|
||||||
MLOG_INFO("Showing platform window: " << platformWindow->GetHandle());
|
MLOG_INFO("Showing platform window: " << platformWindow->getHandle());
|
||||||
::ShowWindow(platformWindow->GetHandle(), platformWindow->GetCmdShow());
|
::ShowWindow(platformWindow->getHandle(), platformWindow->getCmdShow());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win32WindowInterface::Add(mt::Window* window, DesktopManager* desktopManager)
|
void Win32WindowInterface::add(mt::Window* window, DesktopManager* desktopManager, Win32DxInterface* dxInterface)
|
||||||
{
|
{
|
||||||
auto context = dynamic_cast<Win32ApplicationContext*>(desktopManager->getMainApp()->GetApplicationContext());
|
auto context = dynamic_cast<Win32ApplicationContext*>(desktopManager->getMainApp()->GetApplicationContext());
|
||||||
|
|
||||||
auto win32_window = Win32Window::Create(window);
|
auto win32_window = Win32Window::Create(window, dxInterface);
|
||||||
win32_window->CreateNative(context, desktopManager);
|
win32_window->createNative(context, desktopManager);
|
||||||
win32_window->SetCmdShow(context->nCmdShow);
|
win32_window->setCmdShow(context->nCmdShow);
|
||||||
window->setPlatformWindow(std::move(win32_window), nullptr, DrawingMode::GRAPH);
|
window->setPlatformWindow(std::move(win32_window), nullptr, DrawingMode::GRAPH);
|
||||||
|
|
||||||
|
window->getPlatformWindow()->beforePaint(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
class DesktopManager;
|
class DesktopManager;
|
||||||
class FontsManager;
|
class FontsManager;
|
||||||
|
class Win32DxInterface;
|
||||||
|
|
||||||
class Win32ApplicationContext : public IApplicationContext
|
class Win32ApplicationContext : public IApplicationContext
|
||||||
{
|
{
|
||||||
|
@ -22,9 +23,9 @@ class Win32WindowInterface
|
||||||
public:
|
public:
|
||||||
Win32WindowInterface();
|
Win32WindowInterface();
|
||||||
|
|
||||||
void Add(mt::Window* window, DesktopManager* desktopManager);
|
void add(mt::Window* window, DesktopManager* desktopManager, Win32DxInterface* dxInterface = nullptr);
|
||||||
|
|
||||||
void Show(mt::Window* window);
|
void show(mt::Window* window);
|
||||||
};
|
};
|
||||||
|
|
||||||
using Win32WindowInterfacePtr = std::unique_ptr<Win32WindowInterface>;
|
using Win32WindowInterfacePtr = std::unique_ptr<Win32WindowInterface>;
|
20
src/windows/ui_interfaces/win32/shaders.hlsl
Normal file
20
src/windows/ui_interfaces/win32/shaders.hlsl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
struct PSInput
|
||||||
|
{
|
||||||
|
float4 position : SV_POSITION;
|
||||||
|
float4 color : COLOR;
|
||||||
|
};
|
||||||
|
|
||||||
|
PSInput VSMain(float4 position : POSITION, float4 color : COLOR)
|
||||||
|
{
|
||||||
|
PSInput result;
|
||||||
|
|
||||||
|
result.position = position;
|
||||||
|
result.color = color;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 PSMain(PSInput input) : SV_TARGET
|
||||||
|
{
|
||||||
|
return input.color;
|
||||||
|
}
|
Loading…
Reference in a new issue