depth buffering

This commit is contained in:
Mars 2024-10-11 19:09:37 -04:00
parent f541f6ec8c
commit 02cd99a73a
Signed by untrusted user: pupbrained
GPG key ID: 874E22DF2F9DFCB5
3 changed files with 176 additions and 120 deletions

View file

@ -1,11 +1,13 @@
#include <chrono> #include <chrono>
#include <fmt/format.h> #include <fmt/format.h>
#include <fstream> #include <fstream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream> #include <iostream>
#include <set> #include <set>
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h> #include <stb_image.h>
@ -42,7 +44,7 @@ constexpr bool enableValidationLayers = true;
#endif #endif
struct Vertex { struct Vertex {
glm::vec2 pos; glm::vec3 pos;
glm::vec3 color; glm::vec3 color;
glm::vec2 tex_coord; glm::vec2 tex_coord;
@ -52,21 +54,30 @@ struct Vertex {
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 3> { static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 3> {
return { return {
{ { 0, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, pos) }, { { 0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, pos) },
{ 1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color) }, { 1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color) },
{ 2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) } } { 2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) } }
}; };
} }
}; };
constexpr std::array<Vertex, 4> vertices = { constexpr std::array<Vertex, 8> vertices = {
{ { { -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F }, { 1.0F, 0.0F } }, { { { -0.5F, -0.5F, 0.0F }, { 1.0F, 0.0F, 0.0F }, { 0.0F, 0.0F } },
{ { 0.5F, -0.5F }, { 0.0F, 1.0F, 0.0F }, { 0.0F, 0.0F } }, { { 0.5F, -0.5F, 0.0F }, { 0.0F, 1.0F, 0.0F }, { 1.0F, 0.0F } },
{ { 0.5F, 0.5F }, { 0.0F, 0.0F, 1.0F }, { 0.0F, 1.0F } }, { { 0.5F, 0.5F, 0.0F }, { 0.0F, 0.0F, 1.0F }, { 1.0F, 1.0F } },
{ { -0.5F, 0.5F }, { 1.0F, 1.0F, 1.0F }, { 1.0F, 1.0F } } } { { -0.5F, 0.5F, 0.0F }, { 1.0F, 1.0F, 1.0F }, { 0.0F, 1.0F } },
{ { -0.5F, -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F }, { 0.0F, 0.0F } },
{ { 0.5F, -0.5F, -0.5F }, { 0.0F, 1.0F, 0.0F }, { 1.0F, 0.0F } },
{ { 0.5F, 0.5F, -0.5F }, { 0.0F, 0.0F, 1.0F }, { 1.0F, 1.0F } },
{ { -0.5F, 0.5F, -0.5F }, { 1.0F, 1.0F, 1.0F }, { 0.0F, 1.0F } } }
}; };
constexpr std::array<u16, 6> indices = { 0, 1, 2, 2, 3, 0 }; // clang-format off
constexpr std::array<u16, 12> indices = {
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4
};
// clang-format on
class VulkanApp { class VulkanApp {
public: public:
@ -105,6 +116,10 @@ class VulkanApp {
vk::UniqueCommandPool mCommandPool; vk::UniqueCommandPool mCommandPool;
vk::UniqueImage mDepthImage;
vk::UniqueDeviceMemory mDepthImageMemory;
vk::UniqueImageView mDepthImageView;
vk::UniqueImage mTextureImage; vk::UniqueImage mTextureImage;
vk::UniqueDeviceMemory mTextureImageMemory; vk::UniqueDeviceMemory mTextureImageMemory;
vk::UniqueImageView mTextureImageView; vk::UniqueImageView mTextureImageView;
@ -196,8 +211,9 @@ class VulkanApp {
createRenderPass(); createRenderPass();
createDescriptorSetLayout(); createDescriptorSetLayout();
createGraphicsPipeline(); createGraphicsPipeline();
createFramebuffers();
createCommandPool(); createCommandPool();
createDepthResources();
createFramebuffers();
createTextureImage(); createTextureImage();
createTextureImageView(); createTextureImageView();
createTextureSampler(); createTextureSampler();
@ -220,10 +236,8 @@ class VulkanApp {
} }
fn cleanupSwapChain() -> void { fn cleanupSwapChain() -> void {
for (vk::UniqueFramebuffer& mSwapChainFramebuffer : mSwapChainFramebuffers) { for (vk::UniqueFramebuffer& mSwapChainFramebuffer : mSwapChainFramebuffers) mSwapChainFramebuffer.reset();
mSwapChainFramebuffer.reset(); for (vk::UniqueImageView& mSwapChainImageView : mSwapChainImageViews) mSwapChainImageView.reset();
}
for (vk::UniqueImageView& mSwapChainImageView : mSwapChainImageViews) { mSwapChainImageView.reset(); }
mSwapChain.reset(); mSwapChain.reset();
} }
@ -243,6 +257,7 @@ class VulkanApp {
createSwapChain(); createSwapChain();
createImageViews(); createImageViews();
createDepthResources();
createFramebuffers(); createFramebuffers();
} }
@ -415,26 +430,9 @@ class VulkanApp {
fn createImageViews() -> void { fn createImageViews() -> void {
mSwapChainImageViews.resize(mSwapChainImages.size()); mSwapChainImageViews.resize(mSwapChainImages.size());
for (u32 i = 0; i < mSwapChainImages.size(); i++) { for (u32 i = 0; i < mSwapChainImages.size(); i++)
vk::ImageViewCreateInfo createInfo { mSwapChainImageViews[i] =
.image = mSwapChainImages[i], createImageView(mSwapChainImages[i], mSwapChainImageFormat, vk::ImageAspectFlagBits::eColor);
.viewType = vk::ImageViewType::e2D,
.format = mSwapChainImageFormat,
// clang-format off
.components = { .r = vk::ComponentSwizzle::eIdentity,
.g = vk::ComponentSwizzle::eIdentity,
.b = vk::ComponentSwizzle::eIdentity,
.a = vk::ComponentSwizzle::eIdentity },
.subresourceRange = { .aspectMask = vk::ImageAspectFlagBits::eColor,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1 },
// clang-format on
};
mSwapChainImageViews[i] = mDevice->createImageViewUnique(createInfo);
}
} }
fn createRenderPass() -> void { fn createRenderPass() -> void {
@ -449,23 +447,47 @@ class VulkanApp {
.finalLayout = vk::ImageLayout::ePresentSrcKHR, .finalLayout = vk::ImageLayout::ePresentSrcKHR,
}; };
vk::AttachmentDescription depthAttachment { .format = findDepthFormat(),
.samples = vk::SampleCountFlagBits::e1,
.loadOp = vk::AttachmentLoadOp::eClear,
.storeOp = vk::AttachmentStoreOp::eDontCare,
.stencilLoadOp = vk::AttachmentLoadOp::eDontCare,
.stencilStoreOp = vk::AttachmentStoreOp::eDontCare,
.initialLayout = vk::ImageLayout::eUndefined,
.finalLayout =
vk::ImageLayout::eDepthStencilAttachmentOptimal };
vk::AttachmentReference colorAttachmentRef { vk::AttachmentReference colorAttachmentRef {
.attachment = 0, .attachment = 0,
.layout = vk::ImageLayout::eColorAttachmentOptimal, .layout = vk::ImageLayout::eColorAttachmentOptimal,
}; };
vk::SubpassDescription subpass { vk::AttachmentReference depthAttachmentRef { .attachment = 1,
.pipelineBindPoint = vk::PipelineBindPoint::eGraphics, .layout = vk::ImageLayout::eDepthStencilAttachmentOptimal };
.colorAttachmentCount = 1,
.pColorAttachments = &colorAttachmentRef,
};
vk::RenderPassCreateInfo renderPassInfo { vk::SubpassDescription subpass { .pipelineBindPoint = vk::PipelineBindPoint::eGraphics,
.attachmentCount = 1, .colorAttachmentCount = 1,
.pAttachments = &colorAttachment, .pColorAttachments = &colorAttachmentRef,
.subpassCount = 1, .pDepthStencilAttachment = &depthAttachmentRef };
.pSubpasses = &subpass,
}; vk::SubpassDependency dependency { .srcSubpass = vk::SubpassExternal,
.dstSubpass = {},
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
vk::PipelineStageFlagBits::eEarlyFragmentTests,
.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
vk::PipelineStageFlagBits::eEarlyFragmentTests,
.srcAccessMask = {},
.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite |
vk::AccessFlagBits::eDepthStencilAttachmentWrite };
std::array<vk::AttachmentDescription, 2> attachments = { colorAttachment, depthAttachment };
vk::RenderPassCreateInfo renderPassInfo { .attachmentCount = static_cast<u32>(attachments.size()),
.pAttachments = attachments.data(),
.subpassCount = 1,
.pSubpasses = &subpass,
.dependencyCount = 1,
.pDependencies = &dependency };
mRenderPass = mDevice->createRenderPassUnique(renderPassInfo); mRenderPass = mDevice->createRenderPassUnique(renderPassInfo);
} }
@ -504,17 +526,13 @@ class VulkanApp {
vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode); vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode);
vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode); vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode);
vk::PipelineShaderStageCreateInfo vertShaderStageInfo { vk::PipelineShaderStageCreateInfo vertShaderStageInfo { .stage = vk::ShaderStageFlagBits::eVertex,
.stage = vk::ShaderStageFlagBits::eVertex, .module = vertShaderModule.get(),
.module = vertShaderModule.get(), .pName = "main" };
.pName = "main",
};
vk::PipelineShaderStageCreateInfo fragShaderStageInfo { vk::PipelineShaderStageCreateInfo fragShaderStageInfo { .stage = vk::ShaderStageFlagBits::eFragment,
.stage = vk::ShaderStageFlagBits::eFragment, .module = fragShaderModule.get(),
.module = fragShaderModule.get(), .pName = "main" };
.pName = "main",
};
std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = { vertShaderStageInfo, std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = { vertShaderStageInfo,
fragShaderStageInfo }; fragShaderStageInfo };
@ -527,38 +545,36 @@ class VulkanApp {
.vertexBindingDescriptionCount = 1, .vertexBindingDescriptionCount = 1,
.pVertexBindingDescriptions = &bindingDescription, .pVertexBindingDescriptions = &bindingDescription,
.vertexAttributeDescriptionCount = static_cast<u32>(attributeDescriptions.size()), .vertexAttributeDescriptionCount = static_cast<u32>(attributeDescriptions.size()),
.pVertexAttributeDescriptions = attributeDescriptions.data(), .pVertexAttributeDescriptions = attributeDescriptions.data()
}; };
vk::PipelineInputAssemblyStateCreateInfo inputAssembly { vk::PipelineInputAssemblyStateCreateInfo inputAssembly { .topology = vk::PrimitiveTopology::eTriangleList,
.topology = vk::PrimitiveTopology::eTriangleList, .primitiveRestartEnable = vk::False };
.primitiveRestartEnable = vk::False,
};
vk::PipelineViewportStateCreateInfo viewportState { vk::PipelineViewportStateCreateInfo viewportState { .viewportCount = 1, .scissorCount = 1 };
.viewportCount = 1,
.scissorCount = 1,
};
vk::PipelineRasterizationStateCreateInfo rasterizer { vk::PipelineRasterizationStateCreateInfo rasterizer { .depthClampEnable = vk::False,
.depthClampEnable = vk::False, .rasterizerDiscardEnable = vk::False,
.rasterizerDiscardEnable = vk::False, .polygonMode = vk::PolygonMode::eFill,
.polygonMode = vk::PolygonMode::eFill, .cullMode = vk::CullModeFlagBits::eBack,
.cullMode = vk::CullModeFlagBits::eBack, .frontFace = vk::FrontFace::eCounterClockwise,
.frontFace = vk::FrontFace::eCounterClockwise, .depthBiasEnable = vk::False,
.depthBiasEnable = vk::False, .lineWidth = 1.0F };
.lineWidth = 1.0F,
};
vk::PipelineMultisampleStateCreateInfo multisampling { vk::PipelineMultisampleStateCreateInfo multisampling { .rasterizationSamples =
.rasterizationSamples = vk::SampleCountFlagBits::e1, vk::SampleCountFlagBits::e1,
.sampleShadingEnable = vk::False, .sampleShadingEnable = vk::False };
};
vk::PipelineDepthStencilStateCreateInfo depthStencil { .depthTestEnable = vk::True,
.depthWriteEnable = vk::True,
.depthCompareOp = vk::CompareOp::eLess,
.depthBoundsTestEnable = vk::False,
.stencilTestEnable = vk::False };
vk::PipelineColorBlendAttachmentState colorBlendAttachment { vk::PipelineColorBlendAttachmentState colorBlendAttachment {
.blendEnable = vk::False, .blendEnable = vk::False,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA, vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA
}; };
vk::PipelineColorBlendStateCreateInfo colorBlending { vk::PipelineColorBlendStateCreateInfo colorBlending {
@ -566,37 +582,33 @@ class VulkanApp {
.logicOp = vk::LogicOp::eCopy, .logicOp = vk::LogicOp::eCopy,
.attachmentCount = 1, .attachmentCount = 1,
.pAttachments = &colorBlendAttachment, .pAttachments = &colorBlendAttachment,
.blendConstants = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 0.0F }, .blendConstants = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 0.0F }
}; };
std::vector<vk::DynamicState> dynamicStates = { vk::DynamicState::eViewport, vk::DynamicState::eScissor }; std::vector<vk::DynamicState> dynamicStates = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
vk::PipelineDynamicStateCreateInfo dynamicState { vk::PipelineDynamicStateCreateInfo dynamicState { .dynamicStateCount =
.dynamicStateCount = static_cast<u32>(dynamicStates.size()), static_cast<u32>(dynamicStates.size()),
.pDynamicStates = dynamicStates.data(), .pDynamicStates = dynamicStates.data() };
};
vk::PipelineLayoutCreateInfo pipelineLayoutInfo { vk::PipelineLayoutCreateInfo pipelineLayoutInfo { .setLayoutCount = 1,
.setLayoutCount = 1, .pSetLayouts = &mDescriptorSetLayout.get() };
.pSetLayouts = &mDescriptorSetLayout.get(),
};
mPipelineLayout = mDevice->createPipelineLayoutUnique(pipelineLayoutInfo); mPipelineLayout = mDevice->createPipelineLayoutUnique(pipelineLayoutInfo);
vk::GraphicsPipelineCreateInfo pipelineInfo { vk::GraphicsPipelineCreateInfo pipelineInfo { .stageCount = static_cast<u32>(shaderStages.size()),
.stageCount = static_cast<u32>(shaderStages.size()), .pStages = shaderStages.data(),
.pStages = shaderStages.data(), .pVertexInputState = &vertexInputInfo,
.pVertexInputState = &vertexInputInfo, .pInputAssemblyState = &inputAssembly,
.pInputAssemblyState = &inputAssembly, .pViewportState = &viewportState,
.pViewportState = &viewportState, .pRasterizationState = &rasterizer,
.pRasterizationState = &rasterizer, .pMultisampleState = &multisampling,
.pMultisampleState = &multisampling, .pDepthStencilState = &depthStencil,
.pColorBlendState = &colorBlending, .pColorBlendState = &colorBlending,
.pDynamicState = &dynamicState, .pDynamicState = &dynamicState,
.layout = mPipelineLayout.get(), .layout = mPipelineLayout.get(),
.renderPass = mRenderPass.get(), .renderPass = mRenderPass.get(),
.subpass = 0, .subpass = 0 };
};
vk::Result graphicsPipelineResult = vk::Result::eSuccess; vk::Result graphicsPipelineResult = vk::Result::eSuccess;
vk::UniquePipeline graphicsPipelineValue; vk::UniquePipeline graphicsPipelineValue;
@ -614,14 +626,14 @@ class VulkanApp {
mSwapChainFramebuffers.resize(mSwapChainImageViews.size()); mSwapChainFramebuffers.resize(mSwapChainImageViews.size());
for (usize i = 0; i < mSwapChainImageViews.size(); i++) { for (usize i = 0; i < mSwapChainImageViews.size(); i++) {
vk::FramebufferCreateInfo framebufferInfo { std::array<vk::ImageView, 2> attachments = { mSwapChainImageViews[i].get(), mDepthImageView.get() };
.renderPass = mRenderPass.get(),
.attachmentCount = 1, vk::FramebufferCreateInfo framebufferInfo { .renderPass = mRenderPass.get(),
.pAttachments = &mSwapChainImageViews[i].get(), .attachmentCount = static_cast<u32>(attachments.size()),
.width = mSwapChainExtent.width, .pAttachments = attachments.data(),
.height = mSwapChainExtent.height, .width = mSwapChainExtent.width,
.layers = 1, .height = mSwapChainExtent.height,
}; .layers = 1 };
mSwapChainFramebuffers[i] = mDevice->createFramebufferUnique(framebufferInfo); mSwapChainFramebuffers[i] = mDevice->createFramebufferUnique(framebufferInfo);
} }
@ -638,6 +650,51 @@ class VulkanApp {
mCommandPool = mDevice->createCommandPoolUnique(poolInfo); mCommandPool = mDevice->createCommandPoolUnique(poolInfo);
} }
fn createDepthResources() -> void {
vk::Format depthFormat = findDepthFormat();
createImage(
mSwapChainExtent.width,
mSwapChainExtent.height,
depthFormat,
vk::ImageTiling::eOptimal,
vk::ImageUsageFlagBits::eDepthStencilAttachment,
vk::MemoryPropertyFlagBits::eDeviceLocal,
mDepthImage,
mDepthImageMemory
);
mDepthImageView = createImageView(mDepthImage.get(), depthFormat, vk::ImageAspectFlagBits::eDepth);
}
fn findSupportedFormat(
const std::vector<vk::Format>& candidates,
vk::ImageTiling tiling,
vk::FormatFeatureFlags features
) -> vk::Format {
for (vk::Format format : candidates) {
vk::FormatProperties props = mPhysicalDevice.getFormatProperties(format);
if (tiling == vk::ImageTiling::eLinear && (props.linearTilingFeatures & features) == features)
return format;
if (tiling == vk::ImageTiling::eOptimal && (props.optimalTilingFeatures & features) == features)
return format;
}
throw std::runtime_error("Failed to find supported format!");
}
fn findDepthFormat() -> vk::Format {
return findSupportedFormat(
{ vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint },
vk::ImageTiling::eOptimal,
vk::FormatFeatureFlagBits::eDepthStencilAttachment
);
}
static fn hasStencilComponent(vk::Format format) {
return format == vk::Format::eD32SfloatS8Uint || format == vk::Format::eD24UnormS8Uint;
}
fn createTextureImage() -> void { fn createTextureImage() -> void {
i32 texWidth = 0, texHeight = 0, texChannels = 0; i32 texWidth = 0, texHeight = 0, texChannels = 0;
u8* pixels = stbi_load("src/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); u8* pixels = stbi_load("src/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
@ -783,8 +840,6 @@ class VulkanApp {
vk::UniqueCommandBuffer commandBuffer = beginSingleTimeCommands(); vk::UniqueCommandBuffer commandBuffer = beginSingleTimeCommands();
vk::ImageMemoryBarrier barrier { vk::ImageMemoryBarrier barrier {
.srcAccessMask = { },
.dstAccessMask = { },
.oldLayout = oldLayout, .oldLayout = oldLayout,
.newLayout = newLayout, .newLayout = newLayout,
.srcQueueFamilyIndex = vk::QueueFamilyIgnored, .srcQueueFamilyIndex = vk::QueueFamilyIgnored,
@ -795,7 +850,7 @@ class VulkanApp {
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = 1, .levelCount = 1,
.baseArrayLayer = 0, .baseArrayLayer = 0,
.layerCount = 1 }, .layerCount = 1 }
// clang-format on // clang-format on
}; };
@ -1080,14 +1135,17 @@ class VulkanApp {
commandBuffer.begin(beginInfo); commandBuffer.begin(beginInfo);
vk::ClearValue clearColor { .color = { .float32 = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 1.0F } } }; std::array<vk::ClearValue, 2> clearValues {
{ { .color = { .float32 = std::array<float, 4> { 0.0F, 0.0F, 0.0F, 1.0F } } },
{ .depthStencil = { .depth = 1.0F, .stencil = 0 } } }
};
vk::RenderPassBeginInfo renderPassInfo { vk::RenderPassBeginInfo renderPassInfo {
.renderPass = mRenderPass.get(), .renderPass = mRenderPass.get(),
.framebuffer = mSwapChainFramebuffers[imageIndex].get(), .framebuffer = mSwapChainFramebuffers[imageIndex].get(),
.renderArea = { .offset = { .x = 0, .y = 0 }, .extent = mSwapChainExtent }, .renderArea = { .offset = { .x = 0, .y = 0 }, .extent = mSwapChainExtent },
.clearValueCount = 1, .clearValueCount = static_cast<u32>(clearValues.size()),
.pClearValues = &clearColor, .pClearValues = clearValues.data()
}; };
commandBuffer.beginRenderPass(renderPassInfo, vk::SubpassContents::eInline); commandBuffer.beginRenderPass(renderPassInfo, vk::SubpassContents::eInline);
@ -1226,8 +1284,6 @@ class VulkanApp {
vk::Result presentResult = mPresentQueue.presentKHR(presentInfo); vk::Result presentResult = mPresentQueue.presentKHR(presentInfo);
fmt::println("Present result: {}", vk::to_string(presentResult));
if (presentResult == vk::Result::eErrorOutOfDateKHR || presentResult == vk::Result::eSuboptimalKHR || if (presentResult == vk::Result::eErrorOutOfDateKHR || presentResult == vk::Result::eSuboptimalKHR ||
mFramebufferResized) { mFramebufferResized) {
mFramebufferResized = false; mFramebufferResized = false;

View file

@ -6,7 +6,7 @@ layout(binding = 0) uniform UniformBufferObject {
mat4 proj; mat4 proj;
} ubo; } ubo;
layout(location = 0) in vec2 inPosition; layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor; layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord; layout(location = 2) in vec2 inTexCoord;
@ -14,7 +14,7 @@ layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord; layout(location = 1) out vec2 fragTexCoord;
void main() { void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
fragColor = inColor; fragColor = inColor;
fragTexCoord = inTexCoord; fragTexCoord = inTexCoord;
} }

Binary file not shown.