Skip to content

Commit

Permalink
Geometry Pass
Browse files Browse the repository at this point in the history
  • Loading branch information
LazyJazz committed Dec 23, 2023
1 parent 2b69014 commit f791353
Show file tree
Hide file tree
Showing 23 changed files with 361 additions and 35 deletions.
36 changes: 20 additions & 16 deletions src/GameX/application/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,34 +65,22 @@ Application::~Application() {
glfwTerminate();
}

void Application::Run() {
Init();

while (!glfwWindowShouldClose(window_)) {
glfwPollEvents();
Update();
Render();
}

core_->Device()->WaitIdle();
Cleanup();
}

void Application::Init() {
CreateCube();
scene_ = std::make_unique<class Scene>(renderer_.get(), SceneSettings());
render_pipeline_ = std::make_unique<RenderPipeline>(renderer_.get());
camera_ = scene_->CreateCamera(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0), 45.0f,
16.0f / 9.0f, 0.1f, 100.0f);
dynamic_entity_ = scene_->CreateEntity(dynamic_cube_.get());
static_entity_ = scene_->CreateEntity(static_cube_.get());
film_ = renderer_->RenderPipeline()->CreateFilm(settings_.width,
settings_.height);
}

void Application::Cleanup() {
camera_.reset();
film_.reset();
static_entity_.reset();
dynamic_entity_.reset();
render_pipeline_.reset();
camera_.reset();
scene_.reset();
static_cube_.reset();
dynamic_cube_.reset();
Expand Down Expand Up @@ -132,6 +120,9 @@ void Application::Render() {
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_MEMORY_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);

renderer_->RenderPipeline()->Render(cmd_buffer->Handle(), *scene_, *camera_,
*film_);

core_->EndFrame();
}

Expand All @@ -157,4 +148,17 @@ void Application::CreateCube() {
static_cube_ = std::make_unique<StaticModel>(Renderer(), cube_);
dynamic_cube_ = std::make_unique<DynamicModel>(Renderer(), &cube_);
}

void Application::Run() {
Init();

while (!glfwWindowShouldClose(window_)) {
glfwPollEvents();
Update();
Render();
}

core_->Device()->WaitIdle();
Cleanup();
}
} // namespace GameX
2 changes: 1 addition & 1 deletion src/GameX/application/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,6 @@ class Application {
std::unique_ptr<Entity> static_entity_;
std::unique_ptr<Entity> dynamic_entity_;

std::unique_ptr<RenderPipeline> render_pipeline_;
std::unique_ptr<RenderPipeline::Film> film_;
};
} // namespace GameX
4 changes: 4 additions & 0 deletions src/GameX/renderer/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ class Camera {
glm::mat4 projection_matrix_;
};

grassland::vulkan::DescriptorSet *DescriptorSet(int frame_index) const {
return descriptor_sets_[frame_index].get();
}

private:
Scene *scene_;
std::unique_ptr<grassland::vulkan::DynamicBuffer<CameraData>> camera_buffer_;
Expand Down
9 changes: 8 additions & 1 deletion src/GameX/renderer/entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@
#include "GameX/renderer/scene.h"

