Compare commits

..

14 Commits
v0.1 ... master

Author SHA1 Message Date
Ковалев Роман Евгеньевич aef172de5b Проверка буфера на существование перед удалением 2022-04-07 14:06:17 +03:00
Ковалев Роман Евгеньевич 4ee50372b3 Фикс коментария 2022-04-07 13:48:42 +03:00
Ковалев Роман Евгеньевич 267a1226ed Добавил виртуальность конструкторам 2022-04-07 13:43:03 +03:00
Ковалев Роман Евгеньевич 7f317fce22 Фикс ожидания ассинхр. задач для удаления буфера 2022-04-07 13:42:51 +03:00
Ковалев Роман Евгеньевич 917c6d0d1f Правка области видимости 2022-04-07 13:24:06 +03:00
Ковалев Роман Евгеньевич 116a474c5f Пример использования класса модели с индексным буфером 2022-04-07 13:17:05 +03:00
Ковалев Роман Евгеньевич 10b58f8556 Фикс коментов 2022-04-07 13:10:30 +03:00
Ковалев Роман Евгеньевич 00fad2a149 фикс оперчатки 2022-04-07 13:06:02 +03:00
Ковалев Роман Евгеньевич eade922953 public: renderBegin, renderEnd 2022-04-07 12:31:44 +03:00
Ковалев Роман Евгеньевич 8f41830da3 Класс модели с индексами 2022-04-07 12:29:47 +03:00
Ковалев Роман Евгеньевич cd152c961e Добавил метод привязки буферов 2022-04-07 12:29:29 +03:00
Ковалев Роман Евгеньевич 688d404c6a Класс модели без индексов 2022-04-07 12:15:15 +03:00
Ковалев Роман Евгеньевич 7fd9bbd4d9 Интерфейс модели 2022-04-07 12:05:16 +03:00
Ковалев Роман Евгеньевич 5c7bd56384 Переместил объект Vulkan 2022-04-07 09:46:17 +03:00
6 changed files with 190 additions and 38 deletions

15
include/I_Model.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef I_MODEL_H
#define I_MODEL_H
#include <vulkan/vulkan.h>
class I_Model
{
public:
virtual ~I_Model() {}; // Виртуальный деструктор для корректной работы деструкторов в полиморфизме
virtual void render(VkCommandBuffer commandBuffer) = 0;
protected:
virtual void bindBuffers(VkCommandBuffer commandBuffer) = 0;
};
#endif // I_MODEL_H

35
include/Model.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef MODEL_H
#define MODEL_H
#include "I_Model.h"
#include "Vertex.h"
// Класс модели без индексов
class Model_wo_indexes : public I_Model
{
public:
Model_wo_indexes(Vertex* vertexArray, uint32_t verteciesCount);
virtual ~Model_wo_indexes();
virtual void render(VkCommandBuffer commandBuffer);
protected:
void bindBuffers(VkCommandBuffer commandBuffer); // привязка используемых буферов данных
private:
uint32_t verteciesCount; // Количество вершин
VkBuffer vertexBuffer; // Буфер вершин
};
// Класс модели с индексами
class Model_w_indexes : public Model_wo_indexes
{
public:
Model_w_indexes(Vertex* vertexArray, uint32_t verteciesCount, uint32_t* indexArray, uint32_t indeciesCount);
virtual ~Model_w_indexes();
virtual void render(VkCommandBuffer commandBuffer);
protected:
void bindBuffers(VkCommandBuffer commandBuffer); // привязка используемых буферов данных
private:
uint32_t indeciesCount; // Количество индексов
VkBuffer indexBuffer; // Буфер индексов
};
#endif // MODEL_H

View File

