Refactoring, use Vulkan result check macro, staging

This commit is contained in:
saschawillems 2016-06-06 10:38:03 +02:00
parent 875f4a93ea
commit 29d726482e
3 changed files with 202 additions and 172 deletions

View file

@ -47,6 +47,7 @@ public:
zoom = -16.0f; zoom = -16.0f;
rotation = glm::vec3(-23.75, 41.25, 21.0); rotation = glm::vec3(-23.75, 41.25, 21.0);
timerSpeed *= 0.25f; timerSpeed *= 0.25f;
enableTextOverlay = true;
title = "Vulkan Example - Gears"; title = "Vulkan Example - Gears";
} }
@ -82,30 +83,18 @@ public:
renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.clearValueCount = 2;
renderPassBeginInfo.pClearValues = clearValues; renderPassBeginInfo.pClearValues = clearValues;
VkResult err;
for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) for (int32_t i = 0; i < drawCmdBuffers.size(); ++i)
{ {
// Set target frame buffer
renderPassBeginInfo.framebuffer = frameBuffers[i]; renderPassBeginInfo.framebuffer = frameBuffers[i];
err = vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo); VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo));
assert(!err);
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
VkViewport viewport = vkTools::initializers::viewport( VkViewport viewport = vkTools::initializers::viewport((float)width, (float)height, 0.0f, 1.0f);
(float)width,
(float)height,
0.0f,
1.0f);
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
VkRect2D scissor = vkTools::initializers::rect2D( VkRect2D scissor = vkTools::initializers::rect2D(width, height, 0, 0);
width,
height,
0,
0);
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solid); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solid);
@ -117,38 +106,10 @@ public:
vkCmdEndRenderPass(drawCmdBuffers[i]); vkCmdEndRenderPass(drawCmdBuffers[i]);
err = vkEndCommandBuffer(drawCmdBuffers[i]); VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i]));
assert(!err);
} }
} }
void draw()
{
VkResult err;
// Get next image in the swap chain (back/front buffer)
err = swapChain.acquireNextImage(semaphores.presentComplete, &currentBuffer);
assert(!err);
submitPostPresentBarrier(swapChain.buffers[currentBuffer].image);
// Command buffer to be sumitted to the queue
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
// Submit to queue
err = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
assert(!err);
submitPrePresentBarrier(swapChain.buffers[currentBuffer].image);
err = swapChain.queuePresent(queue, currentBuffer, semaphores.renderComplete);
assert(!err);
err = vkQueueWaitIdle(queue);
assert(!err);
}
void prepareVertices() void prepareVertices()
{ {
// Gear definitions // Gear definitions
@ -168,22 +129,24 @@ public:
glm::vec3(-3.1, -6.2, 0.0) glm::vec3(-3.1, -6.2, 0.0)
}; };
std::vector<float> rotationSpeeds = { 1.0f, -2.0f, -2.0f }; std::vector<float> rotationSpeeds = { 1.0f, -2.0f, -2.0f };
std::vector<float> rotationStarts = { 0.0f, -9.0f, -30.0f }; std::vector<float> rotationOffsets = { 0.0f, -9.0f, -30.0f };
gears.resize(positions.size()); gears.resize(positions.size());
for (int32_t i = 0; i < gears.size(); ++i) for (int32_t i = 0; i < gears.size(); ++i)
{ {
GearInfo gearInfo = {};
gearInfo.innerRadius = innerRadiuses[i];
gearInfo.outerRadius = outerRadiuses[i];
gearInfo.width = widths[i];
gearInfo.numTeeth = toothCount[i];
gearInfo.toothDepth = toothDepth[i];
gearInfo.color = colors[i];
gearInfo.pos = positions[i];
gearInfo.rotSpeed = rotationSpeeds[i];
gearInfo.rotOffset = rotationOffsets[i];
gears[i] = new VulkanGear(device, this); gears[i] = new VulkanGear(device, this);
gears[i]->generate( gears[i]->generate(&gearInfo, queue);
innerRadiuses[i],
outerRadiuses[i],
widths[i],
toothCount[i],
toothDepth[i],
colors[i],
positions[i],
rotationSpeeds[i],
rotationStarts[i]);
} }
// Binding and attribute descriptions are shared across all gears // Binding and attribute descriptions are shared across all gears
@ -228,7 +191,7 @@ public:
void setupDescriptorPool() void setupDescriptorPool()
{ {
// One UBO for each gears // One UBO for each gear
std::vector<VkDescriptorPoolSize> poolSizes = std::vector<VkDescriptorPoolSize> poolSizes =
{ {
vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3), vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3),
@ -241,8 +204,7 @@ public:
// Three descriptor sets (for each gear) // Three descriptor sets (for each gear)
3); 3);
VkResult vkRes = vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
assert(!vkRes);
} }
void setupDescriptorSetLayout() void setupDescriptorSetLayout()
@ -261,16 +223,14 @@ public:
setLayoutBindings.data(), setLayoutBindings.data(),
setLayoutBindings.size()); setLayoutBindings.size());
VkResult err = vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout));
assert(!err);
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo =
vkTools::initializers::pipelineLayoutCreateInfo( vkTools::initializers::pipelineLayoutCreateInfo(
&descriptorSetLayout, &descriptorSetLayout,
1); 1);
err = vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout); VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout));
assert(!err);
} }
void setupDescriptorSets() void setupDescriptorSets()
@ -292,7 +252,7 @@ public:
VkPipelineRasterizationStateCreateInfo rasterizationState = VkPipelineRasterizationStateCreateInfo rasterizationState =
vkTools::initializers::pipelineRasterizationStateCreateInfo( vkTools::initializers::pipelineRasterizationStateCreateInfo(
VK_POLYGON_MODE_FILL, VK_POLYGON_MODE_FILL,
VK_CULL_MODE_NONE, VK_CULL_MODE_BACK_BIT,
VK_FRONT_FACE_CLOCKWISE, VK_FRONT_FACE_CLOCKWISE,
0); 0);
@ -354,8 +314,7 @@ public:
pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.stageCount = shaderStages.size();
pipelineCreateInfo.pStages = shaderStages.data(); pipelineCreateInfo.pStages = shaderStages.data();
VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid));
assert(!err);
} }
void updateUniformBuffers() void updateUniformBuffers()
@ -367,6 +326,20 @@ public:
} }
} }
void draw()
{
VulkanExampleBase::prepareFrame();
// Command buffer to be sumitted to the queue
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
// Submit to queue
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
VulkanExampleBase::submitFrame();
}
void prepare() void prepare()
{ {
VulkanExampleBase::prepare(); VulkanExampleBase::prepare();

View file

@ -3,7 +3,7 @@
* *
* See readme.md for details * See readme.md for details
* *
* Copyright (C) 2015 by Sascha Willems - www.saschawillems.de * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
* *
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/ */
@ -12,11 +12,7 @@
int32_t VulkanGear::newVertex(std::vector<Vertex> *vBuffer, float x, float y, float z, const glm::vec3& normal) int32_t VulkanGear::newVertex(std::vector<Vertex> *vBuffer, float x, float y, float z, const glm::vec3& normal)
{ {
Vertex v( Vertex v(glm::vec3(x, y, z), normal, color);
glm::vec3(x, y, z),
normal,
color
);
vBuffer->push_back(v); vBuffer->push_back(v);
return vBuffer->size() - 1; return vBuffer->size() - 1;
} }
@ -47,12 +43,12 @@ VulkanGear::~VulkanGear()
vkFreeMemory(device, indexBuffer.mem, nullptr); vkFreeMemory(device, indexBuffer.mem, nullptr);
} }
void VulkanGear::generate(float inner_radius, float outer_radius, float width, int teeth, float tooth_depth, glm::vec3 color, glm::vec3 pos, float rotSpeed, float rotOffset) void VulkanGear::generate(GearInfo *gearinfo, VkQueue queue)
{ {
this->color = color; this->color = gearinfo->color;
this->pos = pos; this->pos = gearinfo->pos;
this->rotOffset = rotOffset; this->rotOffset = gearinfo->rotOffset;
this->rotSpeed = rotSpeed; this->rotSpeed = gearinfo->rotSpeed;
std::vector<Vertex> vBuffer; std::vector<Vertex> vBuffer;
std::vector<uint32_t> iBuffer; std::vector<uint32_t> iBuffer;
@ -65,17 +61,17 @@ void VulkanGear::generate(float inner_radius, float outer_radius, float width, i
float sin_ta, sin_ta_1da, sin_ta_2da, sin_ta_3da, sin_ta_4da; float sin_ta, sin_ta_1da, sin_ta_2da, sin_ta_3da, sin_ta_4da;
int32_t ix0, ix1, ix2, ix3, ix4, ix5; int32_t ix0, ix1, ix2, ix3, ix4, ix5;
r0 = inner_radius; r0 = gearinfo->innerRadius;
r1 = outer_radius - tooth_depth / 2.0; r1 = gearinfo->outerRadius - gearinfo->toothDepth / 2.0;
r2 = outer_radius + tooth_depth / 2.0; r2 = gearinfo->outerRadius + gearinfo->toothDepth / 2.0;
da = 2.0 * M_PI / teeth / 4.0; da = 2.0 * M_PI / gearinfo->numTeeth / 4.0;
glm::vec3 normal; glm::vec3 normal;
for (i = 0; i < teeth; i++) for (i = 0; i < gearinfo->numTeeth; i++)
{ {
ta = i * 2.0 * M_PI / teeth; ta = i * 2.0 * M_PI / gearinfo->numTeeth;
// todo : naming
cos_ta = cos(ta); cos_ta = cos(ta);
cos_ta_1da = cos(ta + da); cos_ta_1da = cos(ta + da);
cos_ta_2da = cos(ta + 2 * da); cos_ta_2da = cos(ta + 2 * da);
@ -97,12 +93,12 @@ void VulkanGear::generate(float inner_radius, float outer_radius, float width, i
// front face // front face
normal = glm::vec3(0.0, 0.0, 1.0); normal = glm::vec3(0.0, 0.0, 1.0);
ix0 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, width * 0.5, normal); ix0 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, gearinfo->width * 0.5, normal);
ix1 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, width * 0.5, normal); ix1 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, gearinfo->width * 0.5, normal);
ix2 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, width * 0.5, normal); ix2 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, gearinfo->width * 0.5, normal);
ix3 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, width * 0.5, normal); ix3 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, gearinfo->width * 0.5, normal);
ix4 = newVertex(&vBuffer, r0 * cos_ta_4da, r0 * sin_ta_4da, width * 0.5, normal); ix4 = newVertex(&vBuffer, r0 * cos_ta_4da, r0 * sin_ta_4da, gearinfo->width * 0.5, normal);
ix5 = newVertex(&vBuffer, r1 * cos_ta_4da, r1 * sin_ta_4da, width * 0.5, normal); ix5 = newVertex(&vBuffer, r1 * cos_ta_4da, r1 * sin_ta_4da, gearinfo->width * 0.5, normal);
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
newFace(&iBuffer, ix2, ix3, ix4); newFace(&iBuffer, ix2, ix3, ix4);
@ -110,21 +106,21 @@ void VulkanGear::generate(float inner_radius, float outer_radius, float width, i
// front sides of teeth // front sides of teeth
normal = glm::vec3(0.0, 0.0, 1.0); normal = glm::vec3(0.0, 0.0, 1.0);
ix0 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, width * 0.5, normal); ix0 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, gearinfo->width * 0.5, normal);
ix1 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, width * 0.5, normal); ix1 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, gearinfo->width * 0.5, normal);
ix2 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, width * 0.5, normal); ix2 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, gearinfo->width * 0.5, normal);
ix3 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, width * 0.5, normal); ix3 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, gearinfo->width * 0.5, normal);
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
// back face // back face
normal = glm::vec3(0.0, 0.0, -1.0); normal = glm::vec3(0.0, 0.0, -1.0);
ix0 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, -width * 0.5, normal); ix0 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, -gearinfo->width * 0.5, normal);
ix1 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, -width * 0.5, normal); ix1 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, -gearinfo->width * 0.5, normal);
ix2 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, -width * 0.5, normal); ix2 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, -gearinfo->width * 0.5, normal);
ix3 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, -width * 0.5, normal); ix3 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, -gearinfo->width * 0.5, normal);
ix4 = newVertex(&vBuffer, r1 * cos_ta_4da, r1 * sin_ta_4da, -width * 0.5, normal); ix4 = newVertex(&vBuffer, r1 * cos_ta_4da, r1 * sin_ta_4da, -gearinfo->width * 0.5, normal);
ix5 = newVertex(&vBuffer, r0 * cos_ta_4da, r0 * sin_ta_4da, -width * 0.5, normal); ix5 = newVertex(&vBuffer, r0 * cos_ta_4da, r0 * sin_ta_4da, -gearinfo->width * 0.5, normal);
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
newFace(&iBuffer, ix2, ix3, ix4); newFace(&iBuffer, ix2, ix3, ix4);
@ -132,51 +128,51 @@ void VulkanGear::generate(float inner_radius, float outer_radius, float width, i
// back sides of teeth // back sides of teeth
normal = glm::vec3(0.0, 0.0, -1.0); normal = glm::vec3(0.0, 0.0, -1.0);
ix0 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, -width * 0.5, normal); ix0 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, -gearinfo->width * 0.5, normal);
ix1 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, -width * 0.5, normal); ix1 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, -gearinfo->width * 0.5, normal);
ix2 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, -width * 0.5, normal); ix2 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, -gearinfo->width * 0.5, normal);
ix3 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, -width * 0.5, normal); ix3 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, -gearinfo->width * 0.5, normal);
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
// draw outward faces of teeth // draw outward faces of teeth
normal = glm::vec3(v1, -u1, 0.0); normal = glm::vec3(v1, -u1, 0.0);
ix0 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, width * 0.5, normal); ix0 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, gearinfo->width * 0.5, normal);
ix1 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, -width * 0.5, normal); ix1 = newVertex(&vBuffer, r1 * cos_ta, r1 * sin_ta, -gearinfo->width * 0.5, normal);
ix2 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, width * 0.5, normal); ix2 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, gearinfo->width * 0.5, normal);
ix3 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, -width * 0.5, normal); ix3 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, -gearinfo->width * 0.5, normal);
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
normal = glm::vec3(cos_ta, sin_ta, 0.0); normal = glm::vec3(cos_ta, sin_ta, 0.0);
ix0 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, width * 0.5, normal); ix0 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, gearinfo->width * 0.5, normal);
ix1 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, -width * 0.5, normal); ix1 = newVertex(&vBuffer, r2 * cos_ta_1da, r2 * sin_ta_1da, -gearinfo->width * 0.5, normal);
ix2 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, width * 0.5, normal); ix2 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, gearinfo->width * 0.5, normal);
ix3 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, -width * 0.5, normal); ix3 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, -gearinfo->width * 0.5, normal);
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
normal = glm::vec3(v2, -u2, 0.0); normal = glm::vec3(v2, -u2, 0.0);
ix0 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, width * 0.5, normal); ix0 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, gearinfo->width * 0.5, normal);
ix1 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, -width * 0.5, normal); ix1 = newVertex(&vBuffer, r2 * cos_ta_2da, r2 * sin_ta_2da, -gearinfo->width * 0.5, normal);
ix2 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, width * 0.5, normal); ix2 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, gearinfo->width * 0.5, normal);
ix3 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, -width * 0.5, normal); ix3 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, -gearinfo->width * 0.5, normal);
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
normal = glm::vec3(cos_ta, sin_ta, 0.0); normal = glm::vec3(cos_ta, sin_ta, 0.0);
ix0 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, width * 0.5, normal); ix0 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, gearinfo->width * 0.5, normal);
ix1 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, -width * 0.5, normal); ix1 = newVertex(&vBuffer, r1 * cos_ta_3da, r1 * sin_ta_3da, -gearinfo->width * 0.5, normal);
ix2 = newVertex(&vBuffer, r1 * cos_ta_4da, r1 * sin_ta_4da, width * 0.5, normal); ix2 = newVertex(&vBuffer, r1 * cos_ta_4da, r1 * sin_ta_4da, gearinfo->width * 0.5, normal);
ix3 = newVertex(&vBuffer, r1 * cos_ta_4da, r1 * sin_ta_4da, -width * 0.5, normal); ix3 = newVertex(&vBuffer, r1 * cos_ta_4da, r1 * sin_ta_4da, -gearinfo->width * 0.5, normal);
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
// draw inside radius cylinder // draw inside radius cylinder
ix0 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, -width * 0.5, glm::vec3(-cos_ta, -sin_ta, 0.0)); ix0 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, -gearinfo->width * 0.5, glm::vec3(-cos_ta, -sin_ta, 0.0));
ix1 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, width * 0.5, glm::vec3(-cos_ta, -sin_ta, 0.0)); ix1 = newVertex(&vBuffer, r0 * cos_ta, r0 * sin_ta, gearinfo->width * 0.5, glm::vec3(-cos_ta, -sin_ta, 0.0));
ix2 = newVertex(&vBuffer, r0 * cos_ta_4da, r0 * sin_ta_4da, -width * 0.5, glm::vec3(-cos_ta_4da, -sin_ta_4da, 0.0)); ix2 = newVertex(&vBuffer, r0 * cos_ta_4da, r0 * sin_ta_4da, -gearinfo->width * 0.5, glm::vec3(-cos_ta_4da, -sin_ta_4da, 0.0));
ix3 = newVertex(&vBuffer, r0 * cos_ta_4da, r0 * sin_ta_4da, width * 0.5, glm::vec3(-cos_ta_4da, -sin_ta_4da, 0.0)); ix3 = newVertex(&vBuffer, r0 * cos_ta_4da, r0 * sin_ta_4da, gearinfo->width * 0.5, glm::vec3(-cos_ta_4da, -sin_ta_4da, 0.0));
newFace(&iBuffer, ix0, ix1, ix2); newFace(&iBuffer, ix0, ix1, ix2);
newFace(&iBuffer, ix1, ix3, ix2); newFace(&iBuffer, ix1, ix3, ix2);
} }
@ -184,43 +180,99 @@ void VulkanGear::generate(float inner_radius, float outer_radius, float width, i
int vertexBufferSize = vBuffer.size() * sizeof(Vertex); int vertexBufferSize = vBuffer.size() * sizeof(Vertex);
int indexBufferSize = iBuffer.size() * sizeof(uint32_t); int indexBufferSize = iBuffer.size() * sizeof(uint32_t);
VkMemoryAllocateInfo memAlloc = vkTools::initializers::memoryAllocateInfo(); bool useStaging = true;
VkMemoryRequirements memReqs;
VkResult err; if (useStaging)
void *data; {
struct {
VkBuffer buffer;
VkDeviceMemory memory;
} vertexStaging, indexStaging;
// Generate vertex buffer // Create staging buffers
VkBufferCreateInfo vBufferInfo = vkTools::initializers::bufferCreateInfo(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, vertexBufferSize); // Vertex data
err = vkCreateBuffer(device, &vBufferInfo, nullptr, &vertexBuffer.buf); exampleBase->createBuffer(
assert(!err); VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
vkGetBufferMemoryRequirements(device, vertexBuffer.buf, &memReqs); VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
memAlloc.allocationSize = memReqs.size; vertexBufferSize,
exampleBase->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memAlloc.memoryTypeIndex); vBuffer.data(),
err = vkAllocateMemory(device, &memAlloc, nullptr, &vertexBuffer.mem); &vertexStaging.buffer,
assert(!err); &vertexStaging.memory);
err = vkMapMemory(device, vertexBuffer.mem, 0, vertexBufferSize, 0, &data); // Index data
assert(!err); exampleBase->createBuffer(
memcpy(data, vBuffer.data(), vertexBufferSize); VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
vkUnmapMemory(device, vertexBuffer.mem); VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
err = vkBindBufferMemory(device, vertexBuffer.buf, vertexBuffer.mem, 0); indexBufferSize,
assert(!err); iBuffer.data(),
&indexStaging.buffer,
&indexStaging.memory);
// Create device local buffers
// Vertex buffer
exampleBase->createBuffer(
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
vertexBufferSize,
nullptr,
&vertexBuffer.buf,
&vertexBuffer.mem);
// Index buffer
exampleBase->createBuffer(
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
indexBufferSize,
nullptr,
&indexBuffer.buf,
&indexBuffer.mem);
// Copy from staging buffers
VkCommandBuffer copyCmd = exampleBase->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
VkBufferCopy copyRegion = {};
copyRegion.size = vertexBufferSize;
vkCmdCopyBuffer(
copyCmd,
vertexStaging.buffer,
vertexBuffer.buf,
1,
&copyRegion);
copyRegion.size = indexBufferSize;
vkCmdCopyBuffer(
copyCmd,
indexStaging.buffer,
indexBuffer.buf,
1,
&copyRegion);
exampleBase->flushCommandBuffer(copyCmd, queue, true);
vkDestroyBuffer(device, vertexStaging.buffer, nullptr);
vkFreeMemory(device, vertexStaging.memory, nullptr);
vkDestroyBuffer(device, indexStaging.buffer, nullptr);
vkFreeMemory(device, indexStaging.memory, nullptr);
}
else
{
// Vertex buffer
exampleBase->createBuffer(
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
vertexBufferSize,
vBuffer.data(),
&vertexBuffer.buf,
&vertexBuffer.mem);
// Index buffer
exampleBase->createBuffer(
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
indexBufferSize,
iBuffer.data(),
&indexBuffer.buf,
&indexBuffer.mem);
}
// Generate index buffer
VkBufferCreateInfo iBufferInfo = vkTools::initializers::bufferCreateInfo(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, indexBufferSize);
err = vkCreateBuffer(device, &iBufferInfo, nullptr, &indexBuffer.buf);
assert(!err);
vkGetBufferMemoryRequirements(device, indexBuffer.buf, &memReqs);
memAlloc.allocationSize = memReqs.size;
exampleBase->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memAlloc.memoryTypeIndex);
err = vkAllocateMemory(device, &memAlloc, nullptr, &indexBuffer.mem);
assert(!err);
err = vkMapMemory(device, indexBuffer.mem, 0, indexBufferSize, 0, &data);
assert(!err);
memcpy(data, iBuffer.data(), indexBufferSize);
vkUnmapMemory(device, indexBuffer.mem);
err = vkBindBufferMemory(device, indexBuffer.buf, indexBuffer.mem, 0);
assert(!err);
indexBuffer.count = iBuffer.size(); indexBuffer.count = iBuffer.size();
prepareUniformBuffer(); prepareUniformBuffer();
@ -254,14 +306,12 @@ void VulkanGear::updateUniformBuffer(glm::mat4 perspective, glm::vec3 rotation,
ubo.normal = glm::inverseTranspose(ubo.view * ubo.model); ubo.normal = glm::inverseTranspose(ubo.view * ubo.model);
//ubo.lightPos = lightPos;
ubo.lightPos = glm::vec3(0.0f, 0.0f, 2.5f); ubo.lightPos = glm::vec3(0.0f, 0.0f, 2.5f);
ubo.lightPos.x = sin(glm::radians(timer)) * 8.0f; ubo.lightPos.x = sin(glm::radians(timer)) * 8.0f;
ubo.lightPos.z = cos(glm::radians(timer)) * 8.0f; ubo.lightPos.z = cos(glm::radians(timer)) * 8.0f;
uint8_t *pData; uint8_t *pData;
VkResult err = vkMapMemory(device, uniformData.memory, 0, sizeof(ubo), 0, (void **)&pData); VK_CHECK_RESULT(vkMapMemory(device, uniformData.memory, 0, sizeof(ubo), 0, (void **)&pData));
assert(!err);
memcpy(pData, &ubo, sizeof(ubo)); memcpy(pData, &ubo, sizeof(ubo));
vkUnmapMemory(device, uniformData.memory); vkUnmapMemory(device, uniformData.memory);
} }
@ -274,8 +324,7 @@ void VulkanGear::setupDescriptorSet(VkDescriptorPool pool, VkDescriptorSetLayout
&descriptorSetLayout, &descriptorSetLayout,
1); 1);
VkResult vkRes = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
assert(!vkRes);
// Binding 0 : Vertex shader uniform buffer // Binding 0 : Vertex shader uniform buffer
VkWriteDescriptorSet writeDescriptorSet = VkWriteDescriptorSet writeDescriptorSet =
@ -290,8 +339,6 @@ void VulkanGear::setupDescriptorSet(VkDescriptorPool pool, VkDescriptorSetLayout
void VulkanGear::prepareUniformBuffer() void VulkanGear::prepareUniformBuffer()
{ {
VkResult err;
// Vertex shader uniform buffer block // Vertex shader uniform buffer block
VkMemoryAllocateInfo allocInfo = vkTools::initializers::memoryAllocateInfo(); VkMemoryAllocateInfo allocInfo = vkTools::initializers::memoryAllocateInfo();
VkMemoryRequirements memReqs; VkMemoryRequirements memReqs;
@ -300,15 +347,12 @@ void VulkanGear::prepareUniformBuffer()
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
sizeof(ubo)); sizeof(ubo));
err = vkCreateBuffer(device, &bufferInfo, nullptr, &uniformData.buffer); VK_CHECK_RESULT(vkCreateBuffer(device, &bufferInfo, nullptr, &uniformData.buffer));
assert(!err);
vkGetBufferMemoryRequirements(device, uniformData.buffer, &memReqs); vkGetBufferMemoryRequirements(device, uniformData.buffer, &memReqs);
allocInfo.allocationSize = memReqs.size; allocInfo.allocationSize = memReqs.size;
exampleBase->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &allocInfo.memoryTypeIndex); allocInfo.memoryTypeIndex = exampleBase->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
err = vkAllocateMemory(device, &allocInfo, nullptr, &uniformData.memory); VK_CHECK_RESULT(vkAllocateMemory(device, &allocInfo, nullptr, &uniformData.memory));
assert(!err); VK_CHECK_RESULT(vkBindBufferMemory(device, uniformData.buffer, uniformData.memory, 0));
err = vkBindBufferMemory(device, uniformData.buffer, uniformData.memory, 0);
assert(!err);
uniformData.descriptor.buffer = uniformData.buffer; uniformData.descriptor.buffer = uniformData.buffer;
uniformData.descriptor.offset = 0; uniformData.descriptor.offset = 0;

View file

@ -44,6 +44,19 @@ struct Vertex
} }
}; };
struct GearInfo
{
float innerRadius;
float outerRadius;
float width;
int numTeeth;
float toothDepth;
glm::vec3 color;
glm::vec3 pos;
float rotSpeed;
float rotOffset;
};
class VulkanGear class VulkanGear
{ {
private: private:
@ -96,7 +109,7 @@ public:
VulkanGear(VkDevice device, VulkanExampleBase *example); VulkanGear(VkDevice device, VulkanExampleBase *example);
~VulkanGear(); ~VulkanGear();
void generate(float inner_radius, float outer_radius, float width, int teeth, float tooth_depth, glm::vec3 color, glm::vec3 pos, float rotSpeed, float rotOffset); void generate(GearInfo *gearinfo, VkQueue queue);
}; };