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
|
#include "first_app.hpp"
#include "xe_camera.hpp"
#include "xe_game_object.hpp"
#include "xe_model.hpp"
#include "keyboard_movement_controller.hpp"
#define GLM_FORCE_RADIANS
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
#include <array>
#include <chrono>
#include <cassert>
#include <stdexcept>
#include <iostream>
namespace xe {
struct UniformBuffer {
alignas(16) glm::mat4 projectionView{1.f};
alignas(4) glm::vec3 lightDirection = glm::normalize(glm::vec3{-1.f, 3.f, 1.f});
};
struct PushConstant {
alignas(16) glm::mat4 modelMatrix{1.f};
alignas(16) glm::mat4 normalMatrix{1.f};
};
FirstApp::FirstApp() : xeEngine{WIDTH, HEIGHT, "Hello, Vulkan!"} {
loadGameObjects();
}
FirstApp::~FirstApp() {}
void FirstApp::run() {
std::unique_ptr<XeRenderSystem> simpleRenderSystem = xeEngine.createRenderSystem(
"res/shaders/simple_shader.vert.spv",
"res/shaders/simple_shader.frag.spv",
sizeof(PushConstant),
sizeof(UniformBuffer));
XeCamera camera{};
camera.setViewTarget(glm::vec3(-1.f, -2.f, 20.f), glm::vec3(0.f, 0.f, 2.5f));
auto viewerObject = XeGameObject::createGameObject();
KeyboardMovementController cameraController{};
auto currentTime = std::chrono::high_resolution_clock::now();
while (!xeEngine.getWindow().shouldClose()) {
glfwPollEvents();
auto newTime = std::chrono::high_resolution_clock::now();
float frameTime = std::chrono::duration<float, std::chrono::seconds::period>(newTime - currentTime).count();
currentTime = newTime;
cameraController.moveInPlaneXZ(xeEngine.getWindow().getGLFWwindow(), frameTime, viewerObject);
camera.setViewYXZ(viewerObject.transform.translation, viewerObject.transform.rotation);
float aspect = xeEngine.getRenderer().getAspectRatio();
camera.setPerspectiveProjection(glm::radians(50.f), aspect, 0.1f, 100.f);
if(xeEngine.beginFrame()) {
PushConstant pc{};
pc.modelMatrix = gameObjects[0].transform.mat4();
pc.normalMatrix = gameObjects[0].transform.normalMatrix();
UniformBuffer ubo{};
ubo.projectionView = camera.getProjection() * camera.getView();
xeEngine.render(
*simpleRenderSystem,
gameObjects,
&pc,
sizeof(pc),
&ubo,
sizeof(ubo)
);
xeEngine.endFrame();
}
}
xeEngine.close();
}
void FirstApp::loadGameObjects() {
std::shared_ptr<XeModel> xeModel = xeEngine.createModel("res/models/stanford-dragon.obj");
auto cube = XeGameObject::createGameObject();
cube.model = xeModel;
cube.transform.translation = {.0f, .0f, 2.5f};
cube.transform.scale = {.5f, .5f, .5f};
gameObjects.push_back(std::move(cube));
}
}
|