1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-26 05:37:46 +00:00

Properly render out model

Right now it doesn't actually display anything, because we
don't have any camera.
This commit is contained in:
Joshua Goins 2022-04-12 01:57:37 -04:00
parent 338c485018
commit 92c52e358a
3 changed files with 125 additions and 10 deletions

View file

@ -48,11 +48,13 @@ public:
} }
void render() { void render() {
m_renderer->render(); m_renderer->render(models);
m_instance->presentQueued(this); m_instance->presentQueued(this);
requestUpdate(); requestUpdate();
} }
std::vector<RenderModel> models;
private: private:
bool m_initialized = false; bool m_initialized = false;
Renderer* m_renderer; Renderer* m_renderer;
@ -85,5 +87,5 @@ MainWindow::MainWindow(GameData& data) : data(data) {
layout->addWidget(widget); layout->addWidget(widget);
data.extractFile("chara/equipment/e0000/model/c0201e0000_top.mdl", "top.mdl"); data.extractFile("chara/equipment/e0000/model/c0201e0000_top.mdl", "top.mdl");
renderer->addModel(parseMDL("top.mdl")); vkWindow->models.push_back(renderer->addModel(parseMDL("top.mdl")));
} }

View file

@ -4,10 +4,13 @@
#include <vector> #include <vector>
#include <array> #include <array>
#include "mdlparser.h"; #include "mdlparser.h"
struct RenderModel { struct RenderModel {
size_t numIndices;
VkBuffer vertexBuffer, indexBuffer;
VkDeviceMemory vertexMemory, indexMemory;
}; };
class Renderer { class Renderer {
@ -20,7 +23,7 @@ public:
RenderModel addModel(const Model& model); RenderModel addModel(const Model& model);
void render(); void render(std::vector<RenderModel> models);
VkInstance instance = VK_NULL_HANDLE; VkInstance instance = VK_NULL_HANDLE;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
@ -37,6 +40,8 @@ public:
std::array<VkFence, 3> inFlightFences; std::array<VkFence, 3> inFlightFences;
std::array<VkSemaphore, 3> imageAvailableSemaphores, renderFinishedSemaphores; std::array<VkSemaphore, 3> imageAvailableSemaphores, renderFinishedSemaphores;
uint32_t currentFrame = 0; uint32_t currentFrame = 0;
VkPipeline pipeline;
VkPipelineLayout pipelineLayout;
std::tuple<VkBuffer, VkDeviceMemory> createBuffer(size_t size, VkBufferUsageFlags usageFlags); std::tuple<VkBuffer, VkDeviceMemory> createBuffer(size_t size, VkBufferUsageFlags usageFlags);

View file

@ -134,8 +134,6 @@ Renderer::Renderer() {
vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool); vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool);
initPipeline();
fmt::print("Initialized renderer!\n"); fmt::print("Initialized renderer!\n");
} }
@ -287,6 +285,8 @@ void Renderer::initSwapchain(VkSurfaceKHR surface, int width, int height) {
vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass); vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass);
initPipeline();
swapchainFramebuffers.resize(swapchainViews.size()); swapchainFramebuffers.resize(swapchainViews.size());
for (size_t i = 0; i < swapchainViews.size(); i++) { for (size_t i = 0; i < swapchainViews.size(); i++) {
@ -333,7 +333,7 @@ void Renderer::resize(VkSurfaceKHR surface, int width, int height) {
initSwapchain(surface, width, height); initSwapchain(surface, width, height);
} }
void Renderer::render() { void Renderer::render(std::vector<RenderModel> models) {
vkWaitForFences( vkWaitForFences(
device, 1, device, 1,
&inFlightFences[currentFrame], &inFlightFences[currentFrame],
@ -376,6 +376,16 @@ void Renderer::render() {
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
for(auto model : models) {
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &model.vertexBuffer, offsets);
vkCmdBindIndexBuffer(commandBuffer, model.indexBuffer, 0, VK_INDEX_TYPE_UINT16);
vkCmdDrawIndexed(commandBuffer, model.numIndices, 1, 0, 0, 0);
}
vkCmdEndRenderPass(commandBuffer); vkCmdEndRenderPass(commandBuffer);
vkEndCommandBuffer(commandBuffer); vkEndCommandBuffer(commandBuffer);
@ -480,7 +490,7 @@ RenderModel Renderer::addModel(const Model& model) {
vkMapMemory(device, vertexMemory, 0, vertexSize, 0, &mapped_data); vkMapMemory(device, vertexMemory, 0, vertexSize, 0, &mapped_data);
for(int i = 0; i < model.lods[0].parts[0].vertices.size(); i++) { 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); memcpy((char*)mapped_data + ((sizeof(float) * 3) * i), model.lods[0].parts[0].vertices[i].position.data(), sizeof(float) * 3);
} }
VkMappedMemoryRange range = {}; VkMappedMemoryRange range = {};
@ -508,12 +518,110 @@ RenderModel Renderer::addModel(const Model& model) {
vkUnmapMemory(device, indexMemory); vkUnmapMemory(device, indexMemory);
} }
renderModel.numIndices = model.lods[0].parts[0].indices.size();
renderModel.vertexBuffer = vertexBuffer;
renderModel.vertexMemory = vertexMemory;
renderModel.indexBuffer = indexBuffer;
renderModel.indexMemory = indexMemory;
return renderModel; return renderModel;
} }
void Renderer::initPipeline() { void Renderer::initPipeline() {
auto vertexModule = loadShaderFromDisk("mesh.vert.spv"); VkPipelineShaderStageCreateInfo vertexShaderStageInfo = {};
auto fragmentModule = loadShaderFromDisk("mesh.frag.spv"); vertexShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertexShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertexShaderStageInfo.module = loadShaderFromDisk("mesh.vert.spv");
vertexShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = {};
fragmentShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragmentShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragmentShaderStageInfo.module = loadShaderFromDisk("mesh.frag.spv");
fragmentShaderStageInfo.pName = "main";
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = {vertexShaderStageInfo, fragmentShaderStageInfo};
VkVertexInputBindingDescription binding = {};
binding.stride = sizeof(float) * 3;
VkVertexInputAttributeDescription positionAttribute = {};
positionAttribute.format = VK_FORMAT_R32G32B32_SFLOAT;
VkPipelineVertexInputStateCreateInfo vertexInputState = {};
vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputState.vertexBindingDescriptionCount = 1;
vertexInputState.pVertexBindingDescriptions = &binding;
vertexInputState.vertexAttributeDescriptionCount = 1;
vertexInputState.pVertexAttributeDescriptions = &positionAttribute;
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
VkViewport viewport = {};
viewport.width = 640;
viewport.height = 480;
viewport.maxDepth = 1.0f;
VkRect2D scissor = {};
scissor.extent.width = 640;
scissor.extent.height = 489;
VkPipelineViewportStateCreateInfo viewportState = {};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.viewportCount = 1;
viewportState.pViewports = &viewport;
viewportState.scissorCount = 1;
viewportState.pScissors = &scissor;
VkPipelineRasterizationStateCreateInfo rasterizer = {};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
VkPipelineMultisampleStateCreateInfo multisampling = {};
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
VkPipelineColorBlendStateCreateInfo colorBlending = {};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment;
std::array<VkDynamicState, 2> dynamicStates = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
VkPipelineDynamicStateCreateInfo dynamicState = {};
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
dynamicState.pDynamicStates = dynamicStates.data();
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout);
VkGraphicsPipelineCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
createInfo.stageCount = shaderStages.size();
createInfo.pStages = shaderStages.data();
createInfo.pVertexInputState = &vertexInputState;
createInfo.pInputAssemblyState = &inputAssembly;
createInfo.pViewportState = &viewportState;
createInfo.pRasterizationState = &rasterizer;
createInfo.pMultisampleState = &multisampling;
createInfo.pColorBlendState = &colorBlending;
createInfo.pDynamicState = &dynamicState;
createInfo.layout = pipelineLayout;
createInfo.renderPass = renderPass;
vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &createInfo, nullptr, &pipeline);
} }
VkShaderModule Renderer::createShaderModule(const uint32_t* code, const int length) { VkShaderModule Renderer::createShaderModule(const uint32_t* code, const int length) {