#include #include #include #include #ifdef PLATFORM_WINDOWS #define SOKOL_D3D11 #elifdef PLATFORM_MACOS #define SOKOL_METAL #elifdef PLATFORM_LINUX #define SOKOL_GLCORE #elifdef PLATFORM_WASM #define SOKOL_GLES3 #else #error "unsupported platform" #endif #define SOKOL_IMPL #include "sokol/sokol_app.h" #include "sokol/sokol_gfx.h" #include "sokol/sokol_glue.h" #include "sokol/sokol_log.h" #include "sokol/util/sokol_debugtext.h" #include "base.c" #include "arena.c" #include "math.c" #include "basic.glsl.h" typedef struct { Matrix model; Matrix view; Matrix proj; } UBO; sg_pass_action pass_action; sg_bindings g_bind; sg_pipeline g_pipeline; s64 g_frame = 0; UBO g_ubo; Matrix g_proj; Vec3 g_camera; static void init(void) { scope_exit { printf("leaving init...\n"); }; sg_setup(&(sg_desc){ .environment = sglue_environment(), .logger.func = slog_func, }); g_proj = make_proj_matrix(90, 1280, 720, 0.01, 100.0); g_camera = (Vec3){0, 0, -1.0}; float vertices[] = { -0.5, 0.5, -0.5, 1.0, 1.0, 1.0, 1.0, -0.5, -0.5, -0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 0.5, -0.5, 0.0, 0.0, 1.0, 1.0, 0.5, -0.5, -0.5, 1.0, 0.0, 1.0, 1.0, -0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, -0.5, -0.5, 0.5, 1.0, 1.0, 0.0, 1.0, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.5, -0.5, 0.5, 0.0, 1.0, 0.0, 1.0 }; u32 indices[] = { 0, 2, 1, 1, 2, 3, // back 0, 1, 4, 4, 1, 5, // left 3, 2, 6, 6, 7, 3, // right 2, 0, 6, 6, 0, 4, // top 1, 3, 7, 7, 5, 1, // bot 4, 5, 6, 6, 5, 7, // front }; g_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ .usage = {.dynamic_update = true}, .size = 1024, .label = "cube vertices", }); g_bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){ .data = SG_RANGE(indices), .usage = {.index_buffer = true}, .label = "cube indices", }); sg_shader shader = sg_make_shader(basic_shader_desc(sg_query_backend())); g_pipeline = sg_make_pipeline(&(sg_pipeline_desc){ .shader = shader, .layout = { .attrs = { [ATTR_basic_pos].format = SG_VERTEXFORMAT_FLOAT3, [ATTR_basic_vcolor].format = SG_VERTEXFORMAT_FLOAT4, }, }, .cull_mode = SG_CULLMODE_BACK, .index_type = SG_INDEXTYPE_UINT32, .label = "cube pipeline", }); pass_action = (sg_pass_action) { .colors[0] = { .load_action = SG_LOADACTION_CLEAR, .clear_value = { 1.0f, 0.0f, 0.0f, 1.0f } } }; sdtx_setup(&(sdtx_desc_t){ .fonts = { [0] = sdtx_font_kc853(), [1] = sdtx_font_kc854(), [2] = sdtx_font_z1013(), [3] = sdtx_font_cpc(), [4] = sdtx_font_c64(), [5] = sdtx_font_oric(), }, }); } static void frame(void) { sg_begin_pass(&(sg_pass){ .action.colors[0] = { .load_action = SG_LOADACTION_CLEAR, .clear_value = { 0.10f, 0.10f, 0.10f, 1.0f }, }, .swapchain = sglue_swapchain(), }); sdtx_origin(0, 0); sdtx_canvas(sapp_widthf(), sapp_heightf()); sdtx_font(3); sdtx_pos(1, 1); sdtx_color3b(0, 0xFF, 0); sdtx_puts("press escape to quit"); sdtx_draw(); float vertices[] = { -0.5, 0.5, -0.5, 1.0, 1.0, 1.0, 1.0, -0.5, -0.5, -0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 0.5, -0.5, 0.0, 1.0, 1.0, 1.0, 0.5, -0.5, -0.5, 0.0, 0.0, 1.0, 1.0, -0.5, 0.5, 0.5, 1.0, 1.0, 0.0, 1.0, -0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 1.0 }; // get angle from frame number // wrap to angle s64 rate = 333; s64 wframe = g_frame; if(wframe >= TAU32*rate) wframe -= TAU32*rate; float angle = (f32)wframe/rate; Matrix rot = make_rotation((Vec3){0.0, 1.0, 0.0}, angle); Vec3 p; for(int i = 0; i < 8; ++i) { int vertex = i*7; p = (Vec3){vertices[vertex + 0], vertices[vertex + 1], vertices[vertex + 2]}; p = m4v3_mul(rot, p); vertices[vertex + 0] = p.x; vertices[vertex + 1] = p.y; vertices[vertex + 2] = p.z; } sg_update_buffer(g_bind.vertex_buffers[0], &SG_RANGE(vertices)); sg_apply_pipeline(g_pipeline); sg_apply_bindings(&g_bind); Matrix model = make_translation((Vec3){0, 0, 0}); Matrix lookat = make_lookat(g_camera, (Vec3){0, 0, 0}, (Vec3){0, 1, 0}); g_ubo.model = model; g_ubo.view = lookat; g_ubo.proj = g_proj; sg_apply_uniforms(UB_UBO, &SG_RANGE(g_ubo)); sg_draw(0, 36, 1); sg_end_pass(); sg_commit(); g_frame += 1; } static void cleanup(void) { sdtx_shutdown(); sg_shutdown(); } static void event(const sapp_event* event) { if (event->type == SAPP_EVENTTYPE_KEY_DOWN) { if (event->key_code == SAPP_KEYCODE_ESCAPE) { sapp_request_quit(); } } } sapp_desc sokol_main(int argc, char* argv[]) { return (sapp_desc) { .init_cb = init, .frame_cb = frame, .cleanup_cb = cleanup, .event_cb = event, .logger.func = slog_func, .width = 1280, .height = 720, .window_title = "hello, world", }; }