Skip to content

Commit

Permalink
Multiple mesh per model compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
PR3C14D0 committed Apr 12, 2023
1 parent 246f527 commit f04f6b6
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 76 deletions.
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
add_executable (Lumina "main.cpp" "public/Engine/Core.h" "private/Engine/Core.cpp" "public/Engine/Util.h" "public/Engine/ScreenQuad.h" "public/DirectXIncludes.h" "private/Engine/ScreenQuad.cpp" "public/Engine/Vertex.h" "public/Engine/Shader/Shader.h" "private/Engine/Shader/Shader.cpp" "public/Engine/Scene/Scene.h" "private/Engine/Scene/Scene.cpp" "public/Engine/GameObject/GameObject.h" "private/Engine/GameObject/GameObject.cpp" "public/Math/Vector3.h" "private/Math/Vector3.cpp" "public/Math/Transform.h" "private/Math/Transform.cpp" "public/Engine/Camera/Camera.h" "private/Engine/Camera/Camera.cpp" "public/Engine/Scene/SceneManager.h" "private/Engine/Scene/SceneManager.cpp" "public/Engine/ConstantBuffers.h" "public/Engine/GameObject/Component/Component.h" "public/Engine/GameObject/Component/Mesh.h" "private/Engine/GameObject/Component/Mesh.cpp" "private/Engine/GameObject/Component/Component.cpp" "public/Engine/Input.h" "private/Engine/Input.cpp" "private/Engine/Camera/EditorCamera.cpp" "public/Engine/Camera/EditorCamera.h" "public/Engine/Time.h" "private/Engine/Time.cpp" "public/Engine/Editor/Editor.h" "private/Engine/Editor/Editor.cpp")
add_executable (Lumina "main.cpp" "public/Engine/Core.h" "private/Engine/Core.cpp" "public/Engine/Util.h" "public/Engine/ScreenQuad.h" "public/DirectXIncludes.h" "private/Engine/ScreenQuad.cpp" "public/Engine/Vertex.h" "public/Engine/Shader/Shader.h" "private/Engine/Shader/Shader.cpp" "public/Engine/Scene/Scene.h" "private/Engine/Scene/Scene.cpp" "public/Engine/GameObject/GameObject.h" "private/Engine/GameObject/GameObject.cpp" "public/Math/Vector3.h" "private/Math/Vector3.cpp" "public/Math/Transform.h" "private/Math/Transform.cpp" "public/Engine/Camera/Camera.h" "private/Engine/Camera/Camera.cpp" "public/Engine/Scene/SceneManager.h" "private/Engine/Scene/SceneManager.cpp" "public/Engine/ConstantBuffers.h" "public/Engine/GameObject/Component/Component.h" "public/Engine/GameObject/Component/Mesh.h" "private/Engine/GameObject/Component/Mesh.cpp" "private/Engine/GameObject/Component/Component.cpp" "public/Engine/Input.h" "private/Engine/Input.cpp" "private/Engine/Camera/EditorCamera.cpp" "public/Engine/Camera/EditorCamera.h" "public/Engine/Time.h" "private/Engine/Time.cpp" "public/Engine/Editor/Editor.h" "private/Engine/Editor/Editor.cpp" "public/Engine/ResourceManager.h" "private/Engine/ResourceManager.cpp")

