v2 / examples / gg / random_stars.v
118 lines · 108 sloc · 2.83 KB · de4045d8ee609bb2aa349b748970606ec05ba90b
Raw
1import gg
2import math
3import time
4import rand
5
6const pwidth = 800
7
8const pheight = 600
9
10struct AppState {
11mut:
12 gg &gg.Context = unsafe { nil }
13 istream_idx int
14 pixels [pheight][pwidth]gg.Color
15}
16
17@[direct_array_access]
18fn (mut state AppState) update() {
19 for {
20 unsafe { vmemset(&state.pixels, 0, pwidth * pheight * sizeof[gg.Color]()) }
21 state.draw_sky() or {}
22 time.sleep(30_000 * time.millisecond)
23 }
24}
25
26fn (mut state AppState) draw_sky() ! {
27 for _ in 0 .. 2000 {
28 mut star_size := 1
29 for rand.i32_in_range(0, 100)! < 5 {
30 star_size += 10
31 }
32 for rand.i32_in_range(0, 100000)! < 5 {
33 star_size += 85
34 }
35 sx := if star_size < 10 {
36 rand.i32_in_range(-40, pwidth + 40)!
37 } else {
38 rand.i32_in_range(40, pwidth - 40)!
39 }
40 sy := if star_size < 10 {
41 rand.i32_in_range(-40, pheight + 40)!
42 } else {
43 rand.i32_in_range(40, pheight - 40)!
44 }
45 state.draw_star(sx, sy, gg.Color{
46 r: u8(rand.i32_in_range(50, 255)!)
47 g: u8(rand.i32_in_range(50, 255)!)
48 b: u8(rand.i32_in_range(50, 255)!)
49 }, star_size)
50 }
51}
52
53@[direct_array_access]
54fn (mut state AppState) draw_star(x int, y int, c gg.Color, radius int) {
55 if radius == 0 {
56 return
57 }
58 minx := math.max(0, x - radius)
59 miny := math.max(0, y - radius)
60 maxx := math.min(pwidth, x + radius)
61 maxy := math.min(pheight, y + radius)
62 for cx in minx .. maxx {
63 for cy in miny .. maxy {
64 dx := math.abs[f32](cx - x) / f32(radius)
65 dy := math.abs[f32](cy - y) / f32(radius)
66 gradient := math.max[f32](0, math.min[f32](1, 1 - (math.sqrtf(dx) + math.sqrtf(dy))))
67 if gradient < 0.01 {
68 continue
69 }
70 mut pixel := unsafe { &state.pixels[cy][cx] }
71 color := gg.Color{
72 r: u8(math.min(255, int(pixel.r) + int(f32(c.r) * gradient)))
73 g: u8(math.min(255, int(pixel.g) + int(f32(c.g) * gradient)))
74 b: u8(math.min(255, int(pixel.b) + int(f32(c.b) * gradient)))
75 a: 255
76 }
77 unsafe {
78 *pixel = color
79 }
80 }
81 }
82}
83
84fn (mut state AppState) draw() {
85 mut istream_image := state.gg.get_cached_image_by_idx(state.istream_idx)
86 istream_image.update_pixel_data(unsafe { &u8(&state.pixels) })
87 size := gg.window_size()
88 sx := -50 + 50 * math.sinf(f32(state.gg.frame) / 100)
89 sy := -50 + 50 * math.cosf(f32(state.gg.frame) / 100)
90 scale := 200 + 50 * math.sinf(f32(state.gg.frame) / 300)
91 wx := size.width + scale
92 wy := size.height + scale
93 state.gg.draw_image(sx, sy, wx, wy, istream_image)
94}
95
96fn graphics_init(mut state AppState) {
97 state.istream_idx = state.gg.new_streaming_image(pwidth, pheight, 4, pixel_format: .rgba8)
98}
99
100fn graphics_frame(mut state AppState) {
101 state.gg.begin()
102 state.draw()
103 state.gg.end()
104}
105
106fn main() {
107 mut state := &AppState{}
108 state.gg = gg.new_context(
109 width: pwidth
110 height: pheight
111 window_title: 'Random stars'
112 init_fn: graphics_init
113 frame_fn: graphics_frame
114 user_data: state
115 )
116 spawn state.update()
117 state.gg.run()
118}
119