From 80c24fa4cfb59f46d578ce8f7b488b3c6e5b02b5 Mon Sep 17 00:00:00 2001 From: Andreev Gregory Date: Fri, 18 Jul 2025 20:31:46 +0300 Subject: [PATCH] Drawing a prerecorded texture + fixed a dumb bug --- src/l2/tests/r0.c | 105 ++++++++++++++---------- src/l2/tests/test_shaders/glsl/0/0.frag | 8 +- src/l2/tests/test_shaders/glsl/0/0.vert | 6 +- 3 files changed, 69 insertions(+), 50 deletions(-) diff --git a/src/l2/tests/r0.c b/src/l2/tests/r0.c index cee00e1..859b800 100644 --- a/src/l2/tests/r0.c +++ b/src/l2/tests/r0.c @@ -8,7 +8,7 @@ typedef struct { vec3 pos; - vec3 color; + vec2 tex; } OA_Vertex; typedef struct { @@ -19,7 +19,8 @@ typedef struct { typedef struct { VkBuffer vbo; VkBuffer ebo; - size_t vert_count; + // If topology is triangle list,then this is trice the amount of triangles + size_t indices; } OA_ObjectOnScene; #define OA_ObjectOnScene_drop(vp) {} @@ -131,8 +132,8 @@ PipelineHands create_graphics_pipeline( { .location = 1, .binding = 0, - .format = VK_FORMAT_R32G32B32_SFLOAT, - .offset = offsetof(OA_Vertex, color), + .format = VK_FORMAT_R32G32_SFLOAT, + .offset = offsetof(OA_Vertex, tex), }, }; @@ -213,12 +214,12 @@ PipelineHands create_graphics_pipeline( .descriptorCount = 1, .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, }, - // { - // .binding = 1, - // .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - // .descriptorCount = 1, - // .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - // }, + { + .binding = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }, }; VkDescriptorSetLayoutCreateInfo descriptor_set_layout_crinfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, @@ -309,7 +310,6 @@ void reset_and_record_command_buffer( .extent = image_extent, }; vkCmdSetScissor(command_buffer, 0, 1, &scissor); - for (size_t i = 0; i < scene->oa_objects.len; i++) { const OA_ObjectOnScene* obj = VecOA_ObjectOnScene_cat(&scene->oa_objects, i); VkBuffer attached_buffers[1] = { obj->vbo }; @@ -320,7 +320,7 @@ void reset_and_record_command_buffer( vkCmdBindDescriptorSets( command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout->pipeline_layout, 0, 1, &my_descriptor_set, 0, NULL); - vkCmdDrawIndexed(command_buffer, obj->vert_count, 1, 0, 0, 0); + vkCmdDrawIndexed(command_buffer, obj->indices, 1, 0, 0, 0); } vkCmdEndRenderPass(command_buffer); @@ -417,15 +417,16 @@ int main() { // Filling scene info const OA_Vertex obj1_vertexes[] = { - (OA_Vertex){ .pos = {-0.6f, -1.0f, 0}, .color = {1.f, 0, 0} }, - (OA_Vertex){ .pos = {-0.8f, -0.8f, 0}, .color = {0, 1.f, 0} }, - (OA_Vertex){ .pos = {-0.8f, -0.6f, 0}, .color = {0, 0, 1.f} }, + (OA_Vertex){ .pos = {-1, -1, 0}, .tex = {0, 1} }, + (OA_Vertex){ .pos = {1, -1, 0}, .tex = {1, 1} }, + (OA_Vertex){ .pos = {1, 1, 0}, .tex = {1, 0} }, + (OA_Vertex){ .pos = {-1, 1, 0}, .tex = {0, 0} }, }; - const uint32_t obj1_indices[] = { 0, 1, 2 }; + const uint32_t obj1_indices[] = { 0, 2, 1, 0, 3, 2 }; const OA_Vertex obj2_vertexes[] = { - (OA_Vertex){ .pos = {0.9f, 0.9f}, .color = {1.f, 0, 0} }, - (OA_Vertex){ .pos = {0.4f, -0.9f, 0}, .color = {0, 1.f, 0} }, - (OA_Vertex){ .pos = {-0.2f, 1.f}, .color = {0, 0, 1.f} }, + (OA_Vertex){ .pos = {0.9f, 0.9f}, .tex = {1.f, 0} }, + (OA_Vertex){ .pos = {0.4f, -0.9f, 0}, .tex = {0, 1.f} }, + (OA_Vertex){ .pos = {-0.2f, 1.f}, .tex = {0, 0} }, }; const uint32_t obj2_indices[] = {0, 1, 2}; @@ -447,7 +448,6 @@ int main() { } } - // todo: add a texture into the mix // We have only one staging buffer in host memory (because we don't really need more) MargaretBufferInMemoryInfo host_mem_buffer = (MargaretBufferInMemoryInfo){ .sz = MAX_U64(sizeof(obj1_vertexes), @@ -473,13 +473,14 @@ int main() { }; VkDeviceMemory device_mem = margaret_initialize_buffers_and_images(physical_device, device, (SpanMargaretBufferInMemoryInfo){ .data = device_mem_buffers, .len = ARRAY_SIZE(device_mem_buffers)}, - (SpanMargaretImageInMemoryInfo){ 0 }, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + (SpanMargaretImageInMemoryInfo){ .data = device_mem_images, .len = ARRAY_SIZE(device_mem_images) }, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); MargaretBufferInMemoryInfo device_vbo_1_buffer = device_mem_buffers[0]; MargaretBufferInMemoryInfo device_ebo_1_buffer = device_mem_buffers[1]; MargaretBufferInMemoryInfo device_vbo_2_buffer = device_mem_buffers[2]; MargaretBufferInMemoryInfo device_ebo_2_buffer = device_mem_buffers[3]; MargaretBufferInMemoryInfo device_ubo_my_buffer = device_mem_buffers[4]; - // device_mem_buffers may be considered invalidated, forgotten you might say + MargaretImageInMemoryInfo device_wood_texture = device_mem_images[0]; VkCommandPool command_pool = margaret_create_resettable_command_pool(device, queue_fam.for_graphics); VkCommandBuffer rendering_command_buffer = margaret_allocate_command_buffer(device, command_pool); @@ -504,17 +505,25 @@ int main() { memcpy(host_mem_buffer_mem, obj2_indices, sizeof(obj2_indices)); margaret_copy_buffer_imm(device, command_pool, graphics_queue, device_ebo_2_buffer.buffer, host_mem_buffer.buffer, sizeof(obj2_indices)); + memcpy(host_mem_buffer_mem, wood_texture_data, sizeof(wood_texture_data)); + margaret_copy_buffer_to_texture_for_frag_shader_imm(device, command_pool, graphics_queue, + &device_wood_texture, host_mem_buffer.buffer); // We sent everything we needed. but host_mem_buffer_mem may be used later + // My wood texture needs VkImageView + VkImageView wood_texture_view = margaret_create_view_for_image(device, &device_wood_texture, VK_IMAGE_ASPECT_COLOR_BIT); + Scene scene; scene.oa_objects = VecOA_ObjectOnScene_new_zeroinit(2); *VecOA_ObjectOnScene_at(&scene.oa_objects, 0) = (OA_ObjectOnScene){ - .vbo = device_vbo_1_buffer.buffer, .ebo = device_ebo_1_buffer.buffer, .vert_count = ARRAY_SIZE(obj1_vertexes) }; + .vbo = device_vbo_1_buffer.buffer, .ebo = device_ebo_1_buffer.buffer, .indices = ARRAY_SIZE(obj1_indices) }; *VecOA_ObjectOnScene_at(&scene.oa_objects, 1) = (OA_ObjectOnScene){ - .vbo = device_vbo_2_buffer.buffer, .ebo = device_ebo_2_buffer.buffer, .vert_count = ARRAY_SIZE(obj2_vertexes) }; + .vbo = device_vbo_2_buffer.buffer, .ebo = device_ebo_2_buffer.buffer, .indices = ARRAY_SIZE(obj2_indices) }; // device_vbo/ebo_1/2_buffer won't be used only intrinsically by vulkan, not by us - VkDescriptorPool descriptor_pool = margaret_create_descriptor_set_pool(device, 1, 0, 1); + // Sampler is global for a lot of my future textures + VkSampler my_texture_sampler = margaret_create_sampler(physical_device, device); + VkDescriptorPool descriptor_pool = margaret_create_descriptor_set_pool(device, 1, 1, 2); VkDescriptorSetAllocateInfo descriptor_sets_alloc_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .descriptorPool = descriptor_pool, @@ -524,20 +533,19 @@ int main() { VkDescriptorSet my_descriptor_set; if (vkAllocateDescriptorSets(device, &descriptor_sets_alloc_info, &my_descriptor_set) != VK_SUCCESS) abortf("vkAllocateDescriptorSets"); - - // Configuring my descriptor set (of one single descriptor set layout from my pipeline) + // Configuring my descriptor set, that I just allocated VkDescriptorBufferInfo buffer_info_for_descriptor_0 = { .buffer = device_ubo_my_buffer.buffer, .offset = 0, .range = sizeof(MyUbo), }; - // VkDescriptorImageInfo image_info_for_descriptor_1 { - // .sampler = my_texture_sampler, - // .imageView = my_texture_image_view, - // .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - // }; + VkDescriptorImageInfo image_info_for_descriptor_1 = { + .sampler = my_texture_sampler, + .imageView = wood_texture_view, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; VkWriteDescriptorSet descriptor_writes[] = { - (VkWriteDescriptorSet){ + { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .dstSet = my_descriptor_set, .dstBinding = 0, @@ -546,15 +554,15 @@ int main() { .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .pBufferInfo = &buffer_info_for_descriptor_0, }, - // VkWriteDescriptorSet{ - // .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - // .dstSet = descriptor_sets_for_ubo[i], - // .dstBinding = 1, - // .dstArrayElement = 0, - // .descriptorCount = 1, - // .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - // .pImageInfo = &image_info_for_descriptor_1, - // }, + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = my_descriptor_set, + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &image_info_for_descriptor_1, + }, }; vkUpdateDescriptorSets(device, ARRAY_SIZE(descriptor_writes), descriptor_writes, 0, NULL); @@ -563,7 +571,6 @@ int main() { margaret_ns_time prev_key_frame_time = start; int frame_count_since_key = 0; - // margaret_ns_time prev_timestamp = margaret_clock_gettime_monotonic_raw(); while (true) { margaret_ns_time frame_A0 = margaret_clock_gettime_monotonic_raw(); VecXlib_Event events = margaret_read_x_events(x.dpy); @@ -696,9 +703,17 @@ int main() { VecOA_ObjectOnScene_drop(scene.oa_objects); // destroying vulkan objects vkDestroyDescriptorPool(device, descriptor_pool, NULL); - for (size_t i = 0; i < ARRAY_SIZE(device_mem_buffers); i++) - vkDestroyBuffer(device, device_mem_buffers[i].buffer, NULL); + vkDestroySampler(device, my_texture_sampler, NULL); + vkDestroyImageView(device, wood_texture_view, NULL); + + vkDestroyBuffer(device, device_vbo_1_buffer.buffer, NULL); + vkDestroyBuffer(device, device_ebo_1_buffer.buffer, NULL); + vkDestroyBuffer(device, device_vbo_2_buffer.buffer, NULL); + vkDestroyBuffer(device, device_ebo_2_buffer.buffer, NULL); + vkDestroyBuffer(device, device_ubo_my_buffer.buffer, NULL); + vkDestroyImage(device, device_wood_texture.image, NULL); vkDestroyBuffer(device, host_mem_buffer.buffer, NULL); + vkFreeMemory(device, device_mem, NULL); vkUnmapMemory(device, host_mem); vkFreeMemory(device, host_mem, NULL); diff --git a/src/l2/tests/test_shaders/glsl/0/0.frag b/src/l2/tests/test_shaders/glsl/0/0.frag index d80ed74..f6e2c38 100644 --- a/src/l2/tests/test_shaders/glsl/0/0.frag +++ b/src/l2/tests/test_shaders/glsl/0/0.frag @@ -1,6 +1,6 @@ #version 450 -layout(location = 0) in vec3 fsin_color; +layout(location = 0) in vec2 fsin_tex; layout(location = 0) out vec4 fin_color; @@ -8,6 +8,10 @@ layout(binding = 0) uniform my_ubo { vec3 s; // 0 + 12 + 4 }; +layout(binding = 1) uniform sampler2D wood_texture; + void main() { - fin_color = vec4(fsin_color * s, 1.0); + vec2 tex_offset = 1.0 / textureSize(wood_texture, 0); + + fin_color = texture(wood_texture, gl_FragCoord.xy * tex_offset); } diff --git a/src/l2/tests/test_shaders/glsl/0/0.vert b/src/l2/tests/test_shaders/glsl/0/0.vert index b53aee6..b3968cd 100644 --- a/src/l2/tests/test_shaders/glsl/0/0.vert +++ b/src/l2/tests/test_shaders/glsl/0/0.vert @@ -1,11 +1,11 @@ #version 450 layout(location = 0) in vec3 pos; -layout(location = 1) in vec3 color; +layout(location = 1) in vec2 tex; -layout(location = 0) out vec3 vsout_color; +layout(location = 0) out vec2 vsout_tex; void main() { gl_Position = vec4(pos, 1.0); - vsout_color = color; + vsout_tex = tex; }