character_pipeline.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "character_pipeline.h"
  2. #include "../backend.h"
  3. #include "../shader_cache.h"
  4. #include <QDebug>
  5. #include <QStringList>
  6. #include <qglobal.h>
  7. #include <utility>
  8. namespace Render::GL::BackendPipelines {
  9. auto CharacterPipeline::initialize() -> bool {
  10. if (m_shaderCache == nullptr) {
  11. qWarning() << "CharacterPipeline::initialize: null ShaderCache";
  12. return false;
  13. }
  14. m_basicShader = m_shaderCache->get("basic");
  15. m_archerShader = m_shaderCache->get("archer");
  16. m_swordsmanShader = m_shaderCache->get("swordsman");
  17. m_spearmanShader = m_shaderCache->get("spearman");
  18. if (m_basicShader == nullptr) {
  19. qWarning() << "CharacterPipeline: Failed to load basic shader";
  20. }
  21. if (m_archerShader == nullptr) {
  22. qWarning() << "CharacterPipeline: Failed to load archer shader";
  23. }
  24. if (m_swordsmanShader == nullptr) {
  25. qWarning() << "CharacterPipeline: Failed to load swordsman shader";
  26. }
  27. if (m_spearmanShader == nullptr) {
  28. qWarning() << "CharacterPipeline: Failed to load spearman shader";
  29. }
  30. cacheUniforms();
  31. return is_initialized();
  32. }
  33. void CharacterPipeline::shutdown() {
  34. m_basicShader = nullptr;
  35. m_archerShader = nullptr;
  36. m_swordsmanShader = nullptr;
  37. m_spearmanShader = nullptr;
  38. }
  39. void CharacterPipeline::cacheUniforms() {
  40. m_uniformCache.clear();
  41. cacheBasicUniforms();
  42. cacheArcherUniforms();
  43. cacheKnightUniforms();
  44. cacheSpearmanUniforms();
  45. }
  46. auto CharacterPipeline::is_initialized() const -> bool {
  47. return m_basicShader != nullptr && m_archerShader != nullptr &&
  48. m_swordsmanShader != nullptr && m_spearmanShader != nullptr;
  49. }
  50. void CharacterPipeline::cacheBasicUniforms() {
  51. if (m_basicShader == nullptr) {
  52. return;
  53. }
  54. m_basicUniforms = buildUniformSet(m_basicShader);
  55. m_uniformCache[m_basicShader] = m_basicUniforms;
  56. }
  57. void CharacterPipeline::cacheArcherUniforms() {
  58. if (m_archerShader == nullptr) {
  59. return;
  60. }
  61. m_archerUniforms = buildUniformSet(m_archerShader);
  62. m_uniformCache[m_archerShader] = m_archerUniforms;
  63. cacheNationVariants(QStringLiteral("archer"));
  64. }
  65. void CharacterPipeline::cacheKnightUniforms() {
  66. if (m_swordsmanShader == nullptr) {
  67. return;
  68. }
  69. m_swordsmanUniforms = buildUniformSet(m_swordsmanShader);
  70. m_uniformCache[m_swordsmanShader] = m_swordsmanUniforms;
  71. cacheNationVariants(QStringLiteral("swordsman"));
  72. }
  73. void CharacterPipeline::cacheSpearmanUniforms() {
  74. if (m_spearmanShader == nullptr) {
  75. return;
  76. }
  77. m_spearmanUniforms = buildUniformSet(m_spearmanShader);
  78. m_uniformCache[m_spearmanShader] = m_spearmanUniforms;
  79. cacheNationVariants(QStringLiteral("spearman"));
  80. }
  81. auto CharacterPipeline::buildUniformSet(GL::Shader *shader) const
  82. -> BasicUniforms {
  83. BasicUniforms uniforms;
  84. if (shader == nullptr) {
  85. return uniforms;
  86. }
  87. uniforms.mvp = shader->uniformHandle("u_mvp");
  88. uniforms.model = shader->uniformHandle("u_model");
  89. uniforms.texture = shader->uniformHandle("u_texture");
  90. uniforms.useTexture = shader->uniformHandle("u_useTexture");
  91. uniforms.color = shader->uniformHandle("u_color");
  92. uniforms.alpha = shader->uniformHandle("u_alpha");
  93. uniforms.materialId = shader->optionalUniformHandle("u_materialId");
  94. return uniforms;
  95. }
  96. void CharacterPipeline::cacheNationVariants(const QString &baseKey) {
  97. if (m_shaderCache == nullptr) {
  98. return;
  99. }
  100. static const QStringList nations{QStringLiteral("roman_republic"),
  101. QStringLiteral("carthage")};
  102. for (const QString &nation : nations) {
  103. const QString shaderName = baseKey + QStringLiteral("_") + nation;
  104. if (GL::Shader *variant = m_shaderCache->get(shaderName)) {
  105. m_uniformCache.emplace(variant, buildUniformSet(variant));
  106. }
  107. }
  108. }
  109. auto CharacterPipeline::resolveUniforms(GL::Shader *shader) -> BasicUniforms * {
  110. if (shader == nullptr) {
  111. return nullptr;
  112. }
  113. auto it = m_uniformCache.find(shader);
  114. if (it != m_uniformCache.end()) {
  115. return &it->second;
  116. }
  117. BasicUniforms uniforms = buildUniformSet(shader);
  118. auto [inserted, success] = m_uniformCache.emplace(shader, uniforms);
  119. return &inserted->second;
  120. }
  121. } // namespace Render::GL::BackendPipelines