Add the Vulkan cube example

Features a little bit more than a cube, though.

Change-Id: I636d4875ba9ccf722ed3caab97f14570be785748
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
Laszlo Agocs 2017-03-24 14:54:24 +01:00
parent e7a7931ba1
commit c72b821b59
31 changed files with 5703 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -0,0 +1,58 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** 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.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example hellovulkancubes
\title Hello Vulkan Cubes Example
\ingroup examples-vulkan
\brief Shows the basics of using QVulkanWindow
The \e{Hello Vulkan Cubes Example} shows more advanced usage of QVulkanWindow.
\image hellovulkancubes.png
In this example there is a mesh loaded from a file and two different
materials and corresponding graphics pipelines. The rounded cubes are drawn
using instancing and feature a Phong lighting model with a single
directional light.
Unlike hellovulkantexture and hellovulkantriangle, the uniform buffer
handling takes an alternative approach here: dynamic uniform buffers are
used instead of multiple descriptor sets.
The example requires QtConcurrent since it demonstrates simple usage of
QtConcurrent::run(), QFuture, and QFutureWatcher in combination of
QVulkanWindow. Mesh and shader data loading, the potentially expensive
graphics pipeline construction, and the building of the frame command buffer
are all done in separate worker threads.
The scene is embedded into a widget-based user interface. The QVulkanWindow
subclass handles mouse and keyboard input as well since it provides a
first-person style camera in order to allow moving around in the scene.
\include examples-run.qdocinc
*/

View File