@ -9,6 +9,9 @@
#include "Queue.h" #include "Queue.h"
#include <map> #include <map>
#include <list>
#include "Model.h"
class Vulkan class Vulkan
{ {
@ -16,8 +19,13 @@ class Vulkan
void init(GLFWwindow* window); // инициализация void init(GLFWwindow* window); // инициализация
void destroy(); // завершение работы void destroy(); // завершение работы
void renderFrame(); // рендер кадра void renderFrame(); // рендер кадра
void renderBegin(); // Начало рендера кадра
void renderEnd(); // Окончание рендера кадра
VkBuffer createDataBuffer(void* data, VkDeviceSize size, VkBufferUsageFlags usage); // Создание буфера данных VkBuffer createDataBuffer(void* data, VkDeviceSize size, VkBufferUsageFlags usage); // Создание буфера данных
void destroyBuffer(VkBuffer buffer); // Уничтожение буфера и освобождение его памяти void destroyBuffer(VkBuffer buffer); // Уничтожение буфера и освобождение его памяти
void addToRenderList(I_Model* model); // Добавление модели в список рендера
void removeFromRenderList(I_Model* model); // Удалеие модели из список рендера
void clearRenderList(); // Очистка списка рендера моделей
private: private:
VkInstance instance; // Экземпляр Vulkan VkInstance instance; // Экземпляр Vulkan
PhysicalDevice physicalDevice; // Физическое устройство PhysicalDevice physicalDevice; // Физическое устройство
@ -33,8 +41,6 @@ class Vulkan
VkPipeline graphicsPipeline; // Графический конвейер VkPipeline graphicsPipeline; // Графический конвейер
VkCommandPool commandPool; // Пул команд VkCommandPool commandPool; // Пул команд
std::vector<VkCommandBuffer> commandBuffers; // Буферы команд std::vector<VkCommandBuffer> commandBuffers; // Буферы команд
VkBuffer vertexBuffer; // Буфер вершин
VkBuffer indexBuffer; // Буфер индексов
std::vector<VkSemaphore> imageAvailableSemaphores; // семафор доступности изображения std::vector<VkSemaphore> imageAvailableSemaphores; // семафор доступности изображения
std::vector<VkSemaphore> renderFinishedSemaphores; // семафор окончания рендера std::vector<VkSemaphore> renderFinishedSemaphores; // семафор окончания рендера
std::vector<VkFence> inWorkFences; // барьер кадра в работе std::vector<VkFence> inWorkFences; // барьер кадра в работе
@ -42,6 +48,7 @@ class Vulkan
uint32_t imageIndex; // Текущее изображение из списка показа uint32_t imageIndex; // Текущее изображение из списка показа
std::map<VkBuffer, std::pair<VkDevice, VkDeviceMemory>> databuffers; // Словарь для сопоставления дескриптору буфера дескрипторов лог. устройства и памяти std::map<VkBuffer, std::pair<VkDevice, VkDeviceMemory>> databuffers; // Словарь для сопоставления дескриптору буфера дескрипторов лог. устройства и памяти
std::list<I_Model*> renderList; // Спискок моделей для рендера
// Структура для хранения флагов // Структура для хранения флагов
struct struct
@ -64,8 +71,6 @@ class Vulkan
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); // Копирование между буферами данных void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); // Копирование между буферами данных
void createSyncObjects(); // Создание объектов синхронизации void createSyncObjects(); // Создание объектов синхронизации
void createFramebuffers(); // Создание буферов кадра void createFramebuffers(); // Создание буферов кадра
void renderBegin(); // Начало рендера кадра
void renderEnd(); // Окончание рендера кадра
}; };
#endif // VK_H #endif // VK_H

70
src/Model.cpp Normal file
View File

