Archived
1
Fork 0

Add level editor

This commit is contained in:
Joshua Goins 2018-12-21 06:32:37 -05:00
parent 086c26265e
commit 707396f384
13 changed files with 263 additions and 48 deletions

View file

@ -44,8 +44,7 @@ IMPORTED_LOCATION ${ASSIMP_IMPORTED_PATH})
INTERFACE_INCLUDE_DIRECTORIES ${ASSIMP_INCLUDE_DIRS}) INTERFACE_INCLUDE_DIRECTORIES ${ASSIMP_INCLUDE_DIRS})
endif() endif()
set(GRAPH_SRC set(ENGINE_SRC
src/main.cpp
src/renderer.cpp src/renderer.cpp
src/worldpass.cpp src/worldpass.cpp
src/postpass.cpp src/postpass.cpp
@ -61,18 +60,17 @@ set(GRAPH_SRC
src/smaapass.cpp) src/smaapass.cpp)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(GRAPH_SRC set(ENGINE_SRC
${GRAPH_SRC} ${ENGINE_SRC}
src/imguipass.cpp) src/imguipass.cpp)
endif() endif()
add_executable(Graph add_library(Engine
${GRAPH_SRC}) ${ENGINE_SRC})
target_compile_options(Engine
target_compile_options(Graph
PUBLIC PUBLIC
-fno-exceptions) -fno-exceptions)
target_link_libraries(Graph target_link_libraries(Engine
PUBLIC PUBLIC
SDL2::SDL2 SDL2::SDL2
Vulkan::Vulkan Vulkan::Vulkan
@ -82,17 +80,23 @@ target_link_libraries(Graph
SMAA::SMAA) SMAA::SMAA)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_link_libraries(Graph target_link_libraries(Engine
PUBLIC PUBLIC
imgui::imgui) imgui::imgui)
endif() endif()
target_include_directories(Graph target_include_directories(Engine
PUBLIC PUBLIC
include include
PRIVATE PRIVATE
${GLM_INCLUDE_DIRS}) ${GLM_INCLUDE_DIRS})
add_executable(Graph
src/main.cpp)
target_link_libraries(Graph
PRIVATE
Engine)
add_shaders(Graph add_shaders(Graph
shaders/mesh.vert shaders/mesh.vert
shaders/mesh.frag shaders/mesh.frag
@ -121,3 +125,5 @@ add_data(Graph
data/test.material data/test.material
data/empty.world data/empty.world
data/player.obj) data/player.obj)
add_subdirectory(tools)

View file

@ -85,6 +85,9 @@ struct RenderTarget {
struct GraphicsConfig { struct GraphicsConfig {
int shadowResolution, dofDownscale; int shadowResolution, dofDownscale;
bool vsync = true, filterPCF; bool vsync = true, filterPCF;
#ifdef DEBUG
bool enableImgui = true;
#endif
}; };
struct World; struct World;

View file

@ -33,6 +33,7 @@ Renderer::Renderer(GraphicsConfig config) : config_(config) {
postPass_ = new PostPass(*this); postPass_ = new PostPass(*this);
dofPass_ = new DoFPass(*this); dofPass_ = new DoFPass(*this);
#ifdef DEBUG #ifdef DEBUG
if(config.enableImgui)
imguiPass_ = new ImGuiPass(*this); imguiPass_ = new ImGuiPass(*this);
#endif #endif
skyPass_ = new SkyPass(*this); skyPass_ = new SkyPass(*this);
@ -45,6 +46,7 @@ Renderer::~Renderer() {
delete smaaPass_; delete smaaPass_;
delete skyPass_; delete skyPass_;
#ifdef DEBUG #ifdef DEBUG
if(config_.enableImgui)
delete imguiPass_; delete imguiPass_;
#endif #endif
delete dofPass_; delete dofPass_;
@ -168,6 +170,7 @@ void Renderer::render(World& world, RenderTarget* target) {
postPass_->render(commandBuffer, target); postPass_->render(commandBuffer, target);
#ifdef DEBUG #ifdef DEBUG
if(config_.enableImgui)
imguiPass_->render(commandBuffer, target); imguiPass_->render(commandBuffer, target);
#endif #endif
@ -729,6 +732,8 @@ void Renderer::destroyRenderTarget(RenderTarget* target) {
delete[] target->commandBuffers; delete[] target->commandBuffers;
vkFreeDescriptorSets(device_, descriptorPool_, target->numImages, target->blendDescriptorSets);
vkFreeDescriptorSets(device_, descriptorPool_, target->numImages, target->edgeDescriptorSets);
vkFreeDescriptorSets(device_, descriptorPool_, target->numImages, target->dofSets); vkFreeDescriptorSets(device_, descriptorPool_, target->numImages, target->dofSets);
vkFreeDescriptorSets(device_, descriptorPool_, target->numImages, target->postSets); vkFreeDescriptorSets(device_, descriptorPool_, target->numImages, target->postSets);
@ -799,6 +804,8 @@ void Renderer::destroyRenderTarget(RenderTarget* target) {
delete[] target->swapchainImageViews; delete[] target->swapchainImageViews;
delete[] target->swapchainImages; delete[] target->swapchainImages;
delete[] target->blendDescriptorSets;
delete[] target->edgeDescriptorSets;
delete[] target->dofSets; delete[] target->dofSets;
delete[] target->postSets; delete[] target->postSets;
@ -1512,8 +1519,8 @@ void Renderer::createPresentationRenderPass() {
void Renderer::createDescriptorPool() { void Renderer::createDescriptorPool() {
const std::array<VkDescriptorPoolSize, 2> poolSizes = { const std::array<VkDescriptorPoolSize, 2> poolSizes = {
VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 25}, VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 50},
VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 25} VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 50}
}; };
VkDescriptorPoolCreateInfo poolInfo = {}; VkDescriptorPoolCreateInfo poolInfo = {};
@ -1521,7 +1528,7 @@ void Renderer::createDescriptorPool() {
poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
poolInfo.poolSizeCount = poolSizes.size(); poolInfo.poolSizeCount = poolSizes.size();
poolInfo.pPoolSizes = poolSizes.data(); poolInfo.pPoolSizes = poolSizes.data();
poolInfo.maxSets = 25; poolInfo.maxSets = 50;
vkCreateDescriptorPool(device_, &poolInfo, nullptr, &descriptorPool_); vkCreateDescriptorPool(device_, &poolInfo, nullptr, &descriptorPool_);
} }

View file

@ -62,8 +62,7 @@ void SMAAPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) {
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = edgeRenderPass; renderPassInfo.renderPass = edgeRenderPass;
renderPassInfo.framebuffer = target->edgeFramebuffers[target->currentResource]; renderPassInfo.framebuffer = target->edgeFramebuffers[target->currentResource];
renderPassInfo.renderArea.extent.width = 1280; renderPassInfo.renderArea.extent = target->extent;
renderPassInfo.renderArea.extent.height = 720;
renderPassInfo.clearValueCount = 1; renderPassInfo.clearValueCount = 1;
renderPassInfo.pClearValues = &clearValue; renderPassInfo.pClearValues = &clearValue;
@ -410,21 +409,10 @@ void SMAAPass::createPipelines() {
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
inputAssembly.primitiveRestartEnable = VK_FALSE; inputAssembly.primitiveRestartEnable = VK_FALSE;
VkViewport viewport = {};
viewport.width = 1280;
viewport.height = 720;
viewport.maxDepth = 1.0f;
VkRect2D scissor = {};
scissor.extent.width = 1280;
scissor.extent.height = 720;
VkPipelineViewportStateCreateInfo viewportState = {}; VkPipelineViewportStateCreateInfo viewportState = {};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.viewportCount = 1; viewportState.viewportCount = 1;
viewportState.pViewports = &viewport;
viewportState.scissorCount = 1; viewportState.scissorCount = 1;
viewportState.pScissors = &scissor;
VkPipelineRasterizationStateCreateInfo rasterizer = {}; VkPipelineRasterizationStateCreateInfo rasterizer = {};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
@ -451,6 +439,16 @@ void SMAAPass::createPipelines() {
colorBlending.attachmentCount = 1; colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment; colorBlending.pAttachments = &colorBlendAttachment;
const std::array<VkDynamicState, 2> dynamicStates = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo dynamicState = {};
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicState.dynamicStateCount = dynamicStates.size();
dynamicState.pDynamicStates = dynamicStates.data();
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {}; VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 1; pipelineLayoutInfo.setLayoutCount = 1;
@ -468,6 +466,7 @@ void SMAAPass::createPipelines() {
pipelineInfo.pRasterizationState = &rasterizer; pipelineInfo.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling; pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pColorBlendState = &colorBlending; pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = &dynamicState;
pipelineInfo.layout = edgePipelineLayout; pipelineInfo.layout = edgePipelineLayout;
pipelineInfo.renderPass = edgeRenderPass; pipelineInfo.renderPass = edgeRenderPass;

1
tools/CMakeLists.txt Normal file
View file

@ -0,0 +1 @@
add_subdirectory(leveleditor)

View file

@ -0,0 +1,15 @@
find_package(Qt5Widgets CONFIG REQUIRED)
set(INCLUDE_FILES
include/mainwindow.h
include/renderwindow.h)
qt5_wrap_cpp(EDITOR_SRC ${INCLUDE_FILES})
add_executable(LevelEditor
src/main.cpp
src/mainwindow.cpp
src/renderwindow.cpp
${EDITOR_SRC})
target_include_directories(LevelEditor PRIVATE include)
target_link_libraries(LevelEditor Qt5::Widgets Engine)

View file

@ -0,0 +1,7 @@
#pragma once
class Renderer;
struct Context {
Renderer* renderer;
};

View file

@ -0,0 +1,10 @@
#pragma once
#include <QMainWindow>
struct Context;
class MainWindow : public QMainWindow {
public:
MainWindow(Context& context);
};

View file

@ -0,0 +1,29 @@
#pragma once
#include <QWindow>
#include <vulkan/vulkan.h>
#include "context.h"
struct RenderTarget;
class RendererWindow : public QWindow {
Q_OBJECT
public:
RendererWindow(Context& context);
~RendererWindow();
protected:
void exposeEvent(QExposeEvent* event) override;
bool event(QEvent* event) override;
private:
void init();
void render();
VkSurfaceKHR surface = nullptr;
RenderTarget* target = nullptr;
bool initialized = false;
Context& context;
};

View file

@ -0,0 +1,63 @@
#include <QApplication>
#include <QVulkanInstance>
#include "mainwindow.h"
#include "platform.h"
#include "context.h"
#include "renderer.h"
#include "worldmanager.h"
#include "assetmanager.h"
#include "ecs.h"
static std::vector<std::string> extensionList;
std::vector<const char*> platform::getRequiredExtensions() {
QVulkanInstance instance;
instance.create();
for(const auto& extension : instance.extensions())
extensionList.push_back(extension.data());
instance.destroy();
std::vector<const char*> extensions;
for(const auto& extension : extensionList)
extensions.push_back(extension.c_str());
return extensions;
}
uint32_t platform::getTime() {
return 0;
}
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
GraphicsConfig config;
config.shadowResolution = 256;
config.dofDownscale = 2;
config.filterPCF = true;
config.enableImgui = false;
Context context;
context.renderer = new Renderer(config);
assetManager.setRenderer(context.renderer);
worldManager.loadWorld("test.world");
worldManager.switchWorld("test.world");
EntityID entity = ECS::createEntity(worldManager.getCurrentWorld());
auto cameraTransform = ECS::addComponent<TransformComponent>(entity);
cameraTransform->position = glm::vec3(5, 5, 5);
auto cameraComponent = ECS::addComponent<CameraComponent>(entity);
cameraComponent->fov = 70.0f;
MainWindow window(context);
window.show();
return app.exec();
}

View file

@ -0,0 +1,20 @@
#include "mainwindow.h"
#include <QVulkanWindow>
#include "renderwindow.h"
#include "renderer.h"
MainWindow::MainWindow(Context& context) {
setWindowTitle("Level Editor");
QVulkanInstance* instance = new QVulkanInstance();
instance->setVkInstance(context.renderer->getInstance());
instance->create();
RendererWindow* window = new RendererWindow(context);
window->setVulkanInstance(instance);
QWidget* wrapper = QWidget::createWindowContainer(window);
setCentralWidget(wrapper);
}

View file

@ -0,0 +1,55 @@
#include "renderwindow.h"
#include <QVulkanInstance>
#include <QResizeEvent>
#include "renderer.h"
#include "worldmanager.h"
RendererWindow::RendererWindow(Context& context) : QWindow(), context(context) {
setSurfaceType(SurfaceType::VulkanSurface);
}
RendererWindow::~RendererWindow() {
}
void RendererWindow::exposeEvent(QExposeEvent*) {
if (isExposed() && !initialized) {
init();
render();
initialized = true;
}
}
bool RendererWindow::event(QEvent* event) {
switch(event->type()) {
case QEvent::UpdateRequest:
render();
break;
default:
break;
}
return QWindow::event(event);
}
void RendererWindow::init() {
surface = QVulkanInstance::surfaceForWindow(this);
target = context.renderer->createSurfaceRenderTarget(surface);
}
void RendererWindow::render() {
context.renderer->render(*worldManager.getCurrentWorld(), target);
const auto width = size().width();
const auto height = size().height();
if(target->extent.width != width || target->extent.height != height)
target = context.renderer->createSurfaceRenderTarget(surface, target);
vulkanInstance()->presentQueued(this);
requestUpdate();
}