-
Notifications
You must be signed in to change notification settings - Fork 2
/
05-mesh.cpp
128 lines (115 loc) · 4.11 KB
/
05-mesh.cpp
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "../framework/vulkanApp.h"
#include "quadric/include/teapot.h"
class MeshApp : public VulkanApp
{
struct DescriptorSetTable : magma::DescriptorSetTable
{
magma::descriptor::UniformBuffer worldViewProj = 0;
MAGMA_REFLECT(worldViewProj)
} setTable;
std::unique_ptr<quadric::Teapot> mesh;
std::shared_ptr<magma::UniformBuffer<rapid::matrix>> uniformBuffer;
std::shared_ptr<magma::DescriptorSet> descriptorSet;
std::shared_ptr<magma::GraphicsPipeline> wireframePipeline;
rapid::matrix viewProj;
public:
MeshApp(const AppEntry& entry):
VulkanApp(entry, TEXT("05 - Mesh"), 512, 512, true)
{
initialize();
setupView();
createMesh();
createUniformBuffer();
setupDescriptorSet();
setupPipeline();
recordCommandBuffer(Buffer::Front);
recordCommandBuffer(Buffer::Back);
timer->run();
}
void render(uint32_t bufferIndex) override
{
updatePerspectiveTransform();
submitCommandBuffer(bufferIndex);
}
void setupView()
{
const rapid::vector3 eye(0.f, 3.f, 8.f);
const rapid::vector3 center(0.f, 2.f, 0.f);
const rapid::vector3 up(0.f, 1.f, 0.f);
constexpr float fov = rapid::radians(60.f);
const float aspect = width/(float)height;
constexpr float zn = 1.f, zf = 100.f;
const rapid::matrix view = rapid::lookAtRH(eye, center, up);
const rapid::matrix proj = rapid::perspectiveFovRH(fov, aspect, zn, zf);
viewProj = view * proj;
}
void updatePerspectiveTransform()
{
constexpr float speed = 0.05f;
static float angle = 0.f;
angle += timer->millisecondsElapsed() * speed;
const rapid::matrix world = rapid::rotationY(rapid::radians(angle));
magma::helpers::mapScoped(uniformBuffer,
[this, &world](auto *worldViewProj)
{
*worldViewProj = world * viewProj;
});
}
void createMesh()
{
constexpr uint16_t subdivisionDegree = 4;
mesh = std::make_unique<quadric::Teapot>(subdivisionDegree, cmdBufferCopy);
}
void createUniformBuffer()
{
uniformBuffer = std::make_shared<magma::UniformBuffer<rapid::matrix>>(device);
}
void setupDescriptorSet()
{
setTable.worldViewProj = uniformBuffer;
descriptorSet = std::make_shared<magma::DescriptorSet>(descriptorPool,
setTable, VK_SHADER_STAGE_VERTEX_BIT,
nullptr, 0, shaderReflectionFactory, "transform");
}
void setupPipeline()
{
std::unique_ptr<magma::PipelineLayout> layout = std::make_unique<magma::PipelineLayout>(descriptorSet->getLayout());
wireframePipeline = std::make_shared<GraphicsPipeline>(device,
"transform", "normal",
mesh->getVertexInput(),
magma::renderstate::triangleList,
negateViewport ? magma::renderstate::lineCullBackCcw
: magma::renderstate::lineCullBackCw,
magma::renderstate::dontMultisample,
magma::renderstate::depthLessOrEqual,
magma::renderstate::dontBlendRgb,
std::move(layout),
renderPass, 0,
pipelineCache);
}
void recordCommandBuffer(uint32_t index)
{
auto& cmdBuffer = commandBuffers[index];
cmdBuffer->begin();
{
cmdBuffer->beginRenderPass(renderPass, framebuffers[index],
{
magma::clear::gray,
magma::clear::depthOne
});
{
cmdBuffer->setViewport(0, 0, width, negateViewport ? -height : height);
cmdBuffer->setScissor(0, 0, width, height);
cmdBuffer->bindDescriptorSet(wireframePipeline, 0, descriptorSet);
cmdBuffer->bindPipeline(wireframePipeline);
mesh->draw(cmdBuffer);
}
cmdBuffer->endRenderPass();
}
cmdBuffer->end();
}
};
std::unique_ptr<IApplication> appFactory(const AppEntry& entry)
{
return std::unique_ptr<MeshApp>(new MeshApp(entry));
}