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}