1
0

optimize dx11 engine

This commit is contained in:
2026-01-05 16:51:58 +08:00
parent 7110becf66
commit 52916db08f
10 changed files with 152 additions and 117 deletions

View File

@@ -1,5 +1,4 @@
#include <basalt_export.hpp>
#include <directx_util.hpp>
#include <engine.hpp>
#include <windows.h>
#include <d3d11.h>
@@ -14,6 +13,91 @@ using Microsoft::WRL::ComPtr;
throw std::runtime_error("bad DirectX calling"); \
}
#pragma region Win32 Window Creation
// Window procedure for the render window
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CLOSE:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
// Create a render window for DirectX
static HWND CreateRenderWindow(std::uint32_t width, std::uint32_t height, const std::wstring_view& title) {
static bool g_CLSREG = false;
constexpr wchar_t class_name[] = L"DirectXRenderWindowClass";
std::wstring c_title(title);
if (!g_CLSREG) {
WNDCLASSEXW wc = {0};
wc.cbSize = sizeof(WNDCLASSEXW);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = GetModuleHandleW(nullptr);
wc.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszClassName = class_name;
if (!RegisterClassExW(&wc)) {
throw std::runtime_error("Failed to register window class");
}
g_CLSREG = true;
}
// Calculate window size including borders
RECT rect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
HWND hwnd = CreateWindowExW(0,
class_name,
c_title.c_str(),
WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
rect.right - rect.left,
rect.bottom - rect.top,
nullptr,
nullptr,
GetModuleHandleW(nullptr),
nullptr);
if (!hwnd) {
throw std::runtime_error("Failed to create render window");
}
return hwnd;
}
static void DestroyRenderWindow(HWND hwnd) {
DestroyWindow(hwnd);
}
/**
* @brief Non-block event loop.
* @return True for indicate active exit.
*/
static bool EventLoop() {
MSG msg;
if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) == 0) {
// No msg
return false;
} else {
if (msg.message == WM_QUIT) {
return true;
} else {
TranslateMessage(&msg);
DispatchMessageW(&msg);
return false;
}
}
}
#pragma endregion
// 立方体顶点(位置)
struct Vertex {
float x, y, z;
@@ -61,8 +145,7 @@ Vertex CubeVertices[] = {
{1, -1, 1},
{-1, -1, -1},
{1, -1, 1},
{1, -1, -1}
};
{1, -1, -1}};
// 简单顶点着色器(只传位置)
const char* g_VS = R"(
@@ -80,7 +163,6 @@ const char* g_PS = R"(
using ::Basalt::Shared::Engine::EngineConfig;
using ::Basalt::Shared::Engine::IEngine;
namespace DxUtil = ::Basalt::Shared::DirectX;
class DirectX11Engine : public IEngine {
public:
@@ -88,28 +170,38 @@ public:
virtual ~DirectX11Engine() {}
private:
ComPtr<ID3D11Device> device; ///< 设备
ComPtr<ID3D11DeviceContext> context; ///< 上下文
ComPtr<IDXGISwapChain> swap_chain; ///< 交换链
ComPtr<ID3D11RenderTargetView> rtv; ///< 渲染目标视图
ComPtr<ID3D11Texture2D> back_buffer; ///< 后缓冲
ComPtr<ID3D11Texture2D> depth_buffer; ///< 深度缓冲
ComPtr<ID3D11DepthStencilView> dsv; ///< 深度模板视图
ComPtr<ID3D11Texture2D> depth_staging; ///< 用于CPU读取的深度暂存纹理
ComPtr<ID3D11VertexShader> vs; ///< 顶点着色器
ComPtr<ID3D11PixelShader> ps; ///< 像素着色器
ComPtr<ID3DBlob> vs_blob; ///< 顶点着色器字节码
ComPtr<ID3DBlob> ps_blob; ///< 像素着色器字节码
ComPtr<ID3D11InputLayout> input_layout; ///< 输入布局
ComPtr<ID3D11Buffer> vertex_buffer; ///< 顶点缓冲
ComPtr<ID3D11DepthStencilState> depth_state; ///< 深度状态
HWND window; ///< Win32窗口
ComPtr<ID3D11Device> device; ///< 设备
ComPtr<ID3D11DeviceContext> context; ///< 上下文
ComPtr<IDXGISwapChain> swap_chain; ///< 交换链
ComPtr<ID3D11RenderTargetView> rtv; ///< 渲染目标视图
ComPtr<ID3D11Texture2D> back_buffer; ///< 缓冲
ComPtr<ID3D11Texture2D> depth_buffer; ///< 深度缓冲
ComPtr<ID3D11DepthStencilView> dsv; ///< 深度模板视图
ComPtr<ID3D11Texture2D> depth_staging; ///< 用于CPU读取的深度暂存纹理
ComPtr<ID3D11VertexShader> vs; ///< 顶点着色器
ComPtr<ID3D11PixelShader> ps; ///< 像素着色器
ComPtr<ID3DBlob> vs_blob; ///< 顶点着色器字节码
ComPtr<ID3DBlob> ps_blob; ///< 像素着色器字节码
ComPtr<ID3D11InputLayout> input_layout; ///< 输入布局
ComPtr<ID3D11Buffer> vertex_buffer; ///< 顶点缓冲
ComPtr<ID3D11DepthStencilState> depth_state; ///< 深度状态
ComPtr<ID3D11RasterizerState> rasterizer_state; ///< 光栅化状态
std::vector<BYTE> depth_data; ///< 深度数据
std::vector<BYTE> depth_data; ///< 深度数据
public:
virtual void Startup(EngineConfig&& config) override {
IEngine::Startup(std::move(config));
// 创建Win32窗口并显示
if (this->config.headless) {
window = NULL;
} else {
window = CreateRenderWindow(this->config.width, this->config.height, this->config.title);
ShowWindow(window, SW_SHOW);
UpdateWindow(window);
}
// 初始化 COM
DXCHK(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED));
@@ -133,7 +225,7 @@ public:
sd.SampleDesc.Count = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = DxUtil::CreateRenderWindow(this->config.width, this->config.height, this->config.title); // 创建窗口
sd.OutputWindow = window;
sd.Windowed = TRUE;
ComPtr<IDXGIDevice> dxgi_device;
@@ -228,13 +320,11 @@ public:
//frameCount = 0;
}
virtual void Tick() override {
IEngine::Tick();
virtual bool Tick() override {
if (IEngine::Tick()) return true;
MSG msg;
GetMessage(&msg, nullptr, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
// Event loop
if (EventLoop()) return true;
// 清屏
float clear_color[] = {0.8f, 0.1f, 0.1f, 1.0f};
@@ -274,6 +364,8 @@ public:
DXCHK(swap_chain->Present(0, 0));
//frameCount++;
return false;
}
virtual void Shutdown() override {
@@ -283,6 +375,10 @@ public:
// CloseHandle(hPipe);
//}
CoUninitialize();
if (!this->config.headless) {
CloseWindow(window);
DestroyRenderWindow(window);
}
}
};