Files
XCEngine/main.cpp

221 lines
7.9 KiB
C++

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BattleFireDirect.h"
#include "StaticMeshComponent.h"
#include "stbi/stb_image.h"
#include "Utils.h"
#include "NanoVDBLoader.h"
#pragma comment(lib,"d3d12.lib")
#pragma comment(lib,"dxgi.lib")
#pragma comment(lib,"d3dcompiler.lib")
#pragma comment(lib,"winmm.lib")
LPCWSTR gWindowClassName = L"BattleFire";
void RunNanoVDBTest() {
ID3D12GraphicsCommandList* commandList = GetCommandList();
const char* vdbFiles[] = {
"Res/NanoVDB/bunny.nvdb"
};
for (int i = 0; i < sizeof(vdbFiles) / sizeof(vdbFiles[0]); i++) {
const char* currentVdbFile = vdbFiles[i];
printf("[NanoVDB Test] Loading: %s\n", currentVdbFile);
NanoVDBData vdbData;
bool loadSuccess = LoadNanoVDB(currentVdbFile, vdbData, commandList);
if (loadSuccess) {
printf(" SUCCESS - %llu bytes, %llu elements\n",
(unsigned long long)vdbData.byteSize,
(unsigned long long)vdbData.elementCount);
FreeNanoVDB(vdbData);
} else {
printf(" FAILED\n");
}
}
printf("[NanoVDB Test] Done.\n");
}
LRESULT CALLBACK WindowProc(HWND inHWND, UINT inMSG, WPARAM inWParam, LPARAM inLParam) {
switch (inMSG) {
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return DefWindowProc(inHWND, inMSG, inWParam, inLParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int inShowCmd) {
//register
WNDCLASSEX wndClassEx;
wndClassEx.cbSize = sizeof(WNDCLASSEX);
wndClassEx.style = CS_HREDRAW | CS_VREDRAW;
wndClassEx.cbClsExtra = NULL;//class
wndClassEx.cbWndExtra = NULL;//instance
wndClassEx.hInstance = hInstance;
wndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClassEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClassEx.hbrBackground = NULL;
wndClassEx.lpszMenuName = NULL;
wndClassEx.lpszClassName = gWindowClassName;
wndClassEx.lpfnWndProc = WindowProc;
if (!RegisterClassEx(&wndClassEx)) {
MessageBox(NULL, L"Register Class Failed!", L"Error", MB_OK | MB_ICONERROR);
return -1;
}
//create
int viewportWidth = 1280;
int viewportHeight = 720;
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = viewportWidth;
rect.bottom = viewportHeight;
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
int windowWidth = rect.right - rect.left;
int windowHeight = rect.bottom - rect.top;
HWND hwnd = CreateWindowEx(NULL,
gWindowClassName,
L"My Render Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
windowWidth, windowHeight,
NULL,
NULL,
hInstance,
NULL);
if (!hwnd) {
MessageBox(NULL, L"Create Window Failed!", L"Error", MB_OK | MB_ICONERROR);
return -1;
}
//show
InitD3D12(hwnd, 1280, 720);
ID3D12GraphicsCommandList* commandList = GetCommandList();
ID3D12CommandAllocator* commandAllocator = GetCommandAllocator();
StaticMeshComponent staticMeshComponent;
staticMeshComponent.InitFromFile(commandList, "Res/Model/Sphere.lhsm");
bool runTest = false; // set to true to run NanoVDB test
if (runTest) {
RunNanoVDBTest();
}
ID3D12RootSignature* rootSignature = InitRootSignature();
D3D12_SHADER_BYTECODE vs,gs,ps;
CreateShaderFromFile(L"Res/Shader/gs.hlsl", "MainVS", "vs_5_1", &vs);
CreateShaderFromFile(L"Res/Shader/gs.hlsl", "MainGS", "gs_5_1", &gs);
CreateShaderFromFile(L"Res/Shader/gs.hlsl", "MainPS", "ps_5_1", &ps);
ID3D12PipelineState*pso=CreatePSO(rootSignature, vs, ps, gs);
ID3D12Resource* cb = CreateConstantBufferObject(65536);//1024x64(4x4)
DirectX::XMMATRIX projectionMatrix=DirectX::XMMatrixPerspectiveFovLH(
(45.0f*3.141592f)/180.0f,1280.0f/720.0f,0.1f,1000.0f);
DirectX::XMMATRIX viewMatrix = DirectX::XMMatrixIdentity();
DirectX::XMMATRIX modelMatrix = DirectX::XMMatrixTranslation(0.0f,0.0f,5.0f);
//modelMatrix *= DirectX::XMMatrixRotationZ(90.0f*3.141592f/180.0f);
DirectX::XMFLOAT4X4 tempMatrix;
float matrices[64];
DirectX::XMStoreFloat4x4(&tempMatrix, projectionMatrix);
memcpy(matrices, &tempMatrix, sizeof(float) * 16);
DirectX::XMStoreFloat4x4(&tempMatrix, viewMatrix);
memcpy(matrices+16, &tempMatrix, sizeof(float) * 16);
DirectX::XMStoreFloat4x4(&tempMatrix, modelMatrix);
memcpy(matrices + 32, &tempMatrix, sizeof(float) * 16);;
DirectX::XMVECTOR determinant;
DirectX::XMMATRIX inverseModelMatrix = DirectX::XMMatrixInverse(&determinant, modelMatrix);
if (DirectX::XMVectorGetX(determinant) != 0.0f) {
DirectX::XMMATRIX normalMatrix = DirectX::XMMatrixTranspose(inverseModelMatrix);
DirectX::XMStoreFloat4x4(&tempMatrix, modelMatrix);
memcpy(matrices + 48, &tempMatrix, sizeof(float) * 16);;
}
UpdateConstantBuffer(cb, matrices, sizeof(float) * 64);
ID3D12Resource* sb = CreateConstantBufferObject(65536);//1024x64(4x4)
struct MaterialData {
float r;
};
MaterialData* materialDatas = new MaterialData[3000];
for (int i=0;i<3000;i++){
materialDatas[i].r = srandom() * 0.1f + 0.1f;//0.0~1.0
}
UpdateConstantBuffer(sb, materialDatas, sizeof(MaterialData) * 3000);
int imageWidth, imageHeight,imageChannel;
//stbi_set_flip_vertically_on_load(true);
stbi_uc* pixels = stbi_load("Res/Image/earth_d.jpg", &imageWidth, &imageHeight, &imageChannel, 4);
ID3D12Resource* texture = CreateTexture2D(commandList, pixels,
imageWidth * imageHeight * imageChannel, imageWidth, imageHeight,DXGI_FORMAT_R8G8B8A8_UNORM);
delete[]pixels;
ID3D12Device* d3dDevice = GetD3DDevice();
ID3D12DescriptorHeap* srvHeap = nullptr;
D3D12_DESCRIPTOR_HEAP_DESC d3dDescriptorHeapDescSRV = {};
d3dDescriptorHeapDescSRV.NumDescriptors = 3;
d3dDescriptorHeapDescSRV.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
d3dDescriptorHeapDescSRV.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
d3dDevice->CreateDescriptorHeap(&d3dDescriptorHeapDescSRV, IID_PPV_ARGS(&srvHeap));
ID3D12DescriptorHeap* descriptorHeaps[] = {srvHeap};
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
D3D12_CPU_DESCRIPTOR_HANDLE srvHeapPtr = srvHeap->GetCPUDescriptorHandleForHeapStart();
d3dDevice->CreateShaderResourceView(texture, &srvDesc, srvHeapPtr);
srvHeapPtr.ptr += d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
EndCommandList();
WaitForCompletionOfCommandList();
ShowWindow(hwnd, inShowCmd);
UpdateWindow(hwnd);
float color[] = {0.5f,0.5f,0.5f,1.0f};
MSG msg;
DWORD last_time = timeGetTime();
DWORD appStartTime = last_time;
while (true){
ZeroMemory(&msg, sizeof(MSG));
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
if (msg.message == WM_QUIT) {
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
//rendering
WaitForCompletionOfCommandList();
DWORD current_time = timeGetTime();//ms
DWORD frameTime = current_time - last_time;
DWORD timeSinceAppStartInMS = current_time - appStartTime;
last_time = current_time;
float frameTimeInSecond = float(frameTime) / 1000.0f;//second
float timeSinceAppStartInSecond = float(timeSinceAppStartInMS) / 1000.0f;
color[0] = timeSinceAppStartInSecond;
commandAllocator->Reset();
commandList->Reset(commandAllocator, nullptr);
BeginRenderToSwapChain(commandList);
//draw
commandList->SetPipelineState(pso);
commandList->SetGraphicsRootSignature(rootSignature);
commandList->SetDescriptorHeaps(_countof(descriptorHeaps),descriptorHeaps);
commandList->SetGraphicsRootConstantBufferView(0, cb->GetGPUVirtualAddress());
commandList->SetGraphicsRoot32BitConstants(1, 4, color, 0);
commandList->SetGraphicsRootDescriptorTable(2, srvHeap->GetGPUDescriptorHandleForHeapStart());
commandList->SetGraphicsRootShaderResourceView(3, sb->GetGPUVirtualAddress());
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
staticMeshComponent.Render(commandList);
EndRenderToSwapChain(commandList);
EndCommandList();
SwapD3D12Buffers();
}
}
return 0;
}