huh/source/main.c

229 lines
4.9 KiB
C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#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",
};
}