2018-09-26 17:51:22 -04:00
|
|
|
#include <SDL.h>
|
2018-09-29 21:03:06 -04:00
|
|
|
#include <SDL_vulkan.h>
|
2018-10-01 21:02:27 -04:00
|
|
|
#include <iostream>
|
2018-10-17 10:32:31 -04:00
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
2018-11-05 10:26:54 -05:00
|
|
|
#include <json.hpp>
|
2018-10-16 08:49:25 -04:00
|
|
|
#include <assimp/Importer.hpp>
|
|
|
|
#include <assimp/scene.h>
|
|
|
|
#include <assimp/postprocess.h>
|
2018-11-05 20:51:23 -05:00
|
|
|
#include <imgui.h>
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-09-27 20:09:42 -04:00
|
|
|
#include "renderer.h"
|
2018-09-29 21:03:06 -04:00
|
|
|
#include "platform.h"
|
2018-10-16 08:49:25 -04:00
|
|
|
#include "world.h"
|
|
|
|
#include "mesh.h"
|
2018-10-18 21:46:48 -04:00
|
|
|
#include "light.h"
|
2018-10-25 08:57:36 -04:00
|
|
|
#include "camera.h"
|
2018-10-30 21:13:36 -04:00
|
|
|
#include "cinematic.h"
|
2018-11-06 09:08:55 -05:00
|
|
|
#include "material.h"
|
2018-11-08 12:51:32 -05:00
|
|
|
#include "config.h"
|
2018-09-29 21:03:06 -04:00
|
|
|
|
|
|
|
SDL_Window* window = nullptr;
|
2018-10-30 21:13:36 -04:00
|
|
|
Renderer* renderer = nullptr;
|
2018-09-29 21:03:06 -04:00
|
|
|
|
|
|
|
std::vector<const char*> platform::getRequiredExtensions() {
|
|
|
|
uint32_t count = 0;
|
|
|
|
SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr);
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
std::vector<const char*> names(count);
|
|
|
|
SDL_Vulkan_GetInstanceExtensions(window, &count, names.data());
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
return names;
|
|
|
|
}
|
2018-09-26 17:51:22 -04:00
|
|
|
|
2018-10-01 19:39:26 -04:00
|
|
|
uint32_t platform::getTime() {
|
|
|
|
return SDL_GetTicks();
|
|
|
|
}
|
|
|
|
|
2018-10-17 10:32:31 -04:00
|
|
|
int windowX = SDL_WINDOWPOS_CENTERED;
|
|
|
|
int windowY = SDL_WINDOWPOS_CENTERED;
|
|
|
|
int windowWidth = 640;
|
|
|
|
int windowHeight = 480;
|
2018-10-17 17:11:26 -04:00
|
|
|
int windowFullscreen = 0;
|
2018-11-08 12:51:32 -05:00
|
|
|
std::string currentGraphicsPreset = "Medium";
|
|
|
|
GraphicsConfig graphicsConfig;
|
2018-10-17 10:32:31 -04:00
|
|
|
|
|
|
|
int toInt(const std::string &str) {
|
|
|
|
std::stringstream ss(str);
|
|
|
|
|
|
|
|
int num;
|
|
|
|
if((ss >> num).fail())
|
|
|
|
return -1;
|
2018-10-26 20:56:06 -04:00
|
|
|
|
|
|
|
return num;
|
2018-10-17 10:32:31 -04:00
|
|
|
}
|
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
void loadGraphicsConfig() {
|
|
|
|
Config config;
|
|
|
|
if(!config.load("data/graphics_presets.cfg"))
|
2018-10-17 17:19:38 -04:00
|
|
|
return;
|
2018-10-17 10:32:31 -04:00
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
graphicsConfig.shadowResolution = toInt(config.get(currentGraphicsPreset.c_str(), "shadowResolution"));
|
2018-11-08 13:01:54 -05:00
|
|
|
graphicsConfig.dofDownscale = toInt(config.get(currentGraphicsPreset.c_str(), "dofDownscale"));
|
2018-10-17 10:32:31 -04:00
|
|
|
}
|
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
void readConfig() {
|
|
|
|
Config config;
|
|
|
|
if(!config.load("user.cfg"))
|
2018-10-17 17:19:38 -04:00
|
|
|
return;
|
2018-10-17 10:32:31 -04:00
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
windowX = toInt(config.get("Window", "x"));
|
|
|
|
windowY = toInt(config.get("Window", "y"));
|
|
|
|
windowWidth = toInt(config.get("Window", "width"));
|
|
|
|
windowHeight = toInt(config.get("Window", "height"));
|
|
|
|
windowFullscreen = toInt(config.get("Window", "fullscreen"));
|
|
|
|
|
|
|
|
currentGraphicsPreset = config.get("Graphics", "preset");
|
2018-11-08 13:27:24 -05:00
|
|
|
graphicsConfig.vsync = toInt(config.get("Graphics", "vsync"));
|
2018-10-17 10:32:31 -04:00
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
loadGraphicsConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeConfig() {
|
|
|
|
Config config;
|
2018-10-17 10:32:31 -04:00
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
config.set("Window", "x", std::to_string(windowX));
|
|
|
|
config.set("Window", "y", std::to_string(windowY));
|
|
|
|
config.set("Window", "width", std::to_string(windowWidth));
|
|
|
|
config.set("Window", "height", std::to_string(windowHeight));
|
|
|
|
config.set("Window", "fullscreen", std::to_string(windowFullscreen));
|
2018-10-17 10:32:31 -04:00
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
config.set("Graphics", "preset", currentGraphicsPreset);
|
2018-11-08 13:27:24 -05:00
|
|
|
config.set("Graphics", "vsync", std::to_string(graphicsConfig.vsync));
|
2018-10-25 08:40:24 -04:00
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
config.save("user.cfg");
|
2018-10-17 10:32:31 -04:00
|
|
|
}
|
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
Mesh* loadMesh(const char* path) {
|
2018-10-16 08:49:25 -04:00
|
|
|
Assimp::Importer importer;
|
2018-10-30 21:13:36 -04:00
|
|
|
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate);
|
2018-10-16 08:49:25 -04:00
|
|
|
|
|
|
|
Mesh* mesh = new Mesh();
|
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
unsigned int indexOffset = 0;
|
|
|
|
for(unsigned mi = 0; mi < scene->mNumMeshes; mi++) {
|
|
|
|
aiMesh* m = scene->mMeshes[mi];
|
2018-11-05 10:26:54 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
for(unsigned int i = 0; i < m->mNumVertices; i++) {
|
|
|
|
Vertex vertex;
|
|
|
|
vertex.position = glm::vec3(m->mVertices[i].x, m->mVertices[i].y, m->mVertices[i].z);
|
|
|
|
vertex.normal = glm::vec3(m->mNormals[i].x, m->mNormals[i].y, m->mNormals[i].z);
|
2018-11-06 09:08:55 -05:00
|
|
|
vertex.uv = glm::vec2(m->mTextureCoords[0][i].x, m->mTextureCoords[0][i].y);
|
2018-10-17 10:32:31 -04:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
mesh->vertices.push_back(vertex);
|
|
|
|
}
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
for(unsigned int i = 0; i < m->mNumFaces; i++) {
|
|
|
|
aiFace face = m->mFaces[i];
|
|
|
|
for(unsigned int j = 0; j < face.mNumIndices; j++)
|
|
|
|
mesh->indices.push_back(indexOffset + face.mIndices[j]);
|
|
|
|
}
|
2018-11-05 10:26:54 -05:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
indexOffset += m->mNumVertices;
|
2018-10-16 08:49:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
renderer->fillMeshBuffers(mesh);
|
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
return mesh;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> tokenize(const std::string& str) {
|
|
|
|
size_t lastPos = str.find_first_not_of(',', 0);
|
|
|
|
size_t pos = str.find_first_of(',', lastPos);
|
|
|
|
|
|
|
|
std::vector<std::string> tokens;
|
|
|
|
while(pos != std::string::npos || lastPos != std::string::npos) {
|
|
|
|
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
|
|
|
|
|
|
|
lastPos = str.find_first_not_of(',', pos);
|
|
|
|
pos = str.find_first_of(',', lastPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
return tokens;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cinematic* loadCinematic(const char* path) {
|
|
|
|
std::ifstream file(path);
|
|
|
|
if(!file)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
nlohmann::json json;
|
|
|
|
file >> json;
|
|
|
|
|
2018-11-03 20:36:05 -04:00
|
|
|
auto cinematic = new Cinematic();
|
2018-10-30 21:13:36 -04:00
|
|
|
for(auto shotObject : json["shots"]) {
|
|
|
|
Shot* shot = new Shot();
|
|
|
|
shot->start = shotObject["start"];
|
|
|
|
shot->end = shotObject["end"];
|
|
|
|
|
|
|
|
for(auto meshObject : shotObject["meshes"]) {
|
|
|
|
Mesh* mesh = loadMesh(meshObject["path"].get<std::string>().c_str());
|
|
|
|
mesh->name = meshObject["name"];
|
|
|
|
|
|
|
|
shot->meshes.push_back(mesh);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(auto animationObject : shotObject["animations"]) {
|
2018-11-03 20:36:05 -04:00
|
|
|
auto animation = new Animation();
|
2018-10-30 21:13:36 -04:00
|
|
|
for(auto mesh : shot->meshes) {
|
|
|
|
if(mesh->name == animationObject["target"])
|
|
|
|
animation->target = mesh;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto property = animationObject["property"];
|
|
|
|
if(property == "position")
|
|
|
|
animation->property = AnimationProperty::Position;
|
|
|
|
|
|
|
|
for(auto keyframeObject : animationObject["keyframes"]) {
|
|
|
|
Keyframe keyframe;
|
|
|
|
keyframe.time = keyframeObject["time"];
|
|
|
|
|
|
|
|
auto tokens = tokenize(keyframeObject["value"]);
|
|
|
|
|
|
|
|
keyframe.value[0] = atof(tokens[0].c_str());
|
|
|
|
keyframe.value[1] = atof(tokens[1].c_str());
|
|
|
|
keyframe.value[2] = atof(tokens[2].c_str());
|
|
|
|
|
|
|
|
animation->keyframes.push_back(keyframe);
|
|
|
|
}
|
|
|
|
|
|
|
|
shot->animations.push_back(animation);
|
|
|
|
}
|
|
|
|
|
|
|
|
cinematic->shots.push_back(shot);
|
|
|
|
}
|
|
|
|
|
|
|
|
return cinematic;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cinematic* cinematic = nullptr;
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
readConfig();
|
|
|
|
|
|
|
|
bool cinematicMode = false;
|
|
|
|
if(argc > 2 && strcmp(argv[1], "--cinematic") == 0)
|
|
|
|
cinematicMode = true;
|
|
|
|
|
|
|
|
window = SDL_CreateWindow("Graph",
|
|
|
|
windowX,
|
|
|
|
windowY,
|
|
|
|
windowWidth,
|
|
|
|
windowHeight,
|
|
|
|
SDL_WINDOW_VULKAN |
|
|
|
|
SDL_WINDOW_RESIZABLE);
|
|
|
|
if(window == nullptr)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
SDL_SetWindowFullscreen(window, windowFullscreen == 1 ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
ImGui::CreateContext();
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
auto& io = ImGui::GetIO();
|
|
|
|
io.DisplaySize = ImVec2(windowWidth, windowHeight);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
ImGui::StyleColorsDark();
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-08 12:51:32 -05:00
|
|
|
renderer = new Renderer(graphicsConfig);
|
2018-10-30 21:13:36 -04:00
|
|
|
|
|
|
|
VkSurfaceKHR surface = nullptr;
|
|
|
|
SDL_Vulkan_CreateSurface(window, renderer->getInstance(), &surface);
|
|
|
|
|
|
|
|
RenderTarget* target = renderer->createSurfaceRenderTarget(surface);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-10-16 08:49:25 -04:00
|
|
|
World world;
|
2018-10-25 08:40:24 -04:00
|
|
|
|
2018-10-26 20:56:06 -04:00
|
|
|
auto light = new Light();
|
2018-11-07 05:27:00 -05:00
|
|
|
light->type = LightType::Directional;
|
2018-11-08 08:57:41 -05:00
|
|
|
light->position = glm::vec3(66, 56, 25);
|
2018-10-25 08:40:24 -04:00
|
|
|
|
2018-10-18 21:46:48 -04:00
|
|
|
world.lights.push_back(light);
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-10-25 08:57:36 -04:00
|
|
|
Camera camera;
|
2018-11-03 07:24:32 -04:00
|
|
|
camera.position = {5.0, 5.0, 5.0};
|
2018-10-25 08:57:36 -04:00
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
if(cinematicMode)
|
|
|
|
cinematic = loadCinematic(argv[2]);
|
2018-11-06 09:08:55 -05:00
|
|
|
else {
|
|
|
|
Material* material = new Material();
|
|
|
|
material->albedoTexturePath = "data/tile.jpg";
|
|
|
|
|
|
|
|
renderer->fillMaterialBuffers(material);
|
|
|
|
|
|
|
|
Mesh* mesh = loadMesh("data/scene.obj");
|
|
|
|
mesh->material = material;
|
|
|
|
|
|
|
|
world.meshes.push_back(mesh);
|
|
|
|
}
|
2018-10-30 21:13:36 -04:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
float currentTime = 0.0f, lastTime = 0.0f, animationTime = 0.0f;
|
2018-10-30 21:13:36 -04:00
|
|
|
Shot* currentShot = nullptr;
|
|
|
|
|
2018-09-26 17:51:22 -04:00
|
|
|
bool running = true;
|
2018-11-06 09:08:55 -05:00
|
|
|
while(running) {
|
2018-09-26 17:51:22 -04:00
|
|
|
SDL_Event event = {};
|
2018-10-26 20:56:06 -04:00
|
|
|
while(SDL_PollEvent(&event) > 0) {
|
2018-09-26 17:51:22 -04:00
|
|
|
if(event.type == SDL_QUIT)
|
|
|
|
running = false;
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-10-01 21:02:27 -04:00
|
|
|
if(event.type == SDL_WINDOWEVENT) {
|
2018-11-05 20:51:23 -05:00
|
|
|
if(event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
|
|
|
io.DisplaySize = ImVec2(event.window.data1, event.window.data2);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-10-01 21:02:27 -04:00
|
|
|
target = renderer->createSurfaceRenderTarget(surface, target);
|
2018-11-05 20:51:23 -05:00
|
|
|
}
|
2018-10-01 21:02:27 -04:00
|
|
|
}
|
2018-10-25 08:40:24 -04:00
|
|
|
|
2018-10-17 17:11:26 -04:00
|
|
|
if(event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_F11) {
|
|
|
|
if(windowFullscreen == 1) {
|
|
|
|
SDL_SetWindowFullscreen(window, 0);
|
|
|
|
windowFullscreen = 0;
|
|
|
|
} else {
|
|
|
|
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
|
|
|
windowFullscreen = 1;
|
|
|
|
}
|
2018-10-25 08:40:24 -04:00
|
|
|
|
2018-10-17 17:11:26 -04:00
|
|
|
target = renderer->createSurfaceRenderTarget(surface, target);
|
|
|
|
}
|
2018-10-25 08:40:24 -04:00
|
|
|
|
2018-11-03 07:24:32 -04:00
|
|
|
if(event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_F7) {
|
2018-10-30 21:13:36 -04:00
|
|
|
renderer->takeScreenshot("screenshot.ppm", target);
|
2018-10-24 21:13:55 -04:00
|
|
|
}
|
2018-09-26 17:51:22 -04:00
|
|
|
}
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
if(cinematicMode) {
|
|
|
|
float endTime = 0.0f;
|
|
|
|
for(auto shot : cinematic->shots) {
|
|
|
|
if(shot->end > endTime)
|
|
|
|
endTime = shot->end;
|
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
if(animationTime >= shot->start && animationTime < shot->end && currentShot != shot) {
|
2018-10-30 21:13:36 -04:00
|
|
|
if(currentShot != nullptr) {
|
|
|
|
world.meshes.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
for(auto mesh : shot->meshes)
|
|
|
|
world.meshes.push_back(mesh);
|
|
|
|
|
|
|
|
currentShot = shot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// we have reached the end of the cinematic
|
2018-11-05 20:51:23 -05:00
|
|
|
if(animationTime >= endTime) {
|
2018-10-30 21:13:36 -04:00
|
|
|
currentShot = nullptr;
|
|
|
|
|
|
|
|
world.meshes.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(currentShot != nullptr) {
|
|
|
|
for(auto animation : currentShot->animations) {
|
|
|
|
unsigned int frameIndex = 0;
|
|
|
|
for(size_t i = 0; i < animation->keyframes.size(); i++) {
|
2018-11-05 20:51:23 -05:00
|
|
|
if(animationTime < animation->keyframes[i + 1].time) {
|
2018-10-30 21:13:36 -04:00
|
|
|
frameIndex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto currentFrame = animation->keyframes[frameIndex];
|
|
|
|
const auto nextFrame = animation->keyframes[(frameIndex + 1) % animation->keyframes.size()];
|
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
const float delta = (animationTime - currentFrame.time) / (nextFrame.time - currentFrame.time);
|
2018-10-30 21:13:36 -04:00
|
|
|
|
|
|
|
glm::vec3 pos = currentFrame.value + delta * (nextFrame.value - currentFrame.value);
|
|
|
|
|
|
|
|
if(animation->target != nullptr)
|
|
|
|
animation->target->position = pos;
|
|
|
|
else
|
|
|
|
camera.position = pos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
currentTime = SDL_GetTicks() / 1000.0f;
|
|
|
|
const float deltaTime = currentTime - lastTime;
|
|
|
|
lastTime = currentTime;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
ImGui::NewFrame();
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
io.DeltaTime = deltaTime;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
int mouseX = 0, mouseY = 0;
|
|
|
|
const Uint32 mouseButtons = SDL_GetMouseState(&mouseX, &mouseY);
|
|
|
|
io.MouseDown[0] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
|
|
|
|
io.MouseDown[1] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
|
|
|
|
io.MouseDown[2] = (mouseButtons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)
|
|
|
|
io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
|
2018-11-05 21:06:12 -05:00
|
|
|
|
2018-11-08 08:57:41 -05:00
|
|
|
ImGui::DragFloat3("Light Position", &world.lights[0]->position[0]);
|
|
|
|
ImGui::DragFloat3("Camera Position", &camera.position[0], 0.1f);
|
2018-11-06 13:47:48 -05:00
|
|
|
ImGui::DragFloat3("Target", &camera.target[0], 0.1f);
|
2018-11-05 21:06:12 -05:00
|
|
|
ImGui::DragFloat("Aperture", &camera.aperture, 0.01f, 0.0f, 1.0f);
|
|
|
|
ImGui::DragFloat("Focus Distance", &camera.focusDistance);
|
|
|
|
ImGui::Text("dpack[2] = %f", (100 - camera.focusDistance) / 100.0f);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-11-05 20:51:23 -05:00
|
|
|
ImGui::Render();
|
2018-10-25 08:57:36 -04:00
|
|
|
renderer->render(world, camera, target);
|
2018-11-06 09:08:55 -05:00
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
if(cinematicMode) {
|
2018-11-05 20:51:23 -05:00
|
|
|
animationTime += deltaTime;
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
static int frameNum = 0;
|
|
|
|
std::string screenshotName = "frame" + std::to_string(frameNum) + ".ppm";
|
|
|
|
frameNum++;
|
2018-10-25 08:40:24 -04:00
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
renderer->takeScreenshot(screenshotName.c_str(), target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(cinematic == nullptr) {
|
2018-11-06 09:08:55 -05:00
|
|
|
renderer->destroyMaterialBuffers(world.meshes[0]->material);
|
|
|
|
delete world.meshes[0]->material;
|
|
|
|
|
2018-10-30 21:13:36 -04:00
|
|
|
renderer->destroyMeshBuffers(world.meshes[0]);
|
|
|
|
delete world.meshes[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
delete light;
|
2018-10-25 08:40:24 -04:00
|
|
|
|
2018-09-29 21:03:06 -04:00
|
|
|
renderer->destroyRenderTarget(target);
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-10-01 21:02:27 -04:00
|
|
|
vkDestroySurfaceKHR(renderer->getInstance(), surface, nullptr);
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-09-27 20:09:42 -04:00
|
|
|
delete renderer;
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-10-17 10:32:31 -04:00
|
|
|
writeConfig();
|
|
|
|
|
2018-09-27 12:47:21 -04:00
|
|
|
SDL_DestroyWindow(window);
|
2018-10-16 08:49:25 -04:00
|
|
|
|
2018-09-26 17:51:22 -04:00
|
|
|
return 0;
|
|
|
|
}
|