Author SHA1 Message Date
Ivan Belyavtsev ee88ef3771 Default cameras 2025-04-03 17:41:24 +03:00
Ivan Belyavtsev 65948fdc95 Fixed world matrix 2025-04-03 15:39:24 +03:00
Ivan Belyavtsev cefbd1b4f7 Partially added matrices 2025-03-27 17:57:15 +03:00
Emil Shanaty 2a46168748 It shows the poligons! 2025-03-22 13:37:42 +03:00
Emil Shanaty 32d684bcc4 new commit 2025-03-20 16:12:23 +03:00
2 changed files with 388 additions and 126 deletions
+12 -2
View File
@@ -1,5 +1,15 @@
#version 450
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 projection;
} ubo;
layout(location = 0) out vec3 fragColor;
vec2 positions[3] = vec2[](
@@ -15,6 +25,6 @@ vec3 colors[3] = vec3[] (
);
void main() {
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
fragColor = colors[gl_VertexIndex];
gl_Position = ubo.projection * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = clamp(inNormal, vec3(0.0), vec3(1.0));
}
+376 -124
View File
@@ -18,6 +18,7 @@
#include <filesystem>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "tiny_gltf.h"
using namespace tinygltf;
@@ -28,70 +29,11 @@ struct Vertex {
glm::vec2 uv;
};
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
VkBuffer vertexBuffer;
VkDeviceMemory vertexBufferMemory;
VkBuffer indexBuffer;
VkDeviceMemory indexBufferMemory;
Model model;
void loadModel() {
TinyGLTF loader;
std::string err;
std::string warn;
bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, "C:/Users/emil2/OneDrive/Desktop/Coding/Study/CGDG/vulkan_tweaking/models/Models/BrainStem/glTF/BrainStem.gltf");
if (!warn.empty()) {
std::cout << "GLTF warning: " << warn << std::endl;
}
if (!err.empty()) {
std::cerr << "GLTF error: " << err << std::endl;
}
if (!ret) {
throw std::runtime_error("Failed to load GLTF: " + err);
}
// Ïîëó÷åíèå äàííûõ âåðøèí è èíäåêñîâ
for (const auto& mesh : model.meshes) {
for (const auto& primitive : mesh.primitives) {
// Âåðøèíû
const auto& positionAccessor = model.accessors[primitive.attributes.at("POSITION")];
const auto& positionView = model.bufferViews[positionAccessor.bufferView];
const auto& positionBuffer = model.buffers[positionView.buffer];
const float* positions = reinterpret_cast<const float*>(&positionBuffer.data[positionView.byteOffset + positionAccessor.byteOffset]);
// Íîðìàëè (åñëè åñòü)
const auto& normalAccessor = model.accessors[primitive.attributes.at("NORMAL")];
const auto& normalView = model.bufferViews[normalAccessor.bufferView];
const auto& normalBuffer = model.buffers[normalView.buffer];
const float* normals = reinterpret_cast<const float*>(&normalBuffer.data[normalView.byteOffset + normalAccessor.byteOffset]);
// Èíäåêñû
const auto& indexAccessor = model.accessors[primitive.indices];
const auto& indexView = model.bufferViews[indexAccessor.bufferView];
const auto& indexBuffer = model.buffers[indexView.buffer];
const uint16_t* indicesSrc = reinterpret_cast<const uint16_t*>(&indexBuffer.data[indexView.byteOffset + indexAccessor.byteOffset]);
// Çàïîëíåíèå âåêòîðîâ
for (size_t i = 0; i < positionAccessor.count; i++) {
Vertex vertex{};
vertex.pos = glm::vec3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
vertex.normal = glm::vec3(normals[i * 3], normals[i * 3 + 1], normals[i * 3 + 2]);
vertices.push_back(vertex);
}
for (size_t i = 0; i < indexAccessor.count; i++) {
indices.push_back(indicesSrc[i]);
}
}
}
}
struct UniformBufferObject {
glm::mat4 model;
glm::mat4 view;
glm::mat4 proj;
};
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
@@ -207,17 +149,28 @@ private:
const std::string engineName = "The Best Engine";
const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
"VK_KHR_portability_subset",
};
const std::vector<const char*> validationLayers = {
"VK_LAYER_KHRONOS_validation"
};
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
VkBuffer vertexBuffer;
VkDeviceMemory vertexBufferMemory;
std::vector<std::vector<Vertex>> vertices;
std::vector<std::vector<uint32_t>> indices;
std::vector<glm::mat4x4> worldMatrices;
glm::mat4x4 viewMatrix;
glm::mat4x4 projectionMatrix;
std::vector<VkBuffer> vertexBuffer;
std::vector<VkDeviceMemory> vertexBufferMemory;
std::vector<VkBuffer> indexBuffer;
std::vector<VkDeviceMemory> indexBufferMemory;
Model model;
std::vector<VkBuffer> uniformBuffers;
std::vector<VkDeviceMemory> uniformBuffersMemory;
std::vector<void*> uniformBuffersMapped;
#ifdef NDEBUG
const bool enableValidationLayers = false;
@@ -240,6 +193,9 @@ private:
VkExtent2D swapChainExtent = {};
std::vector<VkImageView> swapChainImageViews;
VkRenderPass renderPass = VK_NULL_HANDLE;
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
std::vector<VkDescriptorSet> descriptorSets;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
VkPipeline graphicsPipeline = VK_NULL_HANDLE;
std::vector<VkFramebuffer> swapChainFramebuffers;
@@ -277,12 +233,16 @@ private:
createSurface();
pickPhysicalDevice();
createLogicalDevice();
loadModel();
loadModel(); // createVertexBuffer()
createVertexBuffer();
createIndexBuffer();
createUniformBuffers();
createSwapChain();
createImageViews();
createRenderPass();
createDescriptorSetLayout();
createDescriptorPool();
createDescriptorSets();
createGraphicsPipeline();
createFramebuffers();
createCommandPool();
@@ -311,42 +271,169 @@ private:
return true;
}
private:
void processNodes(const std::vector<int> &nodes, glm::mat4x4 globalTransform){
for (const auto& node_id : nodes) {
auto node = model.nodes[node_id];
glm::mat4x4 localTransform(1);
if (node.translation.size() == 3) {
localTransform = glm::translate(localTransform, glm::vec3(glm::make_vec3(node.translation.data())));
}
if (node.rotation.size() == 4) {
glm::quat q = glm::make_quat(node.rotation.data());
localTransform *= glm::mat4(q);
}
if (node.scale.size() == 3) {
localTransform = glm::scale(localTransform, glm::vec3(glm::make_vec3(node.scale.data())));
}
if (node.matrix.size() == 16) {
localTransform = glm::make_mat4x4(node.matrix.data());
};
auto transform = globalTransform*localTransform;
if (node.mesh > -1) {
loadMesh(model.meshes[node.mesh]);
worldMatrices.push_back(transform);
}
if (node.camera == 0) {
viewMatrix = glm::inverse(transform);
}
processNodes(node.children, transform);
}
};
void loadMesh(const Mesh& mesh) {
std::cout << "Load mesh\n";
std::vector <Vertex> vb;
std::vector<uint32_t> ib;
for (const auto& primitive : mesh.primitives) {
//
const auto& positionAccessor = model.accessors[primitive.attributes.at("POSITION")];
const auto& positionView = model.bufferViews[positionAccessor.bufferView];
const auto& positionBuffer = model.buffers[positionView.buffer];
const float* positions = reinterpret_cast<const float*>(&positionBuffer.data[positionView.byteOffset + positionAccessor.byteOffset]);
// ( )
const auto& normalAccessor = model.accessors[primitive.attributes.at("NORMAL")];
const auto& normalView = model.bufferViews[normalAccessor.bufferView];
const auto& normalBuffer = model.buffers[normalView.buffer];
const float* normals = reinterpret_cast<const float*>(&normalBuffer.data[normalView.byteOffset + normalAccessor.byteOffset]);
//
const auto& indexAccessor = model.accessors[primitive.indices];
const auto& indexView = model.bufferViews[indexAccessor.bufferView];
const auto& indexBuffer = model.buffers[indexView.buffer];
const uint16_t* indicesSrc = reinterpret_cast<const uint16_t*>(&indexBuffer.data[indexView.byteOffset + indexAccessor.byteOffset]);
//
for (size_t i = 0; i < positionAccessor.count; i++) {
Vertex vertex{};
vertex.pos = glm::vec3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
vertex.normal = glm::vec3(normals[i * 3], normals[i * 3 + 1], normals[i * 3 + 2]);
vb.push_back(vertex);
}
for (size_t i = 0; i < indexAccessor.count; i++) {
ib.push_back(indicesSrc[i]);
}
}
vertices.push_back(vb);
indices.push_back(ib);
}
void loadModel() {
TinyGLTF loader;
std::string err;
std::string warn;
bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, "models/Models/BrainStem/glTF/BrainStem.gltf");
if (!warn.empty()) {
std::cout << "GLTF warning: " << warn << std::endl;
}
if (!err.empty()) {
std::cerr << "GLTF error: " << err << std::endl;
}
if (!ret) {
throw std::runtime_error("Failed to load GLTF: " + err);
}
viewMatrix = glm::mat4x4(1);
projectionMatrix = glm::mat4x4(1);
//glm::perspectiveFovLH(60.f, static_cast<float>(WIDTH), static_cast<float>(HEIGHT), 0.001f, 1000.f);
if (model.cameras.size() > 0)
{
const auto& camera = model.cameras[0];
if (camera.type == "perspective")
{
projectionMatrix = glm::perspectiveRH(camera.perspective.yfov, camera.perspective.aspectRatio, camera.perspective.znear, camera.perspective.zfar);
}
if (camera.type == "orthographic")
{
auto right = camera.orthographic.xmag / 2.f;
auto left = - right;
auto top = camera.orthographic.ymag / 2.f;
auto bottom = - top;
projectionMatrix = glm::orthoRH(left, right, bottom, top, camera.orthographic.znear, camera.orthographic.zfar);
}
}
projectionMatrix[1][1] *= -1.0f;
processNodes(model.scenes[0].nodes, glm::mat4x4(1));
std::cout << "Loaded " << vertices.size() << " vertices, "
<< indices.size() << " indices" << std::endl;
}
void createVertexBuffer() {
if (vertices.empty()) {
throw std::runtime_error("No vertices loaded!");
}
VkDeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = sizeof(vertices[0]) * vertices.size();
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
vertexBuffer.resize(vertices.size());
vertexBufferMemory.resize(vertices.size());
// Óáðàòü this->, òàê êàê device óæå ÷ëåí êëàññà
if (vkCreateBuffer(device, &bufferInfo, nullptr, &vertexBuffer) != VK_SUCCESS) {
throw std::runtime_error("failed to create vertex buffer!");
for (size_t i = 0; i < vertices.size(); i++)
{
auto vb = vertices[i];
std::cout << "Vertex buffer: " << vb.size() << "\n";
VkDeviceSize bufferSize = sizeof(Vertex) * vb.size();
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = bufferSize;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
// this->, device
if (vkCreateBuffer(device, &bufferInfo, nullptr, &vertexBuffer[i]) != VK_SUCCESS) {
throw std::runtime_error("failed to create vertex buffer!");
}
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, vertexBuffer[i], &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);
if (vkAllocateMemory(device, &allocInfo, nullptr, &vertexBufferMemory[i]) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate vertex buffer memory!");
}
vkBindBufferMemory(device, vertexBuffer[i], vertexBufferMemory[i], 0);
void* data;
vkMapMemory(device, vertexBufferMemory[i], 0, bufferInfo.size, 0, &data);
memcpy(data, vb.data(), bufferInfo.size);
vkUnmapMemory(device, vertexBufferMemory[i]);
}
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, 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);
if (vkAllocateMemory(device, &allocInfo, nullptr, &vertexBufferMemory) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate vertex buffer memory!");
}
vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory, 0);
void* data;
vkMapMemory(device, vertexBufferMemory, 0, bufferInfo.size, 0, &data);
memcpy(data, vertices.data(), bufferInfo.size);
vkUnmapMemory(device, vertexBufferMemory);
}
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
VkPhysicalDeviceMemoryProperties memProperties;
@@ -598,6 +685,11 @@ private:
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
createInfo.enabledLayerCount = 0;
VkPhysicalDeviceSynchronization2Features syncFeatures{};
syncFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES;
syncFeatures.synchronization2 = true;
createInfo.pNext = &syncFeatures;
if (enableValidationLayers) {
createInfo.enabledLayerCount = validationLayers.size();
createInfo.ppEnabledLayerNames = validationLayers.data();
@@ -614,36 +706,133 @@ private:
throw std::runtime_error("No indices loaded!");
}
VkDeviceSize bufferSize = sizeof(indices[0]) * indices.size();
indexBuffer.resize(indices.size());
indexBufferMemory.resize(indices.size());
for (size_t i=0; i<indices.size(); i++)
{
auto ib = indices[i];
VkDeviceSize bufferSize = sizeof(uint32_t) * ib.size();
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = bufferSize;
bufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if (vkCreateBuffer(device, &bufferInfo, nullptr, &indexBuffer[i]) != VK_SUCCESS) {
throw std::runtime_error("failed to create index buffer!");
}
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, indexBuffer[i], &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);
if (vkAllocateMemory(device, &allocInfo, nullptr, &indexBufferMemory[i]) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate index buffer memory!");
}
vkBindBufferMemory(device, indexBuffer[i], indexBufferMemory[i], 0);
void* data;
vkMapMemory(device, indexBufferMemory[i], 0, bufferInfo.size, 0, &data);
memcpy(data, ib.data(), bufferInfo.size);
vkUnmapMemory(device, indexBufferMemory[i]);
}
}
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) {
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = sizeof(indices[0]) * indices.size();
bufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
bufferInfo.size = size;
bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if (vkCreateBuffer(device, &bufferInfo, nullptr, &indexBuffer) != VK_SUCCESS) {
throw std::runtime_error("failed to create index buffer!");
if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
throw std::runtime_error("failed to create buffer!");
}
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, indexBuffer, &memRequirements);
vkGetBufferMemoryRequirements(device, buffer, &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);
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate buffer memory!");
}
vkBindBufferMemory(device, buffer, bufferMemory, 0);
}
if (vkAllocateMemory(device, &allocInfo, nullptr, &indexBufferMemory) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate index buffer memory!");
void createUniformBuffers() {
VkDeviceSize bufferSize = sizeof(UniformBufferObject);
uniformBuffers.resize(indices.size());
uniformBuffersMemory.resize(indices.size());
uniformBuffersMapped.resize(indices.size());
for (size_t i = 0; i < indices.size(); i++) {
createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffers[i], uniformBuffersMemory[i]);
vkMapMemory(device, uniformBuffersMemory[i], 0, bufferSize, 0, &uniformBuffersMapped[i]);
}
}
void createDescriptorPool() {
VkDescriptorPoolSize poolSize{};
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSize.descriptorCount = 1;
VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;
poolInfo.maxSets = 1;
if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor pool!");
}
}
void createDescriptorSets() {
std::cout << "createDescriptorSets: " << indices.size() << "\n";
std::vector<VkDescriptorSetLayout> layouts(indices.size(), descriptorSetLayout);
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorSetCount = indices.size();
allocInfo.pSetLayouts = layouts.data();
descriptorSets.resize(indices.size());
if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSets.data()) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate descriptor sets!");
}
vkBindBufferMemory(device, indexBuffer, indexBufferMemory, 0);
for (size_t i = 0; i < indices.size(); i++) {
VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = uniformBuffers[i];
bufferInfo.offset = 0;
bufferInfo.range = sizeof(UniformBufferObject);
void* data;
vkMapMemory(device, indexBufferMemory, 0, bufferInfo.size, 0, &data);
memcpy(data, indices.data(), bufferInfo.size);
vkUnmapMemory(device, indexBufferMemory);
VkWriteDescriptorSet descriptorWrite{};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = descriptorSets[i];
descriptorWrite.dstBinding = 0;
descriptorWrite.dstArrayElement = 0;
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrite.descriptorCount = 1;
descriptorWrite.pBufferInfo = &bufferInfo;
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
}
}
void createSwapChain() {
@@ -768,6 +957,24 @@ private:
}
}
void createDescriptorSetLayout() {
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
uboLayoutBinding.pImmutableSamplers = nullptr;
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = 1;
layoutInfo.pBindings = &uboLayoutBinding;
if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor set layout!");
}
}
void createGraphicsPipeline() {
auto vertShaderCode = readFile("shaders/vert.spv");
auto fragShaderCode = readFile("shaders/frag.spv");
@@ -838,7 +1045,7 @@ private:
rasterizerState.polygonMode = VK_POLYGON_MODE_FILL;
rasterizerState.lineWidth = 1.0f;
rasterizerState.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizerState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; // Èñïðàâëåíî íà ïðàâèëüíîå íàïðàâëåíèå
rasterizerState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; //
rasterizerState.depthBiasEnable = VK_FALSE;
VkPipelineMultisampleStateCreateInfo multisamplingState{};
@@ -871,7 +1078,8 @@ private:
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 0;
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
pipelineLayoutInfo.pushConstantRangeCount = 0;
if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
@@ -882,7 +1090,7 @@ private:
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = shaderStages.size();
pipelineInfo.pStages = shaderStages.data();
pipelineInfo.pVertexInputState = &vertexInputInfo; // Èñïðàâëåííûé vertex input
pipelineInfo.pVertexInputState = &vertexInputInfo; // vertex input
pipelineInfo.pInputAssemblyState = &inputAssemblyState;
pipelineInfo.pViewportState = &viewportState;
pipelineInfo.pRasterizationState = &rasterizerState;
@@ -1001,7 +1209,16 @@ private:
scissor.extent = swapChainExtent;
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
// TODO: Add VertexBUffer binding
for (size_t i=0; i<indices.size(); i++)
{
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer[i], offsets);
vkCmdBindIndexBuffer(commandBuffer, indexBuffer[i], 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[i], 0, nullptr);
vkCmdDraw(commandBuffer, indices[i].size(), 1, 0, 0);
}
vkCmdEndRenderPass(commandBuffer);
@@ -1010,6 +1227,18 @@ private:
}
}
void updateUniformBuffer() {
for (size_t i=0; i<indices.size(); i++)
{
UniformBufferObject ubo{};
ubo.model = worldMatrices[i];
ubo.view = viewMatrix;
ubo.proj = projectionMatrix;
memcpy(uniformBuffersMapped[i], &ubo, sizeof(ubo));
}
}
void drawFrame() {
vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &inFlightFence);
@@ -1017,6 +1246,8 @@ private:
uint32_t imageIndex;
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
updateUniformBuffer();
vkResetCommandBuffer(commandBuffer, 0);
recordCommandBuffer(commandBuffer, imageIndex);
@@ -1061,10 +1292,22 @@ private:
}
void cleanup() {
vkDestroyBuffer(device, vertexBuffer, nullptr);
vkFreeMemory(device, vertexBufferMemory, nullptr);
vkDestroyBuffer(device, indexBuffer, nullptr);
vkFreeMemory(device, indexBufferMemory, nullptr);
for (auto vb : vertexBuffer)
{
vkDestroyBuffer(device, vb, nullptr);
}
for (auto vbm : vertexBufferMemory)
{
vkFreeMemory(device, vbm, nullptr);
}
for (auto ib : indexBuffer)
{
vkDestroyBuffer(device, ib, nullptr);
}
for (auto ibm : indexBufferMemory)
{
vkFreeMemory(device, ibm, nullptr);
}
vkDeviceWaitIdle(device);
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
@@ -1075,6 +1318,15 @@ private:
}
vkDestroyPipeline(device, graphicsPipeline, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
for (size_t i = 0; i < indices.size(); i++) {
vkDestroyBuffer(device, uniformBuffers[i], nullptr);
vkFreeMemory(device, uniformBuffersMemory[i], nullptr);
}
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
vkDestroyRenderPass(device, renderPass, nullptr);
for (auto imageView : swapChainImageViews) {
vkDestroyImageView(device, imageView, nullptr);