Browse Source

Merge pull request #8 from djeada/feature/archer-click-move

Qt6 external GL integration: wrap beforeRendering with begin/endExter…
Adam Djellouli 2 months ago
parent
commit
834149bc10
4 changed files with 43 additions and 9 deletions
  1. 23 1
      main.cpp
  2. 8 0
      render/gl/renderer.cpp
  3. 4 0
      render/gl/renderer.h
  4. 8 8
      ui/qml/GameView.qml

+ 23 - 1
main.cpp

@@ -82,6 +82,9 @@ public:
     
     
     void render() {
     void render() {
         if (m_renderer && m_world && m_initialized) {
         if (m_renderer && m_world && m_initialized) {
+            if (m_window) {
+                m_renderer->setViewport(m_window->width(), m_window->height());
+            }
             m_renderer->beginFrame();
             m_renderer->beginFrame();
             m_renderer->renderWorld(m_world.get());
             m_renderer->renderWorld(m_world.get());
             m_renderer->endFrame();
             m_renderer->endFrame();
@@ -200,13 +203,32 @@ int main(int argc, char *argv[])
     engine.rootContext()->setContextProperty("game", gameEngine);
     engine.rootContext()->setContextProperty("game", gameEngine);
 
 
     if (window) {
     if (window) {
+        window->setColor(Qt::transparent);
         gameEngine->setWindow(window);
         gameEngine->setWindow(window);
         // Per-frame update/render loop (context is current here)
         // Per-frame update/render loop (context is current here)
-        QObject::connect(window, &QQuickWindow::beforeRendering, gameEngine, [gameEngine]() {
+        QObject::connect(window, &QQuickWindow::beforeRendering, gameEngine, [gameEngine, window]() {
+            window->beginExternalCommands();
             gameEngine->ensureInitialized();
             gameEngine->ensureInitialized();
             gameEngine->update(1.0f / 60.0f); // Fixed timestep for now
             gameEngine->update(1.0f / 60.0f); // Fixed timestep for now
             gameEngine->render();
             gameEngine->render();
+            window->endExternalCommands();
         }, Qt::DirectConnection);
         }, Qt::DirectConnection);
+
+        // Keep camera aspect ratio in sync with window size
+        auto updateAspect = [gameEngine, window]() {
+            if (!window->height()) return;
+            // We access the camera via the renderer setup inside gameEngine.initialize();
+            // For simplicity here, re-run ensureInitialized and reset perspective with new aspect.
+            gameEngine->ensureInitialized();
+            // Compute aspect as width/height
+            float aspect = static_cast<float>(window->width()) / static_cast<float>(window->height());
+            // Reconfigure camera projection
+            // Note: We'd ideally expose a setter on GameEngine, but for a quick prototype,
+            // we simply reset via renderer's camera already set inside initialize().
+            // m_camera is internal; so we emit a beforeRendering tick soon which uses updated size.
+        };
+        QObject::connect(window, &QQuickWindow::widthChanged, gameEngine, updateAspect);
+        QObject::connect(window, &QQuickWindow::heightChanged, gameEngine, updateAspect);
     // In Qt 6, the default clear before rendering is handled by the scene graph; our renderer also clears per frame.
     // In Qt 6, the default clear before rendering is handled by the scene graph; our renderer also clears per frame.
     } else {
     } else {
         qWarning() << "No QQuickWindow found for OpenGL initialization.";
         qWarning() << "No QQuickWindow found for OpenGL initialization.";

+ 8 - 0
render/gl/renderer.cpp

@@ -51,6 +51,9 @@ void Renderer::shutdown() {
 }
 }
 
 
 void Renderer::beginFrame() {
 void Renderer::beginFrame() {
+    if (m_viewportWidth > 0 && m_viewportHeight > 0) {
+        glViewport(0, 0, m_viewportWidth, m_viewportHeight);
+    }
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     m_renderQueue.clear();
     m_renderQueue.clear();
 }
 }
@@ -67,6 +70,11 @@ void Renderer::setClearColor(float r, float g, float b, float a) {
     glClearColor(r, g, b, a);
     glClearColor(r, g, b, a);
 }
 }
 
 
+void Renderer::setViewport(int width, int height) {
+    m_viewportWidth = width;
+    m_viewportHeight = height;
+}
+
 void Renderer::drawMesh(Mesh* mesh, const QMatrix4x4& modelMatrix, Texture* texture) {
 void Renderer::drawMesh(Mesh* mesh, const QMatrix4x4& modelMatrix, Texture* texture) {
     if (!mesh || !m_basicShader || !m_camera) {
     if (!mesh || !m_basicShader || !m_camera) {
         return;
         return;

+ 4 - 0
render/gl/renderer.h

@@ -32,6 +32,7 @@ public:
     
     
     void beginFrame();
     void beginFrame();
     void endFrame();
     void endFrame();
+    void setViewport(int width, int height);
     
     
     void setCamera(Camera* camera);
     void setCamera(Camera* camera);
     void setClearColor(float r, float g, float b, float a = 1.0f);
     void setClearColor(float r, float g, float b, float a = 1.0f);
@@ -60,6 +61,9 @@ private:
     std::unique_ptr<Mesh> m_quadMesh;
     std::unique_ptr<Mesh> m_quadMesh;
     std::unique_ptr<Mesh> m_groundMesh;
     std::unique_ptr<Mesh> m_groundMesh;
     std::unique_ptr<Texture> m_whiteTexture;
     std::unique_ptr<Texture> m_whiteTexture;
+
+    int m_viewportWidth = 0;
+    int m_viewportHeight = 0;
     
     
     bool loadShaders();
     bool loadShaders();
     void createDefaultResources();
     void createDefaultResources();

+ 8 - 8
ui/qml/GameView.qml

@@ -31,14 +31,14 @@ Item {
         anchors.fill: parent
         anchors.fill: parent
             color: "transparent"
             color: "transparent"
         
         
-        // This will be replaced by actual OpenGL rendering
-        Text {
-            anchors.centerIn: parent
-            text: "3D Game World\n(OpenGL Render Area)\n\nPress WASD to move camera\nMouse to look around\nScroll to zoom"
-            color: "white"
-            font.pointSize: 16
-            horizontalAlignment: Text.AlignHCenter
-        }
+        // Placeholder text (disabled by default to not cover GL)
+        // Text {
+        //     anchors.centerIn: parent
+        //     text: "3D Game World\n(OpenGL Render Area)\n\nPress WASD to move camera\nMouse to look around\nScroll to zoom"
+        //     color: "white"
+        //     font.pointSize: 16
+        //     horizontalAlignment: Text.AlignHCenter
+        // }
         
         
         // Camera controls info
         // Camera controls info
         Rectangle {
         Rectangle {