Drawing a prerecorded texture + fixed a dumb bug

This commit is contained in:
Андреев Григорий 2025-07-18 20:31:46 +03:00
parent 2f1dd814b6
commit 80c24fa4cf
3 changed files with 69 additions and 50 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}