MaterialParser.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include "MaterialParser.h"
  2. #include "TextureParser.h"
  3. #include "WallpaperEngine/Data/Model/Material.h"
  4. #include "WallpaperEngine/Data/Model/Project.h"
  5. #include "WallpaperEngine/Data/Parsers/ShaderConstantParser.h"
  6. #include "WallpaperEngine/FileSystem/Container.h"
  7. using namespace WallpaperEngine::Data::Parsers;
  8. using namespace WallpaperEngine::Data::Model;
  9. MaterialUniquePtr MaterialParser::load (const Project& project, const std::string& filename) {
  10. const auto materialJson = JSON::parseAsset (project.assetLocator->readString (filename));
  11. return parse (materialJson, filename, project);
  12. }
  13. MaterialUniquePtr MaterialParser::parse (const JSON& it, const std::string& filename, const Project& project) {
  14. return std::make_unique<Material> (Material {
  15. .filename = filename,
  16. .passes = parsePasses (it.require ("passes", "Material must have passes to render"), project),
  17. });
  18. }
  19. std::vector<MaterialPassUniquePtr> MaterialParser::parsePasses (const JSON& it, const Project& project) {
  20. std::vector<MaterialPassUniquePtr> result = {};
  21. if (!it.is_array ()) {
  22. return result;
  23. }
  24. for (const auto& cur : it) {
  25. result.push_back (parsePass (cur, project));
  26. }
  27. return result;
  28. }
  29. MaterialPassUniquePtr MaterialParser::parsePass (const JSON& it, const Project& project) {
  30. const auto textures = it.optional ("textures");
  31. const auto usertextures = it.optional ("usertextures");
  32. const auto combos = it.optional ("combos");
  33. const auto constants = it.optional ("constantshadervalues");
  34. return std::make_unique<MaterialPass> (MaterialPass {
  35. // TODO: avoid this std::string construction
  36. .blending = parseBlendMode (it.optional ("blending", std::string ("normal"))),
  37. // left unknown when missing, which draws like nocull/disabled, 3D models pick their own defaults
  38. .cullmode = it.contains ("cullmode") ? parseCullMode (it["cullmode"]) : CullingMode_Unknown,
  39. .depthtest = it.contains ("depthtest") ? parseDepthtestMode (it["depthtest"]) : DepthtestMode_Unknown,
  40. .depthwrite = it.contains ("depthwrite") ? parseDepthwriteMode (it["depthwrite"]) : DepthwriteMode_Unknown,
  41. .shader = it.require<std::string> ("shader", "Material pass must have a shader"),
  42. .textures = textures.has_value () ? TextureParser::parseTextureMap (*textures) : TextureMap {},
  43. .usertextures = usertextures.has_value () ? TextureParser::parseTextureMap (*usertextures) : TextureMap {},
  44. .combos = combos.has_value () ? parseCombos (*combos) : ComboMap {},
  45. .constants = constants.has_value () ? ShaderConstantParser::parse (*constants, project) : ShaderConstantMap {},
  46. });
  47. }
  48. std::map<std::string, int> MaterialParser::parseCombos (const JSON& it) {
  49. std::map<std::string, int> result = {};
  50. if (!it.is_object ()) {
  51. return result;
  52. }
  53. for (const auto& cur : it.items ()) {
  54. result.emplace (cur.key (), cur.value ());
  55. }
  56. return result;
  57. }
  58. BlendingMode MaterialParser::parseBlendMode (const std::string& mode) {
  59. if (mode == "normal") {
  60. return BlendingMode_Normal;
  61. }
  62. if (mode == "additive") {
  63. return BlendingMode_Additive;
  64. }
  65. if (mode == "translucent") {
  66. return BlendingMode_Translucent;
  67. }
  68. sLog.error ("Unknown blending mode: ", mode, " defaulting to normal");
  69. return BlendingMode_Normal;
  70. }
  71. CullingMode MaterialParser::parseCullMode (const std::string& mode) {
  72. if (mode == "nocull") {
  73. return CullingMode_Disable;
  74. }
  75. if (mode == "normal") {
  76. return CullingMode_Normal;
  77. }
  78. sLog.error ("Unknown culling mode: ", mode, " defaulting to nocull");
  79. return CullingMode_Disable;
  80. }
  81. DepthtestMode MaterialParser::parseDepthtestMode (const std::string& mode) {
  82. if (mode == "disabled") {
  83. return DepthtestMode_Disabled;
  84. }
  85. if (mode == "enabled") {
  86. return DepthtestMode_Enabled;
  87. }
  88. sLog.error ("Unknown depthtest mode: ", mode, " defaulting to disabled");
  89. return DepthtestMode_Disabled;
  90. }
  91. DepthwriteMode MaterialParser::parseDepthwriteMode (const std::string& mode) {
  92. if (mode == "disabled") {
  93. return DepthwriteMode_Disabled;
  94. }
  95. if (mode == "enabled") {
  96. return DepthwriteMode_Enabled;
  97. }
  98. sLog.error ("Unknown depthwrite mode: ", mode, " defaulting to disabled");
  99. return DepthwriteMode_Disabled;
  100. }