// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \example compacthealth
    \ingroup canvaspainter-examples
    \title Qt Canvas Painter - Compact Health Example
    \examplecategory {Graphics}
    \brief Demonstrates the use of QCanvasPainter in a QWindow.

    \image compacthealth-example.webp

    This example demonstrates using Qt Canvas Painter in a pure QWindow
    application. Qt Quick or QWidget are not used at all, and there is no
    dependency on Qt modules other than Core, Gui, and Canvas Painter.

    The application sets up accelerated 3D rendering using QRhi, and renders all
    content in the window with QCanvasPainter. The rendering and QCanvasPainter's
    integration with QRhi is managed via QCanvasRhiPaintDriver.

    \section1 Walkthrough

    While choosing a 3D API to use based on the platform, the application also offers
    the possibility of requesting one using command-line arguments.

    \snippet compacthealth/main.cpp main

    MainWindow is a subclass of PainterWindow, which is a QWindow. PainterWindow
    implements a window that shows content rendered via \l QRhi, Qt's 3D
    graphics abstraction. Its task is to initialize a QRhi instance upon
    receiving an expose event, i.e., when the window is shown, manage a
    swapchain and a depth-stencil buffer, while also taking care of acting when
    the window is resized, and to invoke a virtual paint() function that is
    implemented in MainWindow.

    For a better understanding of the PainterWindow implementation, it is
    recommended to check out the \l {RHI Window Example}, since in essence it is
    very similar to the RhiWindow class in that example.

    One QCanvasPainter-specific step is to retrieve a \l QCanvasPainterFactory instance once
    a \l QRhi is successfully initialized:

    \snippet compacthealth/painterwindow.cpp painterfactory

    Rendering a new frame happens in the render() function, which is invoked
    when the window is shown, resized, and in response to update requests
    scheduled via \l{QWindow::}{requestUpdate()}.

    Unlike in the \l {RHI Window Example}, we will not create vertex and uniform
    buffers or graphics pipelines via the \l QRhi API, and issue draw calls
    directly. Instead, \l QCanvasRhiPaintDriver is used to record a render pass with
    the QCanvasPainter-generated rendering.

    \snippet compacthealth/painterwindow.cpp renderloop

    MainWindow's paint() implementation works with the QCanvasPainter API, and does not
    need to worry about low-level details such as the \l QRhi.

    First, it loads and registers images if not yet done:

    \snippet compacthealth/mainwindow.cpp paint-1

    This is followed by the actual drawing, involving the filling and stroking
    of paths, rendering text, and drawing images. For example:

    \snippet compacthealth/mainwindow.cpp paint-2

    The QCanvasPainter fill and stroke calls prepare vertex, index, uniform data and
    QRhi-based draw calls internally. The stream of commands is flushed when
    \l{QCanvasRhiPaintDriver::}{endPaint()} is called in PainterWindow::render().
    That is where a render pass is recorded on the associated \l
    QRhiCommandBuffer.

    Before returning, MainWindow::paint() calls requestUpdate(), a QWindow
    function that requests a new frame, synchronized with the display's
    presentation rate. This is what ensures that the window content is
    continuously updated and so it can animate.

    Check the full example source code linked below for details.
*/
