gl_view.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include "gl_view.h"
  2. #include "../app/core/game_engine.h"
  3. #include <QOpenGLContext>
  4. #include <QOpenGLFramebufferObject>
  5. #include <QOpenGLFramebufferObjectFormat>
  6. #include <QQuickWindow>
  7. #include <exception>
  8. #include <qglobal.h>
  9. #include <qobject.h>
  10. #include <qopenglcontext.h>
  11. #include <qopenglframebufferobject.h>
  12. #include <qpointer.h>
  13. #include <qquickframebufferobject.h>
  14. #include <qtmetamacros.h>
  15. #include <utility>
  16. GLView::GLView() {
  17. setMirrorVertically(true);
  18. QOpenGLContext *ctx = QOpenGLContext::currentContext();
  19. if (ctx == nullptr) {
  20. qWarning() << "GLView: No OpenGL context available";
  21. qWarning() << "GLView: 3D rendering will not work in software mode";
  22. qWarning() << "GLView: Try running without QT_QUICK_BACKEND=software for "
  23. "full functionality";
  24. }
  25. }
  26. auto GLView::createRenderer() const -> QQuickFramebufferObject::Renderer * {
  27. QOpenGLContext *ctx = QOpenGLContext::currentContext();
  28. if ((ctx == nullptr) || !ctx->isValid()) {
  29. qCritical() << "GLView::createRenderer() - No valid OpenGL context";
  30. qCritical() << "Running in software rendering mode - 3D view not available";
  31. return nullptr;
  32. }
  33. return new GLRenderer(m_engine);
  34. }
  35. auto GLView::engine() const -> QObject * { return m_engine; }
  36. void GLView::setEngine(QObject *eng) {
  37. if (m_engine == eng) {
  38. return;
  39. }
  40. m_engine = qobject_cast<GameEngine *>(eng);
  41. emit engineChanged();
  42. update();
  43. }
  44. GLView::GLRenderer::GLRenderer(QPointer<GameEngine> engine)
  45. : m_engine(std::move(std::move(engine))) {}
  46. void GLView::GLRenderer::render() {
  47. if (m_engine == nullptr) {
  48. qWarning() << "GLRenderer::render() - engine is null";
  49. return;
  50. }
  51. QOpenGLContext *ctx = QOpenGLContext::currentContext();
  52. if ((ctx == nullptr) || !ctx->isValid()) {
  53. qCritical() << "GLRenderer::render() - OpenGL context lost";
  54. return;
  55. }
  56. try {
  57. m_engine->ensureInitialized();
  58. m_engine->update(1.0F / 60.0F);
  59. m_engine->render(m_size.width(), m_size.height());
  60. } catch (const std::exception &e) {
  61. qCritical() << "GLRenderer::render() exception:" << e.what();
  62. return;
  63. } catch (...) {
  64. qCritical() << "GLRenderer::render() unknown exception";
  65. return;
  66. }
  67. update();
  68. }
  69. auto GLView::GLRenderer::createFramebufferObject(const QSize &size)
  70. -> QOpenGLFramebufferObject * {
  71. m_size = size;
  72. QOpenGLContext *ctx = QOpenGLContext::currentContext();
  73. if ((ctx == nullptr) || !ctx->isValid()) {
  74. qCritical()
  75. << "GLRenderer::createFramebufferObject() - No valid OpenGL context";
  76. return nullptr;
  77. }
  78. QOpenGLFramebufferObjectFormat fmt;
  79. fmt.setAttachment(QOpenGLFramebufferObject::Depth);
  80. fmt.setSamples(0);
  81. return new QOpenGLFramebufferObject(size, fmt);
  82. }
  83. void GLView::GLRenderer::synchronize(QQuickFramebufferObject *item) {
  84. auto *view = dynamic_cast<GLView *>(item);
  85. m_engine = qobject_cast<GameEngine *>(view->engine());
  86. }