Skip to content

Commit

Permalink
add new shared-bindings-sapp sample
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Oct 26, 2024
1 parent a4731a0 commit 2053f5e
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 0 deletions.
1 change: 1 addition & 0 deletions fips-files/verbs/webpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def get_build_config(api):
[ 'primtypes', 'primtypes-sapp.c', 'primtypes-sapp.glsl'],
[ 'uvwrap', 'uvwrap-sapp.c', 'uvwrap-sapp.glsl'],
[ 'mipmap', 'mipmap-sapp.c', 'mipmap-sapp.glsl'],
[ 'shared-bindings', 'shared-bindings-sapp.c', 'shared-bindings-sapp.glsl' ],
[ 'uniformtypes', 'uniformtypes-sapp.c', 'uniformtypes-sapp.glsl' ],
[ 'blend', 'blend-sapp.c', 'blend-sapp.glsl' ],
[ 'sdf', 'sdf-sapp.c', 'sdf-sapp.glsl'],
Expand Down
14 changes: 14 additions & 0 deletions sapp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,20 @@ fips_begin_app(dyntex-sapp-ui windowed)
target_compile_definitions(dyntex-sapp-ui PRIVATE USE_DBG_UI)
fips_end_app()

fips_ide_group(Samples)
fips_begin_app(shared-bindings-sapp windowed)
fips_files(shared-bindings-sapp.c)
sokol_shader(shared-bindings-sapp.glsl ${slang})
fips_deps(sokol)
fips_end_app()
fips_ide_group(SamplesWithDebugUI)
fips_begin_app(shared-bindings-sapp-ui windowed)
fips_files(shared-bindings-sapp.c)
sokol_shader(shared-bindings-sapp.glsl ${slang})
fips_deps(sokol dbgui)
target_compile_definitions(shared-bindings-sapp-ui PRIVATE USE_DBG_UI)
fips_end_app()

fips_ide_group(Samples)
fips_begin_app(mipmap-sapp windowed)
fips_files(mipmap-sapp.c)
Expand Down
223 changes: 223 additions & 0 deletions sapp/shared-bindings-sapp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
//------------------------------------------------------------------------------
// sharedbindings-sapp.c
//
// Test/demonstrate how to share a common sg_bindings struct between
// different shaders using explicit bindslots, and also test that
// gaps between bind slots work.
//------------------------------------------------------------------------------
#define HANDMADE_MATH_IMPLEMENTATION
#define HANDMADE_MATH_NO_SSE
#include "HandmadeMath.h"
#include "sokol_gfx.h"
#include "sokol_app.h"
#include "sokol_log.h"
#include "sokol_glue.h"
#include "dbgui/dbgui.h"
#include "shared-bindings-sapp.glsl.h"

#define RED_CUBE (0)
#define GREEN_CUBE (1)
#define BLUE_CUBE (2)
#define NUM_CUBES (3)

static struct {
float rx, ry;
sg_bindings bind;
sg_pipeline pip[NUM_CUBES];
sg_pass_action pass_action;
} state;

typedef struct {
float x, y, z;
uint32_t color;
int16_t u, v;
} vertex_t;

static hmm_mat4 compute_mvp(void);

