src/draw_call.c
  1#include "alba.h"
  2#include "internal.h"
  3
  4DrawCall* window_create_draw_call(AlbaWindow* window)
  5{
  6    DrawCall draw_call = {0};
  7    draw_call.buffers_dirty = 1;
  8    draw_call.bind_group_dirty = 1;
  9    draw_call.new_vertices = alba_create_array(sizeof(AlbaVector), 0);
 10    draw_call.new_attributes = alba_create_array(sizeof(AlbaAttribute), 0);
 11    draw_call.new_indices = alba_create_array(sizeof(uint32_t), 0);
 12    draw_call.new_texts = alba_create_array(sizeof(Text), 0);
 13    alba_array_append(&window->draw_calls, &draw_call);
 14    return alba_array_last(&window->draw_calls);
 15}
 16
 17void window_set_texture(AlbaWindow* window, const WGPUTexture texture)
 18{
 19    DrawCall* draw_call = alba_array_last(&window->draw_calls);
 20    if (draw_call->texture_set)
 21    {
 22        draw_call = window_create_draw_call(window);
 23    }
 24    draw_call_set_texture(draw_call, texture);
 25    draw_call->texture_set = 1;
 26}
 27
 28void window_clear(AlbaWindow* window)
 29{
 30    alba_array_clear(&window->draw_calls);
 31}
 32
 33void clear_texture_bind_group(const DrawCall* draw_call)
 34{
 35    wgpuBindGroupRelease(draw_call->bind_group);
 36}
 37
 38void draw_call_set_texture(DrawCall* draw_call, const WGPUTexture texture)
 39{
 40    if (draw_call->view != NULL)
 41    {
 42        wgpuTextureViewRelease(draw_call->view);
 43    }
 44    if (draw_call->texture != NULL)
 45    {
 46        wgpuTextureDestroy(draw_call->texture);
 47        wgpuTextureRelease(draw_call->texture);
 48    }
 49
 50    draw_call->texture = texture;
 51    draw_call->view = wgpuTextureCreateView(draw_call->texture, NULL);
 52    draw_call->bind_group_dirty = 1;
 53}
 54
 55void draw_call_update_bind_group(const AlbaWindow* window, DrawCall* draw_call)
 56{
 57    WGPUBindGroupEntry bind_group_entries[2] = {0};
 58
 59    // Texture
 60    if (draw_call->texture == NULL)
 61    {
 62        draw_call_set_texture(
 63            draw_call,
 64            // 1x1 white texture
 65            create_texture(
 66                window,
 67                WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst,
 68                (AlbaVector){1, 1},
 69                WGPUTextureFormat_RGBA8UnormSrgb, 1,
 70                &(AlbaColor)WHITE
 71            )
 72        );
 73    }
 74
 75    // @binding(1)
 76    bind_group_entries[0].binding = 0; // @group(1) @binding(0)
 77    bind_group_entries[0].textureView = draw_call->view;
 78
 79    // Sampler
 80    if (draw_call->sampler == NULL)
 81    {
 82        WGPUSamplerDescriptor sampler_options = {0};
 83        sampler_options.addressModeU = WGPUAddressMode_ClampToEdge;
 84        sampler_options.addressModeV = WGPUAddressMode_ClampToEdge;
 85        sampler_options.addressModeW = WGPUAddressMode_ClampToEdge;
 86        sampler_options.magFilter = WGPUFilterMode_Linear;
 87        sampler_options.minFilter = WGPUFilterMode_Linear;
 88        sampler_options.mipmapFilter = WGPUMipmapFilterMode_Linear;
 89        sampler_options.lodMinClamp = 0;
 90        sampler_options.lodMaxClamp = 1;
 91        sampler_options.maxAnisotropy = 1;
 92        draw_call->sampler = wgpuDeviceCreateSampler(window->device, &sampler_options);
 93    }
 94
 95    // @binding(2)
 96    bind_group_entries[1].binding = 1; // @group(1) @binding(1)
 97    bind_group_entries[1].sampler = draw_call->sampler;
 98
 99    WGPUBindGroupDescriptor binding_group_options = {0};
100    binding_group_options.layout = window->texture_bind_group_layout;
101    binding_group_options.entryCount = 2;
102    binding_group_options.entries = bind_group_entries;
103
104    if (draw_call->bind_group != NULL)
105    {
106        wgpuBindGroupRelease(draw_call->bind_group);
107    }
108    draw_call->bind_group = wgpuDeviceCreateBindGroup(window->device, &binding_group_options);
109}
110
111void draw_call_release(const DrawCall* draw_call)
112{
113    wgpuBufferDestroy(draw_call->vertices);
114    wgpuBufferRelease(draw_call->vertices);
115    alba_array_release(&draw_call->new_vertices);
116
117    wgpuBufferDestroy(draw_call->attributes);
118    wgpuBufferRelease(draw_call->attributes);
119    alba_array_release(&draw_call->new_attributes);
120
121    wgpuBufferDestroy(draw_call->indices);
122    wgpuBufferRelease(draw_call->indices);
123    alba_array_release(&draw_call->new_indices);
124
125    wgpuTextureViewRelease(draw_call->view);
126    wgpuTextureDestroy(draw_call->texture);
127    wgpuTextureRelease(draw_call->texture);
128    wgpuSamplerRelease(draw_call->sampler);
129    wgpuBindGroupRelease(draw_call->bind_group);
130}