#include "app.hpp" #include "model.hpp" #include "ui.hpp" #include "video.hpp" extern "C" { #include "plat.h" #include "memory.h" } #include #include #define video_arena_size (1024 * 1024 * 16) #define asset_arena_size (1024 * 1024 * 4) #define ui_arena_size (1024 * 16) #define per_frame_memory_size (1024 * 1024) static float verts[] = { 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f }; struct C2 : public App { Device* dev; void on_resize() override { dev->on_resize(); } }; static Buffer_Id upload_verts(Device* dev) { Buffer_Id stage = dev->create_buffer( "temp", sizeof verts, Buffer_Flags::copy_src | Buffer_Flags::cpu_readwrite ); Buffer_Id vbo = dev->create_buffer( "autism triangle vbo", sizeof verts, Buffer_Flags::vertex_buffer | Buffer_Flags::copy_dst ); { void* mem; mem = dev->map_buffer(stage, 0, sizeof verts); memcpy(mem, verts, sizeof verts); dev->unmap_buffer(stage); } { Context& ctx = dev->acquire(); ctx.copy(vbo, stage); dev->submit(ctx); } dev->destroy_bufferi(stage); return vbo; } static Sampler_Id create_clamped_linear(Device* dev) { Sampler_State s{}; s.min = Filter_Mode::linear; s.mag = Filter_Mode::linear; s.address_u = Address_Mode::repeat; s.address_v = Address_Mode::repeat; return dev->create_sampler("repeated linear", s); } struct Config_Buffer { float offset[2]; }; struct Config_Buffer2 { m4f transform; m4f projection; }; extern "C" int entrypoint() { Arena video_arena, asset_arena, ui_arena; Model_Loader model_loader; Asset_Arena assets; Device* dev; Shader* shader, * ui_shader; Texture* texture; Texture* texture2; Model* monkey; Buffer_Id vbo, cbuf; Sampler_Id clamped_linear; UI* ui; C2* app = App::create("c2"); void* per_frame; int frame = 0; app->running = 1; init_arena( &video_arena, arena_alloc(app->arena, video_arena_size), video_arena_size ); init_arena( &asset_arena, arena_alloc(app->arena, asset_arena_size), asset_arena_size ); init_arena( &ui_arena, arena_alloc(app->arena, ui_arena_size), ui_arena_size ); assets.init(&asset_arena, "pack", 128); dev = Device::create(&video_arena, app); model_loader.init(dev, &assets); register_asset_loader("MODL", &model_loader); monkey = (Model*)assets.load("monkey.mdl"); app->dev = dev; shader = (Shader*)assets.load("triangle.csh"); ui_shader = (Shader*)assets.load("ui.csh"); texture = (Texture*)assets.load("22.tex"); texture2 = (Texture*)assets.load("kita.tex"); cbuf = dev->create_buffer( "config buffer", sizeof(Config_Buffer), Buffer_Flags::constant_buffer | Buffer_Flags::cpu_readwrite ); per_frame = heap_alloc( dev->heap, per_frame_memory_size ); clamped_linear = create_clamped_linear(dev); ui = UI::create(dev, &ui_arena, ui_shader->id); assert(per_frame != 0); uint8_t r = 0; float rot = 0.0f; v3f raxis(0.0f, 1.0f, 0.0); vbo = upload_verts(dev); while (app->running) { Arena frame_arena; init_arena(&frame_arena, per_frame, per_frame_memory_size); app->begin(); dev->begin_frame(); ui->update(&frame_arena); { void* mem; mem = dev->map_buffer(cbuf, 0, sizeof(Config_Buffer)); Config_Buffer* c = (Config_Buffer*)mem; c->offset[0] = sinf((float)frame / 10.0f); c->offset[1] = cosf((float)frame / 30.0f); dev->unmap_buffer(cbuf); } Pipeline_Builder pb(&frame_arena, dev); pb.begin_rp(); pb.rp_target(dev->get_backbuffer(), { r, 0x00, 0xff, 0xff }); Render_Pass& pass = pb.build_rp(); pb.begin(); pb.shader(shader->id); pb.vertex_format(shader->vf); pb.texture( shader->descriptor_binding("colour_texture"), frame % 2? texture->id: texture2->id, clamped_linear ); pb.cbuffer( shader->descriptor_binding("config_buffer"), cbuf ); Pipeline& pip = pb.build(); Vertex_Buffer_Binding binding[] = {{ .id = vbo, .offset = 0, .target = shader->binding_index("verts") }, {}}; Draw draw{}; draw.verts = binding; draw.vertex_count = 3; draw.instance_count = 1; Context& ctx = dev->get_ctx(); ctx.debug_push("autism triangle"); ctx.submit(draw, pip, pass); ctx.debug_pop(); pb.begin_rp(); pb.rp_depth_target(dev->get_depth_target(), 1.0f); dev->get_ctx().submit(pb.build_rp()); pb.begin_rp(); pb.rp_depth_target(dev->get_depth_target(), Clear_Mode::restore); Render_Pass& depth_prepass = pb.build_rp(); pb.begin_rp(); pb.rp_target(dev->get_backbuffer(), Clear_Mode::restore); pb.rp_depth_target(dev->get_depth_target(), Clear_Mode::restore); Render_Pass& pass2 = pb.build_rp(); Texture& bb = dev->get_texture(dev->get_backbuffer()); m4f projection = m4f::pers( 70.0f, (float)bb.w / (float)bb.h, 0.01f, 100.0f ); m4f transform = (m4f::translate( m4f::identity(), v3f(0.0f, 0.0f, -5.0f) ) * m4f::rotate( m4f::identity(), rot, raxis )); monkey->update_transforms(); monkey->update_cbuffers( dev, transform, projection ); ctx.debug_push("depth prepass"); monkey->render( dev, &frame_arena, depth_prepass ); ctx.debug_pop(); ctx.debug_push("forward"); monkey->render( dev, &frame_arena, pass2 ); ctx.debug_pop(); ctx.debug_push("ui"); ui->render(&frame_arena, dev->get_backbuffer()); ctx.debug_pop(); r += 10; rot += 0.05f; frame++; dev->present(); app->end(); } ui->destroy(); assets.destroy(); dev->destroy_sampler(clamped_linear); dev->destroy_buffer(vbo); dev->destroy_buffer(cbuf); dev->destroy(); app->destroy(); return 0; }