summaryrefslogtreecommitdiffstats
path: root/examples/vulkan/hellovulkancubes/renderer.h
blob: c1500f8c8d569d2131f7519a47f1a94f50393c48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

#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