namespace GameX {
Entity::Entity(Scene *scene, const Model *model) {
Entity::Entity(Scene *scene, const class Model *model) {
scene_ = scene;
model_ = model;

entity_buffer_ =
std::make_unique<grassland::vulkan::DynamicBuffer<EntitySettings>>(
scene_->Renderer()->App()->Core(), 1,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);

entity_buffer_->At(0).model = glm::mat4(1.0f);

scene_->Renderer()->RegisterSyncObject(entity_buffer_.get());

descriptor_sets_.resize(
scene_->Renderer()->App()->Core()->MaxFramesInFlight());

Expand Down Expand Up @@ -41,6 +47,7 @@ Entity::Entity(Scene *scene, const Model *model) {
}

Entity::~Entity() {
scene_->Renderer()->UnregisterSyncObject(entity_buffer_.get());
scene_->DestroyEntity(this);
}
} // namespace GameX
8 changes: 8 additions & 0 deletions src/GameX/renderer/entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ class Entity {

~Entity();

grassland::vulkan::DescriptorSet *DescriptorSet(int frame_index) const {
return descriptor_sets_[frame_index].get();
}

const class Model *Model() const {
return model_;
}

private:
class Scene *scene_;
const class Model *model_;
Expand Down
3 changes: 3 additions & 0 deletions src/GameX/renderer/geometry_buffer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "GameX/renderer/geometry_buffer.h"

namespace GameX {} // namespace GameX
5 changes: 5 additions & 0 deletions src/GameX/renderer/geometry_buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "GameX/utils/utils.h"

namespace GameX {}
2 changes: 1 addition & 1 deletion src/GameX/renderer/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct StaticModel : public Model {
}

uint32_t IndexCount() const override {
return index_buffer_.Size();
return index_buffer_.Length();
}

private:
Expand Down
188 changes: 187 additions & 1 deletion src/GameX/renderer/render_pipeline.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,189 @@
#include "GameX/renderer/render_pipeline.h"

namespace GameX {}
#include "GameX/application/application.h"
#include "GameX/renderer/camera.h"
#include "GameX/renderer/entity.h"
#include "GameX/renderer/renderer.h"
#include "GameX/shaders/shaders.h"

namespace GameX {
RenderPipeline::RenderPipeline(struct Renderer *renderer, int max_film)
: renderer_(renderer) {
std::vector<VkAttachmentDescription> attachment_descriptions;
attachment_descriptions.push_back(VkAttachmentDescription{
0, VK_FORMAT_R32G32B32A32_SFLOAT, VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL});
attachment_descriptions.push_back(VkAttachmentDescription{
0, VK_FORMAT_R32G32B32A32_SFLOAT, VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL});
attachment_descriptions.push_back(VkAttachmentDescription{
0, VK_FORMAT_R32G32B32A32_SFLOAT, VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL});
attachment_descriptions.push_back(VkAttachmentDescription{
0, VK_FORMAT_D32_SFLOAT, VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL});

std::vector<VkAttachmentReference> color_attachment_references;
color_attachment_references.push_back(
VkAttachmentReference{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});
color_attachment_references.push_back(
VkAttachmentReference{1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});
color_attachment_references.push_back(
VkAttachmentReference{2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});

std::optional<VkAttachmentReference> depth_attachment_reference =
VkAttachmentReference{3,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};

geometry_pass_render_pass_ = std::make_unique<grassland::vulkan::RenderPass>(
renderer->App()->Core(), attachment_descriptions,
color_attachment_references, depth_attachment_reference);

geometry_pass_vertex_shader_ =
std::make_unique<grassland::vulkan::ShaderModule>(
renderer->App()->Core(), BuiltInShaderSpv("geometry_pass.vert"));
geometry_pass_fragment_shader_ =
std::make_unique<grassland::vulkan::ShaderModule>(
renderer->App()->Core(), BuiltInShaderSpv("geometry_pass.frag"));

geometry_pass_pipeline_layout_ =
std::make_unique<grassland::vulkan::PipelineLayout>(
renderer->App()->Core(),
std::vector<grassland::vulkan::DescriptorSetLayout *>{
renderer->CameraDescriptorSetLayout(),
renderer->EntityDescriptorSetLayout()});

grassland::vulkan::PipelineSettings geometry_pass_pipeline_settings(
geometry_pass_render_pass_.get(), geometry_pass_pipeline_layout_.get());
geometry_pass_pipeline_settings.AddShaderStage(
geometry_pass_vertex_shader_.get(), VK_SHADER_STAGE_VERTEX_BIT);
geometry_pass_pipeline_settings.AddShaderStage(
geometry_pass_fragment_shader_.get(), VK_SHADER_STAGE_FRAGMENT_BIT);
geometry_pass_pipeline_settings.AddInputBinding(0, sizeof(Vertex),
VK_VERTEX_INPUT_RATE_VERTEX);
geometry_pass_pipeline_settings.AddInputAttribute(
0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, position));
geometry_pass_pipeline_settings.AddInputAttribute(
0, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, color));
geometry_pass_pipeline_settings.AddInputAttribute(
0, 2, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, texCoord));
geometry_pass_pipeline_settings.AddInputAttribute(
0, 3, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, normal));
geometry_pass_pipeline_settings.AddInputAttribute(
0, 4, VK_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, tangent));

geometry_pass_pipeline_settings.SetPrimitiveTopology(
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);

geometry_pass_pipeline_settings.SetMultiSampleState(VK_SAMPLE_COUNT_1_BIT);

geometry_pass_pipeline_settings.SetCullMode(VK_CULL_MODE_BACK_BIT);

geometry_pass_pipeline_ = std::make_unique<grassland::vulkan::Pipeline>(
renderer->App()->Core(), geometry_pass_pipeline_settings);
}

