1
0
Files
BasaltMeter/BasaltPresenter/Plugins/Engine/DirectX11Engine/main.cpp

234 lines
7.7 KiB
C++
Raw Normal View History

2026-01-04 16:12:36 +08:00
#include <basalt_export.hpp>
2026-01-04 17:16:54 +08:00
#include <engine.hpp>
#include <windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <wrl/client.h>
#include <vector>
#include <iostream>
using Microsoft::WRL::ComPtr;
// <20><><EFBFBD><EFBFBD>
constexpr UINT Width = 800;
constexpr UINT Height = 600;
constexpr const wchar_t* PipeName = L"\\\\.\\pipe\\54da494c-301a-47a9-9d67-4fbebaeda8cf";
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣨λ<E3A3A8>ã<EFBFBD>
struct Vertex {
float x, y, z;
};
Vertex CubeVertices[] = {
// ǰ<><C7B0>
{-1, -1, -1},
{1, -1, -1},
{1, 1, -1},
{-1, -1, -1},
{1, 1, -1},
{-1, 1, -1},
// <20><><EFBFBD><EFBFBD>
{-1, -1, 1},
{-1, 1, 1},
{1, 1, 1},
{-1, -1, 1},
{1, 1, 1},
{1, -1, 1},
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...<2E><>Ϊ<EFBFBD>򻯣<EFBFBD><F2BBAFA3>˴<EFBFBD><CBB4>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ʵ<>ʽ<EFBFBD><CABD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>12<31><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>棨36<33><36><EFBFBD>
};
// Ϊ<>򻯣<EFBFBD><F2BBAFA3><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>Ⱦǰ<C8BE>棬ʵ<E6A3AC><CAB5><EFBFBD>벹ȫ
// <20>򵥶<EFBFBD><F2B5A5B6><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>λ<EFBFBD>ã<EFBFBD>
const char* g_VS = R"(
float4 main(float3 pos : POSITION) : SV_POSITION {
return float4(pos, 1.0f);
}
)";
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع̶<D8B9><CCB6><EFBFBD>ɫ<EFBFBD><C9AB>
const char* g_PS = R"(
float4 main() : SV_TARGET {
return float4(0.2f, 0.4f, 0.8f, 1.0f);
}
)";
int main() {
// <20><>ʼ<EFBFBD><CABC> COM
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ComPtr<ID3D11Device> device;
ComPtr<ID3D11DeviceContext> context;
D3D11CreateDevice(
nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_DEBUG, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><C8BE><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD>
ComPtr<IDXGISwapChain> swapChain;
DXGI_SWAP_CHAIN_DESC sd = {};
sd.BufferDesc.Width = Width;
sd.BufferDesc.Height = Height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.SampleDesc.Count = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = GetConsoleWindow(); // <20>򴴽<EFBFBD><F2B4B4BD><EFBFBD><EFBFBD><EFBFBD>
sd.Windowed = TRUE;
ComPtr<IDXGIDevice> dxgiDevice;
device.As(&dxgiDevice);
ComPtr<IDXGIAdapter> adapter;
dxgiDevice->GetAdapter(&adapter);
ComPtr<IDXGIFactory> factory;
adapter->GetParent(IID_PPV_ARGS(&factory));
factory->CreateSwapChain(device.Get(), &sd, &swapChain);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȾĿ<C8BE><C4BF>
ComPtr<ID3D11RenderTargetView> rtv;
ComPtr<ID3D11Texture2D> backBuffer;
swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer));
device->CreateRenderTargetView(backBuffer.Get(), nullptr, &rtv);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB>壨D32_FLOAT<41><54>
ComPtr<ID3D11Texture2D> depthBuffer;
D3D11_TEXTURE2D_DESC depthDesc = {};
depthDesc.Width = Width;
depthDesc.Height = Height;
depthDesc.MipLevels = 1;
depthDesc.ArraySize = 1;
depthDesc.Format = DXGI_FORMAT_D32_FLOAT;
depthDesc.SampleDesc.Count = 1;
depthDesc.Usage = D3D11_USAGE_DEFAULT;
depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
device->CreateTexture2D(&depthDesc, nullptr, &depthBuffer);
ComPtr<ID3D11DepthStencilView> dsv;
device->CreateDepthStencilView(depthBuffer.Get(), nullptr, &dsv);
// <20><><EFBFBD><EFBFBD> staging texture <20><><EFBFBD><EFBFBD> CPU <20><>ȡ<EFBFBD><C8A1><EFBFBD>ȣ<EFBFBD>R32_FLOAT<41><54>
ComPtr<ID3D11Texture2D> depthStaging;
D3D11_TEXTURE2D_DESC stagingDesc = depthDesc;
stagingDesc.Format = DXGI_FORMAT_R32_FLOAT; // ע<>⣺DSV <20><> D32_FLOAT<41><54>staging <20><> R32_FLOAT
stagingDesc.BindFlags = 0;
stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
stagingDesc.Usage = D3D11_USAGE_STAGING;
device->CreateTexture2D(&stagingDesc, nullptr, &depthStaging);
// <20><><EFBFBD><EFBFBD><EBB2A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>
ComPtr<ID3D11VertexShader> vs;
ComPtr<ID3D11PixelShader> ps;
ComPtr<ID3DBlob> vsBlob, psBlob;
D3DCompile(g_VS, strlen(g_VS), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vsBlob, nullptr);
D3DCompile(g_PS, strlen(g_PS), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &psBlob, nullptr);
device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &vs);
device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &ps);
// <20><><EFBFBD><EFBFBD><EBB2BC>
D3D11_INPUT_ELEMENT_DESC layout[] = {{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}};
ComPtr<ID3D11InputLayout> inputLayout;
device->CreateInputLayout(layout, 1, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &inputLayout);
// <20><><EFBFBD><EFBFBD><E3BBBA>
ComPtr<ID3D11Buffer> vertexBuffer;
D3D11_BUFFER_DESC vbDesc = {};
vbDesc.ByteWidth = sizeof(CubeVertices);
vbDesc.Usage = D3D11_USAGE_DEFAULT;
vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA vbData = {CubeVertices};
device->CreateBuffer(&vbDesc, &vbData, &vertexBuffer);
// <20><><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ComPtr<ID3D11DepthStencilState> depthState;
D3D11_DEPTH_STENCIL_DESC dsDesc = {};
dsDesc.DepthEnable = TRUE;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
device->CreateDepthStencilState(&dsDesc, &depthState);
// <20>ӿ<EFBFBD>
D3D11_VIEWPORT vp = {0, 0, (float) Width, (float) Height, 0, 1};
context->RSSetViewports(1, &vp);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD><D1B4><EFBFBD><EFBFBD><EFBFBD>
HANDLE hPipe = CreateFileW(PipeName, GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
if (hPipe == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open named pipe. Ensure another process created it.\n";
return -1;
}
constexpr size_t depthSize = Width * Height * sizeof(float);
std::vector<BYTE> depthData(depthSize);
// <20><>Ⱦѭ<C8BE><D1AD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ֻ<EFBFBD><D6BB>Ⱦ10֡<30><D6A1>
for (int frame = 0; frame < 10; ++frame) {
// <20><><EFBFBD><EFBFBD>
float clearColor[] = {0.1f, 0.1f, 0.1f, 1.0f};
context->ClearRenderTargetView(rtv.Get(), clearColor);
context->ClearDepthStencilView(dsv.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
// <20><><EFBFBD>ù<EFBFBD><C3B9><EFBFBD>
context->OMSetRenderTargets(1, rtv.GetAddressOf(), dsv.Get());
context->OMSetDepthStencilState(depthState.Get(), 1);
context->VSSetShader(vs.Get(), nullptr, 0);
context->PSSetShader(ps.Get(), nullptr, 0);
context->IASetInputLayout(inputLayout.Get());
UINT stride = sizeof(Vertex), offset = 0;
context->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offset);
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
context->Draw(6, 0); // <20><>ǰ<EFBFBD>棬ʵ<E6A3AC><CAB5>ӦΪ36
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB>嵽 staging texture
context->CopyResource(depthStaging.Get(), depthBuffer.Get());
// Map <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
D3D11_MAPPED_SUBRESOURCE mapped;
context->Map(depthStaging.Get(), 0, D3D11_MAP_READ, 0, &mapped);
memcpy(depthData.data(), mapped.pData, depthSize);
context->Unmap(depthStaging.Get(), 0);
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD>
DWORD written;
if (!WriteFile(hPipe, depthData.data(), static_cast<DWORD>(depthSize), &written, nullptr) || written != depthSize) {
std::cerr << "WriteFile failed or incomplete.\n";
break;
}
// <20><><EFBFBD>֣<EFBFBD><D6A3><EFBFBD>ѡ<EFBFBD><D1A1>
swapChain->Present(0, 0);
}
CloseHandle(hPipe);
CoUninitialize();
return 0;
}
using ::Basalt::Shared::Engine::EngineConfig;
using ::Basalt::Shared::Engine::IEngine;
class DirectX11Engine : public IEngine {
public:
DirectX11Engine() : IEngine() {}
virtual ~DirectX11Engine() {}
private:
ComPtr<ID3D11Device> device; ///< <20>
ComPtr<ID3D11DeviceContext> context; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ComPtr<IDXGISwapChain> swapChain; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public:
virtual void Startup(EngineConfig&& config) override { IEngine::Startup(std::move(config)); }
virtual void Tick() override { IEngine::Tick(); }
virtual void Shutdown() override { IEngine::Shutdown(); }
};
2026-01-04 16:12:36 +08:00
BS_EXPORT void* BSCreateInstance() {
2026-01-04 17:16:54 +08:00
return new DirectX11Engine();
2026-01-04 16:12:36 +08:00
}
BS_EXPORT void BSDestroyInstance(void* instance) {
2026-01-04 17:16:54 +08:00
delete reinterpret_cast<DirectX11Engine*>(instance);
2026-01-04 16:12:36 +08:00
}