character_pipeline.cpp 4.1 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. cache_uniforms();
  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::cache_uniforms() {
  40. m_uniformCache.clear();
  41. cache_basic_uniforms();
  42. cache_archer_uniforms();
  43. cache_knight_uniforms();
  44. cache_spearman_uniforms();
  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::cache_basic_uniforms() {
  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::cache_archer_uniforms() {
  58. if (m_archerShader == nullptr) {
  59. return;
  60. }
  61. m_archerUniforms = buildUniformSet(m_archerShader);
  62. m_uniformCache[m_archerShader] = m_archerUniforms;
  63. cache_nation_variants(QStringLiteral("archer"));
  64. }
  65. void CharacterPipeline::cache_knight_uniforms() {
  66. if (m_swordsmanShader == nullptr) {
  67. return;
  68. }
  69. m_swordsmanUniforms = buildUniformSet(m_swordsmanShader);
  70. m_uniformCache[m_swordsmanShader] = m_swordsmanUniforms;
  71. cache_nation_variants(QStringLiteral("swordsman"));
  72. }
  73. void CharacterPipeline::cache_spearman_uniforms() {
  74. if (m_spearmanShader == nullptr) {
  75. return;
  76. }
  77. m_spearmanUniforms = buildUniformSet(m_spearmanShader);
  78. m_uniformCache[m_spearmanShader] = m_spearmanUniforms;
  79. cache_nation_variants(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->uniform_handle("u_mvp");
  88. uniforms.model = shader->uniform_handle("u_model");
  89. uniforms.texture = shader->uniform_handle("u_texture");
  90. uniforms.useTexture = shader->uniform_handle("u_useTexture");
  91. uniforms.color = shader->uniform_handle("u_color");
  92. uniforms.alpha = shader->uniform_handle("u_alpha");
  93. uniforms.materialId = shader->optional_uniform_handle("u_materialId");
  94. return uniforms;
  95. }
  96. void CharacterPipeline::cache_nation_variants(const QString &base_key) {
  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 = base_key + 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