@ -0,0 +1,70 @@
#include "Model.h"
#include "vk.h"
#include <iostream>
// Конструктор класса без индексов - принимает массив вершин
Model_wo_indexes::Model_wo_indexes(Vertex* vertexArray, uint32_t count) : verteciesCount(count)
{
extern Vulkan vulkan;
// Создание и инициализация буфера вершин
vertexBuffer = vulkan.createDataBuffer(vertexArray, verteciesCount * sizeof(Vertex), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
}
// Деструктор класса без индексов
Model_wo_indexes::~Model_wo_indexes()
{
extern Vulkan vulkan;
vulkan.destroyBuffer(vertexBuffer);
}
// привзка используемых буферов данных
void Model_wo_indexes::bindBuffers(VkCommandBuffer commandBuffer)
{
VkBuffer vertexBuffers[] = {vertexBuffer};
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
}
// Рендер модели без индексов
void Model_wo_indexes::render(VkCommandBuffer commandBuffer)
{
bindBuffers(commandBuffer);
vkCmdDraw(commandBuffer, verteciesCount, 1, 0, 0);
}
// Конструктор класса с индексами - принимает массивы вершин и индексов
Model_w_indexes::Model_w_indexes(Vertex* vertexArray, uint32_t vCount, uint32_t* indexArray, uint32_t iCount)
: Model_wo_indexes(vertexArray, vCount), indeciesCount(iCount)
{
extern Vulkan vulkan;
// Создание и инициализация буфера индексов
indexBuffer = vulkan.createDataBuffer(indexArray, indeciesCount * sizeof(uint32_t), VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
}
// Деструктор класса с индексами
Model_w_indexes::~Model_w_indexes()
{
extern Vulkan vulkan;
vulkan.destroyBuffer(indexBuffer);
}
// привзка используемых буферов данных
void Model_w_indexes::bindBuffers(VkCommandBuffer commandBuffer)
{
// Привязка родительских буферов
Model_wo_indexes::bindBuffers(commandBuffer);
// Привязка индексного буфера
vkCmdBindIndexBuffer(commandBuffer, indexBuffer, 0, VK_INDEX_TYPE_UINT32);
}
// Рендер модели с индексами
void Model_w_indexes::render(VkCommandBuffer commandBuffer)
{
bindBuffers(commandBuffer);
vkCmdDrawIndexed(commandBuffer, indeciesCount, 1, 0, 0, 0);
}

View File

@ -1,11 +1,26 @@
#include "vk.h" #include "vk.h"
#include <iostream> #include <iostream>
void vkInit(); #include "Model.h"
int main(int argc, char* argv[]) { int main(int argc, char* argv[])
{
// объект класса-обертки Vulkan API
extern Vulkan vulkan;
//Вершины, записываемые в буфер
Vertex vertices[] = {
{ {-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f} },
{ { 0.5f, -0.5f}, {0.0f, 1.0f, 0.0f} },
{ { 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f} },
{ {-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f} }
};
// Индексы, записываемые в буфер
uint32_t indices[] = {0, 1, 2, 2, 3, 0};
I_Model * model;
// Инициализация GLFW // Инициализация GLFW
glfwInit(); glfwInit();
@ -13,9 +28,6 @@ int main(int argc, char* argv[]) {
// Проверка доступности Vulkan // Проверка доступности Vulkan
if (glfwVulkanSupported()) if (glfwVulkanSupported())
{ {
// объект класса-обертки Vulkan API
Vulkan vulkan;
// Отключим создание контекста // Отключим создание контекста
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
// Отключим возможность изменения размеров окна // Отключим возможность изменения размеров окна
@ -26,13 +38,19 @@ int main(int argc, char* argv[]) {
// Инициализация Vulkan API // Инициализация Vulkan API
vulkan.init(window); vulkan.init(window);
model = new Model_w_indexes(vertices, 4, indices, 6);
vulkan.addToRenderList(model);
// Жизненный цикл // Жизненный цикл
while(!glfwWindowShouldClose(window)) { while(!glfwWindowShouldClose(window))
{
// Обработка событий // Обработка событий
glfwPollEvents(); glfwPollEvents();
vulkan.renderFrame(); vulkan.renderFrame();
} }
delete model;
// Уничтожение окна // Уничтожение окна
glfwDestroyWindow(window); glfwDestroyWindow(window);

View File

@ -7,6 +7,9 @@
#include "macroses.h" #include "macroses.h"
// объект класса-обертки Vulkan API
Vulkan vulkan;
// инициализация // инициализация
void Vulkan::init(GLFWwindow* window) void Vulkan::init(GLFWwindow* window)
{ {
@ -21,23 +24,6 @@ void Vulkan::init(GLFWwindow* window)
createFramebuffers(); // Создание буферов кадра createFramebuffers(); // Создание буферов кадра
createGraphicPipeline(); // Создание графического конвейера createGraphicPipeline(); // Создание графического конвейера
createCommandPool(); // Создание пула команд createCommandPool(); // Создание пула команд
//Вершины, записываемые в буфер
Vertex vertices[] = {
{ {-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f} },
{ { 0.5f, -0.5f}, {0.0f, 1.0f, 0.0f} },
{ { 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f} },
{ {-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f} }
};
// Размер буфера в байтах
VkDeviceSize bufferSize = sizeof(Vertex) * 4;
vertexBuffer = createDataBuffer(vertices, bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); // Создание буфера вершин
// Индексы, записываемые в буфер
uint16_t indices[] = {0, 1, 2, 2, 3, 0};
// Размер буфера в байтах
bufferSize = sizeof(uint16_t) * 6;
indexBuffer = createDataBuffer(indices, bufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); // Создание буфера индексов
createSyncObjects(); // Создание объектов синхронизации createSyncObjects(); // Создание объектов синхронизации
} }
@ -823,10 +809,16 @@ void Vulkan::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryP
// Уничтожение буфера и освобождение его памяти // Уничтожение буфера и освобождение его памяти
void Vulkan::destroyBuffer(VkBuffer buffer) void Vulkan::destroyBuffer(VkBuffer buffer)
{ {
// Проверка что такой буфер ещё существует
if (databuffers.find(buffer) != databuffers.end())
{
vkDeviceWaitIdle(logicalDevice); // Ожидание окончания асинхронных задач
vkDestroyBuffer(databuffers[buffer].first /*logicalDevice*/, buffer, nullptr); // Уничтожение буфера vkDestroyBuffer(databuffers[buffer].first /*logicalDevice*/, buffer, nullptr); // Уничтожение буфера
vkFreeMemory(databuffers[buffer].first /*logicalDevice*/, databuffers[buffer].second /*VkDeviceMemory*/, nullptr); // Освобождение памяти буфера vkFreeMemory(databuffers[buffer].first /*logicalDevice*/, databuffers[buffer].second /*VkDeviceMemory*/, nullptr); // Освобождение памяти буфера
databuffers.erase(buffer); // Удалим ключ из словаря databuffers.erase(buffer); // Удалим ключ из словаря
} }
}
// Создание пула команд // Создание пула команд
void Vulkan::createCommandPool() void Vulkan::createCommandPool()
@ -988,13 +980,10 @@ void Vulkan::renderFrame()
{ {
renderBegin(); // Начало рендера renderBegin(); // Начало рендера
VkBuffer vertexBuffers[] = {vertexBuffer}; for (auto const& model : renderList)
VkDeviceSize offsets[] = {0}; {
vkCmdBindVertexBuffers(commandBuffers[currentFrame], 0, 1, vertexBuffers, offsets); model->render(commandBuffers[currentFrame]);
}
vkCmdBindIndexBuffer(commandBuffers[currentFrame], indexBuffer, 0, VK_INDEX_TYPE_UINT16);
vkCmdDrawIndexed(commandBuffers[currentFrame], 6, 1, 0, 0, 0);
renderEnd(); // Конец рендера renderEnd(); // Конец рендера
} }
@ -1096,3 +1085,23 @@ void Vulkan::renderEnd()
throw std::runtime_error("Unable to present swap chain image"); throw std::runtime_error("Unable to present swap chain image");
} }
} }
// Добавление модели в список рендера
void Vulkan::addToRenderList(I_Model* model)
{
if (model)
renderList.push_back(model);
}
// Удаление модели из список рендера
void Vulkan::removeFromRenderList(I_Model* model)
{
if (model)
renderList.remove(model);
}
// Очистка списка рендера моделей
void Vulkan::clearRenderList()
{
renderList.clear();
}