hellovulkanwidget.cpp Example File | Qt GUI 5.12.9

- Qt 5.12
- Qt GUI
- Hello Vulkan Widget Example
- hellovulkanwidget.cpp Example File
- Qt 5.12.9 Reference Documentation

# hellovulkanwidget.cpp Example File

hellovulkanwidget/hellovulkanwidget.cpp

     /****************************************************************************
     **
     ** Copyright (C) 2017 The Qt Company Ltd.
     ** Contact: https://www.qt.io/licensing/
     **
     ** This file is part of the examples of the Qt Toolkit.
     **
     ** $QT_BEGIN_LICENSE:BSD$
     ** Commercial License Usage
     ** Licensees holding valid commercial Qt licenses may use this file in
     ** accordance with the commercial license agreement provided with the
     ** Software or, alternatively, in accordance with the terms contained in
     ** a written agreement between you and The Qt Company. For licensing terms
     ** and conditions see https://www.qt.io/terms-conditions. For further
     ** information use the contact form at https://www.qt.io/contact-us.
     **
     ** BSD License Usage
     ** Alternatively, you may use this file under the terms of the BSD license
     ** as follows:
     **
     ** "Redistribution and use in source and binary forms, with or without
     ** modification, are permitted provided that the following conditions are
     ** met:
     **   * Redistributions of source code must retain the above copyright
     **     notice, this list of conditions and the following disclaimer.
     **   * Redistributions in binary form must reproduce the above copyright
     **     notice, this list of conditions and the following disclaimer in
     **     the documentation and/or other materials provided with the
     **     distribution.
     **   * Neither the name of The Qt Company Ltd nor the names of its
     **     contributors may be used to endorse or promote products derived
     **     from this software without specific prior written permission.
     **
     **
     ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
     **
     ** $QT_END_LICENSE$
     **
     ****************************************************************************/

     #include "hellovulkanwidget.h"
     #include <QVulkanFunctions>
     #include <QApplication>
     #include <QVBoxLayout>
     #include <QPlainTextEdit>
     #include <QPushButton>
     #include <QLCDNumber>
     #include <QFileDialog>
     #include <QMessageBox>
     #include <QTabWidget>

     MainWindow::MainWindow(VulkanWindow *w, QPlainTextEdit *logWidget)
         : m_window(w)
     {
         QWidget *wrapper = QWidget::createWindowContainer(w);

         m_info = new QPlainTextEdit;
         m_info->setReadOnly(true);

         m_number = new QLCDNumber(3);
         m_number->setSegmentStyle(QLCDNumber::Filled);

         QPushButton *grabButton = new QPushButton(tr("&Grab"));
         grabButton->setFocusPolicy(Qt::NoFocus);

         connect(grabButton, &QPushButton::clicked, this, &MainWindow::onGrabRequested);

         QPushButton *quitButton = new QPushButton(tr("&Quit"));
         quitButton->setFocusPolicy(Qt::NoFocus);

         connect(quitButton, &QPushButton::clicked, qApp, &QCoreApplication::quit);

         QVBoxLayout *layout = new QVBoxLayout;
         m_infoTab = new QTabWidget(this);
         m_infoTab->addTab(m_info, tr("Vulkan Info"));
         m_infoTab->addTab(logWidget, tr("Debug Log"));
         layout->addWidget(m_infoTab, 2);
         layout->addWidget(m_number, 1);
         layout->addWidget(wrapper, 5);
         layout->addWidget(grabButton, 1);
         layout->addWidget(quitButton, 1);
         setLayout(layout);
     }

     void MainWindow::onVulkanInfoReceived(const QString &text)
     {
         m_info->setPlainText(text);
     }

     void MainWindow::onFrameQueued(int colorValue)
     {
         m_number->display(colorValue);
     }

     void MainWindow::onGrabRequested()
     {
         if (!m_window->supportsGrab()) {
             QMessageBox::warning(this, tr("Cannot grab"), tr("This swapchain does not support readbacks."));
             return;
         }

         QImage img = m_window->grab();

         // Our startNextFrame() implementation is synchronous so img is ready to be
         // used right here.

         QFileDialog fd(this);
         fd.setAcceptMode(QFileDialog::AcceptSave);
         fd.setDefaultSuffix("png");
         fd.selectFile("test.png");
         if (fd.exec() == QDialog::Accepted)
             img.save(fd.selectedFiles().first());
     }

     QVulkanWindowRenderer *VulkanWindow::createRenderer()
     {
         return new VulkanRenderer(this);
     }

     VulkanRenderer::VulkanRenderer(VulkanWindow *w)
         : TriangleRenderer(w)
     {
     }

     void VulkanRenderer::initResources()
     {
         TriangleRenderer::initResources();

         QVulkanInstance *inst = m_window->vulkanInstance();
         m_devFuncs = inst->deviceFunctions(m_window->device());

         QString info;
         info += QString().sprintf("Number of physical devices: %d\n", m_window->availablePhysicalDevices().count());

         QVulkanFunctions *f = inst->functions();
         VkPhysicalDeviceProperties props;
         f->vkGetPhysicalDeviceProperties(m_window->physicalDevice(), &props);
         info += QString().sprintf("Active physical device name: '%s' version %d.%d.%d\nAPI version %d.%d.%d\n",
                                   props.deviceName,
                                   VK_VERSION_MAJOR(props.driverVersion), VK_VERSION_MINOR(props.driverVersion),
                                   VK_VERSION_PATCH(props.driverVersion),
                                   VK_VERSION_MAJOR(props.apiVersion), VK_VERSION_MINOR(props.apiVersion),
                                   VK_VERSION_PATCH(props.apiVersion));

         info += QStringLiteral("Supported instance layers:\n");
         for (const QVulkanLayer &layer : inst->supportedLayers())
             info += QString().sprintf("    %s v%u\n", layer.name.constData(), layer.version);
         info += QStringLiteral("Enabled instance layers:\n");
         for (const QByteArray &layer : inst->layers())
             info += QString().sprintf("    %s\n", layer.constData());

         info += QStringLiteral("Supported instance extensions:\n");
         for (const QVulkanExtension &ext : inst->supportedExtensions())
             info += QString().sprintf("    %s v%u\n", ext.name.constData(), ext.version);
         info += QStringLiteral("Enabled instance extensions:\n");
         for (const QByteArray &ext : inst->extensions())
             info += QString().sprintf("    %s\n", ext.constData());

         info += QString().sprintf("Color format: %u\nDepth-stencil format: %u\n",
                                   m_window->colorFormat(), m_window->depthStencilFormat());

         info += QStringLiteral("Supported sample counts:");
         const QVector<int> sampleCounts = m_window->supportedSampleCounts();
         for (int count : sampleCounts)
             info += QLatin1Char(' ') + QString::number(count);
         info += QLatin1Char('\n');

         emit static_cast<VulkanWindow *>(m_window)->vulkanInfoReceived(info);
     }

     void VulkanRenderer::startNextFrame()
     {
         TriangleRenderer::startNextFrame();
         emit static_cast<VulkanWindow *>(m_window)->frameQueued(int(m_rotation) % 360);
     }