static void init(void) {
sg_setup(&(sg_desc){
.environment = sglue_environment(),
.logger.func = slog_func,
});
__dbgui_setup(sapp_sample_count());

// pass action for clearing the framebuffer
state.pass_action = (sg_pass_action){
.colors[0] = { .load_action = SG_LOADACTION_CLEAR, .clear_value = { 0.0f, 0.0f, 0.0f, 1.0f } },
};

// a cube vertex buffer
vertex_t vertices[] = {
// pos color uvs
{ -1.0f, -1.0f, -1.0f, 0xFFFFFFFF, 0, 0 },
{ 1.0f, -1.0f, -1.0f, 0xFFFFFFFF, 32767, 0 },
{ 1.0f, 1.0f, -1.0f, 0xFFFFFFFF, 32767, 32767 },
{ -1.0f, 1.0f, -1.0f, 0xFFFFFFFF, 0, 32767 },

{ -1.0f, -1.0f, 1.0f, 0xFFDDDDDD, 0, 0 },
{ 1.0f, -1.0f, 1.0f, 0xFFDDDDDD, 32767, 0 },
{ 1.0f, 1.0f, 1.0f, 0xFFDDDDDD, 32767, 32767 },
{ -1.0f, 1.0f, 1.0f, 0xFFDDDDDD, 0, 32767 },

{ -1.0f, -1.0f, -1.0f, 0xFFBBBBBB, 0, 0 },
{ -1.0f, 1.0f, -1.0f, 0xFFBBBBBB, 32767, 0 },
{ -1.0f, 1.0f, 1.0f, 0xFFBBBBBB, 32767, 32767 },
{ -1.0f, -1.0f, 1.0f, 0xFFBBBBBB, 0, 32767 },

{ 1.0f, -1.0f, -1.0f, 0xFF999999, 0, 0 },
{ 1.0f, 1.0f, -1.0f, 0xFF999999, 32767, 0 },
{ 1.0f, 1.0f, 1.0f, 0xFF999999, 32767, 32767 },
{ 1.0f, -1.0f, 1.0f, 0xFF999999, 0, 32767 },

{ -1.0f, -1.0f, -1.0f, 0xFF777777, 0, 0 },
{ -1.0f, -1.0f, 1.0f, 0xFF777777, 32767, 0 },
{ 1.0f, -1.0f, 1.0f, 0xFF777777, 32767, 32767 },
{ 1.0f, -1.0f, -1.0f, 0xFF777777, 0, 32767 },

{ -1.0f, 1.0f, -1.0f, 0xFF555555, 0, 0 },
{ -1.0f, 1.0f, 1.0f, 0xFF555555, 32767, 0 },
{ 1.0f, 1.0f, 1.0f, 0xFF555555, 32767, 32767 },
{ 1.0f, 1.0f, -1.0f, 0xFF555555, 0, 32767 },
};
state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
.data = SG_RANGE(vertices),
.label = "cube-vertices"
});

// create an index buffer for the cube
uint16_t indices[] = {
0, 1, 2, 0, 2, 3,
6, 5, 4, 7, 6, 4,
8, 9, 10, 8, 10, 11,
14, 13, 12, 15, 14, 12,
16, 17, 18, 16, 18, 19,
22, 21, 20, 23, 22, 20
};
state.bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
.type = SG_BUFFERTYPE_INDEXBUFFER,
.data = SG_RANGE(indices),
.label = "cube-indices"
});

// create 3 textures, shaders and pipeline objects
for (int i = 0; i < NUM_CUBES; i++) {
int img_slot, smp_slot;
uint32_t color;
const char* label;
sg_shader shd;
switch (i) {
case RED_CUBE:
img_slot = IMG_tex_red;
smp_slot = SMP_smp_red;
color = 0xFF0000FF;
label = "red";
shd = sg_make_shader(red_shader_desc(sg_query_backend()));
break;
case GREEN_CUBE:
img_slot = IMG_tex_green;
smp_slot = SMP_smp_green;
color = 0xFF00FF00;
label = "green";
shd = sg_make_shader(green_shader_desc(sg_query_backend()));
break;
default:
img_slot = IMG_tex_blue;
smp_slot = SMP_smp_blue;
color = 0xFFFF0000;
label = "blue";
shd = sg_make_shader(blue_shader_desc(sg_query_backend()));
break;
}
uint32_t pixels[4][4];
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
// make a checkerboard
pixels[y][x] = ((x ^ y) & 1) ? color : 0xFF000000;
}
}
state.bind.images[img_slot] = sg_make_image(&(sg_image_desc){
.width = 4,
.height = 4,
.data.subimage[0][0] = SG_RANGE(pixels),
.label = label,
});
state.bind.samplers[smp_slot] = sg_make_sampler(&(sg_sampler_desc){
.label = label,
});
state.pip[i] = sg_make_pipeline(&(sg_pipeline_desc){
.shader = shd,
.layout.attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT3,
[1].format = SG_VERTEXFORMAT_UBYTE4N,
[2].format = SG_VERTEXFORMAT_SHORT2N,
},
.index_type = SG_INDEXTYPE_UINT16,
.cull_mode = SG_CULLMODE_BACK,
.depth = {
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
},
.label = label,
});
}
}

static void frame(void) {
const float dt = (float)(sapp_frame_duration() * 60.0);
const float dw = sapp_widthf();
const float dh = sapp_heightf();

state.rx += 1.0f * dt; state.ry += 2.0f * dt;

const vs_params_t vs_params = { .mvp = compute_mvp() };

const float vpw = dw * 0.333f;
const float vph = vpw;
const float vpy = dh * 0.5f - vph * 0.5f;

sg_begin_pass(&(sg_pass){ .action = state.pass_action, .swapchain = sglue_swapchain() });
for (int i = 0; i < 3; i++) {
const float vpx = dw * 0.5f - 1.5f * vpw + i * vpw;
sg_apply_viewportf(vpx, vpy, vpw, vph, true);
sg_apply_pipeline(state.pip[i]);
sg_apply_bindings(&state.bind);
sg_apply_uniforms(UB_vs_params, &SG_RANGE(vs_params));
sg_draw(0, 36, 1);
}
__dbgui_draw();
sg_end_pass();
sg_commit();
}

static void cleanup(void) {
__dbgui_shutdown();
sg_shutdown();
}

static hmm_mat4 compute_mvp(void) {
hmm_mat4 proj = HMM_Perspective(60.0f, 1.0f, 0.01f, 10.0f);
hmm_mat4 view = HMM_LookAt(HMM_Vec3(0.0f, 0.0f, 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);
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);
return HMM_MultiplyMat4(view_proj, model);
}

sapp_desc sokol_main(int argc, char* argv[]) {
(void)argc;
(void)argv;
return (sapp_desc){
.init_cb = init,
.frame_cb = frame,
.cleanup_cb = cleanup,
.event_cb = __dbgui_event,
.width = 800,
.height = 600,
.sample_count = 4,
.window_title = "shared-bindings-sapp.c",
.icon.sokol_default = true,
.logger.func = slog_func,
};
}
63 changes: 63 additions & 0 deletions sapp/shared-bindings-sapp.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
@ctype mat4 hmm_mat4

@vs vs
layout(binding=0) uniform vs_params {
mat4 mvp;
};

layout(location=0) in vec4 pos;
layout(location=1) in vec4 color0;
layout(location=2) in vec2 texcoord0;

out vec4 color;
out vec2 uv;

void main() {
gl_Position = mvp * pos;
color = color0;
uv = texcoord0 * 5.0;
}
@end

@fs fs_red
layout(binding=0) uniform texture2D tex_red;
layout(binding=8) uniform sampler smp_red;

in vec4 color;
in vec2 uv;
out vec4 frag_color;

void main() {
frag_color = texture(sampler2D(tex_red, smp_red), uv) * color;
}
@end

@fs fs_green
layout(binding=2) uniform texture2D tex_green;
layout(binding=4) uniform sampler smp_green;

in vec4 color;
in vec2 uv;
out vec4 frag_color;

void main() {
frag_color = texture(sampler2D(tex_green, smp_green), uv) * color;
}
@end

@fs fs_blue
layout(binding=4) uniform texture2D tex_blue;
layout(binding=2) uniform sampler smp_blue;

in vec4 color;
in vec2 uv;
out vec4 frag_color;

void main() {
frag_color = texture(sampler2D(tex_blue, smp_blue), uv) * color;
}
@end

@program red vs fs_red
@program green vs fs_green
@program blue vs fs_blue
Binary file added webpage/shared-bindings.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2053f5e

Please sign in to comment.