-
Notifications
You must be signed in to change notification settings - Fork 24
/
clear_screen.c
161 lines (135 loc) · 4.15 KB
/
clear_screen.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "example_base.h"
#include <string.h>
/* -------------------------------------------------------------------------- *
* WebGPU Example - Clear Screen
*
* This example shows how to set up a swap chain and clearing the screen.
*
* Ref:
* https://tsherif.github.io/webgpu-examples
* https://github.com/tsherif/webgpu-examples/blob/gh-pages/blank.html
* -------------------------------------------------------------------------- */
// Render pass descriptor for frame buffer writes
static struct {
WGPURenderPassColorAttachment color_attachments[1];
WGPURenderPassDescriptor descriptor;
} render_pass = {0};
// Other variables
static const char* example_title = "Clear Screen";
static bool prepared = false;
static void setup_render_pass(wgpu_context_t* wgpu_context)
{
UNUSED_VAR(wgpu_context);
// Color attachment
render_pass.color_attachments[0] = (WGPURenderPassColorAttachment) {
.view = NULL, /* Assigned later */
.depthSlice = ~0,
.loadOp = WGPULoadOp_Clear,
.storeOp = WGPUStoreOp_Store,
.clearValue = (WGPUColor) {
.r = 1.0f,
.g = 1.0f,
.b = 1.0f,
.a = 1.0f,
},
};
// Render pass descriptor
render_pass.descriptor = (WGPURenderPassDescriptor){
.label = "Render pass descriptor",
.colorAttachmentCount = 1,
.colorAttachments = render_pass.color_attachments,
.depthStencilAttachment = NULL,
};
}
static int example_initialize(wgpu_example_context_t* context)
{
if (context) {
// Setup render pass
setup_render_pass(context->wgpu_context);
prepared = true;
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
static WGPUColor lerp(WGPUColor* a, WGPUColor* b, float t)
{
return (WGPUColor){
.r = (1 - t) * a->r + t * b->r,
.g = (1 - t) * a->g + t * b->g,
.b = (1 - t) * a->b + t * b->b,
};
}
static WGPUCommandBuffer build_command_buffer(wgpu_example_context_t* context)
{
render_pass.color_attachments[0].view
= context->wgpu_context->swap_chain.frame_buffer;
/* Figure out how far along duration we are, between 0.0 and 1.0 */
const float t = cos(context->frame.timestamp_millis * 0.001f) * 0.5f + 0.5f;
/* Interpolate between two colors */
render_pass.color_attachments[0].clearValue = lerp(
&(WGPUColor){
.r = 0.0f,
.g = 0.0f,
.b = 0.0f,
},
&(WGPUColor){
.r = 1.0f,
.g = 1.0f,
.b = 1.0f,
},
t);
/* Create command encoder */
WGPUCommandEncoder cmd_encoder
= wgpuDeviceCreateCommandEncoder(context->wgpu_context->device, NULL);
/* Create render pass */
WGPURenderPassEncoder rpass
= wgpuCommandEncoderBeginRenderPass(cmd_encoder, &render_pass.descriptor);
/* End render pass */
wgpuRenderPassEncoderEnd(rpass);
WGPU_RELEASE_RESOURCE(RenderPassEncoder, rpass)
/* Get command buffer */
WGPUCommandBuffer command_buffer = wgpu_get_command_buffer(cmd_encoder);
ASSERT(command_buffer != NULL)
WGPU_RELEASE_RESOURCE(CommandEncoder, cmd_encoder)
return command_buffer;
}
static int example_draw(wgpu_example_context_t* context)
{
// Prepare frame
prepare_frame(context);
// Command buffer to be submitted to the queue
wgpu_context_t* wgpu_context = context->wgpu_context;
wgpu_context->submit_info.command_buffer_count = 1;
wgpu_context->submit_info.command_buffers[0] = build_command_buffer(context);
// Submit command buffer to queue
submit_command_buffers(context);
// Submit frame
submit_frame(context);
return EXIT_SUCCESS;
}
static int example_render(wgpu_example_context_t* context)
{
if (!prepared) {
return EXIT_FAILURE;
}
return example_draw(context);
}
// Clean up used resources
static void example_destroy(wgpu_example_context_t* context)
{
UNUSED_VAR(context);
}
void example_clear_screen(int argc, char* argv[])
{
// clang-format off
example_run(argc, argv, &(refexport_t){
.example_settings = (wgpu_example_settings_t){
.title = example_title,
.vsync = true,
},
.example_initialize_func = &example_initialize,
.example_render_func = &example_render,
.example_destroy_func = &example_destroy,
});
// clang-format on
}