Compare commits
14 Commits
Author | SHA1 | Date |
---|---|---|
Ковалев Роман Евгеньевич | aef172de5b | |
Ковалев Роман Евгеньевич | 4ee50372b3 | |
Ковалев Роман Евгеньевич | 267a1226ed | |
Ковалев Роман Евгеньевич | 7f317fce22 | |
Ковалев Роман Евгеньевич | 917c6d0d1f | |
Ковалев Роман Евгеньевич | 116a474c5f | |
Ковалев Роман Евгеньевич | 10b58f8556 | |
Ковалев Роман Евгеньевич | 00fad2a149 | |
Ковалев Роман Евгеньевич | eade922953 | |
Ковалев Роман Евгеньевич | 8f41830da3 | |
Ковалев Роман Евгеньевич | cd152c961e | |
Ковалев Роман Евгеньевич | 688d404c6a | |
Ковалев Роман Евгеньевич | 7fd9bbd4d9 | |
Ковалев Роман Евгеньевич | 5c7bd56384 |
|
@ -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
|
|
@ -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
|
13
include/vk.h
13
include/vk.h
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
32
src/main.cpp
32
src/main.cpp
|
@ -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);
|
||||||
|
|
||||||
|
|
63
src/vk.cpp
63
src/vk.cpp
|
@ -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,9 +809,15 @@ void Vulkan::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryP
|
||||||
// Уничтожение буфера и освобождение его памяти
|
// Уничтожение буфера и освобождение его памяти
|
||||||
void Vulkan::destroyBuffer(VkBuffer buffer)
|
void Vulkan::destroyBuffer(VkBuffer buffer)
|
||||||
{
|
{
|
||||||
vkDestroyBuffer(databuffers[buffer].first /*logicalDevice*/, buffer, nullptr); // Уничтожение буфера
|
// Проверка что такой буфер ещё существует
|
||||||
vkFreeMemory(databuffers[buffer].first /*logicalDevice*/, databuffers[buffer].second /*VkDeviceMemory*/, nullptr); // Освобождение памяти буфера
|
if (databuffers.find(buffer) != databuffers.end())
|
||||||
databuffers.erase(buffer); // Удалим ключ из словаря
|
{
|
||||||
|
vkDeviceWaitIdle(logicalDevice); // Ожидание окончания асинхронных задач
|
||||||
|
|
||||||
|
vkDestroyBuffer(databuffers[buffer].first /*logicalDevice*/, buffer, nullptr); // Уничтожение буфера
|
||||||
|
vkFreeMemory(databuffers[buffer].first /*logicalDevice*/, databuffers[buffer].second /*VkDeviceMemory*/, nullptr); // Освобождение памяти буфера
|
||||||
|
databuffers.erase(buffer); // Удалим ключ из словаря
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Создание пула команд
|
// Создание пула команд
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue