Add model loading
This commit is contained in:
parent
0568c6e5d2
commit
4378a90f74
10 changed files with 1737 additions and 70 deletions
|
@ -12,11 +12,11 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
add_definitions(-DDEBUG)
|
add_definitions(-DDEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(Graph
|
add_executable(Graph
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/renderer.cpp
|
src/renderer.cpp
|
||||||
src/worldpass.cpp)
|
src/worldpass.cpp)
|
||||||
target_link_libraries(Graph PUBLIC SDL2::SDL2 SDL2::SDL2main ${Vulkan_LIBRARY})
|
target_link_libraries(Graph PUBLIC SDL2::SDL2 SDL2::SDL2main ${Vulkan_LIBRARY} assimp)
|
||||||
target_include_directories(Graph PUBLIC include ${Vulkan_INCLUDE_DIRS})
|
target_include_directories(Graph PUBLIC include ${Vulkan_INCLUDE_DIRS})
|
||||||
|
|
||||||
macro(compile_shader src)
|
macro(compile_shader src)
|
||||||
|
@ -34,3 +34,5 @@ compile_shader(triangle.frag)
|
||||||
|
|
||||||
add_custom_target(BuildShaders DEPENDS ${SPV_FILES})
|
add_custom_target(BuildShaders DEPENDS ${SPV_FILES})
|
||||||
add_dependencies(Graph BuildShaders)
|
add_dependencies(Graph BuildShaders)
|
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/data/suzanne.obj ${CMAKE_CURRENT_SOURCE_DIR}/build/suzanne.obj COPYONLY)
|
||||||
|
|
1512
data/suzanne.obj
Normal file
1512
data/suzanne.obj
Normal file
File diff suppressed because it is too large
Load diff
22
include/mesh.h
Normal file
22
include/mesh.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
glm::vec3 position;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Mesh {
|
||||||
|
public:
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
|
||||||
|
VkBuffer vertexBuffer = nullptr;
|
||||||
|
VkDeviceMemory vertexMemory = nullptr;
|
||||||
|
|
||||||
|
VkBuffer indexBuffer = nullptr;
|
||||||
|
VkDeviceMemory indexMemory = nullptr;
|
||||||
|
};
|
|
@ -7,45 +7,52 @@
|
||||||
struct RenderTarget {
|
struct RenderTarget {
|
||||||
VkSurfaceKHR surface = nullptr;
|
VkSurfaceKHR surface = nullptr;
|
||||||
VkSwapchainKHR swapchain = nullptr;
|
VkSwapchainKHR swapchain = nullptr;
|
||||||
|
|
||||||
VkExtent2D extent = {};
|
VkExtent2D extent = {};
|
||||||
uint32_t numImages = 0;
|
uint32_t numImages = 0;
|
||||||
|
|
||||||
VkImage* images = nullptr;
|
VkImage* images = nullptr;
|
||||||
VkImageView* imageViews = nullptr;
|
VkImageView* imageViews = nullptr;
|
||||||
VkFramebuffer* framebuffers = nullptr;
|
VkFramebuffer* framebuffers = nullptr;
|
||||||
|
|
||||||
VkCommandBuffer* commandBuffers = nullptr;
|
VkCommandBuffer* commandBuffers = nullptr;
|
||||||
|
|
||||||
VkSemaphore imageAvailableSemaphore = nullptr;
|
VkSemaphore imageAvailableSemaphore = nullptr;
|
||||||
VkSemaphore renderFinishedSemaphore = nullptr;
|
VkSemaphore renderFinishedSemaphore = nullptr;
|
||||||
VkFence* fences = nullptr;
|
VkFence* fences = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class World;
|
||||||
|
class Mesh;
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
void render(RenderTarget* target);
|
void render(World& world, RenderTarget* target);
|
||||||
|
|
||||||
RenderTarget* createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTarget* oldRenderTarget = nullptr);
|
RenderTarget* createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTarget* oldRenderTarget = nullptr);
|
||||||
void destroyRenderTarget(RenderTarget* target);
|
void destroyRenderTarget(RenderTarget* target);
|
||||||
|
|
||||||
VkShaderModule createShader(const char* path);
|
VkShaderModule createShader(const char* path);
|
||||||
|
|
||||||
|
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
|
||||||
|
|
||||||
|
void fillMeshBuffers(Mesh* mesh);
|
||||||
|
|
||||||
VkInstance getInstance() const {
|
VkInstance getInstance() const {
|
||||||
return instance_;
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDevice getDevice() const {
|
VkDevice getDevice() const {
|
||||||
return device_;
|
return device_;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkRenderPass getRenderPass() const {
|
VkRenderPass getRenderPass() const {
|
||||||
return presentationRenderPass_;
|
return presentationRenderPass_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createInstance();
|
void createInstance();
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -54,18 +61,18 @@ private:
|
||||||
void createLogicalDevice();
|
void createLogicalDevice();
|
||||||
void createCommandPool();
|
void createCommandPool();
|
||||||
void createPresentationRenderPass();
|
void createPresentationRenderPass();
|
||||||
|
|
||||||
VkInstance instance_ = nullptr;
|
VkInstance instance_ = nullptr;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool enableDebug = false;
|
bool enableDebug = false;
|
||||||
|
|
||||||
PFN_vkCreateDebugUtilsMessengerEXT createMessenger_ = nullptr;
|
PFN_vkCreateDebugUtilsMessengerEXT createMessenger_ = nullptr;
|
||||||
PFN_vkDestroyDebugUtilsMessengerEXT destroyMessenger_ = nullptr;
|
PFN_vkDestroyDebugUtilsMessengerEXT destroyMessenger_ = nullptr;
|
||||||
|
|
||||||
VkDebugUtilsMessengerEXT messenger_ = nullptr;
|
VkDebugUtilsMessengerEXT messenger_ = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VkPhysicalDevice physicalDevice_ = nullptr;
|
VkPhysicalDevice physicalDevice_ = nullptr;
|
||||||
VkDevice device_ = nullptr;
|
VkDevice device_ = nullptr;
|
||||||
|
|
||||||
|
@ -74,10 +81,10 @@ private:
|
||||||
} queueIndices;
|
} queueIndices;
|
||||||
|
|
||||||
VkQueue graphicsQueue_ = nullptr;
|
VkQueue graphicsQueue_ = nullptr;
|
||||||
|
|
||||||
VkCommandPool commandPool_ = nullptr;
|
VkCommandPool commandPool_ = nullptr;
|
||||||
|
|
||||||
VkRenderPass presentationRenderPass_ = nullptr;
|
VkRenderPass presentationRenderPass_ = nullptr;
|
||||||
|
|
||||||
WorldPass* worldPass_ = nullptr;
|
WorldPass* worldPass_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
10
include/world.h
Normal file
10
include/world.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Mesh;
|
||||||
|
|
||||||
|
class World {
|
||||||
|
public:
|
||||||
|
std::vector<Mesh*> meshes;
|
||||||
|
};
|
|
@ -3,19 +3,20 @@
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
class Renderer;
|
class Renderer;
|
||||||
|
class World;
|
||||||
|
|
||||||
class WorldPass {
|
class WorldPass {
|
||||||
public:
|
public:
|
||||||
WorldPass(Renderer& renderer);
|
WorldPass(Renderer& renderer);
|
||||||
~WorldPass();
|
~WorldPass();
|
||||||
|
|
||||||
void render(VkCommandBuffer commandBuffer);
|
void render(World& world, VkCommandBuffer commandBuffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createPipeline();
|
void createPipeline();
|
||||||
|
|
||||||
VkPipelineLayout pipelineLayout_ = nullptr;
|
VkPipelineLayout pipelineLayout_ = nullptr;
|
||||||
VkPipeline pipeline_ = nullptr;
|
VkPipeline pipeline_ = nullptr;
|
||||||
|
|
||||||
Renderer& renderer_;
|
Renderer& renderer_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
#version 460 core
|
#version 460 core
|
||||||
|
|
||||||
vec2 positions[3] = vec2[](
|
layout(location = 0) in vec3 inPosition;
|
||||||
vec2(0.0, -0.5),
|
|
||||||
vec2(0.5, 0.5),
|
|
||||||
vec2(-0.5, 0.5)
|
|
||||||
);
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
gl_Position = vec4(inPosition, 1.0);
|
||||||
}
|
}
|
||||||
|
|
58
src/main.cpp
58
src/main.cpp
|
@ -2,18 +2,24 @@
|
||||||
#include <SDL_vulkan.h>
|
#include <SDL_vulkan.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "world.h"
|
||||||
|
#include "mesh.h"
|
||||||
|
|
||||||
SDL_Window* window = nullptr;
|
SDL_Window* window = nullptr;
|
||||||
|
|
||||||
std::vector<const char*> platform::getRequiredExtensions() {
|
std::vector<const char*> platform::getRequiredExtensions() {
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr);
|
SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr);
|
||||||
|
|
||||||
std::vector<const char*> names(count);
|
std::vector<const char*> names(count);
|
||||||
SDL_Vulkan_GetInstanceExtensions(window, &count, names.data());
|
SDL_Vulkan_GetInstanceExtensions(window, &count, names.data());
|
||||||
|
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,37 +31,61 @@ int main(int, char*[]) {
|
||||||
window = SDL_CreateWindow("Graph", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
|
window = SDL_CreateWindow("Graph", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
|
||||||
if(!window)
|
if(!window)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
Renderer* renderer = new Renderer();
|
Renderer* renderer = new Renderer();
|
||||||
|
|
||||||
VkSurfaceKHR surface = nullptr;
|
VkSurfaceKHR surface = nullptr;
|
||||||
SDL_Vulkan_CreateSurface(window, renderer->getInstance(), &surface);
|
SDL_Vulkan_CreateSurface(window, renderer->getInstance(), &surface);
|
||||||
|
|
||||||
RenderTarget* target = renderer->createSurfaceRenderTarget(surface);
|
RenderTarget* target = renderer->createSurfaceRenderTarget(surface);
|
||||||
|
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene* scene = importer.ReadFile("suzanne.obj", aiProcess_Triangulate);
|
||||||
|
|
||||||
|
aiMesh* m = scene->mMeshes[0];
|
||||||
|
Mesh* mesh = new Mesh();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
mesh->vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(face.mIndices[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->fillMeshBuffers(mesh);
|
||||||
|
|
||||||
|
World world;
|
||||||
|
world.meshes.push_back(mesh);
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
while(running) {
|
while(running) {
|
||||||
SDL_Event event = {};
|
SDL_Event event = {};
|
||||||
while(SDL_PollEvent(&event)) {
|
while(SDL_PollEvent(&event)) {
|
||||||
if(event.type == SDL_QUIT)
|
if(event.type == SDL_QUIT)
|
||||||
running = false;
|
running = false;
|
||||||
|
|
||||||
if(event.type == SDL_WINDOWEVENT) {
|
if(event.type == SDL_WINDOWEVENT) {
|
||||||
if(event.window.event == SDL_WINDOWEVENT_RESIZED)
|
if(event.window.event == SDL_WINDOWEVENT_RESIZED)
|
||||||
target = renderer->createSurfaceRenderTarget(surface, target);
|
target = renderer->createSurfaceRenderTarget(surface, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->render(target);
|
renderer->render(world, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->destroyRenderTarget(target);
|
renderer->destroyRenderTarget(target);
|
||||||
|
|
||||||
vkDestroySurfaceKHR(renderer->getInstance(), surface, nullptr);
|
vkDestroySurfaceKHR(renderer->getInstance(), surface, nullptr);
|
||||||
|
|
||||||
delete renderer;
|
delete renderer;
|
||||||
|
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "mesh.h"
|
||||||
|
|
||||||
Renderer::Renderer() {
|
Renderer::Renderer() {
|
||||||
createInstance();
|
createInstance();
|
||||||
|
@ -40,7 +41,7 @@ Renderer::~Renderer() {
|
||||||
vkDestroyInstance(instance_, nullptr);
|
vkDestroyInstance(instance_, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::render(RenderTarget* target) {
|
void Renderer::render(World& world, RenderTarget* target) {
|
||||||
uint32_t imageIndex = 0;
|
uint32_t imageIndex = 0;
|
||||||
vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &imageIndex);
|
vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &imageIndex);
|
||||||
|
|
||||||
|
@ -81,7 +82,7 @@ void Renderer::render(RenderTarget* target) {
|
||||||
|
|
||||||
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
worldPass_->render(commandBuffer);
|
worldPass_->render(world, commandBuffer);
|
||||||
|
|
||||||
vkCmdEndRenderPass(commandBuffer);
|
vkCmdEndRenderPass(commandBuffer);
|
||||||
|
|
||||||
|
@ -277,6 +278,75 @@ VkShaderModule Renderer::createShader(const char* path) {
|
||||||
return shaderModule;
|
return shaderModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Renderer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
|
||||||
|
VkPhysicalDeviceMemoryProperties memProperties;
|
||||||
|
vkGetPhysicalDeviceMemoryProperties(physicalDevice_, &memProperties);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
|
||||||
|
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::fillMeshBuffers(Mesh* mesh) {
|
||||||
|
// vertex
|
||||||
|
{
|
||||||
|
VkBufferCreateInfo bufferInfo = {};
|
||||||
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
bufferInfo.size = sizeof(Vertex) * mesh->vertices.size();
|
||||||
|
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||||
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
vkCreateBuffer(device_, &bufferInfo, nullptr, &mesh->vertexBuffer);
|
||||||
|
|
||||||
|
VkMemoryRequirements memRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(device_, mesh->vertexBuffer, &memRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocInfo = {};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocInfo.allocationSize = memRequirements.size;
|
||||||
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
|
|
||||||
|
vkAllocateMemory(device_, &allocInfo, nullptr, &mesh->vertexMemory);
|
||||||
|
vkBindBufferMemory(device_, mesh->vertexBuffer, mesh->vertexMemory, 0);
|
||||||
|
|
||||||
|
void* data;
|
||||||
|
vkMapMemory(device_, mesh->vertexMemory, 0, bufferInfo.size, 0, &data);
|
||||||
|
memcpy(data, mesh->vertices.data(), bufferInfo.size);
|
||||||
|
vkUnmapMemory(device_, mesh->vertexMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// index
|
||||||
|
{
|
||||||
|
VkBufferCreateInfo bufferInfo = {};
|
||||||
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
bufferInfo.size = sizeof(uint32_t) * mesh->indices.size();
|
||||||
|
bufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||||
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
vkCreateBuffer(device_, &bufferInfo, nullptr, &mesh->indexBuffer);
|
||||||
|
|
||||||
|
VkMemoryRequirements memRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(device_, mesh->indexBuffer, &memRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocInfo = {};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocInfo.allocationSize = memRequirements.size;
|
||||||
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
|
|
||||||
|
vkAllocateMemory(device_, &allocInfo, nullptr, &mesh->indexMemory);
|
||||||
|
vkBindBufferMemory(device_, mesh->indexBuffer, mesh->indexMemory, 0);
|
||||||
|
|
||||||
|
void* data;
|
||||||
|
vkMapMemory(device_, mesh->indexMemory, 0, bufferInfo.size, 0, &data);
|
||||||
|
memcpy(data, mesh->indices.data(), bufferInfo.size);
|
||||||
|
vkUnmapMemory(device_, mesh->indexMemory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::createInstance() {
|
void Renderer::createInstance() {
|
||||||
uint32_t layerCount = 0;
|
uint32_t layerCount = 0;
|
||||||
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include "world.h"
|
||||||
|
#include "mesh.h"
|
||||||
|
|
||||||
WorldPass::WorldPass(Renderer& renderer) : renderer_(renderer) {
|
WorldPass::WorldPass(Renderer& renderer) : renderer_(renderer) {
|
||||||
createPipeline();
|
createPipeline();
|
||||||
|
@ -13,9 +15,16 @@ WorldPass::~WorldPass() {
|
||||||
vkDestroyPipelineLayout(renderer_.getDevice(), pipelineLayout_, nullptr);
|
vkDestroyPipelineLayout(renderer_.getDevice(), pipelineLayout_, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldPass::render(VkCommandBuffer commandBuffer) {
|
void WorldPass::render(World& world, VkCommandBuffer commandBuffer) {
|
||||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_);
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_);
|
||||||
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
|
||||||
|
for(const auto& mesh : world.meshes) {
|
||||||
|
VkDeviceSize offsets[] = {0};
|
||||||
|
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &mesh->vertexBuffer, offsets);
|
||||||
|
vkCmdBindIndexBuffer(commandBuffer, mesh->indexBuffer, 0, VK_INDEX_TYPE_UINT32);
|
||||||
|
|
||||||
|
vkCmdDrawIndexed(commandBuffer, mesh->indices.size(), 1, 0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldPass::createPipeline() {
|
void WorldPass::createPipeline() {
|
||||||
|
@ -27,64 +36,72 @@ void WorldPass::createPipeline() {
|
||||||
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
vertShaderStageInfo.module = vertShaderModule;
|
vertShaderStageInfo.module = vertShaderModule;
|
||||||
vertShaderStageInfo.pName = "main";
|
vertShaderStageInfo.pName = "main";
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
|
VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
|
||||||
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
fragShaderStageInfo.module = fragShaderModule;
|
fragShaderStageInfo.module = fragShaderModule;
|
||||||
fragShaderStageInfo.pName = "main";
|
fragShaderStageInfo.pName = "main";
|
||||||
|
|
||||||
const std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = {vertShaderStageInfo, fragShaderStageInfo};
|
const std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = {vertShaderStageInfo, fragShaderStageInfo};
|
||||||
|
|
||||||
|
VkVertexInputBindingDescription vertexBindingDescription = {};
|
||||||
|
vertexBindingDescription.stride = sizeof(Vertex);
|
||||||
|
|
||||||
|
VkVertexInputAttributeDescription positionAttributeDescription = {};
|
||||||
|
positionAttributeDescription.format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
|
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
|
||||||
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
vertexInputInfo.vertexBindingDescriptionCount = 0;
|
vertexInputInfo.vertexBindingDescriptionCount = 1;
|
||||||
vertexInputInfo.vertexAttributeDescriptionCount = 0;
|
vertexInputInfo.pVertexBindingDescriptions = &vertexBindingDescription;
|
||||||
|
vertexInputInfo.vertexAttributeDescriptionCount = 1;
|
||||||
|
vertexInputInfo.pVertexAttributeDescriptions = &positionAttributeDescription;
|
||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
|
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
|
||||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
|
|
||||||
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.scissorCount = 1;
|
viewportState.scissorCount = 1;
|
||||||
|
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizer = {};
|
VkPipelineRasterizationStateCreateInfo rasterizer = {};
|
||||||
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
rasterizer.lineWidth = 1.0f;
|
rasterizer.lineWidth = 1.0f;
|
||||||
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||||
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||||
|
|
||||||
VkPipelineMultisampleStateCreateInfo multisampling = {};
|
VkPipelineMultisampleStateCreateInfo multisampling = {};
|
||||||
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
|
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
|
||||||
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
colorBlendAttachment.blendEnable = VK_FALSE;
|
colorBlendAttachment.blendEnable = VK_FALSE;
|
||||||
|
|
||||||
VkPipelineColorBlendStateCreateInfo colorBlending = {};
|
VkPipelineColorBlendStateCreateInfo colorBlending = {};
|
||||||
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||||
colorBlending.attachmentCount = 1;
|
colorBlending.attachmentCount = 1;
|
||||||
colorBlending.pAttachments = &colorBlendAttachment;
|
colorBlending.pAttachments = &colorBlendAttachment;
|
||||||
|
|
||||||
const std::array<VkDynamicState, 2> dynamicStates = {
|
const std::array<VkDynamicState, 2> dynamicStates = {
|
||||||
VK_DYNAMIC_STATE_VIEWPORT,
|
VK_DYNAMIC_STATE_VIEWPORT,
|
||||||
VK_DYNAMIC_STATE_SCISSOR
|
VK_DYNAMIC_STATE_SCISSOR
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineDynamicStateCreateInfo dynamicState = {};
|
VkPipelineDynamicStateCreateInfo dynamicState = {};
|
||||||
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||||
dynamicState.dynamicStateCount = dynamicStates.size();
|
dynamicState.dynamicStateCount = dynamicStates.size();
|
||||||
dynamicState.pDynamicStates = dynamicStates.data();
|
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;
|
||||||
|
|
||||||
vkCreatePipelineLayout(renderer_.getDevice(), &pipelineLayoutInfo, nullptr, &pipelineLayout_);
|
vkCreatePipelineLayout(renderer_.getDevice(), &pipelineLayoutInfo, nullptr, &pipelineLayout_);
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo pipelineInfo = {};
|
VkGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||||
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
pipelineInfo.stageCount = shaderStages.size();
|
pipelineInfo.stageCount = shaderStages.size();
|
||||||
|
@ -98,9 +115,9 @@ void WorldPass::createPipeline() {
|
||||||
pipelineInfo.pDynamicState = &dynamicState;
|
pipelineInfo.pDynamicState = &dynamicState;
|
||||||
pipelineInfo.layout = pipelineLayout_;
|
pipelineInfo.layout = pipelineLayout_;
|
||||||
pipelineInfo.renderPass = renderer_.getRenderPass();
|
pipelineInfo.renderPass = renderer_.getRenderPass();
|
||||||
|
|
||||||
vkCreateGraphicsPipelines(renderer_.getDevice(), nullptr, 1, &pipelineInfo, nullptr, &pipeline_);
|
vkCreateGraphicsPipelines(renderer_.getDevice(), nullptr, 1, &pipelineInfo, nullptr, &pipeline_);
|
||||||
|
|
||||||
vkDestroyShaderModule(renderer_.getDevice(), fragShaderModule, nullptr);
|
vkDestroyShaderModule(renderer_.getDevice(), fragShaderModule, nullptr);
|
||||||
vkDestroyShaderModule(renderer_.getDevice(), vertShaderModule, nullptr);
|
vkDestroyShaderModule(renderer_.getDevice(), vertShaderModule, nullptr);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue