Skip to content

Commit 1b5c386

Browse files
committed
Image rendering
1 parent bb20b90 commit 1b5c386

9 files changed

Lines changed: 133 additions & 20 deletions

File tree

shaders/compile.bat

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
glslc.exe -fshader-stage=vert triangle_vert.glsl -o triangle_vert.spv
22
glslc.exe -fshader-stage=frag triangle_frag.glsl -o triangle_frag.spv
33
glslc.exe -fshader-stage=vert color_vert.glsl -o color_vert.spv
4-
glslc.exe -fshader-stage=frag color_frag.glsl -o color_frag.spv
4+
glslc.exe -fshader-stage=frag color_frag.glsl -o color_frag.spv
5+
glslc.exe -fshader-stage=vert texture_vert.glsl -o texture_vert.spv
6+
glslc.exe -fshader-stage=frag texture_frag.glsl -o texture_frag.spv

shaders/compile.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ glslc -fshader-stage=vert triangle_vert.glsl -o triangle_vert.spv
33
glslc -fshader-stage=frag triangle_frag.glsl -o triangle_frag.spv
44
glslc -fshader-stage=vert color_vert.glsl -o color_vert.spv
55
glslc -fshader-stage=frag color_frag.glsl -o color_frag.spv
6+
glslc -fshader-stage=vert texture_vert.glsl -o texture_vert.spv
7+
glslc -fshader-stage=frag texture_frag.glsl -o texture_frag.spv

shaders/texture_frag.glsl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#version 450 core
2+
3+
layout(location = 0) in vec3 in_color;
4+
layout(location = 1) in vec2 in_uv;
5+
6+
layout(location = 0) out vec4 out_color;
7+
8+
layout(set = 0, binding = 0) uniform sampler2D in_sampledTexture;
9+
10+
void main() {
11+
vec4 texSample = texture(in_sampledTexture, in_uv);
12+
//out_color = texSample * vec4(in_color, 1.0);
13+
out_color = texSample;
14+
}

shaders/texture_frag.spv

808 Bytes
Binary file not shown.

shaders/texture_vert.glsl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#version 450 core
2+
3+
layout(location = 0) in vec2 in_position;
4+
layout(location = 1) in vec3 in_color;
5+
layout(location = 2) in vec2 in_uv;
6+
7+
layout(location = 0) out vec3 out_color;
8+
layout(location = 1) out vec2 out_uv;
9+
10+
void main() {
11+
gl_Position = vec4(in_position, 0.0, 1.0);
12+
out_color = in_color;
13+
out_uv = in_uv;
14+
}

shaders/texture_vert.spv

1.2 KB
Binary file not shown.

src/main.cpp

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ VulkanBuffer vertexBuffer;
2525
VulkanBuffer indexBuffer;
2626
VulkanImage image;
2727