if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET Lumina PROPERTY CXX_STANDARD 20)
Expand Down
177 changes: 107 additions & 70 deletions src/private/Engine/GameObject/Component/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Mesh::Mesh(Transform* parentTransform) : Component::Component() {
this->samplerCPUHandle = this->core->GetDescriptorCPUHandle(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
this->samplerGPUHandle = this->core->GetDescriptorGPUHandle(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
this->nSamplerIncrementSize = this->core->GetDescriptorIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
this->resMgr = ResourceManager::GetInstance();
}

void Mesh::Start() {
Expand Down Expand Up @@ -160,62 +161,91 @@ void Mesh::InitPipeline() {
*/
void Mesh::Draw() {
this->list->SetGraphicsRootSignature(this->rootSig.Get());
this->list->IASetVertexBuffers(0, 1, &this->VBV);
this->list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
this->list->SetPipelineState(this->plState.Get());

D3D12_GPU_DESCRIPTOR_HANDLE cbuffHandle = CD3DX12_GPU_DESCRIPTOR_HANDLE(this->cbv_srvGPUHandle, this->nWVPIndex, this->nCBVHeapIncrementSize);
D3D12_GPU_DESCRIPTOR_HANDLE texSamplerHandle = CD3DX12_GPU_DESCRIPTOR_HANDLE(this->samplerGPUHandle, this->nSamplerIndex, this->nCBVHeapIncrementSize);
D3D12_GPU_DESCRIPTOR_HANDLE textureHandle = CD3DX12_GPU_DESCRIPTOR_HANDLE(this->cbv_srvGPUHandle, this->nTextureIndex, this->nCBVHeapIncrementSize);

this->list->SetGraphicsRootDescriptorTable(0, cbuffHandle);
this->list->SetGraphicsRootDescriptorTable(1, texSamplerHandle);
this->list->SetGraphicsRootDescriptorTable(2, textureHandle);

this->list->DrawInstanced(this->vertices.size(), 1, 0, 0);

int i = 0;
for (D3D12_VERTEX_BUFFER_VIEW VBV : this->VBVs) {
std::string texName = this->textureIndices[i];
UINT nTextureIndex = this->textureSrvIndices[texName];
this->list->IASetVertexBuffers(0, 1, &VBV);
D3D12_GPU_DESCRIPTOR_HANDLE textureHandle = CD3DX12_GPU_DESCRIPTOR_HANDLE(this->cbv_srvGPUHandle, nTextureIndex, this->nCBVHeapIncrementSize);
this->list->SetGraphicsRootDescriptorTable(2, textureHandle);

this->list->DrawInstanced(this->vertices[i].size(), 1, 0, 0);
i++;
}
}

void Mesh::UploadBuffers() {
UINT nVerticesSize = this->vertices.size() * sizeof(Vertex);

D3D12_HEAP_PROPERTIES heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
D3D12_RESOURCE_DESC resDesc = CD3DX12_RESOURCE_DESC::Buffer(nVerticesSize);

ThrowIfFailed(this->dev->CreateCommittedResource(
&heapProps,
D3D12_HEAP_FLAG_NONE,
&resDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(this->VBO.GetAddressOf())
));

this->VBO->SetName(L"Mesh VBO");

PVOID ms;
this->VBO->Map(NULL, nullptr, &ms);
memcpy(ms, this->vertices.data(), nVerticesSize);
this->VBO->Unmap(NULL, nullptr);

this->VBV.BufferLocation = this->VBO->GetGPUVirtualAddress();
this->VBV.SizeInBytes = nVerticesSize;
this->VBV.StrideInBytes = sizeof(Vertex);
for(std::pair<UINT, std::vector<Vertex>> vertex : this->vertices) {
std::vector<Vertex> vert = vertex.second;
UINT nVerticesSize = vert.size() * sizeof(Vertex);
ComPtr<ID3D12Resource> VBO;

D3D12_HEAP_PROPERTIES heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
D3D12_RESOURCE_DESC resDesc = CD3DX12_RESOURCE_DESC::Buffer(nVerticesSize);

ThrowIfFailed(this->dev->CreateCommittedResource(
&heapProps,
D3D12_HEAP_FLAG_NONE,
&resDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(VBO.GetAddressOf())
));

VBO->SetName(L"Mesh VBO");

PVOID ms;
VBO->Map(NULL, nullptr, &ms);
memcpy(ms, vert.data(), nVerticesSize);
VBO->Unmap(NULL, nullptr);

D3D12_VERTEX_BUFFER_VIEW VBV = { };

VBV.BufferLocation = VBO->GetGPUVirtualAddress();
VBV.SizeInBytes = nVerticesSize;
VBV.StrideInBytes = sizeof(Vertex);

this->VBOs.push_back(VBO);
this->VBVs.push_back(VBV);
}

return;
}

void Mesh::PrepareTextures() {
this->nTextureIndex = this->core->GetNewHeapIndex(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
D3D12_CPU_DESCRIPTOR_HANDLE textureCPUHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(this->cbv_srvCPUHandle, this->nTextureIndex, this->nCBVHeapIncrementSize);
std::vector<std::string> preparedTextures;
for (std::pair<UINT, std::string> tex : this->textureIndices) {
for (std::string preparedTex : preparedTextures) {
if (preparedTex == tex.second)
continue;
}

D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = { };
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Format = this->texture->GetDesc().Format;
ComPtr<ID3D12Resource> texture;
this->resMgr->GetResource(tex.second, texture);

this->dev->CreateShaderResourceView(this->texture.Get(), &srvDesc, textureCPUHandle);
UINT nTextureIndex = this->core->GetNewHeapIndex(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
D3D12_CPU_DESCRIPTOR_HANDLE textureCPUHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(this->cbv_srvCPUHandle, nTextureIndex, this->nCBVHeapIncrementSize);

D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = { };
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Format = texture->GetDesc().Format;

this->dev->CreateShaderResourceView(texture.Get(), &srvDesc, textureCPUHandle);

this->textureSrvIndices[tex.second] = nTextureIndex;
preparedTextures.push_back(tex.second);
}

D3D12_SAMPLER_DESC samplerDesc = { };
samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
Expand All @@ -229,7 +259,6 @@ void Mesh::PrepareTextures() {
D3D12_CPU_DESCRIPTOR_HANDLE texSamplerHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(this->samplerCPUHandle, this->nSamplerIndex, this->nSamplerIncrementSize);

this->dev->CreateSampler(&samplerDesc, texSamplerHandle);

return;
}

Expand Down Expand Up @@ -270,39 +299,47 @@ void Mesh::LoadFromFile(std::string file) {
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(file, NULL);

aiMesh* mesh = scene->mMeshes[0]; // TODO: Add multi-mesh support.
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];

for (int i = 0; i < mesh->mNumVertices; i++) {
aiVector3D vec = mesh->mVertices[i];
RGB pos = { vec.x, vec.y, vec.z };
RGB nml = { 0.f, 0.f, 0.f };
RG uv = { 0.f, 0.f };

if (mesh->HasNormals()) {
nml[0] = mesh->mNormals[i].x;
nml[1] = mesh->mNormals[i].y;
nml[2] = mesh->mNormals[i].z;
for (int i = 0; i < scene->mNumMeshes; i++) {
aiMesh* mesh = scene->mMeshes[i];
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
std::vector<Vertex> meshVert;

for (int i = 0; i < mesh->mNumVertices; i++) {
aiVector3D vec = mesh->mVertices[i];
RGB pos = { vec.x, vec.y, vec.z };
RGB nml = { 0.f, 0.f, 0.f };
RG uv = { 0.f, 0.f };

if (mesh->HasNormals()) {
nml[0] = mesh->mNormals[i].x;
nml[1] = mesh->mNormals[i].y;
nml[2] = mesh->mNormals[i].z;
}

if (mesh->HasTextureCoords(0)) {
uv[0] = mesh->mTextureCoords[0][i].x;
uv[1] = mesh->mTextureCoords[0][i].y;
}

Vertex vertex = { { pos[0], pos[1], pos[2] }, { nml[0], nml[1], nml[2] }, { uv[0], uv[1] } };
meshVert.push_back(vertex);
}

if (mesh->HasTextureCoords(0)) {
uv[0] = mesh->mTextureCoords[0][i].x;
uv[1] = mesh->mTextureCoords[0][i].y;
this->vertices[i] = meshVert;

/* Load our texture */
aiString texPath;
if (mat->GetTextureCount(aiTextureType_DIFFUSE) > 0 && mat->GetTexture(aiTextureType_DIFFUSE, 0, &texPath) == AI_SUCCESS) {
const aiTexture* tex = scene->GetEmbeddedTexture(texPath.C_Str());

if (!this->resMgr->ResourceExists(texPath.C_Str())) {
ResourceUploadBatch batch(this->dev.Get());
batch.Begin(D3D12_COMMAND_LIST_TYPE_DIRECT);
ThrowIfFailed(CreateWICTextureFromMemory(this->dev.Get(), batch, (BYTE*)tex->pcData, tex->mWidth, this->texture.GetAddressOf()));
batch.End(this->queue.Get());
this->resMgr->AddResource(this->texture, texPath.C_Str());
}
this->textureIndices[i] = texPath.C_Str();
}

Vertex vertex = { { pos[0], pos[1], pos[2] }, { nml[0], nml[1], nml[2] }, { uv[0], uv[1] } };
this->vertices.push_back(vertex);
}

/* Load our texture */
aiString texPath;
if (mat->GetTextureCount(aiTextureType_DIFFUSE) > 0 && mat->GetTexture(aiTextureType_DIFFUSE, 0, &texPath) == AI_SUCCESS) {
const aiTexture* tex = scene->GetEmbeddedTexture(texPath.C_Str());

ResourceUploadBatch batch(this->dev.Get());
batch.Begin(D3D12_COMMAND_LIST_TYPE_DIRECT);
ThrowIfFailed(CreateWICTextureFromMemory(this->dev.Get(), batch, (BYTE*)tex->pcData, tex->mWidth, this->texture.GetAddressOf()));
batch.End(this->queue.Get());
}

this->bMeshLoaded = true;
Expand Down
37 changes: 37 additions & 0 deletions src/private/Engine/ResourceManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "Engine/ResourceManager.h"

ResourceManager* ResourceManager::instance;

ResourceManager::ResourceManager() {

}

bool ResourceManager::ResourceExists(std::string name) {
if (this->resources.size() > 0) {
if (this->resources.count(name) > 0)
return true;
}

return false;
}

void ResourceManager::AddResource(ComPtr<ID3D12Resource>& resource, std::string name) {
if (this->ResourceExists(name))
return;

this->resources[name] = resource;
return;
}

void ResourceManager::GetResource(std::string name, ComPtr<ID3D12Resource>& resource) {
if (this->ResourceExists(name))
resource = this->resources[name];

return;
}

ResourceManager* ResourceManager::GetInstance() {
if (ResourceManager::instance == nullptr)
ResourceManager::instance = new ResourceManager();
return ResourceManager::instance;
}
16 changes: 11 additions & 5 deletions src/public/Engine/GameObject/Component/Mesh.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include <iostream>
#include <vector>
#include <map>
#include "Engine/GameObject/Component/Component.h"
#include "Math/Transform.h"
#include "DirectXIncludes.h"
Expand All @@ -12,6 +13,7 @@
#include <dxtk/ResourceUploadBatch.h>
#include <dxtk/WICTextureLoader.h>
#include "Engine/ConstantBuffers.h"
#include "Engine/ResourceManager.h"

class Core;
class SceneManager;
Expand All @@ -25,18 +27,20 @@ class Mesh : public Component {
ComPtr<ID3D12GraphicsCommandList> list;
ComPtr<ID3D12CommandQueue> queue;

ComPtr<ID3D12Resource> texture; // TODO: Allow multiple textures.
UINT nTextureIndex;
ComPtr<ID3D12Resource> texture;
UINT nSamplerIndex;

ComPtr<ID3D12Resource> VBO; // TODO: Allow multiple vertex buffers.
D3D12_VERTEX_BUFFER_VIEW VBV;
std::vector<ComPtr<ID3D12Resource>> VBOs;
std::vector<D3D12_VERTEX_BUFFER_VIEW> VBVs;

ComPtr<ID3D12RootSignature> rootSig;

std::map<UINT, std::string> textureIndices;
std::map<std::string, UINT> textureSrvIndices;

ComPtr<ID3D12PipelineState> plState;

std::vector<Vertex> vertices;
std::map<UINT, std::vector<Vertex>> vertices;

Shader* shader;
void InitPipeline();
Expand All @@ -61,6 +65,8 @@ class Mesh : public Component {
void InitCBuffer();
void UpdateCBuffer();
void PrepareTextures();

ResourceManager* resMgr;
public:
Mesh(Transform* parentTransform);

Expand Down
21 changes: 21 additions & 0 deletions src/public/Engine/ResourceManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once
#include <iostream>
#include <map>
#include <wrl.h>
#include "DirectXIncludes.h"

using namespace Microsoft::WRL;

class ResourceManager {
private:
std::map<std::string, ComPtr<ID3D12Resource>> resources;

static ResourceManager* instance;
public:
ResourceManager();
static ResourceManager* GetInstance();

bool ResourceExists(std::string name);
void AddResource(ComPtr<ID3D12Resource>& resource, std::string name);
void GetResource(std::string name, ComPtr<ID3D12Resource>& resource);
};

0 comments on commit f04f6b6

Please sign in to comment.