core: Use vkd3d_instance_get_vk_instance().
[vkmodelviewer.git] / Model / ModelH3D.cpp
blob4f3da546b658dd86e3304729f5ac88699d9b22cd
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // This code is licensed under the MIT License (MIT).
4 // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
5 // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
6 // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
7 // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
8 //
9 // Developed by Minigraph
11 // Author: Alex Nankervis
14 #include "pch.h"
15 #include "Model.h"
16 #include "Utility.h"
17 #include "TextureManager.h"
18 #include "GraphicsCore.h"
19 #include "DescriptorHeap.h"
20 #include "CommandContext.h"
21 #include <stdio.h>
23 using namespace Graphics;
25 bool Model::LoadH3D(const char *filename)
27 FILE *file = nullptr;
28 if (0 != fopen_s(&file, filename, "rb"))
29 return false;
31 bool ok = false;
33 if (1 != fread(&m_Header, sizeof(Header), 1, file)) goto h3d_load_fail;
35 m_pMesh = new Mesh [m_Header.meshCount];
36 m_pMaterial = new Material [m_Header.materialCount];
38 if (m_Header.meshCount > 0)
39 if (1 != fread(m_pMesh, sizeof(Mesh) * m_Header.meshCount, 1, file)) goto h3d_load_fail;
40 if (m_Header.materialCount > 0)
41 if (1 != fread(m_pMaterial, sizeof(Material) * m_Header.materialCount, 1, file)) goto h3d_load_fail;
43 m_VertexStride = m_pMesh[0].vertexStride;
44 m_VertexStrideDepth = m_pMesh[0].vertexStrideDepth;
45 #if _DEBUG
46 for (uint32_t meshIndex = 1; meshIndex < m_Header.meshCount; ++meshIndex)
48 const Mesh& mesh = m_pMesh[meshIndex];
49 ASSERT(mesh.vertexStride == m_VertexStride);
50 ASSERT(mesh.vertexStrideDepth == m_VertexStrideDepth);
52 for (uint32_t meshIndex = 0; meshIndex < m_Header.meshCount; ++meshIndex)
54 const Mesh& mesh = m_pMesh[meshIndex];
56 ASSERT( mesh.attribsEnabled ==
57 (attrib_mask_position | attrib_mask_texcoord0 | attrib_mask_normal | attrib_mask_tangent | attrib_mask_bitangent) );
58 ASSERT(mesh.attrib[0].components == 3 && mesh.attrib[0].format == Model::attrib_format_float); // position
59 ASSERT(mesh.attrib[1].components == 2 && mesh.attrib[1].format == Model::attrib_format_float); // texcoord0
60 ASSERT(mesh.attrib[2].components == 3 && mesh.attrib[2].format == Model::attrib_format_float); // normal
61 ASSERT(mesh.attrib[3].components == 3 && mesh.attrib[3].format == Model::attrib_format_float); // tangent
62 ASSERT(mesh.attrib[4].components == 3 && mesh.attrib[4].format == Model::attrib_format_float); // bitangent
64 ASSERT( mesh.attribsEnabledDepth ==
65 (attrib_mask_position) );
66 ASSERT(mesh.attrib[0].components == 3 && mesh.attrib[0].format == Model::attrib_format_float); // position
68 #endif
70 m_pVertexData = new unsigned char[ m_Header.vertexDataByteSize ];
71 m_pIndexData = new unsigned char[ m_Header.indexDataByteSize ];
72 m_pVertexDataDepth = new unsigned char[ m_Header.vertexDataByteSizeDepth ];
73 m_pIndexDataDepth = new unsigned char[ m_Header.indexDataByteSize ];
75 if (m_Header.vertexDataByteSize > 0)
76 if (1 != fread(m_pVertexData, m_Header.vertexDataByteSize, 1, file)) goto h3d_load_fail;
77 if (m_Header.indexDataByteSize > 0)
78 if (1 != fread(m_pIndexData, m_Header.indexDataByteSize, 1, file)) goto h3d_load_fail;
80 if (m_Header.vertexDataByteSizeDepth > 0)
81 if (1 != fread(m_pVertexDataDepth, m_Header.vertexDataByteSizeDepth, 1, file)) goto h3d_load_fail;
82 if (m_Header.indexDataByteSize > 0)
83 if (1 != fread(m_pIndexDataDepth, m_Header.indexDataByteSize, 1, file)) goto h3d_load_fail;
85 m_VertexBuffer.Create(L"VertexBuffer", m_Header.vertexDataByteSize / m_VertexStride, m_VertexStride, m_pVertexData);
86 m_IndexBuffer.Create(L"IndexBuffer", m_Header.indexDataByteSize / sizeof(uint16_t), sizeof(uint16_t), m_pIndexData);
87 delete [] m_pVertexData;
88 m_pVertexData = nullptr;
89 delete [] m_pIndexData;
90 m_pIndexData = nullptr;
92 m_VertexBufferDepth.Create(L"VertexBufferDepth", m_Header.vertexDataByteSizeDepth / m_VertexStrideDepth, m_VertexStrideDepth, m_pVertexDataDepth);
93 m_IndexBufferDepth.Create(L"IndexBufferDepth", m_Header.indexDataByteSize / sizeof(uint16_t), sizeof(uint16_t), m_pIndexDataDepth);
94 delete [] m_pVertexDataDepth;
95 m_pVertexDataDepth = nullptr;
96 delete [] m_pIndexDataDepth;
97 m_pIndexDataDepth = nullptr;
99 LoadTextures();
101 ok = true;
103 h3d_load_fail:
105 if (EOF == fclose(file))
106 ok = false;
108 return ok;
111 bool Model::SaveH3D(const char *filename) const
113 FILE *file = nullptr;
114 if (0 != fopen_s(&file, filename, "wb"))
115 return false;
117 bool ok = false;
119 if (1 != fwrite(&m_Header, sizeof(Header), 1, file)) goto h3d_save_fail;
121 if (m_Header.meshCount > 0)
122 if (1 != fwrite(m_pMesh, sizeof(Mesh) * m_Header.meshCount, 1, file)) goto h3d_save_fail;
123 if (m_Header.materialCount > 0)
124 if (1 != fwrite(m_pMaterial, sizeof(Material) * m_Header.materialCount, 1, file)) goto h3d_save_fail;
126 if (m_Header.vertexDataByteSize > 0)
127 if (1 != fwrite(m_pVertexData, m_Header.vertexDataByteSize, 1, file)) goto h3d_save_fail;
128 if (m_Header.indexDataByteSize > 0)
129 if (1 != fwrite(m_pIndexData, m_Header.indexDataByteSize, 1, file)) goto h3d_save_fail;
131 if (m_Header.vertexDataByteSizeDepth > 0)
132 if (1 != fwrite(m_pVertexDataDepth, m_Header.vertexDataByteSizeDepth, 1, file)) goto h3d_save_fail;
133 if (m_Header.indexDataByteSize > 0)
134 if (1 != fwrite(m_pIndexDataDepth, m_Header.indexDataByteSize, 1, file)) goto h3d_save_fail;
136 ok = true;
138 h3d_save_fail:
140 if (EOF == fclose(file))
141 ok = false;
143 return ok;
146 void Model::ReleaseTextures()
149 if (m_Textures != nullptr)
151 for (uint32_t materialIdx = 0; materialIdx < m_Header.materialCount; ++materialIdx)
153 for (int n = 0; n < Material::texCount; n++)
155 if (m_Textures[materialIdx * Material::texCount + n])
156 m_Textures[materialIdx * Material::texCount + n]->Release();
157 m_Textures[materialIdx * Material::texCount + n] = nullptr;
160 delete [] m_Textures;
165 void Model::LoadTextures(void)
167 ReleaseTextures();
169 m_SRVs = new D3D12_CPU_DESCRIPTOR_HANDLE[m_Header.materialCount * 6];
171 const ManagedTexture* MatTextures[6] = {};
173 for (uint32_t materialIdx = 0; materialIdx < m_Header.materialCount; ++materialIdx)
175 const Material& pMaterial = m_pMaterial[materialIdx];
177 // Load diffuse
178 MatTextures[0] = TextureManager::LoadFromFile(pMaterial.texDiffusePath, true);
179 if (!MatTextures[0]->IsValid())
180 MatTextures[0] = TextureManager::LoadFromFile("default", true);
182 // Load specular
183 MatTextures[1] = TextureManager::LoadFromFile(pMaterial.texSpecularPath, true);
184 if (!MatTextures[1]->IsValid())
186 MatTextures[1] = TextureManager::LoadFromFile(std::string(pMaterial.texDiffusePath) + "_specular", true);
187 if (!MatTextures[1]->IsValid())
188 MatTextures[1] = TextureManager::LoadFromFile("default_specular", true);
191 // Load emissive
192 //MatTextures[2] = TextureManager::LoadFromFile(pMaterial.texEmissivePath, true);
194 // Load normal
195 MatTextures[3] = TextureManager::LoadFromFile(pMaterial.texNormalPath, false);
196 if (!MatTextures[3]->IsValid())
198 MatTextures[3] = TextureManager::LoadFromFile(std::string(pMaterial.texDiffusePath) + "_normal", false);
199 if (!MatTextures[3]->IsValid())
200 MatTextures[3] = TextureManager::LoadFromFile("default_normal", false);
203 // Load lightmap
204 //MatTextures[4] = TextureManager::LoadFromFile(pMaterial.texLightmapPath, true);
206 // Load reflection
207 //MatTextures[5] = TextureManager::LoadFromFile(pMaterial.texReflectionPath, true);
209 m_SRVs[materialIdx * 6 + 0] = MatTextures[0]->GetSRV();
210 m_SRVs[materialIdx * 6 + 1] = MatTextures[1]->GetSRV();
211 m_SRVs[materialIdx * 6 + 2] = MatTextures[0]->GetSRV();
212 m_SRVs[materialIdx * 6 + 3] = MatTextures[3]->GetSRV();
213 m_SRVs[materialIdx * 6 + 4] = MatTextures[0]->GetSRV();
214 m_SRVs[materialIdx * 6 + 5] = MatTextures[0]->GetSRV();