backend.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include "backend.h"
  2. #include "../draw_queue.h"
  3. #include "../geom/selection_disc.h"
  4. #include "../geom/selection_ring.h"
  5. #include "mesh.h"
  6. #include "shader.h"
  7. #include "state_scopes.h"
  8. #include "texture.h"
  9. #include <QDebug>
  10. namespace Render::GL {
  11. Backend::~Backend() = default;
  12. void Backend::initialize() {
  13. initializeOpenGLFunctions();
  14. glEnable(GL_DEPTH_TEST);
  15. glDepthFunc(GL_LESS);
  16. glDepthRange(0.0, 1.0);
  17. glDepthMask(GL_TRUE);
  18. glEnable(GL_BLEND);
  19. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  20. m_resources = std::make_unique<ResourceManager>();
  21. if (!m_resources->initialize()) {
  22. qWarning() << "Backend: failed to initialize ResourceManager";
  23. }
  24. m_shaderCache = std::make_unique<ShaderCache>();
  25. m_shaderCache->initializeDefaults();
  26. m_basicShader = m_shaderCache->get(QStringLiteral("basic"));
  27. m_gridShader = m_shaderCache->get(QStringLiteral("grid"));
  28. if (!m_basicShader)
  29. qWarning() << "Backend: basic shader missing";
  30. if (!m_gridShader)
  31. qWarning() << "Backend: grid shader missing";
  32. }
  33. void Backend::beginFrame() {
  34. if (m_viewportWidth > 0 && m_viewportHeight > 0) {
  35. glViewport(0, 0, m_viewportWidth, m_viewportHeight);
  36. }
  37. glClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2],
  38. m_clearColor[3]);
  39. glClearDepth(1.0);
  40. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  41. glEnable(GL_DEPTH_TEST);
  42. glDepthFunc(GL_LESS);
  43. glDepthMask(GL_TRUE);
  44. }
  45. void Backend::setViewport(int w, int h) {
  46. m_viewportWidth = w;
  47. m_viewportHeight = h;
  48. }
  49. void Backend::setClearColor(float r, float g, float b, float a) {
  50. m_clearColor[0] = r;
  51. m_clearColor[1] = g;
  52. m_clearColor[2] = b;
  53. m_clearColor[3] = a;
  54. }
  55. void Backend::execute(const DrawQueue &queue, const Camera &cam) {
  56. if (!m_basicShader)
  57. return;
  58. m_basicShader->use();
  59. m_basicShader->setUniform("u_view", cam.getViewMatrix());
  60. m_basicShader->setUniform("u_projection", cam.getProjectionMatrix());
  61. for (const auto &cmd : queue.items()) {
  62. if (std::holds_alternative<MeshCmd>(cmd)) {
  63. const auto &it = std::get<MeshCmd>(cmd);
  64. if (!it.mesh)
  65. continue;
  66. glDepthMask(GL_TRUE);
  67. if (glIsEnabled(GL_POLYGON_OFFSET_FILL))
  68. glDisable(GL_POLYGON_OFFSET_FILL);
  69. m_basicShader->use();
  70. m_basicShader->setUniform("u_view", cam.getViewMatrix());
  71. m_basicShader->setUniform("u_projection", cam.getProjectionMatrix());
  72. m_basicShader->setUniform("u_model", it.model);
  73. if (it.texture) {
  74. it.texture->bind(0);
  75. m_basicShader->setUniform("u_texture", 0);
  76. m_basicShader->setUniform("u_useTexture", true);
  77. } else {
  78. if (m_resources && m_resources->white()) {
  79. m_resources->white()->bind(0);
  80. m_basicShader->setUniform("u_texture", 0);
  81. }
  82. m_basicShader->setUniform("u_useTexture", false);
  83. }
  84. m_basicShader->setUniform("u_color", it.color);
  85. m_basicShader->setUniform("u_alpha", it.alpha);
  86. it.mesh->draw();
  87. } else if (std::holds_alternative<GridCmd>(cmd)) {
  88. if (!m_gridShader)
  89. continue;
  90. const auto &gc = std::get<GridCmd>(cmd);
  91. m_gridShader->use();
  92. m_gridShader->setUniform("u_view", cam.getViewMatrix());
  93. m_gridShader->setUniform("u_projection", cam.getProjectionMatrix());
  94. QMatrix4x4 model = gc.model;
  95. m_gridShader->setUniform("u_model", model);
  96. m_gridShader->setUniform("u_gridColor", gc.color);
  97. m_gridShader->setUniform("u_lineColor", QVector3D(0.22f, 0.25f, 0.22f));
  98. m_gridShader->setUniform("u_cellSize", gc.cellSize);
  99. m_gridShader->setUniform("u_thickness", gc.thickness);
  100. if (m_resources) {
  101. if (auto *plane = m_resources->ground())
  102. plane->draw();
  103. }
  104. } else if (std::holds_alternative<SelectionRingCmd>(cmd)) {
  105. const auto &sc = std::get<SelectionRingCmd>(cmd);
  106. Mesh *ring = Render::Geom::SelectionRing::get();
  107. if (!ring)
  108. continue;
  109. m_basicShader->use();
  110. m_basicShader->setUniform("u_view", cam.getViewMatrix());
  111. m_basicShader->setUniform("u_projection", cam.getProjectionMatrix());
  112. m_basicShader->setUniform("u_useTexture", false);
  113. m_basicShader->setUniform("u_color", sc.color);
  114. DepthMaskScope depthMask(false);
  115. PolygonOffsetScope poly(-1.0f, -1.0f);
  116. BlendScope blend(true);
  117. {
  118. QMatrix4x4 m = sc.model;
  119. m.scale(1.08f, 1.0f, 1.08f);
  120. m_basicShader->setUniform("u_model", m);
  121. m_basicShader->setUniform("u_alpha", sc.alphaOuter);
  122. ring->draw();
  123. }
  124. {
  125. m_basicShader->setUniform("u_model", sc.model);
  126. m_basicShader->setUniform("u_alpha", sc.alphaInner);
  127. ring->draw();
  128. }
  129. } else if (std::holds_alternative<SelectionSmokeCmd>(cmd)) {
  130. const auto &sm = std::get<SelectionSmokeCmd>(cmd);
  131. Mesh *disc = Render::Geom::SelectionDisc::get();
  132. if (!disc)
  133. continue;
  134. m_basicShader->use();
  135. m_basicShader->setUniform("u_view", cam.getViewMatrix());
  136. m_basicShader->setUniform("u_projection", cam.getProjectionMatrix());
  137. m_basicShader->setUniform("u_useTexture", false);
  138. m_basicShader->setUniform("u_color", sm.color);
  139. DepthMaskScope depthMask(false);
  140. DepthTestScope depthTest(false);
  141. PolygonOffsetScope poly(-0.1f, -0.1f);
  142. BlendScope blend(true);
  143. for (int i = 0; i < 7; ++i) {
  144. float scale = 1.35f + 0.12f * i;
  145. float a = sm.baseAlpha * (1.0f - 0.09f * i);
  146. QMatrix4x4 m = sm.model;
  147. m.translate(0.0f, 0.02f, 0.0f);
  148. m.scale(scale, 1.0f, scale);
  149. m_basicShader->setUniform("u_model", m);
  150. m_basicShader->setUniform("u_alpha", a);
  151. disc->draw();
  152. }
  153. }
  154. }
  155. m_basicShader->release();
  156. }
  157. } // namespace Render::GL