// Copyright(C) 2019 Lars Pontoppidan. All rights reserved. // Use of this source code is governed by an MIT license file distributed with this software package module main import time import sokol import sokol.sapp import sokol.gfx import sokol.sgl import particle const ( used_import = sokol.used_import ) fn main() { mut app := &App{ width: 800 height: 400 pass_action: gfx.create_clear_pass(0.1, 0.1, 0.1, 1.0) } app.init() app.run() } struct App { pass_action C.sg_pass_action mut: width int height int frame i64 last i64 ps particle.System alpha_pip C.sgl_pipeline } fn (mut a App) init() { a.frame = 0 a.last = time.ticks() a.ps = particle.System{ width: a.width height: a.height } a.ps.init(particle.SystemConfig{ pool: 20000 }) } fn (mut a App) cleanup() { a.ps.free() } fn (mut a App) run() { title := 'V Particle Example' desc := C.sapp_desc{ width: a.width height: a.height user_data: a init_userdata_cb: init frame_userdata_cb: frame event_userdata_cb: event window_title: title.str html5_canvas_name: title.str cleanup_userdata_cb: cleanup } sapp.run(&desc) } fn (a App) draw() { sgl.load_pipeline(a.alpha_pip) a.ps.draw() } fn init(user_data voidptr) { mut app := &App(user_data) desc := sapp.create_desc() gfx.setup(&desc) sgl_desc := C.sgl_desc_t{ max_vertices: 50 * 65536 } sgl.setup(&sgl_desc) mut pipdesc := C.sg_pipeline_desc{} unsafe {C.memset(&pipdesc, 0, sizeof(pipdesc))} pipdesc.blend.enabled = true pipdesc.blend.src_factor_rgb = C.SG_BLENDFACTOR_SRC_ALPHA pipdesc.blend.dst_factor_rgb = C.SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA app.alpha_pip = sgl.make_pipeline(&pipdesc) } fn cleanup(user_data voidptr) { mut app := &App(user_data) app.cleanup() gfx.shutdown() } fn frame(user_data voidptr) { mut app := &App(user_data) app.width = sapp.width() app.height = sapp.height() t := time.ticks() dt := f64(t - app.last) / 1000.0 app.ps.update(dt) draw(app) gfx.begin_default_pass(&app.pass_action, app.width, app.height) sgl.default_pipeline() sgl.draw() gfx.end_pass() gfx.commit() app.frame++ app.last = t } fn event(ev &C.sapp_event, user_data voidptr) { mut app := &App(user_data) if ev.@type == .mouse_move { app.ps.explode(ev.mouse_x, ev.mouse_y) } if ev.@type == .mouse_up || ev.@type == .mouse_down { if ev.mouse_button == .left { is_pressed := ev.@type == .mouse_down if is_pressed { app.ps.explode(ev.mouse_x, ev.mouse_y) } } } if ev.@type == .key_up || ev.@type == .key_down { if ev.key_code == .r { is_pressed := ev.@type == .key_down if is_pressed { app.ps.reset() } } } if ev.@type == .touches_began || ev.@type == .touches_moved { if ev.num_touches > 0 { touch_point := ev.touches[0] app.ps.explode(touch_point.pos_x, touch_point.pos_y) } } } fn draw(a &App) { sgl.defaults() sgl.matrix_mode_projection() sgl.ortho(0, f32(sapp.width()), f32(sapp.height()), 0.0, -1.0, 1.0) sgl.push_matrix() a.draw() sgl.pop_matrix() }