@ -0,0 +1,112 @@
/****************************************************************************
**
** 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 "camera.h"
Camera::Camera(const QVector3D &pos)
: m_forward(0.0f, 0.0f, -1.0f),
m_right(1.0f, 0.0f, 0.0f),
m_up(0.0f, 1.0f, 0.0f),
m_pos(pos),
m_yaw(0.0f),
m_pitch(0.0f)
{
}
static inline void clamp360(float *v)
{
if (*v > 360.0f)
*v -= 360.0f;
if (*v < -360.0f)
*v += 360.0f;
}
void Camera::yaw(float degrees)
{
m_yaw += degrees;
clamp360(&m_yaw);
m_yawMatrix.setToIdentity();
m_yawMatrix.rotate(m_yaw, 0, 1, 0);
QMatrix4x4 rotMat = m_pitchMatrix * m_yawMatrix;
m_forward = (QVector4D(0.0f, 0.0f, -1.0f, 0.0f) * rotMat).toVector3D();
m_right = (QVector4D(1.0f, 0.0f, 0.0f, 0.0f) * rotMat).toVector3D();
}
void Camera::pitch(float degrees)
{
m_pitch += degrees;
clamp360(&m_pitch);
m_pitchMatrix.setToIdentity();
m_pitchMatrix.rotate(m_pitch, 1, 0, 0);
QMatrix4x4 rotMat = m_pitchMatrix * m_yawMatrix;
m_forward = (QVector4D(0.0f, 0.0f, -1.0f, 0.0f) * rotMat).toVector3D();
m_up = (QVector4D(0.0f, 1.0f, 0.0f, 0.0f) * rotMat).toVector3D();
}
void Camera::walk(float amount)
{
m_pos[0] += amount * m_forward.x();
m_pos[2] += amount * m_forward.z();
}
void Camera::strafe(float amount)
{
m_pos[0] += amount * m_right.x();
m_pos[2] += amount * m_right.z();
}
QMatrix4x4 Camera::viewMatrix() const
{
QMatrix4x4 m = m_pitchMatrix * m_yawMatrix;
m.translate(-m_pos);
return m;
}

View File

@ -0,0 +1,80 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef CAMERA_H
#define CAMERA_H
#include <QVector3D>
#include <QMatrix4x4>
class Camera
{
public:
Camera(const QVector3D &pos);
void yaw(float degrees);
void pitch(float degrees);
void walk(float amount);
void strafe(float amount);
QMatrix4x4 viewMatrix() const;
private:
QVector3D m_forward;
QVector3D m_right;
QVector3D m_up;
QVector3D m_pos;
float m_yaw;
float m_pitch;
QMatrix4x4 m_yawMatrix;
QMatrix4x4 m_pitchMatrix;
};
#endif

View File

@ -0,0 +1,12 @@
#version 440
layout(push_constant) uniform PC {
layout(offset = 64) vec3 color;
} pc;
layout(location = 0) out vec4 fragColor;
void main()
{
fragColor = vec4(pc.color, 1.0);
}

View File

@ -0,0 +1,14 @@
#version 440
layout(location = 0) in vec4 position;
out gl_PerVertex { vec4 gl_Position; };
layout(push_constant) uniform PC {
mat4 mvp;
} pc;
void main()
{
gl_Position = pc.mvp * position;
}

Binary file not shown.

View File

@ -0,0 +1,39 @@
#version 440
layout(location = 0) in vec3 vECVertNormal;
layout(location = 1) in vec3 vECVertPos;
layout(location = 2) flat in vec3 vDiffuseAdjust;
layout(std140, binding = 1) uniform buf {
vec3 ECCameraPosition;
vec3 ka;
vec3 kd;
vec3 ks;
// Have one light only for now.
vec3 ECLightPosition;
vec3 attenuation;
vec3 color;
float intensity;
float specularExp;
} ubuf;
layout(location = 0) out vec4 fragColor;
void main()
{
vec3 unnormL = ubuf.ECLightPosition - vECVertPos;
float dist = length(unnormL);
float att = 1.0 / (ubuf.attenuation.x + ubuf.attenuation.y * dist + ubuf.attenuation.z * dist * dist);
vec3 N = normalize(vECVertNormal);
vec3 L = normalize(unnormL);
float NL = max(0.0, dot(N, L));
vec3 dColor = att * ubuf.intensity * ubuf.color * NL;
vec3 R = reflect(-L, N);
vec3 V = normalize(ubuf.ECCameraPosition - vECVertPos);
float RV = max(0.0, dot(R, V));
vec3 sColor = att * ubuf.intensity * ubuf.color * pow(RV, ubuf.specularExp);
fragColor = vec4(ubuf.ka + (ubuf.kd + vDiffuseAdjust) * dColor + ubuf.ks * sColor, 1.0);
}

View File

@ -0,0 +1,32 @@
#version 440
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 normal;
// Instanced attributes to variate the translation of the model and the diffuse
// color of the material.
layout(location = 2) in vec3 instTranslate;
layout(location = 3) in vec3 instDiffuseAdjust;
out gl_PerVertex { vec4 gl_Position; };
layout(location = 0) out vec3 vECVertNormal;
layout(location = 1) out vec3 vECVertPos;
layout(location = 2) flat out vec3 vDiffuseAdjust;
layout(std140, binding = 0) uniform buf {
mat4 vp;
mat4 model;
mat3 modelNormal;
} ubuf;
void main()
{
vECVertNormal = normalize(ubuf.modelNormal * normal);
mat4 t = mat4(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
instTranslate.x, instTranslate.y, instTranslate.z, 1);
vECVertPos = vec3(t * ubuf.model * position);
vDiffuseAdjust = instDiffuseAdjust;
gl_Position = ubuf.vp * t * ubuf.model * position;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
QT += widgets concurrent
HEADERS += \
mainwindow.h \
vulkanwindow.h \
renderer.h \
mesh.h \
shader.h \
camera.h
SOURCES += \
main.cpp \
mainwindow.cpp \
vulkanwindow.cpp \
renderer.cpp \
mesh.cpp \
shader.cpp \
camera.cpp
RESOURCES += hellovulkancubes.qrc
# install
target.path = $$[QT_INSTALL_EXAMPLES]/vulkan/hellovulkancubes
INSTALLS += target

View File

@ -0,0 +1,10 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="block.buf">../shared/block.buf</file>
<file alias="qt_logo.buf">../shared/qt_logo.buf</file>
<file>color_phong_vert.spv</file>
<file>color_phong_frag.spv</file>
<file>color_vert.spv</file>
<file>color_frag.spv</file>
</qresource>
</RCC>

View File

@ -0,0 +1,92 @@
/****************************************************************************
**
** 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 <QApplication>
#include <QLoggingCategory>
#include "mainwindow.h"
#include "vulkanwindow.h"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
const bool dbg = qEnvironmentVariableIntValue("QT_VK_DEBUG");
QVulkanInstance inst;
if (dbg) {
QLoggingCategory::setFilterRules(QStringLiteral("qt.vulkan=true"));
#ifndef Q_OS_ANDROID
inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation");
#else
inst.setLayers(QByteArrayList()
<< "VK_LAYER_GOOGLE_threading"
<< "VK_LAYER_LUNARG_parameter_validation"
<< "VK_LAYER_LUNARG_object_tracker"
<< "VK_LAYER_LUNARG_core_validation"
<< "VK_LAYER_LUNARG_image"
<< "VK_LAYER_LUNARG_swapchain"
<< "VK_LAYER_GOOGLE_unique_objects");
#endif
}
if (!inst.create())
qFatal("Failed to create Vulkan instance: %d", inst.errorCode());
VulkanWindow *vulkanWindow = new VulkanWindow(dbg);
vulkanWindow->setVulkanInstance(&inst);
MainWindow mainWindow(vulkanWindow);
mainWindow.resize(1024, 768);
mainWindow.show();
return app.exec();
}

View File

@ -0,0 +1,117 @@
/****************************************************************************
**
** 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 "mainwindow.h"
#include "vulkanwindow.h"
#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QLCDNumber>
#include <QCheckBox>
#include <QGridLayout>
MainWindow::MainWindow(VulkanWindow *vulkanWindow)
{
QWidget *wrapper = QWidget::createWindowContainer(vulkanWindow);
wrapper->setFocusPolicy(Qt::StrongFocus);
wrapper->setFocus();
infoLabel = new QLabel;
infoLabel->setFrameStyle(QFrame::Box | QFrame::Raised);
infoLabel->setAlignment(Qt::AlignCenter);
infoLabel->setText(tr("This example demonstrates instanced drawing\nof a mesh loaded from a file.\n"
"Uses a Phong material with a single light.\n"
"Also demonstrates dynamic uniform buffers\nand a bit of threading with QtConcurrent.\n"
"Uses 4x MSAA when available.\n"
"Comes with an FPS camera.\n"
"Hit [Shift+]WASD to walk and strafe.\nPress and move mouse to look around.\n"
"Click Add New to increase the number of instances."));
meshSwitch = new QCheckBox(tr("&Use Qt logo"));
meshSwitch->setFocusPolicy(Qt::NoFocus); // do not interfere with vulkanWindow's keyboard input
counterLcd = new QLCDNumber(5);
counterLcd->setSegmentStyle(QLCDNumber::Filled);
counterLcd->display(m_count);
newButton = new QPushButton(tr("&Add new"));
newButton->setFocusPolicy(Qt::NoFocus);
quitButton = new QPushButton(tr("&Quit"));
quitButton->setFocusPolicy(Qt::NoFocus);
pauseButton = new QPushButton(tr("&Pause"));
pauseButton->setFocusPolicy(Qt::NoFocus);
connect(quitButton, &QPushButton::clicked, qApp, &QCoreApplication::quit);
connect(newButton, &QPushButton::clicked, vulkanWindow, [=] {
vulkanWindow->addNew();
m_count = vulkanWindow->instanceCount();
counterLcd->display(m_count);
});
connect(pauseButton, &QPushButton::clicked, vulkanWindow, &VulkanWindow::togglePaused);
connect(meshSwitch, &QCheckBox::clicked, vulkanWindow, &VulkanWindow::meshSwitched);
QGridLayout *layout = new QGridLayout;
layout->addWidget(infoLabel, 0, 2);
layout->addWidget(meshSwitch, 1, 2);
layout->addWidget(createLabel(tr("INSTANCES")), 2, 2);
layout->addWidget(counterLcd, 3, 2);
layout->addWidget(newButton, 4, 2);
layout->addWidget(pauseButton, 5, 2);
layout->addWidget(quitButton, 6, 2);
layout->addWidget(wrapper, 0, 0, 7, 2);
setLayout(layout);
}
QLabel *MainWindow::createLabel(const QString &text)
{
QLabel *lbl = new QLabel(text);
lbl->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
return lbl;
}

View File

@ -0,0 +1,83 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLCDNumber;
class QLabel;
class QPushButton;
class QCheckBox;
QT_END_NAMESPACE
class VulkanWindow;
class MainWindow : public QWidget
{
public:
MainWindow(VulkanWindow *vulkanWindow);
private:
QLabel *createLabel(const QString &text);
QLabel *infoLabel;
QCheckBox *meshSwitch;
QLCDNumber *counterLcd;
QPushButton *newButton;
QPushButton *quitButton;
QPushButton *pauseButton;
int m_count = 128;
};
#endif

View File

@ -0,0 +1,98 @@
/****************************************************************************
**
** 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 "mesh.h"
#include <QtConcurrentRun>
#include <QFile>
void Mesh::load(const QString &fn)
{
reset();
m_maybeRunning = true;
m_future = QtConcurrent::run([fn]() {
MeshData md;
QFile f(fn);
if (!f.open(QIODevice::ReadOnly)) {
qWarning("Failed to open %s", qPrintable(fn));
return md;
}
QByteArray buf = f.readAll();
const char *p = buf.constData();
quint32 format;
memcpy(&format, p, 4);
if (format != 1) {
qWarning("Invalid format in %s", qPrintable(fn));
return md;
}
int ofs = 4;
memcpy(&md.vertexCount, p + ofs, 4);
ofs += 4;
memcpy(md.aabb, p + ofs, 6 * 4);
ofs += 6 * 4;
const int byteCount = md.vertexCount * 8 * 4;
md.geom.resize(byteCount);
memcpy(md.geom.data(), p + ofs, byteCount);
return md;
});
}
MeshData *Mesh::data()
{
if (m_maybeRunning && !m_data.isValid())
m_data = m_future.result();
return &m_data;
}
void Mesh::reset()
{
*data() = MeshData();
m_maybeRunning = false;
}

View File

@ -0,0 +1,79 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef MESH_H
#define MESH_H
#include <QString>
#include <QFuture>
struct MeshData
{
bool isValid() const { return vertexCount > 0; }
int vertexCount = 0;
float aabb[6];
QByteArray geom; // x, y, z, u, v, nx, ny, nz
};
class Mesh
{
public:
void load(const QString &fn);
MeshData *data();
bool isValid() { return data()->isValid(); }
void reset();
private:
bool m_maybeRunning = false;
QFuture<MeshData> m_future;
MeshData m_data;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef RENDERER_H
#define RENDERER_H
#include "vulkanwindow.h"
#include "mesh.h"
#include "shader.h"
#include "camera.h"
#include <QFutureWatcher>
#include <QMutex>
class Renderer : public QVulkanWindowRenderer
{
public:
Renderer(VulkanWindow *w, int initialCount);
void preInitResources() override;
void initResources() override;
void initSwapChainResources() override;
void releaseSwapChainResources() override;
void releaseResources() override;
void startNextFrame() override;
bool animating() const { return m_animating; }
void setAnimating(bool a) { m_animating = a; }
int instanceCount() const { return m_instCount; }
void addNew();
void yaw(float degrees);
void pitch(float degrees);
void walk(float amount);
void strafe(float amount);
void setUseLogo(bool b);
private:
void createPipelines();
void createItemPipeline();
void createFloorPipeline();
void ensureBuffers();
void ensureInstanceBuffer();
void getMatrices(QMatrix4x4 *mvp, QMatrix4x4 *model, QMatrix3x3 *modelNormal, QVector3D *eyePos);
void writeFragUni(quint8 *p, const QVector3D &eyePos);
void buildFrame();
void buildDrawCallsForItems();
void buildDrawCallsForFloor();
void markViewProjDirty() { m_vpDirty = m_window->concurrentFrameCount(); }
VulkanWindow *m_window;
QVulkanDeviceFunctions *m_devFuncs;
bool m_useLogo = false;
Mesh m_blockMesh;
Mesh m_logoMesh;
VkBuffer m_blockVertexBuf = VK_NULL_HANDLE;
VkBuffer m_logoVertexBuf = VK_NULL_HANDLE;
struct {
VkDeviceSize vertUniSize;
VkDeviceSize fragUniSize;
VkDeviceSize uniMemStartOffset;
Shader vs;
Shader fs;
VkDescriptorPool descPool = VK_NULL_HANDLE;
VkDescriptorSetLayout descSetLayout = VK_NULL_HANDLE;
VkDescriptorSet descSet;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
VkPipeline pipeline = VK_NULL_HANDLE;
} m_itemMaterial;
VkBuffer m_floorVertexBuf = VK_NULL_HANDLE;
struct {
Shader vs;
Shader fs;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
VkPipeline pipeline = VK_NULL_HANDLE;
} m_floorMaterial;
VkDeviceMemory m_bufMem = VK_NULL_HANDLE;
VkBuffer m_uniBuf = VK_NULL_HANDLE;
VkPipelineCache m_pipelineCache = VK_NULL_HANDLE;
QFuture<void> m_pipelinesFuture;
QVector3D m_lightPos;
Camera m_cam;
QMatrix4x4 m_proj;
int m_vpDirty = 0;
QMatrix4x4 m_floorModel;
bool m_animating;
float m_rotation = 0.0f;
int m_instCount;
int m_preparedInstCount = 0;
QByteArray m_instData;
VkBuffer m_instBuf = VK_NULL_HANDLE;
VkDeviceMemory m_instBufMem = VK_NULL_HANDLE;
QFutureWatcher<void> m_frameWatcher;
bool m_framePending;
QMutex m_guiMutex;
};
#endif

View File

@ -0,0 +1,94 @@
/****************************************************************************
**
** 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 "shader.h"
#include <QtConcurrentRun>
#include <QFile>
#include <QVulkanDeviceFunctions>
void Shader::load(QVulkanInstance *inst, VkDevice dev, const QString &fn)
{
reset();
m_maybeRunning = true;
m_future = QtConcurrent::run([inst, dev, fn]() {
ShaderData sd;
QFile f(fn);
if (!f.open(QIODevice::ReadOnly)) {
qWarning("Failed to open %s", qPrintable(fn));
return sd;
}
QByteArray blob = f.readAll();
VkShaderModuleCreateInfo shaderInfo;
memset(&shaderInfo, 0, sizeof(shaderInfo));
shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderInfo.codeSize = blob.size();
shaderInfo.pCode = reinterpret_cast<const uint32_t *>(blob.constData());
VkResult err = inst->deviceFunctions(dev)->vkCreateShaderModule(dev, &shaderInfo, nullptr, &sd.shaderModule);
if (err != VK_SUCCESS) {
qWarning("Failed to create shader module: %d", err);
return sd;
}
return sd;
});
}
ShaderData *Shader::data()
{
if (m_maybeRunning && !m_data.isValid())
m_data = m_future.result();
return &m_data;
}
void Shader::reset()
{
*data() = ShaderData();
m_maybeRunning = false;
}

View File

@ -0,0 +1,77 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef SHADER_H
#define SHADER_H
#include <QVulkanInstance>
#include <QFuture>
struct ShaderData
{
bool isValid() const { return shaderModule != VK_NULL_HANDLE; }
VkShaderModule shaderModule = VK_NULL_HANDLE;
};
class Shader
{
public:
void load(QVulkanInstance *inst, VkDevice dev, const QString &fn);
ShaderData *data();
bool isValid() { return data()->isValid(); }
void reset();
private:
bool m_maybeRunning = false;
QFuture<ShaderData> m_future;
ShaderData m_data;
};
#endif

View File

@ -0,0 +1,134 @@
/****************************************************************************
**
** 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 "vulkanwindow.h"
#include "renderer.h"
#include <QMouseEvent>
#include <QKeyEvent>
VulkanWindow::VulkanWindow(bool dbg)
: m_debug(dbg)
{
}
QVulkanWindowRenderer *VulkanWindow::createRenderer()
{
m_renderer = new Renderer(this, 128);
return m_renderer;
}
void VulkanWindow::addNew()
{
m_renderer->addNew();
}
void VulkanWindow::togglePaused()
{
m_renderer->setAnimating(!m_renderer->animating());
}
void VulkanWindow::meshSwitched(bool enable)
{
m_renderer->setUseLogo(enable);
}
void VulkanWindow::mousePressEvent(QMouseEvent *e)
{
m_pressed = true;
m_lastPos = e->pos();
}
void VulkanWindow::mouseReleaseEvent(QMouseEvent *)
{
m_pressed = false;
}
void VulkanWindow::mouseMoveEvent(QMouseEvent *e)
{
if (!m_pressed)
return;
int dx = e->pos().x() - m_lastPos.x();
int dy = e->pos().y() - m_lastPos.y();
if (dy)
m_renderer->pitch(dy / 10.0f);
if (dx)
m_renderer->yaw(dx / 10.0f);
m_lastPos = e->pos();
}
void VulkanWindow::keyPressEvent(QKeyEvent *e)
{
const float amount = e->modifiers().testFlag(Qt::ShiftModifier) ? 1.0f : 0.1f;
switch (e->key()) {
case Qt::Key_W:
m_renderer->walk(amount);
break;
case Qt::Key_S:
m_renderer->walk(-amount);
break;
case Qt::Key_A:
m_renderer->strafe(-amount);
break;
case Qt::Key_D:
m_renderer->strafe(amount);
break;
default:
break;
}
}
int VulkanWindow::instanceCount() const
{
return m_renderer->instanceCount();
}

View File

@ -0,0 +1,85 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef VULKANWINDOW_H
#define VULKANWINDOW_H
#include <QVulkanWindow>
class Renderer;
class VulkanWindow : public QVulkanWindow
{
public:
VulkanWindow(bool dbg);
QVulkanWindowRenderer *createRenderer() override;
bool isDebugEnabled() const { return m_debug; }
int instanceCount() const;
public slots:
void addNew();
void togglePaused();
void meshSwitched(bool enable);
private:
void mousePressEvent(QMouseEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
void mouseMoveEvent(QMouseEvent *) override;
void keyPressEvent(QKeyEvent *) override;
bool m_debug;
Renderer *m_renderer;
bool m_pressed = false;
QPoint m_lastPos;
};
#endif

Binary file not shown.

View File

@ -0,0 +1,100 @@
# Blender v2.78 (sub 0) OBJ File: ''
# www.blender.org
mtllib block.mtl
o Cube_Cube.001
v 0.450000 -0.500000 -0.450000
v 0.450000 -0.500000 0.450000
v -0.450000 -0.500000 0.450000
v -0.450000 -0.500000 -0.450000
v -0.500000 0.450000 0.450000
v -0.500000 0.450000 -0.450000
v -0.500000 -0.450000 -0.450000
v -0.500000 -0.450000 0.450000
v -0.450000 0.500000 -0.450000
v -0.450000 0.500000 0.450000
v 0.450000 0.500000 0.450000
v 0.450000 0.500000 -0.450000
v -0.450000 0.450000 -0.500000
v 0.450000 0.450000 -0.500000
v 0.450000 -0.450000 -0.500000
v -0.450000 -0.450000 -0.500000
v 0.450000 0.450000 0.500000
v -0.450000 0.450000 0.500000
v -0.450000 -0.450000 0.500000
v 0.450000 -0.450000 0.500000
v 0.500000 -0.450000 -0.450000
v 0.500000 0.450000 -0.450000
v 0.500000 -0.450000 0.450000
v 0.500000 0.450000 0.450000
vn 0.0000 -1.0000 -0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 -0.0000 1.0000
vn 0.5774 -0.5773 -0.5774
vn 0.5774 0.5774 -0.5774
vn 0.5774 -0.5774 0.5774
vn 0.5774 0.5773 0.5774
vn -0.5774 -0.5773 -0.5774
vn -0.5773 0.5774 -0.5774
vn -0.5774 -0.5774 0.5774
vn -0.5774 0.5773 0.5774
vn 0.7071 0.0000 -0.7071
vn 0.7071 0.7071 0.0000
vn 0.7071 -0.0000 0.7071
vn 0.7071 -0.7071 -0.0000
vn 0.0000 0.7071 0.7071
vn -0.7071 -0.0000 0.7071
vn 0.0000 -0.7071 0.7071
vn -0.7071 0.7071 0.0000
vn -0.7071 0.0000 -0.7071
vn -0.7071 -0.7071 -0.0000
vn 0.0000 0.7071 -0.7071
vn 0.0000 -0.7071 -0.7071
vn 1.0000 0.0000 0.0000
usemtl None
s 1
f 2//1 4//1 1//1
f 6//2 8//2 5//2
f 10//3 12//3 9//3
f 14//4 16//4 13//4
f 18//5 20//5 17//5
f 15//6 21//6 1//6
f 14//7 12//7 22//7
f 20//8 2//8 23//8
f 11//9 17//9 24//9
f 16//10 4//10 7//10
f 9//11 13//11 6//11
f 8//12 3//12 19//12
f 10//13 5//13 18//13
f 14//14 21//14 15//14
f 11//15 22//15 12//15
f 20//16 24//16 17//16
f 1//17 23//17 2//17
f 10//18 17//18 11//18
f 8//19 18//19 5//19
f 2//20 19//20 3//20
f 9//21 5//21 10//21
f 16//22 6//22 13//22
f 3//23 7//23 4//23
f 12//24 13//24 9//24
f 4//25 15//25 1//25
f 24//26 21//26 22//26
f 2//1 3//1 4//1
f 6//2 7//2 8//2
f 10//3 11//3 12//3
f 14//4 15//4 16//4
f 18//5 19//5 20//5
f 14//14 22//14 21//14
f 11//15 24//15 22//15
f 20//16 23//16 24//16
f 1//17 21//17 23//17
f 10//18 18//18 17//18
f 8//19 19//19 18//19
f 2//20 20//20 19//20
f 9//21 6//21 5//21
f 16//22 7//22 6//22
f 3//23 8//23 7//23
f 12//24 14//24 13//24
f 4//25 16//25 15//25
f 24//26 23//26 21//26

View File

@ -0,0 +1,241 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
var fs = require('fs');
var metadata = {
vertexCount: 0,
aabb: [[null, null], [null, null], [null, null]],
emitVertex: function(v) {
++metadata.vertexCount;
var aabb = metadata.aabb;
if (aabb[0][0] === null || v[0] < aabb[0][0]) // min x
aabb[0][0] = v[0];
if (aabb[0][1] === null || v[0] > aabb[0][1]) // max x
aabb[0][1] = v[0];
if (aabb[1][0] === null || v[1] < aabb[1][0]) // min y
aabb[1][0] = v[1];
if (aabb[1][1] === null || v[1] > aabb[1][1]) // max y
aabb[1][1] = v[1];
if (aabb[2][0] === null || v[2] < aabb[2][0]) // min z
aabb[2][0] = v[2];
if (aabb[2][1] === null || v[2] > aabb[2][1]) // max z
aabb[2][1] = v[2];
},
getBuffer: function() {
var aabb = metadata.aabb;
console.log(metadata.vertexCount + " vertices");
console.log("AABB: " + aabb[0][0] + ".." + aabb[0][1]
+ ", " + aabb[1][0] + ".." + aabb[1][1]
+ ", " + aabb[2][0] + ".." + aabb[2][1]);
var buf = new Buffer((2 + 6) * 4);
var format = 1, p = 0;
buf.writeUInt32LE(format, p++);
buf.writeUInt32LE(metadata.vertexCount, p++ * 4);
for (var i = 0; i < 3; ++i) {
buf.writeFloatLE(aabb[i][0], p++ * 4);
buf.writeFloatLE(aabb[i][1], p++ * 4);
}
return buf;
}
};
function makeVec(s, n) {
var v = [];
s.split(' ').forEach(function (coordStr) {
var coord = parseFloat(coordStr);
if (!isNaN(coord))
v.push(coord);
});
if (v.length != n) {
console.error("Wrong vector size, expected " + n + ", got " + v.length);
process.exit();
}
return v;
}
function parseObj(filename, callback) {
fs.readFile(filename, "ascii", function (err, data) {
if (err)
throw err;
var groupCount = 0;
var parsed = { 'vertices': [], 'normals': [], 'texcoords': [], 'links': [] };
var missingTexCount = 0, missingNormCount = 0;
data.split('\n').forEach(function (line) {
var s = line.trim();
if (!s.length || groupCount > 1)
return;
if (s[0] === '#')
return;
if (s[0] === 'g') {
++groupCount;
} else if (s.substr(0, 2) === "v ") {
parsed.vertices.push(makeVec(s, 3));
} else if (s.substr(0, 3) === "vn ") {
parsed.normals.push(makeVec(s, 3));
} else if (s.substr(0, 3) === "vt ") {
parsed.texcoords.push(makeVec(s, 2));
} else if (s.substr(0, 2) === "f ") {
var refs = s.split(' ');
var vertCount = refs.length - 1;
if (vertCount != 3)
console.warn("Face " + parsed.links.length / 3 + " has " + vertCount + " vertices! (not triangulated?)");
for (var i = 1, ie = Math.min(4, refs.length); i < ie; ++i) {
var refComps = refs[i].split('/');
var vertIndex = parseInt(refComps[0]) - 1;
var texIndex = -1;
if (refComps.length >= 2 && refComps[1].length)
texIndex = parseInt(refComps[1]) - 1;
var normIndex = -1;
if (refComps.length >= 3 && refComps[2].length)
normIndex = parseInt(refComps[2]) - 1;
parsed.links.push([vertIndex, texIndex, normIndex]);
if (texIndex == -1)
++missingTexCount;
if (normIndex == -1)
++missingNormCount;
}
}
});
console.log(missingTexCount + " missing texture coordinates, " + missingNormCount + " missing normals");
callback(parsed);
});
}
function fillVert(src, index, dst, elemCount, isVertexCoord) {
var vertex = [];
if (index >= 0) {
for (var i = 0; i < elemCount; ++i) {
var elem = src[index][i];
if (isVertexCoord)
vertex.push(elem);
dst.buf.writeFloatLE(elem, dst.bufptr++ * 4);
}
if (vertex.length == 3)
metadata.emitVertex(vertex);
} else {
if (isVertexCoord) {
console.error("Missing vertex");
process.exit();
}
for (var i = 0; i < elemCount; ++i)
dst.buf.writeFloatLE(0, dst.bufptr++ * 4);
}
return vertex;
}
function normalize(v) {
var len = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
if (len == 0.0 || len == 1.0)
return;
len = Math.sqrt(len);
return [ v[0] / len, v[1] / len, v[2] / len ];
}
function surfaceNormal(a, b, c) {
var u = [ b[0] - a[0], b[1] - a[1], b[2] - a[2] ];
var v = [ c[0] - a[0], c[1] - a[1], c[2] - a[2] ];
var result = [ u[1] * v[2] - u[2] * v[1],
u[2] * v[0] - u[0] * v[2],
u[0] * v[1] - u[1] * v[0] ];
return normalize(result);
}
function objDataToBuf(parsed) {
var floatCount = parsed.links.length * (3 + 2 + 3);
var buf = new Buffer(floatCount * 4);
var dst = { 'buf': buf, 'bufptr': 0 };
var tri = [];
var genNormals = false;
var genNormCount = 0;
for (var i = 0; i < parsed.links.length; ++i) {
var link = parsed.links[i];
var vertIndex = link[0], texIndex = link[1], normIndex = link[2];
tri.push(fillVert(parsed.vertices, vertIndex, dst, 3, true));
fillVert(parsed.texcoords, texIndex, dst, 2);
fillVert(parsed.normals, normIndex, dst, 3);
if (normIndex == -1)
genNormals = true;
if (tri.length == 3) {
if (genNormals) {
var norm = surfaceNormal(tri[0], tri[1], tri[2]);
for (var nvIdx = 0; nvIdx < 3; ++nvIdx) {
dst.buf.writeFloatLE(norm[0], (dst.bufptr - 3 - nvIdx * 8) * 4);
dst.buf.writeFloatLE(norm[1], (dst.bufptr - 2 - nvIdx * 8) * 4);
dst.buf.writeFloatLE(norm[2], (dst.bufptr - 1 - nvIdx * 8) * 4);
}
genNormCount += 3;
}
tri = [];
}
}
if (genNormCount)
console.log("Generated " + genNormCount + " normals");
return buf;
}
var inFilename = process.argv[2];
var outFilename = process.argv[3];
if (process.argv.length < 4) {
console.log("Usage: objconvert file.obj file.buf");
process.exit();
}
parseObj(inFilename, function (parsed) {
var buf = objDataToBuf(parsed);
var f = fs.createWriteStream(outFilename);
f.on("error", function (e) { console.error(e); });
f.write(metadata.getBuffer());
f.write(buf);
f.end();
console.log("Written to " + outFilename + ", format is:");
console.log(" uint32 version, uint32 vertex_count, float32 aabb[6], vertex_count * (float32 vertex[3], float32 texcoord[2], float32 normal[3])");
});

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -4,4 +4,7 @@ SUBDIRS = hellovulkanwindow \
hellovulkantriangle \
hellovulkantexture
qtHaveModule(widgets): SUBDIRS += hellovulkanwidget
qtHaveModule(widgets) {
SUBDIRS += hellovulkanwidget
qtHaveModule(concurrent): SUBDIRS += hellovulkancubes
}