Add NanoVDBLoader with test support
This commit is contained in:
@@ -11,6 +11,7 @@ set(SOURCES
|
||||
StaticMeshComponent.cpp
|
||||
Utils.cpp
|
||||
stbi/stb_image.cpp
|
||||
NanoVDBLoader.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
|
||||
117
NanoVDBLoader.cpp
Normal file
117
NanoVDBLoader.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#define NOMINMAX
|
||||
#include "NanoVDBLoader.h"
|
||||
#include <windows.h>
|
||||
#include "BattleFireDirect.h"
|
||||
#include <nanovdb/io/IO.h>
|
||||
#include <nanovdb/GridHandle.h>
|
||||
#include <nanovdb/HostBuffer.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
bool LoadNanoVDB(const char* filePath, NanoVDBData& outData, ID3D12GraphicsCommandList* cmdList) {
|
||||
try {
|
||||
nanovdb::GridHandle<nanovdb::HostBuffer> gridHandle = nanovdb::io::readGrid(filePath);
|
||||
|
||||
const uint64_t byteSize = gridHandle.buffer().bufferSize();
|
||||
const uint64_t elementCount = byteSize / sizeof(uint32_t);
|
||||
|
||||
void* bufferData = malloc(byteSize);
|
||||
if (!bufferData) {
|
||||
std::cerr << "Failed to allocate memory for NanoVDB" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(bufferData, gridHandle.buffer().data(), byteSize);
|
||||
|
||||
outData.cpuData = bufferData;
|
||||
outData.byteSize = byteSize;
|
||||
outData.elementCount = elementCount;
|
||||
|
||||
ID3D12Device* device = GetD3DDevice();
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
|
||||
D3D12_RESOURCE_DESC resourceDesc = {};
|
||||
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
resourceDesc.Width = byteSize;
|
||||
resourceDesc.Height = 1;
|
||||
resourceDesc.DepthOrArraySize = 1;
|
||||
resourceDesc.MipLevels = 1;
|
||||
resourceDesc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
resourceDesc.SampleDesc.Count = 1;
|
||||
|
||||
HRESULT hr = device->CreateCommittedResource(
|
||||
&heapProps,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&outData.gpuBuffer)
|
||||
);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
std::cerr << "Failed to create GPU buffer for NanoVDB" << std::endl;
|
||||
free(bufferData);
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES uploadHeapProps = {};
|
||||
uploadHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
|
||||
ID3D12Resource* uploadBuffer = nullptr;
|
||||
hr = device->CreateCommittedResource(
|
||||
&uploadHeapProps,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&resourceDesc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&uploadBuffer)
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
void* mappedData = nullptr;
|
||||
D3D12_RANGE readRange = {0, 0};
|
||||
uploadBuffer->Map(0, &readRange, &mappedData);
|
||||
memcpy(mappedData, bufferData, byteSize);
|
||||
uploadBuffer->Unmap(0, nullptr);
|
||||
|
||||
cmdList->CopyBufferRegion(outData.gpuBuffer, 0, uploadBuffer, 0, byteSize);
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Transition.pResource = outData.gpuBuffer;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_GENERIC_READ;
|
||||
cmdList->ResourceBarrier(1, &barrier);
|
||||
|
||||
uploadBuffer->Release();
|
||||
}
|
||||
|
||||
std::cout << "[NanoVDB] Loaded: " << byteSize << " bytes, " << elementCount << " elements" << std::endl;
|
||||
std::cout.flush();
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "[NanoVDB] Error: " << e.what() << std::endl;
|
||||
std::cerr.flush();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void FreeNanoVDB(NanoVDBData& data) {
|
||||
if (data.gpuBuffer) {
|
||||
data.gpuBuffer->Release();
|
||||
data.gpuBuffer = nullptr;
|
||||
}
|
||||
if (data.cpuData) {
|
||||
free(data.cpuData);
|
||||
data.cpuData = nullptr;
|
||||
}
|
||||
data.byteSize = 0;
|
||||
data.elementCount = 0;
|
||||
}
|
||||
|
||||
|
||||
15
NanoVDBLoader.h
Normal file
15
NanoVDBLoader.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <d3d12.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct NanoVDBData {
|
||||
ID3D12Resource* gpuBuffer;
|
||||
void* cpuData;
|
||||
uint64_t byteSize;
|
||||
uint64_t elementCount;
|
||||
};
|
||||
|
||||
bool LoadNanoVDB(const char* filePath, NanoVDBData& outData, ID3D12GraphicsCommandList* cmdList = nullptr);
|
||||
void FreeNanoVDB(NanoVDBData& data);
|
||||
|
||||
43
main.cpp
43
main.cpp
@@ -1,8 +1,11 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.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")
|
||||
@@ -11,6 +14,35 @@
|
||||
|
||||
LPCWSTR gWindowClassName = L"BattleFire";
|
||||
|
||||
void RunNanoVDBTest() {
|
||||
ID3D12GraphicsCommandList* commandList = GetCommandList();
|
||||
const char* vdbFiles[] = {
|
||||
"Res/NanoVDB/sphere2.nvdb",
|
||||
"Res/NanoVDB/bunny.nvdb",
|
||||
"Res/NanoVDB/torus_knot_helix.nvdb",
|
||||
"Res/NanoVDB/boat_points.nvdb",
|
||||
"Res/NanoVDB/explosion.nvdb",
|
||||
"Res/NanoVDB/nano_wdas_cloud_half.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:
|
||||
@@ -70,6 +102,17 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
|
||||
StaticMeshComponent staticMeshComponent;
|
||||
staticMeshComponent.InitFromFile(commandList, "Res/Model/Sphere.lhsm");
|
||||
|
||||
bool runTest = false;
|
||||
for (int i = 0; i < __argc; i++) {
|
||||
if (strcmp(__argv[i], "-test") == 0) {
|
||||
runTest = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (runTest) {
|
||||
RunNanoVDBTest();
|
||||
}
|
||||
|
||||
ID3D12RootSignature* rootSignature = InitRootSignature();
|
||||
D3D12_SHADER_BYTECODE vs,gs,ps;
|
||||
CreateShaderFromFile(L"Res/Shader/gs.hlsl", "MainVS", "vs_5_1", &vs);
|
||||
|
||||
Reference in New Issue
Block a user