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:
parent
338c485018
commit
92c52e358a
3 changed files with 125 additions and 10 deletions
|
@ -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")));
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue