Skip to content

Commit

Permalink
fix dyntex-wgpu sample
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Aug 19, 2023
1 parent 1961b47 commit 149866e
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 94 deletions.
11 changes: 5 additions & 6 deletions wgpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,11 @@ fips_begin_app(arraytex-wgpu windowed)
fips_deps(wgpu_entry)
fips_end_app()

#fips_begin_app(dyntex-wgpu windowed)
# fips_files(dyntex-wgpu.c)
# sokol_shader(dyntex-wgpu.glsl wgpu)
# fips_deps(wgpu_entry)
#fips_end_app()
#
fips_begin_app(dyntex-wgpu windowed)
fips_files(dyntex-wgpu.c)
fips_deps(wgpu_entry)
fips_end_app()

#fips_begin_app(uvwrap-wgpu windowed)
# fips_files(uvwrap-wgpu.c)
# sokol_shader(uvwrap-wgpu.glsl wgpu)
Expand Down
143 changes: 92 additions & 51 deletions wgpu/dyntex-wgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
// dyntex-wgpu.c
// Update dynamic texture with CPU-generated data each frame.
//------------------------------------------------------------------------------
#include "wgpu_entry.h"
#define HANDMADE_MATH_IMPLEMENTATION
#define HANDMADE_MATH_NO_SSE
#include "HandmadeMath.h"
#define SOKOL_IMPL
#define SOKOL_WGPU
#include "sokol_gfx.h"
#include "sokol_log.h"
#include "wgpu_entry.h"
#include "dyntex-wgpu.glsl.h"

#define SAMPLE_COUNT (4)
#define IMAGE_WIDTH (64)
Expand All @@ -26,14 +25,16 @@ static struct {
int update_count;
uint32_t rand_val;
uint32_t pixels[IMAGE_WIDTH][IMAGE_HEIGHT];
} state = {
.rand_val = 0x12345678
};
} state;

typedef struct {
hmm_mat4 mvp;
} vs_params_t;

static void game_of_life_init();
static void game_of_life_update();

/* pseudo-random number generator */
// pseudo-random number generator
static uint32_t xorshift32(void) {
state.rand_val ^= state.rand_val<<13;
state.rand_val ^= state.rand_val>>17;
Expand All @@ -46,54 +47,60 @@ static void init(void) {
.context = wgpu_get_context(),
.logger.func = slog_func,
});
state.rand_val = 0x12345678;

/* a 128x128 image with streaming update strategy */
// an image with streaming update strategy
sg_image img = sg_make_image(&(sg_image_desc){
.width = IMAGE_WIDTH,
.height = IMAGE_HEIGHT,
.pixel_format = SG_PIXELFORMAT_RGBA8,
.usage = SG_USAGE_STREAM,
.label = "dynamic-texture"
});

// ...and sampler
sg_sampler smp = sg_make_sampler(&(sg_sampler_desc){
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
.wrap_u = SG_WRAP_CLAMP_TO_EDGE,
.wrap_v = SG_WRAP_CLAMP_TO_EDGE,
.label = "dynamic-texture"
.label = "sampler",
});