std::unique_ptr<RenderPipeline::Film> RenderPipeline::CreateFilm(int width,
int height) {
std::unique_ptr<Film> film = std::make_unique<Film>();
VkExtent2D extent{static_cast<uint32_t>(width),
static_cast<uint32_t>(height)};
film->albedo_image = std::make_unique<grassland::vulkan::Image>(
renderer_->App()->Core(), VK_FORMAT_R32G32B32A32_SFLOAT, extent,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
film->normal_image = std::make_unique<grassland::vulkan::Image>(
renderer_->App()->Core(), VK_FORMAT_R32G32B32A32_SFLOAT, extent,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
film->position_image = std::make_unique<grassland::vulkan::Image>(
renderer_->App()->Core(), VK_FORMAT_R32G32B32A32_SFLOAT, extent,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
film->depth_image = std::make_unique<grassland::vulkan::Image>(
renderer_->App()->Core(), VK_FORMAT_D32_SFLOAT, extent,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT);
film->framebuffer = std::make_unique<grassland::vulkan::Framebuffer>(
renderer_->App()->Core(), extent, geometry_pass_render_pass_->Handle(),
std::vector<VkImageView>{
film->albedo_image->ImageView(), film->normal_image->ImageView(),
film->position_image->ImageView(), film->depth_image->ImageView()});
return film;
}

void RenderPipeline::Render(VkCommandBuffer cmd_buffer,
const Scene &scene,
const Camera &cameras,
const RenderPipeline::Film &film) {
VkRenderPassBeginInfo render_pass_begin_info{};
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
render_pass_begin_info.renderPass = geometry_pass_render_pass_->Handle();
render_pass_begin_info.framebuffer = film.framebuffer->Handle();
render_pass_begin_info.renderArea.offset = {0, 0};
render_pass_begin_info.renderArea.extent = film.Extent();
std::array<VkClearValue, 4> clear_values{};
clear_values[0].color = {0.0f, 0.0f, 0.0f, 0.0f};
clear_values[1].color = {0.0f, 0.0f, 0.0f, 0.0f};
clear_values[2].color = {0.0f, 0.0f, 0.0f, 0.0f};
clear_values[3].depthStencil = {1.0f, 0};
render_pass_begin_info.clearValueCount =
static_cast<uint32_t>(clear_values.size());
render_pass_begin_info.pClearValues = clear_values.data();
vkCmdBeginRenderPass(cmd_buffer, &render_pass_begin_info,
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
geometry_pass_pipeline_->Handle());

VkDescriptorSet camera_descriptor_set =
cameras.DescriptorSet(renderer_->App()->Core()->CurrentFrame())->Handle();
vkCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
geometry_pass_pipeline_layout_->Handle(), 0, 1,
&camera_descriptor_set, 0, nullptr);

// Viewport and scissor
VkViewport viewport{};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = film.Extent().width;
viewport.height = film.Extent().height;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(cmd_buffer, 0, 1, &viewport);

VkRect2D scissor{};
scissor.offset = {0, 0};
scissor.extent = film.Extent();
vkCmdSetScissor(cmd_buffer, 0, 1, &scissor);

for (auto &entity : scene.Entities()) {
VkDescriptorSet entity_descriptor_set =
entity->DescriptorSet(renderer_->App()->Core()->CurrentFrame())
->Handle();
vkCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
geometry_pass_pipeline_layout_->Handle(), 1, 1,
&entity_descriptor_set, 0, nullptr);

VkBuffer vertex_buffers[] = {
entity->Model()
->VertexBuffer(renderer_->App()->Core()->CurrentFrame())
->Handle()};
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(cmd_buffer, 0, 1, vertex_buffers, offsets);
vkCmdBindIndexBuffer(
cmd_buffer,
entity->Model()
->IndexBuffer(renderer_->App()->Core()->CurrentFrame())
->Handle(),
0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(cmd_buffer, entity->Model()->IndexCount(), 1, 0, 0, 0);
}

vkCmdEndRenderPass(cmd_buffer);
}
} // namespace GameX
22 changes: 20 additions & 2 deletions src/GameX/renderer/render_pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,26 @@
namespace GameX {
class RenderPipeline {
public:
RenderPipeline(class Renderer *renderer, int max_film = 1024)
: renderer_(renderer){};
RenderPipeline(class Renderer *renderer, int max_film = 1024);

struct Film {
std::unique_ptr<grassland::vulkan::Image> albedo_image;
std::unique_ptr<grassland::vulkan::Image> normal_image;
std::unique_ptr<grassland::vulkan::Image> position_image;
std::unique_ptr<grassland::vulkan::Image> depth_image;
std::unique_ptr<grassland::vulkan::Framebuffer> framebuffer;

VkExtent2D Extent() const {
return albedo_image->Extent();
}
};

std::unique_ptr<Film> CreateFilm(int width, int height);

void Render(VkCommandBuffer cmd_buffer,
const Scene &scene,
const Camera &cameras,
const Film &film);

private:
class Renderer *renderer_;
Expand Down
13 changes: 13 additions & 0 deletions src/GameX/renderer/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ Renderer::Renderer(Application *app) : app_(app) {
CreateAssetManager();
CreateCameraSetLayout();
CreateEntitySetLayout();
CreateRenderPipeline();
}

Renderer::~Renderer() {
render_pipeline_.reset();
entity_descriptor_set_layout_.reset();
camera_descriptor_set_layout_.reset();
asset_manager_.reset();
depth_render_pass_.reset();
}

void Renderer::CreateDepthRenderPass() {
Expand Down Expand Up @@ -79,4 +88,8 @@ void Renderer::CreateEntitySetLayout() {
bindings);
}

void Renderer::CreateRenderPipeline() {
render_pipeline_ = std::make_unique<class RenderPipeline>(this);
}

} // namespace GameX
Loading

0 comments on commit f791353

Please sign in to comment.