main.cpp 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // System/Qt headers
  2. #include <QGuiApplication>
  3. #include <QQmlApplicationEngine>
  4. #include <QOpenGLContext>
  5. #include <QSurfaceFormat>
  6. #include <QDebug>
  7. #include <QDir>
  8. #include <QQuickWindow>
  9. #include <QQmlContext>
  10. #include <QSGRendererInterface>
  11. // App headers
  12. #include "app/game_engine.h"
  13. #include "ui/gl_view.h"
  14. int main(int argc, char *argv[])
  15. {
  16. // Force desktop OpenGL + GLX path BEFORE any window is created.
  17. if (qEnvironmentVariableIsSet("WAYLAND_DISPLAY") && qEnvironmentVariableIsSet("DISPLAY")) {
  18. qputenv("QT_QPA_PLATFORM", "xcb"); // prefer XCB/GLX over Wayland/EGL when XWayland is present
  19. }
  20. qputenv("QT_OPENGL", "desktop"); // desktop GL, not GLES/EGL
  21. qputenv("QSG_RHI_BACKEND", "opengl"); // OpenGL RHI
  22. QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
  23. // Request desktop GL 3.3 core.
  24. QSurfaceFormat fmt;
  25. fmt.setVersion(3, 3);
  26. fmt.setProfile(QSurfaceFormat::CoreProfile);
  27. fmt.setDepthBufferSize(24);
  28. fmt.setStencilBufferSize(8);
  29. fmt.setSamples(0);
  30. QSurfaceFormat::setDefaultFormat(fmt);
  31. QGuiApplication app(argc, argv);
  32. auto gameEngine = new GameEngine();
  33. QQmlApplicationEngine engine;
  34. // Expose to QML BEFORE loading (safer if QML binds early).
  35. engine.rootContext()->setContextProperty("game", gameEngine);
  36. // Register our GLView item so QML can embed the GL scene inside the scene graph
  37. qmlRegisterType<GLView>("StandardOfIron", 1, 0, "GLView");
  38. engine.load(QUrl(QStringLiteral("qrc:/StandardOfIron/ui/qml/Main.qml")));
  39. if (engine.rootObjects().isEmpty()) {
  40. qWarning() << "Failed to load QML file";
  41. return -1;
  42. }
  43. QObject* rootObj = engine.rootObjects().first();
  44. QQuickWindow* window = qobject_cast<QQuickWindow*>(rootObj);
  45. if (!window) window = rootObj->findChild<QQuickWindow*>();
  46. if (!window) {
  47. qWarning() << "No QQuickWindow found for OpenGL initialization.";
  48. return -2;
  49. }
  50. // Let Qt Quick manage the clear; keep window color default.
  51. gameEngine->setWindow(window);
  52. // Informative logging (no current-context check here).
  53. QObject::connect(window, &QQuickWindow::sceneGraphInitialized, window, [window]() {
  54. if (auto *ri = window->rendererInterface()) {
  55. auto api = ri->graphicsApi();
  56. const char* name = api == QSGRendererInterface::OpenGLRhi ? "OpenGLRhi" :
  57. api == QSGRendererInterface::VulkanRhi ? "VulkanRhi" :
  58. api == QSGRendererInterface::Direct3D11Rhi ? "D3D11Rhi" :
  59. api == QSGRendererInterface::MetalRhi ? "MetalRhi" :
  60. api == QSGRendererInterface::Software ? "Software" : "Unknown";
  61. qInfo() << "QSG graphicsApi:" << name;
  62. }
  63. });
  64. QObject::connect(window, &QQuickWindow::sceneGraphError, &app,
  65. [&](QQuickWindow::SceneGraphError, const QString &msg){
  66. qCritical() << "Failed to initialize OpenGL scene graph:" << msg;
  67. app.exit(3);
  68. });
  69. qDebug() << "Application started successfully";
  70. qDebug() << "Assets directory:" << QDir::currentPath() + "/assets";
  71. return app.exec();
  72. }
  73. // no Q_OBJECT in this TU anymore