1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
// 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)) }
color_state := C.sg_color_state{
blend: C.sg_blend_state{
enabled: true
src_factor_rgb: gfx.BlendFactor(C.SG_BLENDFACTOR_SRC_ALPHA)
dst_factor_rgb: gfx.BlendFactor(C.SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA)
}
}
pipdesc.colors[0] = color_state
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, mut app App) {
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()
}
|