Model.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include "anki/resource/Model.h"
  6. #include "anki/resource/ResourceManager.h"
  7. #include "anki/resource/Material.h"
  8. #include "anki/resource/Mesh.h"
  9. #include "anki/resource/MeshLoader.h"
  10. #include "anki/resource/ShaderResource.h"
  11. #include "anki/misc/Xml.h"
  12. #include "anki/util/Logger.h"
  13. #include "anki/renderer/Ms.h"
  14. #include "anki/renderer/Is.h"
  15. #include "anki/renderer/Sm.h"
  16. namespace anki {
  17. //==============================================================================
  18. // Misc =
  19. //==============================================================================
  20. /// Visit the textures to bind them
  21. class UpdateTexturesVisitor
  22. {
  23. public:
  24. U m_count = 0;
  25. ResourceGroupInitializer* m_init = nullptr;
  26. template<typename TMaterialVariableTemplate>
  27. Error visit(const TMaterialVariableTemplate& var)
  28. {
  29. // Do nothing
  30. return ErrorCode::NONE;
  31. }
  32. };
  33. // Specialize for texture
  34. template<>
  35. Error UpdateTexturesVisitor
  36. ::visit<MaterialVariableTemplate<TextureResourcePtr>>(
  37. const MaterialVariableTemplate<TextureResourcePtr>& var)
  38. {
  39. m_init->m_textures[m_count++].m_texture =
  40. (*var.begin())->getGlTexture();
  41. return ErrorCode::NONE;
  42. }
  43. //==============================================================================
  44. // ModelPatch =
  45. //==============================================================================
  46. //==============================================================================
  47. ModelPatch::~ModelPatch()
  48. {}
  49. //==============================================================================
  50. void ModelPatch::getRenderingDataSub(
  51. const RenderingKey& key,
  52. SArray<U8> subMeshIndicesArray,
  53. ResourceGroupPtr& resourceGroup,
  54. PipelinePtr& ppline,
  55. Array<U32, ANKI_GL_MAX_SUB_DRAWCALLS>& indicesCountArray,
  56. Array<PtrSize, ANKI_GL_MAX_SUB_DRAWCALLS>& indicesOffsetArray,
  57. U32& drawcallCount) const
  58. {
  59. // Get the resources
  60. RenderingKey meshKey = key;
  61. meshKey.m_lod = min<U>(key.m_lod, m_meshCount - 1);
  62. const Mesh& mesh = getMesh(meshKey);
  63. resourceGroup = m_grResources[meshKey.m_lod];
  64. // Get ppline
  65. RenderingKey mtlKey = key;
  66. mtlKey.m_lod = min<U>(key.m_lod, m_mtl->getLodCount() - 1);
  67. ppline = getPipeline(mtlKey);
  68. if(subMeshIndicesArray.getSize() == 0 || mesh.getSubMeshesCount() == 0)
  69. {
  70. drawcallCount = 1;
  71. indicesOffsetArray[0] = 0;
  72. indicesCountArray[0] = mesh.getIndicesCount();
  73. }
  74. else
  75. {
  76. ANKI_ASSERT(0 && "TODO");
  77. }
  78. }
  79. //==============================================================================
  80. U ModelPatch::getLodCount() const
  81. {
  82. return max<U>(m_meshCount, getMaterial().getLodCount());
  83. }
  84. //==============================================================================
  85. Error ModelPatch::create(
  86. SArray<CString> meshFNames,
  87. const CString& mtlFName,
  88. ResourceManager* manager)
  89. {
  90. ANKI_ASSERT(meshFNames.getSize() > 0);
  91. // Load material
  92. ANKI_CHECK(m_mtl.load(mtlFName, manager));
  93. // Iterate material variables for textures
  94. ResourceGroupInitializer rcinit;
  95. UpdateTexturesVisitor visitor;
  96. visitor.m_init = &rcinit;
  97. for(const auto& var : m_mtl->getVariables())
  98. {
  99. Error err = var->acceptVisitor(visitor);
  100. (void)err;
  101. }
  102. // Load meshes and update resource group
  103. m_meshCount = 0;
  104. for(U i = 0; i < meshFNames.getSize(); i++)
  105. {
  106. ANKI_CHECK(m_meshes[i].load(meshFNames[i], manager));
  107. // Sanity check
  108. if(i > 0 && !m_meshes[i]->isCompatible(*m_meshes[i - 1]))
  109. {
  110. ANKI_LOGE("Meshes not compatible");
  111. return ErrorCode::USER_DATA;
  112. }
  113. rcinit.m_vertexBuffers[0].m_buffer = m_meshes[i]->getVertexBuffer();
  114. rcinit.m_indexBuffer.m_buffer = m_meshes[i]->getIndexBuffer();
  115. m_grResources[i] =
  116. manager->getGrManager().newInstance<ResourceGroup>(rcinit);
  117. ++m_meshCount;
  118. }
  119. return ErrorCode::NONE;
  120. }
  121. //==============================================================================
  122. PipelinePtr ModelPatch::getPipeline(const RenderingKey& key) const
  123. {
  124. // Preconditions
  125. ANKI_ASSERT(key.m_lod < m_mtl->getLodCount());
  126. if(key.m_tessellation && !m_mtl->getTessellationEnabled())
  127. {
  128. ANKI_ASSERT(0);
  129. }
  130. if(key.m_pass == Pass::SM && !m_mtl->getShadowEnabled())
  131. {
  132. ANKI_ASSERT(0);
  133. }
  134. PipelinePtr& ppline =
  135. m_pplines[U(key.m_pass)][key.m_lod][key.m_tessellation];
  136. // Lazily create it
  137. if(ANKI_UNLIKELY(!ppline.isCreated()))
  138. {
  139. PipelineInitializer pplineInit;
  140. computePipelineInitializer(key, pplineInit);
  141. pplineInit.m_shaders[U(ShaderType::VERTEX)] =
  142. m_mtl->getShader(key, ShaderType::VERTEX);
  143. if(key.m_tessellation)
  144. {
  145. pplineInit.m_shaders[U(ShaderType::TESSELLATION_CONTROL)] =
  146. m_mtl->getShader(key, ShaderType::TESSELLATION_CONTROL);
  147. pplineInit.m_shaders[U(ShaderType::TESSELLATION_EVALUATION)] =
  148. m_mtl->getShader(key, ShaderType::TESSELLATION_EVALUATION);
  149. }
  150. pplineInit.m_shaders[U(ShaderType::FRAGMENT)] =
  151. m_mtl->getShader(key, ShaderType::FRAGMENT);
  152. // Create
  153. ppline = m_model->getManager().getGrManager()
  154. .newInstance<Pipeline>(pplineInit);
  155. }
  156. return ppline;
  157. }
  158. //==============================================================================
  159. void ModelPatch::computePipelineInitializer(
  160. const RenderingKey& key, PipelineInitializer& pinit) const
  161. {
  162. //
  163. // Vertex state
  164. //
  165. VertexStateInfo& vert = pinit.m_vertex;
  166. if(m_meshes[0]->hasBoneWeights())
  167. {
  168. ANKI_ASSERT(0 && "TODO");
  169. }
  170. else
  171. {
  172. vert.m_bindingCount = 1;
  173. vert.m_attributeCount = 4;
  174. vert.m_bindings[0].m_stride =
  175. sizeof(Vec3) + sizeof(HVec2) + 2 * sizeof(U32);
  176. vert.m_attributes[0].m_format = PixelFormat(
  177. ComponentFormat::R32G32B32, TransformFormat::FLOAT);
  178. vert.m_attributes[0].m_offset = 0;
  179. vert.m_attributes[1].m_format = PixelFormat(
  180. ComponentFormat::R16G16, TransformFormat::FLOAT);
  181. vert.m_attributes[1].m_offset = sizeof(Vec3);
  182. if(key.m_pass == Pass::MS_FS)
  183. {
  184. vert.m_attributes[2].m_format = PixelFormat(
  185. ComponentFormat::R10G10B10A2, TransformFormat::SNORM);
  186. vert.m_attributes[2].m_offset = sizeof(Vec3) + sizeof(U32);
  187. vert.m_attributes[3].m_format = PixelFormat(
  188. ComponentFormat::R10G10B10A2, TransformFormat::SNORM);
  189. vert.m_attributes[3].m_offset = sizeof(Vec3) + sizeof(U32) * 2;
  190. }
  191. else
  192. {
  193. vert.m_attributeCount = 2;
  194. }
  195. }
  196. //
  197. // Depth/stencil state
  198. //
  199. DepthStencilStateInfo& ds = pinit.m_depthStencil;
  200. if(key.m_pass == Pass::SM)
  201. {
  202. ds.m_format = Sm::DEPTH_RT_PIXEL_FORMAT;
  203. ds.m_polygonOffsetFactor = 7.0;
  204. ds.m_polygonOffsetUnits = 5.0;
  205. }
  206. else if(m_mtl->getForwardShading())
  207. {
  208. ds.m_format = Ms::DEPTH_RT_PIXEL_FORMAT;
  209. ds.m_depthWriteEnabled = false;
  210. }
  211. else
  212. {
  213. ds.m_format = Ms::DEPTH_RT_PIXEL_FORMAT;
  214. }
  215. //
  216. // Color state
  217. //
  218. ColorStateInfo& color = pinit.m_color;
  219. if(key.m_pass == Pass::SM)
  220. {
  221. // Default
  222. }
  223. else if(m_mtl->getForwardShading())
  224. {
  225. color.m_attachmentCount = 1;
  226. color.m_attachments[0].m_format = Is::RT_PIXEL_FORMAT;
  227. color.m_attachments[0].m_srcBlendMethod = BlendMethod::SRC_ALPHA;
  228. color.m_attachments[0].m_dstBlendMethod =
  229. BlendMethod::ONE_MINUS_SRC_ALPHA;
  230. }
  231. else
  232. {
  233. color.m_attachmentCount = Ms::ATTACHMENT_COUNT;
  234. ANKI_ASSERT(Ms::ATTACHMENT_COUNT == 3);
  235. color.m_attachments[0].m_format = Ms::RT_PIXEL_FORMATS[0];
  236. color.m_attachments[1].m_format = Ms::RT_PIXEL_FORMATS[1];
  237. color.m_attachments[2].m_format = Ms::RT_PIXEL_FORMATS[2];
  238. }
  239. }
  240. //==============================================================================
  241. // Model =
  242. //==============================================================================
  243. //==============================================================================
  244. Model::~Model()
  245. {
  246. auto alloc = getAllocator();
  247. for(ModelPatch* patch : m_modelPatches)
  248. {
  249. alloc.deleteInstance(patch);
  250. }
  251. m_modelPatches.destroy(alloc);
  252. }
  253. //==============================================================================
  254. Error Model::load(const ResourceFilename& filename)
  255. {
  256. auto alloc = getAllocator();
  257. // Load
  258. //
  259. XmlElement el;
  260. XmlDocument doc;
  261. ANKI_CHECK(openFileParseXml(filename, doc));
  262. XmlElement rootEl;
  263. ANKI_CHECK(doc.getChildElement("model", rootEl));
  264. // <modelPatches>
  265. XmlElement modelPatchesEl;
  266. ANKI_CHECK(rootEl.getChildElement("modelPatches", modelPatchesEl));
  267. XmlElement modelPatchEl;
  268. ANKI_CHECK(modelPatchesEl.getChildElement("modelPatch", modelPatchEl));
  269. // Count
  270. U count = 0;
  271. do
  272. {
  273. ++count;
  274. // Move to next
  275. ANKI_CHECK(
  276. modelPatchEl.getNextSiblingElement("modelPatch", modelPatchEl));
  277. } while(modelPatchEl);
  278. // Check number of model patches
  279. if(count < 1)
  280. {
  281. ANKI_LOGE("Zero number of model patches");
  282. return ErrorCode::USER_DATA;
  283. }
  284. m_modelPatches.create(alloc, count);
  285. count = 0;
  286. ANKI_CHECK(modelPatchesEl.getChildElement("modelPatch", modelPatchEl));
  287. do
  288. {
  289. XmlElement materialEl;
  290. ANKI_CHECK(modelPatchEl.getChildElement("material", materialEl));
  291. Array<CString, 3> meshesFnames;
  292. U meshesCount = 1;
  293. // Get mesh
  294. XmlElement meshEl;
  295. ANKI_CHECK(modelPatchEl.getChildElement("mesh", meshEl));
  296. XmlElement meshEl1;
  297. ANKI_CHECK(modelPatchEl.getChildElementOptional("mesh1", meshEl1));
  298. XmlElement meshEl2;
  299. ANKI_CHECK(modelPatchEl.getChildElementOptional("mesh2", meshEl2));
  300. ANKI_CHECK(meshEl.getText(meshesFnames[0]));
  301. if(meshEl1)
  302. {
  303. ++meshesCount;
  304. ANKI_CHECK(meshEl1.getText(meshesFnames[1]));
  305. }
  306. if(meshEl2)
  307. {
  308. ++meshesCount;
  309. ANKI_CHECK(meshEl2.getText(meshesFnames[2]));
  310. }
  311. CString cstr;
  312. ANKI_CHECK(materialEl.getText(cstr));
  313. ModelPatch* mpatch = alloc.newInstance<ModelPatch>(this);
  314. if(mpatch == nullptr)
  315. {
  316. return ErrorCode::OUT_OF_MEMORY;
  317. }
  318. ANKI_CHECK(mpatch->create(
  319. SArray<CString>(&meshesFnames[0], meshesCount), cstr,
  320. &getManager()));
  321. m_modelPatches[count++] = mpatch;
  322. // Move to next
  323. ANKI_CHECK(
  324. modelPatchEl.getNextSiblingElement("modelPatch", modelPatchEl));
  325. } while(modelPatchEl);
  326. // Calculate compound bounding volume
  327. RenderingKey key;
  328. key.m_lod = 0;
  329. m_visibilityShape = m_modelPatches[0]->getMesh(key).getBoundingShape();
  330. for(auto it = m_modelPatches.begin() + 1;
  331. it != m_modelPatches.end();
  332. ++it)
  333. {
  334. m_visibilityShape = m_visibilityShape.getCompoundShape(
  335. (*it)->getMesh(key).getBoundingShape());
  336. }
  337. return ErrorCode::NONE;
  338. }
  339. } // end namespace anki