28+
VkSampler sampler;
29+
VkDescriptorPool descriptorPool;
30+
VkDescriptorSet descriptorSet;
31+
VkDescriptorSetLayout descriptorLayout;
32+
2833
bool handleMessage() {
2934
SDL_Event event;
3035
while (SDL_PollEvent(&event)) {
@@ -60,17 +65,21 @@ void recreateRenderPass() {
6065
}
6166

6267
float vertexData[] = {
63-
0.5f, -0.5f,
64-
1.0f, 0.0f, 0.0f,
68+
0.5f, -0.5f, // Position
69+
1.0f, 0.0f, 0.0f, // Color
70+
1.0f, 0.0f, // Texcoord
6571

6672
0.5f, 0.5f,
6773
0.0f, 1.0f, 0.0f,
74+
1.0f, 1.0f,
6875

6976
-0.5f, 0.5f,
7077
0.0f, 0.0f, 1.0f,
78+
0.0f, 1.0f,
7179

7280
-0.5f, -0.5f,
7381
0.0f, 1.0f, 0.0f,
82+
0.0f, 0.0f,
7483
};
7584

7685
uint32_t indexData[] = {
@@ -99,7 +108,70 @@ void initApplication(SDL_Window* window) {
99108

100109
recreateRenderPass();
101110

102-
VkVertexInputAttributeDescription vertexAttributeDescriptions[2] = {};
111+
{
112+
VkSamplerCreateInfo createInfo = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
113+
createInfo.magFilter = VK_FILTER_NEAREST;
114+
createInfo.minFilter = VK_FILTER_NEAREST;
115+
createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
116+
createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
117+
createInfo.addressModeV = createInfo.addressModeU;
118+
createInfo.addressModeW = createInfo.addressModeU;
119+
createInfo.mipLodBias = 0.0f;
120+
createInfo.maxAnisotropy = 1.0f;
121+
createInfo.minLod = 0.0f;
122+
createInfo.maxLod = 1.0f;
123+
VKA(vkCreateSampler(context->device, &createInfo, 0, &sampler));
124+
}
125+
126+
{
127+
int width, height, channels;
128+
uint8_t* data = stbi_load("../data/images/logo.png", &width, &height, &channels, 4);
129+
if(!data) {
130+
LOG_ERROR("Could not load image data");
131+
}
132+
createImage(context, &image, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
133+
uploadDataToImage(context, &image, data, width * height * 4, width, height, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
134+
stbi_image_free(data);
135+
}
136+
137+
{
138+
VkDescriptorPoolSize poolSizes[] = {
139+
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1},
140+
};
141+
VkDescriptorPoolCreateInfo createInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};
142+
createInfo.maxSets = 1;
143+
createInfo.poolSizeCount = ARRAY_COUNT(poolSizes);
144+
createInfo.pPoolSizes = poolSizes;
145+
VKA(vkCreateDescriptorPool(context->device, &createInfo, 0, &descriptorPool));
146+
}
147+
148+
{
149+
VkDescriptorSetLayoutBinding bindings[] = {
150+
{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, 0},
151+
};
152+
VkDescriptorSetLayoutCreateInfo createInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO};
153+
createInfo.bindingCount = ARRAY_COUNT(bindings);
154+
createInfo.pBindings = bindings;
155+
VKA(vkCreateDescriptorSetLayout(context->device, &createInfo, 0, &descriptorLayout));
156+
157+
VkDescriptorSetAllocateInfo allocateInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO};
158+
allocateInfo.descriptorPool = descriptorPool;
159+
allocateInfo.descriptorSetCount = 1;
160+
allocateInfo.pSetLayouts = &descriptorLayout;
161+
VKA(vkAllocateDescriptorSets(context->device, &allocateInfo, &descriptorSet));
162+
163+
VkDescriptorImageInfo imageInfo = { sampler, image.view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
164+
VkWriteDescriptorSet descriptorWrites[1];
165+
descriptorWrites[0] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET};
166+
descriptorWrites[0].dstSet = descriptorSet;
167+
descriptorWrites[0].dstBinding = 0;
168+
descriptorWrites[0].descriptorCount = 1;
169+
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
170+
descriptorWrites[0].pImageInfo = &imageInfo;
171+
VK(vkUpdateDescriptorSets(context->device, ARRAY_COUNT(descriptorWrites), descriptorWrites, 0, 0));
172+
}
173+
174+
VkVertexInputAttributeDescription vertexAttributeDescriptions[3] = {};
103175
vertexAttributeDescriptions[0].binding = 0;
104176
vertexAttributeDescriptions[0].location = 0;
105177
vertexAttributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
@@ -108,11 +180,15 @@ void initApplication(SDL_Window* window) {
108180
vertexAttributeDescriptions[1].location = 1;
109181
vertexAttributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
110182
vertexAttributeDescriptions[1].offset = sizeof(float) * 2;
183+
vertexAttributeDescriptions[2].binding = 0;
184+
vertexAttributeDescriptions[2].location = 2;
185+
vertexAttributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
186+
vertexAttributeDescriptions[2].offset = sizeof(float) * 5;
111187
VkVertexInputBindingDescription vertexInputBinding = {};
112188
vertexInputBinding.binding = 0;
113189
vertexInputBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
114-
vertexInputBinding.stride = sizeof(float) * 5;
115-
pipeline = createPipeline(context, "../shaders/color_vert.spv", "../shaders/color_frag.spv", renderPass, swapchain.width, swapchain.height, vertexAttributeDescriptions, ARRAY_COUNT(vertexAttributeDescriptions), &vertexInputBinding);
190+
vertexInputBinding.stride = sizeof(float) * 7;
191+
pipeline = createPipeline(context, "../shaders/texture_vert.spv", "../shaders/texture_frag.spv", renderPass, swapchain.width, swapchain.height, vertexAttributeDescriptions, ARRAY_COUNT(vertexAttributeDescriptions), &vertexInputBinding, 1, &descriptorLayout);
116192

117193
for(uint32_t i = 0; i < ARRAY_COUNT(fences); ++i) {
118194
VkFenceCreateInfo createInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
@@ -144,17 +220,6 @@ void initApplication(SDL_Window* window) {
144220

145221
createBuffer(context, &indexBuffer, sizeof(indexData), VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
146222
uploadDataToBuffer(context, &indexBuffer, indexData, sizeof(indexData));
147-
148-
{
149-
int width, height, channels;
150-
uint8_t* data = stbi_load("../data/images/logo.png", &width, &height, &channels, 4);
151-
if(!data) {
152-
LOG_ERROR("Could not load image data");
153-
}
154-
createImage(context, &image, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
155-
uploadDataToImage(context, &image, data, width * height * 4, width, height, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
156-
stbi_image_free(data);
157-
}
158223
}
159224

160225
void recreateSwapchain() {
@@ -221,6 +286,7 @@ void renderApplication() {
221286
VkDeviceSize offset = 0;
222287
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.buffer, &offset);
223288
vkCmdBindIndexBuffer(commandBuffer, indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32);
289+
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipelineLayout, 0, 1, &descriptorSet, 0, 0);
224290

225291
vkCmdDrawIndexed(commandBuffer, ARRAY_COUNT(indexData), 1, 0, 0, 0);
226292

@@ -260,6 +326,9 @@ void renderApplication() {
260326
void shutdownApplication() {
261327
VKA(vkDeviceWaitIdle(context->device));
262328

329+
VK(vkDestroyDescriptorPool(context->device, descriptorPool, 0));
330+
VK(vkDestroyDescriptorSetLayout(context->device, descriptorLayout, 0));
331+
263332
destroyBuffer(context, &vertexBuffer);
264333
destroyBuffer(context, &indexBuffer);
265334

@@ -276,6 +345,8 @@ void shutdownApplication() {
276345

277346
destroyPipeline(context, &pipeline);
278347

348+
vkDestroySampler(context->device, sampler, 0);
349+
279350
for (uint32_t i = 0; i < framebuffers.size(); ++i) {
280351
VK(vkDestroyFramebuffer(context->device, framebuffers[i], 0));
281352
}

src/vulkan_base/vulkan_base.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,6 @@ void createImage(VulkanContext* context, VulkanImage* image, uint32_t width, uin
7070
void uploadDataToImage(VulkanContext* context, VulkanImage* image, void* data, size_t size, uint32_t width, uint32_t height, VkImageLayout finalLayout, VkAccessFlags dstAccessMask);
7171
void destroyImage(VulkanContext* context, VulkanImage* image);
7272

73-
VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFilename, const char* fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height, VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding);
73+
VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFilename, const char* fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height,
74+
VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding, uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts);
7475
void destroyPipeline(VulkanContext* context, VulkanPipeline* pipeline);

src/vulkan_base/vulkan_pipeline.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ VkShaderModule createShaderModule(VulkanContext* context, const char* shaderFile
2727
return result;
2828
}
2929

30-
VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFilename, const char* fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height, VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding) {
30+
VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFilename, const char* fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height,
31+
VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding, uint32_t numSetLayouts, VkDescriptorSetLayout* setLayouts) {
3132
VkShaderModule vertexShaderModule = createShaderModule(context, vertexShaderFilename);
3233
VkShaderModule fragmentShaderModule = createShaderModule(context, fragmentShaderFilename);
3334

@@ -66,7 +67,13 @@ VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFi
6667

6768
VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
6869
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
69-
colorBlendAttachment.blendEnable = VK_FALSE;
70+
colorBlendAttachment.blendEnable = VK_TRUE;
71+
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
72+
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
73+
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
74+
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
75+
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
76+
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
7077
VkPipelineColorBlendStateCreateInfo colorBlendState = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
7178
colorBlendState.attachmentCount = 1;
7279
colorBlendState.pAttachments = &colorBlendAttachment;
@@ -79,6 +86,8 @@ VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFi
7986
VkPipelineLayout pipelineLayout;
8087
{
8188
VkPipelineLayoutCreateInfo createInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
89+
createInfo.setLayoutCount = numSetLayouts;
90+
createInfo.pSetLayouts = setLayouts;
8291
VKA(vkCreatePipelineLayout(context->device, &createInfo, 0, &pipelineLayout));
8392
}
8493

0 commit comments

Comments
 (0)