1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-27 06:07:45 +00:00

Load vertex data and load shaders from disk

This commit is contained in:
Joshua Goins 2022-04-12 00:54:11 -04:00
parent fd9ce7c361
commit 338c485018
9 changed files with 168 additions and 8 deletions

View file

@ -82,13 +82,8 @@ MainWindow::MainWindow(GameData& data) : data(data) {
vkWindow->setVulkanInstance(inst);
auto widget = QWidget::createWindowContainer(vkWindow);
//widget->resize(640, 480);
layout->addWidget(widget);
//vkWindow->show();
//auto surface = inst.surfaceForWindow(vkWindow);
//renderer->initSwapchain(surface);
data.extractFile("chara/equipment/e0000/model/c0201e0000_top.mdl", "top.mdl");
renderer->addModel(parseMDL("top.mdl"));
}

View file

@ -2,4 +2,4 @@ find_package(Vulkan REQUIRED)
add_library(renderer src/renderer.cpp)
target_include_directories(renderer PUBLIC include)
target_link_libraries(renderer PUBLIC Vulkan::Vulkan fmt::fmt)
target_link_libraries(renderer PUBLIC Vulkan::Vulkan fmt::fmt libxiv)

View file

@ -4,13 +4,22 @@
#include <vector>
#include <array>
#include "mdlparser.h";
struct RenderModel {
};
class Renderer {
public:
Renderer();
void initPipeline();
void initSwapchain(VkSurfaceKHR surface, int width, int height);
void resize(VkSurfaceKHR surface, int width, int height);
RenderModel addModel(const Model& model);
void render();
VkInstance instance = VK_NULL_HANDLE;
@ -28,4 +37,12 @@ public:
std::array<VkFence, 3> inFlightFences;
std::array<VkSemaphore, 3> imageAvailableSemaphores, renderFinishedSemaphores;
uint32_t currentFrame = 0;
std::tuple<VkBuffer, VkDeviceMemory> createBuffer(size_t size, VkBufferUsageFlags usageFlags);
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
VkShaderModule createShaderModule(const uint32_t *code, const int length);
VkShaderModule loadShaderFromDisk(const std::string_view path);
};

View file

@ -0,0 +1,4 @@
#!/bin/sh
glslc mesh.vert -o mesh.vert.spv &&
glslc mesh.frag -o mesh.frag.spv

View file

@ -0,0 +1,7 @@
#version 450
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(0.0, 1.0, 0.0, 1.0);
}

Binary file not shown.

View file

@ -0,0 +1,7 @@
#version 450
layout(location = 0) in vec3 inPosition;
void main() {
gl_Position = vec4(inPosition, 1.0);
}

Binary file not shown.

View file

@ -5,6 +5,7 @@
#include <array>
#include <vector>
#include <valarray>
#include <fstream>
Renderer::Renderer() {
VkApplicationInfo applicationInfo = {};
@ -133,6 +134,8 @@ Renderer::Renderer() {
vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool);
initPipeline();
fmt::print("Initialized renderer!\n");
}
@ -412,4 +415,131 @@ void Renderer::render() {
vkQueuePresentKHR(presentQueue, &presentInfo);
currentFrame = (currentFrame + 1) % 3;
}
std::tuple<VkBuffer, VkDeviceMemory> Renderer::createBuffer(size_t size, VkBufferUsageFlags usageFlags) {
vkDeviceWaitIdle(device);
// create buffer
VkBufferCreateInfo bufferInfo = {};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
bufferInfo.usage = usageFlags;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VkBuffer handle;
vkCreateBuffer(device, &bufferInfo, nullptr, &handle);
// allocate memory
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, handle, &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);
VkDeviceMemory memory;
vkAllocateMemory(device, &allocInfo, nullptr, &memory);
vkBindBufferMemory(device, handle, memory, 0);
return {handle, memory};
}
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 -1;
}
RenderModel Renderer::addModel(const Model& model) {
RenderModel renderModel;
size_t vertexSize = model.lods[0].parts[0].vertices.size() * sizeof(float) * 3;
auto [vertexBuffer, vertexMemory] = createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
size_t indexSize = model.lods[0].parts[0].indices.size() * sizeof(uint16_t);
auto [indexBuffer, indexMemory] = createBuffer(indexSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
// copy vertex data
{
void* mapped_data = nullptr;
vkMapMemory(device, vertexMemory, 0, vertexSize, 0, &mapped_data);
for(int i = 0; i < model.lods[0].parts[0].vertices.size(); i++) {
memcpy(mapped_data, model.lods[0].parts[0].vertices[i].position.data(), sizeof(float) * 3);
}
VkMappedMemoryRange range = {};
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range.memory = vertexMemory;
range.size = vertexSize;
vkFlushMappedMemoryRanges(device, 1, &range);
vkUnmapMemory(device, vertexMemory);
}
// copy index data
{
void* mapped_data = nullptr;
vkMapMemory(device, indexMemory, 0, indexSize, 0, &mapped_data);
memcpy(mapped_data, model.lods[0].parts[0].indices.data(), indexSize);
VkMappedMemoryRange range = {};
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range.memory = indexMemory;
range.size = indexSize;
vkFlushMappedMemoryRanges(device, 1, &range);
vkUnmapMemory(device, indexMemory);
}
return renderModel;
}
void Renderer::initPipeline() {
auto vertexModule = loadShaderFromDisk("mesh.vert.spv");
auto fragmentModule = loadShaderFromDisk("mesh.frag.spv");
}
VkShaderModule Renderer::createShaderModule(const uint32_t* code, const int length) {
VkShaderModuleCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = length;
createInfo.pCode = reinterpret_cast<const uint32_t*>(code);
VkShaderModule shaderModule;
vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule);
return shaderModule;
}
VkShaderModule Renderer::loadShaderFromDisk(const std::string_view path) {
std::ifstream file(path.data(), std::ios::ate | std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error(fmt::format("failed to open shader file {}", path));
}
size_t fileSize = (size_t) file.tellg();
std::vector<char> buffer(fileSize);
file.seekg(0);
file.read(buffer.data(), fileSize);
return createShaderModule(reinterpret_cast<const uint32_t *>(buffer.data()), fileSize);
}