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); }