119 lines
2.8 KiB
V
119 lines
2.8 KiB
V
import gg
|
|
import math
|
|
import time
|
|
import rand
|
|
|
|
const pwidth = 800
|
|
|
|
const pheight = 600
|
|
|
|
struct AppState {
|
|
mut:
|
|
gg &gg.Context = unsafe { nil }
|
|
istream_idx int
|
|
pixels [pheight][pwidth]gg.Color
|
|
}
|
|
|
|
@[direct_array_access]
|
|
fn (mut state AppState) update() {
|
|
for {
|
|
unsafe { vmemset(&state.pixels, 0, pwidth * pheight * sizeof[gg.Color]()) }
|
|
state.draw_sky() or {}
|
|
time.sleep(30_000 * time.millisecond)
|
|
}
|
|
}
|
|
|
|
fn (mut state AppState) draw_sky() ! {
|
|
for _ in 0 .. 2000 {
|
|
mut star_size := 1
|
|
for rand.i32_in_range(0, 100)! < 5 {
|
|
star_size += 10
|
|
}
|
|
for rand.i32_in_range(0, 100000)! < 5 {
|
|
star_size += 85
|
|
}
|
|
sx := if star_size < 10 {
|
|
rand.i32_in_range(-40, pwidth + 40)!
|
|
} else {
|
|
rand.i32_in_range(40, pwidth - 40)!
|
|
}
|
|
sy := if star_size < 10 {
|
|
rand.i32_in_range(-40, pheight + 40)!
|
|
} else {
|
|
rand.i32_in_range(40, pheight - 40)!
|
|
}
|
|
state.draw_star(sx, sy, gg.Color{
|
|
r: u8(rand.i32_in_range(50, 255)!)
|
|
g: u8(rand.i32_in_range(50, 255)!)
|
|
b: u8(rand.i32_in_range(50, 255)!)
|
|
}, star_size)
|
|
}
|
|
}
|
|
|
|
@[direct_array_access]
|
|
fn (mut state AppState) draw_star(x int, y int, c gg.Color, radius int) {
|
|
if radius == 0 {
|
|
return
|
|
}
|
|
minx := math.max(0, x - radius)
|
|
miny := math.max(0, y - radius)
|
|
maxx := math.min(pwidth, x + radius)
|
|
maxy := math.min(pheight, y + radius)
|
|
for cx in minx .. maxx {
|
|
for cy in miny .. maxy {
|
|
dx := math.abs[f32](cx - x) / f32(radius)
|
|
dy := math.abs[f32](cy - y) / f32(radius)
|
|
gradient := math.max[f32](0, math.min[f32](1, 1 - (math.sqrtf(dx) + math.sqrtf(dy))))
|
|
if gradient < 0.01 {
|
|
continue
|
|
}
|
|
mut pixel := unsafe { &state.pixels[cy][cx] }
|
|
color := gg.Color{
|
|
r: u8(math.min(255, int(pixel.r) + int(f32(c.r) * gradient)))
|
|
g: u8(math.min(255, int(pixel.g) + int(f32(c.g) * gradient)))
|
|
b: u8(math.min(255, int(pixel.b) + int(f32(c.b) * gradient)))
|
|
a: 255
|
|
}
|
|
unsafe {
|
|
*pixel = color
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn (mut state AppState) draw() {
|
|
mut istream_image := state.gg.get_cached_image_by_idx(state.istream_idx)
|
|
istream_image.update_pixel_data(unsafe { &u8(&state.pixels) })
|
|
size := gg.window_size()
|
|
sx := -50 + 50 * math.sinf(f32(state.gg.frame) / 100)
|
|
sy := -50 + 50 * math.cosf(f32(state.gg.frame) / 100)
|
|
scale := 200 + 50 * math.sinf(f32(state.gg.frame) / 300)
|
|
wx := size.width + scale
|
|
wy := size.height + scale
|
|
state.gg.draw_image(sx, sy, wx, wy, istream_image)
|
|
}
|
|
|
|
fn graphics_init(mut state AppState) {
|
|
state.istream_idx = state.gg.new_streaming_image(pwidth, pheight, 4, pixel_format: .rgba8)
|
|
}
|
|
|
|
fn graphics_frame(mut state AppState) {
|
|
state.gg.begin()
|
|
state.draw()
|
|
state.gg.end()
|
|
}
|
|
|
|
fn main() {
|
|
mut state := &AppState{}
|
|
state.gg = gg.new_context(
|
|
width: pwidth
|
|
height: pheight
|
|
window_title: 'Random stars'
|
|
init_fn: graphics_init
|
|
frame_fn: graphics_frame
|
|
user_data: state
|
|
)
|
|
spawn state.update()
|
|
state.gg.run()
|
|
}
|