Model.cpp 9.8 KB

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