/* cube vertex buffer */
float vertices[] = {
/* pos color uvs */
// cube vertex buffer
static const float vertices[] = {
// pos color uvs
-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,

-1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,

-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,

1.0f, -1.0f, -1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, -1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, -1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f, 1.0f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f,

-1.0f, -1.0f, -1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f,
-1.0f, -1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f,

-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 0.0f, 1.0f
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.5f, 1.0f, 0.0f, 1.0f
};
uint16_t indices[] = {
static const uint16_t indices[] = {
0, 1, 2, 0, 2, 3,
6, 5, 4, 7, 6, 4,
8, 9, 10, 8, 10, 11,
Expand All @@ -112,16 +119,49 @@ static void init(void) {
.label = "cube-indices"
});

/* a shader to render a textured cube */
sg_shader shd = sg_make_shader(dyntex_shader_desc(sg_query_backend()));
// a shader to render a textured cube
sg_shader shd = sg_make_shader(&(sg_shader_desc){
.vs = {
.uniform_blocks[0].size = sizeof(vs_params_t),
.source =
"struct vs_params {\n"
" mvp: mat4x4f,\n"
"}\n"
"@group(0) @binding(0) var<uniform> in: vs_params;\n"
"struct vs_out {\n"
" @builtin(position) pos: vec4f,\n"
" @location(0) color: vec4f,\n"
" @location(1) uv: vec2f,\n"
"}\n"
"@vertex fn main(@location(0) pos: vec4f, @location(1) color: vec4f, @location(2) uv: vec2f) -> vs_out {\n"
" var out: vs_out;\n"
" out.pos = in.mvp * pos;\n"
" out.color = color;\n"
" out.uv = uv;\n"
" return out;\n"
"}\n",
},
.fs = {
.images[0].used = true,
.samplers[0].used = true,
.image_sampler_pairs[0] = { .used = true, .image_slot = 0, .sampler_slot = 0 },
.source =
"@group(2) @binding(0) var tex: texture_2d<f32>;\n"
"@group(2) @binding(1) var smp: sampler;\n"
"@fragment fn main(@location(0) color: vec4f, @location(1) uv: vec2f) -> @location(0) vec4f {\n"
" return textureSample(tex, smp, uv) * color;\n"
"}\n",
},
.label = "cube-shader",
});

/* a pipeline state object */
// a pipeline state object
state.pip = sg_make_pipeline(&(sg_pipeline_desc){
.layout = {
.attrs = {
[ATTR_vs_position].format = SG_VERTEXFORMAT_FLOAT3,
[ATTR_vs_color0].format = SG_VERTEXFORMAT_FLOAT4,
[ATTR_vs_texcoord0].format = SG_VERTEXFORMAT_FLOAT2
[0].format = SG_VERTEXFORMAT_FLOAT3,
[1].format = SG_VERTEXFORMAT_FLOAT4,
[2].format = SG_VERTEXFORMAT_FLOAT2
}
},
.shader = shd,
Expand All @@ -134,42 +174,46 @@ static void init(void) {
.label = "cube-pipelin"
});

/* setup the resource bindings */
// setup the resource bindings
state.bind = (sg_bindings) {
.vertex_buffers[0] = vbuf,
.index_buffer = ibuf,
.fs_images[SLOT_tex] = img
.fs = {
.images[0] = img,
.samplers[0] = smp,
}
};

/* initialize the game-of-life state */
// initialize the game-of-life state
game_of_life_init();
}

void frame(void) {
/* compute model-view-projection matrix */
// compute model-view-projection matrix
hmm_mat4 proj = HMM_Perspective(60.0f, (float)wgpu_width()/(float)wgpu_height(), 0.01f, 10.0f);
hmm_mat4 view = HMM_LookAt(HMM_Vec3(0.0f, 1.5f, 4.0f), HMM_Vec3(0.0f, 0.0f, 0.0f), HMM_Vec3(0.0f, 1.0f, 0.0f));
hmm_mat4 view_proj = HMM_MultiplyMat4(proj, view);
vs_params_t vs_params;
state.rx += 0.1f; state.ry += 0.2f;
hmm_mat4 rxm = HMM_Rotate(state.rx, HMM_Vec3(1.0f, 0.0f, 0.0f));
hmm_mat4 rym = HMM_Rotate(state.ry, HMM_Vec3(0.0f, 1.0f, 0.0f));
hmm_mat4 model = HMM_MultiplyMat4(rxm, rym);
vs_params.mvp = HMM_MultiplyMat4(view_proj, model);
const vs_params_t vs_params = {
.mvp = HMM_MultiplyMat4(view_proj, model)
};

/* update game-of-life state */
// update game-of-life state
game_of_life_update();

/* update the texture */
sg_update_image(state.bind.fs_images[0], &(sg_image_data){
// update the texture
sg_update_image(state.bind.fs.images[0], &(sg_image_data){
.subimage[0][0] = SG_RANGE(state.pixels)
});

/* render the frame */
// render the frame
sg_begin_default_pass(&state.pass_action, wgpu_width(), wgpu_height());
sg_apply_pipeline(state.pip);
sg_apply_bindings(&state.bind);
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, &SG_RANGE(vs_params));
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &SG_RANGE(vs_params));
sg_draw(0, 36, 1);
sg_end_pass();
sg_commit();
Expand All @@ -184,8 +228,7 @@ void game_of_life_init() {
for (int x = 0; x < IMAGE_WIDTH; x++) {
if ((xorshift32() & 255) > 230) {
state.pixels[y][x] = LIVING;
}
else {
} else {
state.pixels[y][x] = DEAD;
}
}
Expand All @@ -206,19 +249,17 @@ void game_of_life_update() {
}
}
}
/* any live cell... */
// any live cell...
if (state.pixels[y][x] == LIVING) {
if (num_living_neighbours < 2) {
/* ... with fewer than 2 living neighbours dies, as if caused by underpopulation */
// ... with fewer than 2 living neighbours dies, as if caused by underpopulation
state.pixels[y][x] = DEAD;
}
else if (num_living_neighbours > 3) {
/* ... with more than 3 living neighbours dies, as if caused by overpopulation */
} else if (num_living_neighbours > 3) {
// ... with more than 3 living neighbours dies, as if caused by overpopulation
state.pixels[y][x] = DEAD;
}
}
else if (num_living_neighbours == 3) {
/* any dead cell with exactly 3 living neighbours becomes a live cell, as if by reproduction */
} else if (num_living_neighbours == 3) {
// any dead cell with exactly 3 living neighbours becomes a live cell, as if by reproduction
state.pixels[y][x] = LIVING;
}
}
Expand Down
36 changes: 0 additions & 36 deletions wgpu/dyntex-wgpu.glsl

This file was deleted.

2 changes: 1 addition & 1 deletion wgpu/texcube-wgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static void init(void) {
// create shader with WGSL source code
const sg_shader shd = sg_make_shader(&(sg_shader_desc){
.vs = {
.uniform_blocks[0] = { .size = 16 * 4 },
.uniform_blocks[0].size = sizeof(vs_params_t),
.source =
"struct vs_params {\n"
" mvp: mat4x4f,\n"
Expand Down

0 comments on commit 149866e

Please sign in to comment.