mirror of
https://github.com/redstrate/Novus.git
synced 2025-05-14 20:47:46 +00:00
Fix the object pass, start rendering a sphere
The sphere doesn't look correct (bad vertex stride) but that doesn't matter. I need to expose the object's transform in libphysis next, before we can start drawing.
This commit is contained in:
parent
66808619f3
commit
fc327ba8b5
7 changed files with 145 additions and 6 deletions
|
@ -11,6 +11,7 @@ target_sources(novus-mapeditor
|
|||
include/objectlistwidget.h
|
||||
include/appstate.h
|
||||
include/objectlistmodel.h
|
||||
include/primitives.h
|
||||
|
||||
src/main.cpp
|
||||
src/mainwindow.cpp
|
||||
|
@ -19,7 +20,8 @@ target_sources(novus-mapeditor
|
|||
src/objectpass.cpp
|
||||
src/objectlistwidget.cpp
|
||||
src/appstate.cpp
|
||||
src/objectlistmodel.cpp)
|
||||
src/objectlistmodel.cpp
|
||||
src/primitives.cpp)
|
||||
target_include_directories(novus-mapeditor
|
||||
PUBLIC
|
||||
include)
|
||||
|
|
26
apps/mapeditor/include/primitives.h
Normal file
26
apps/mapeditor/include/primitives.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "buffer.h"
|
||||
|
||||
class RenderManager;
|
||||
|
||||
struct Sphere {
|
||||
Buffer vertexBuffer, indexBuffer;
|
||||
uint32_t indexCount;
|
||||
};
|
||||
|
||||
class Primitives
|
||||
{
|
||||
public:
|
||||
static void Initialize(RenderManager *renderer);
|
||||
static void Cleanup(RenderManager *renderer);
|
||||
|
||||
static void DrawSphere(VkCommandBuffer commandBuffer);
|
||||
|
||||
static Sphere sphere;
|
||||
};
|
|
@ -1,5 +1,9 @@
|
|||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "objectpass.h"
|
||||
#include "device.h"
|
||||
#include "primitives.h"
|
||||
#include "rendermanager.h"
|
||||
#include "simplerenderer.h"
|
||||
#include "swapchain.h"
|
||||
|
@ -11,11 +15,23 @@ ObjectPass::ObjectPass(RenderManager *renderer)
|
|||
, m_device(m_renderer->device())
|
||||
{
|
||||
createPipeline();
|
||||
|
||||
Primitives::Initialize(m_renderer);
|
||||
}
|
||||
|
||||
void ObjectPass::render(VkCommandBuffer commandBuffer, Camera &camera)
|
||||
{
|
||||
if (auto renderer = dynamic_cast<SimpleRenderer *>(m_renderer->renderer())) {
|
||||
VkDebugUtilsLabelEXT labelExt{};
|
||||
labelExt.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
|
||||
labelExt.pLabelName = "Object Pass";
|
||||
m_renderer->device().beginDebugMarker(commandBuffer, labelExt);
|
||||
|
||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_);
|
||||
|
||||
Primitives::DrawSphere(commandBuffer);
|
||||
|
||||
m_renderer->device().endDebugMarker(commandBuffer);
|
||||
} else {
|
||||
qWarning() << "Can't render object pass in non-simple renderer for now!!";
|
||||
}
|
||||
|
@ -77,8 +93,8 @@ void ObjectPass::createPipeline()
|
|||
|
||||
VkPipelineShaderStageCreateInfo fragmentShaderStageInfo = {};
|
||||
fragmentShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
fragmentShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
fragmentShaderStageInfo.module = m_device.loadShaderFromDisk(":/shaders/debug.vert.spv");
|
||||
fragmentShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
fragmentShaderStageInfo.module = m_device.loadShaderFromDisk(":/shaders/debug.frag.spv");
|
||||
fragmentShaderStageInfo.pName = "main";
|
||||
|
||||
const std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages = {vertexShaderStageInfo, fragmentShaderStageInfo};
|
||||
|
@ -132,7 +148,7 @@ void ObjectPass::createPipeline()
|
|||
dynamicState.pDynamicStates = dynamicStates.data();
|
||||
|
||||
VkPushConstantRange pushConstant = {};
|
||||
pushConstant.size = sizeof(glm::mat4);
|
||||
pushConstant.size = sizeof(glm::mat4) * 2;
|
||||
pushConstant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
||||
|
@ -142,6 +158,13 @@ void ObjectPass::createPipeline()
|
|||
|
||||
vkCreatePipelineLayout(m_device.device, &pipelineLayoutInfo, nullptr, &pipelineLayout_);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
|
||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
depthStencil.depthTestEnable = VK_TRUE;
|
||||
depthStencil.depthWriteEnable = VK_TRUE;
|
||||
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
|
||||
depthStencil.maxDepthBounds = 1.0f;
|
||||
|
||||
auto renderer = dynamic_cast<SimpleRenderer *>(m_renderer->renderer());
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
|
@ -155,6 +178,7 @@ void ObjectPass::createPipeline()
|
|||
pipelineInfo.pMultisampleState = &multisampling;
|
||||
pipelineInfo.pColorBlendState = &colorBlending;
|
||||
pipelineInfo.pDynamicState = &dynamicState;
|
||||
pipelineInfo.pDepthStencilState = &depthStencil;
|
||||
pipelineInfo.layout = pipelineLayout_;
|
||||
pipelineInfo.renderPass = renderer->renderPass();
|
||||
|
||||
|
|
80
apps/mapeditor/src/primitives.cpp
Normal file
80
apps/mapeditor/src/primitives.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "primitives.h"
|
||||
#include "rendermanager.h"
|
||||
|
||||
#include <complex>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/constants.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
Sphere Primitives::sphere;
|
||||
|
||||
void Primitives::Initialize(RenderManager *renderer)
|
||||
{
|
||||
// sphere
|
||||
{
|
||||
std::vector<glm::vec3> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
|
||||
unsigned int xResolution = 64;
|
||||
unsigned int yResolution = 64;
|
||||
float PI = 3.14159265359f;
|
||||
|
||||
for (unsigned int y = 0; y <= yResolution; ++y) {
|
||||
for (unsigned int x = 0; x <= xResolution; ++x) {
|
||||
float xSegment = static_cast<float>(x) / static_cast<float>(xResolution);
|
||||
float ySegment = static_cast<float>(y) / static_cast<float>(yResolution);
|
||||
|
||||
float xPos = glm::cos(xSegment * 2.0f * PI) * glm::sin(ySegment * PI);
|
||||
float yPos = glm::cos(ySegment * PI);
|
||||
float zPos = glm::sin(xSegment * 2.0f * PI) * glm::sin(ySegment * PI);
|
||||
|
||||
vertices.push_back(glm::vec3(xPos, yPos, zPos));
|
||||
}
|
||||
}
|
||||
|
||||
bool oddRow = false;
|
||||
for (unsigned int y = 0; y < yResolution; ++y) {
|
||||
if (!oddRow) {
|
||||
for (unsigned int x = 0; x <= xResolution; ++x) {
|
||||
indices.push_back(y * (xResolution + 1) + x);
|
||||
indices.push_back((y + 1) * (xResolution + 1) + x);
|
||||
}
|
||||
} else {
|
||||
for (int x = xResolution; x >= 0; --x) {
|
||||
indices.push_back((y + 1) * (xResolution + 1) + x);
|
||||
indices.push_back(y * (xResolution + 1) + x);
|
||||
}
|
||||
}
|
||||
oddRow = !oddRow;
|
||||
}
|
||||
sphere.indexCount = static_cast<uint32_t>(indices.size());
|
||||
|
||||
// VERTICES
|
||||
VkDeviceSize vertexSize = sizeof(glm::vec3) * vertices.size();
|
||||
sphere.vertexBuffer = renderer->device().createBuffer(vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
renderer->device().copyToBuffer(sphere.vertexBuffer, vertices.data(), vertexSize);
|
||||
|
||||
// INDICES
|
||||
VkDeviceSize indexSize = sizeof(unsigned int) * indices.size();
|
||||
sphere.indexBuffer = renderer->device().createBuffer(indexSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
|
||||
renderer->device().copyToBuffer(sphere.indexBuffer, indices.data(), indexSize);
|
||||
}
|
||||
}
|
||||
|
||||
void Primitives::Cleanup(RenderManager *renderer)
|
||||
{
|
||||
// TODO: stub
|
||||
}
|
||||
|
||||
void Primitives::DrawSphere(VkCommandBuffer commandBuffer)
|
||||
{
|
||||
VkDeviceSize offsets[] = {0};
|
||||
|
||||
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &sphere.vertexBuffer.buffer, offsets);
|
||||
vkCmdBindIndexBuffer(commandBuffer, sphere.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
|
||||
vkCmdDrawIndexed(commandBuffer, sphere.indexCount, 1, 0, 0, 0);
|
||||
}
|
|
@ -25,9 +25,9 @@ void VulkanWindow::exposeEvent(QExposeEvent *)
|
|||
|
||||
auto surface = m_instance->surfaceForWindow(this);
|
||||
if (!m_renderer->initSwapchain(surface, width() * screen()->devicePixelRatio(), height() * screen()->devicePixelRatio())) {
|
||||
Q_EMIT part->initializeRender();
|
||||
m_initialized = false;
|
||||
} else {
|
||||
Q_EMIT part->initializeRender();
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,11 @@ RenderManager::RenderManager(GameData *data)
|
|||
if (strstr(extension.extensionName, "VK_EXT_debug_utils") != nullptr) {
|
||||
instanceExtensions.push_back(extension.extensionName);
|
||||
}
|
||||
|
||||
// needed for VK_EXT_display_surface_counter
|
||||
if (strstr(extension.extensionName, "VK_KHR_display") != nullptr) {
|
||||
instanceExtensions.push_back(extension.extensionName);
|
||||
}
|
||||
}
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = {};
|
||||
|
|
|
@ -46,6 +46,7 @@ void SimpleRenderer::resize()
|
|||
framebufferInfo.layers = 1;
|
||||
|
||||
vkCreateFramebuffer(m_device.device, &framebufferInfo, nullptr, &m_framebuffer);
|
||||
m_device.nameObject(VK_OBJECT_TYPE_FRAMEBUFFER, reinterpret_cast<uint64_t>(m_framebuffer), "simple renderer framebuffer");
|
||||
}
|
||||
|
||||
void SimpleRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene &scene, const std::vector<DrawObject> &models)
|
||||
|
@ -166,7 +167,7 @@ void SimpleRenderer::render(VkCommandBuffer commandBuffer, Camera &camera, Scene
|
|||
void SimpleRenderer::initRenderPass()
|
||||
{
|
||||
VkAttachmentDescription colorAttachment = {};
|
||||
colorAttachment.format = m_device.swapChain->surfaceFormat;
|
||||
colorAttachment.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
@ -220,6 +221,7 @@ void SimpleRenderer::initRenderPass()
|
|||
renderPassInfo.pDependencies = &dependency;
|
||||
|
||||
vkCreateRenderPass(m_device.device, &renderPassInfo, nullptr, &m_renderPass);
|
||||
m_device.nameObject(VK_OBJECT_TYPE_RENDER_PASS, reinterpret_cast<uint64_t>(m_renderPass), "simple renderer renderpass");
|
||||
}
|
||||
|
||||
void SimpleRenderer::initPipeline()
|
||||
|
|
Loading…
Add table
Reference in a new issue