/****************************************************************************
**
** 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 =newQPlainTextEdit;
m_info->setReadOnly(true);
m_number =newQLCDNumber(3);
m_number->setSegmentStyle(QLCDNumber::Filled);
QPushButton*grabButton =newQPushButton(tr("&Grab"));
grabButton->setFocusPolicy(Qt::NoFocus);
connect(grabButton,&QPushButton::clicked,this,&MainWindow::onGrabRequested);
QPushButton*quitButton =newQPushButton(tr("&Quit"));
quitButton->setFocusPolicy(Qt::NoFocus);
connect(quitButton,&QPushButton::clicked,qApp,&QCoreApplication::quit);
QVBoxLayout*layout =newQVBoxLayout;
m_infoTab =newQTabWidget(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(constQString&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()
{
returnnew 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 (constQVulkanLayer&layer : inst->supportedLayers())
info +=QString().sprintf(" %s v%u\n", layer.name.constData(), layer.version);
info +=QStringLiteral("Enabled instance layers:\n");
for (constQByteArray&layer : inst->layers())
info +=QString().sprintf(" %s\n", layer.constData());
info +=QStringLiteral("Supported instance extensions:\n");
for (constQVulkanExtension&ext : inst->supportedExtensions())
info +=QString().sprintf(" %s v%u\n", ext.name.constData(), ext.version);
info +=QStringLiteral("Enabled instance extensions:\n");
for (constQByteArray&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:");
constQVector<int> sampleCounts = m_window->supportedSampleCounts();
for (int count : sampleCounts)
info += QLatin1Char(' ') +QString::number(count);
info += QLatin1Char('\n');
emitstatic_cast<VulkanWindow *>(m_window)->vulkanInfoReceived(info);
}
void VulkanRenderer::startNextFrame()
{
TriangleRenderer::startNextFrame();
emitstatic_cast<VulkanWindow *>(m_window)->frameQueued(int(m_rotation) %360);
}