Initial commit
This commit is contained in:
commit
dd58a721ec
8 changed files with 617 additions and 0 deletions
347
main.odin
Normal file
347
main.odin
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
package main
|
||||
|
||||
import "base:runtime"
|
||||
import "core:fmt"
|
||||
import "core:math"
|
||||
|
||||
double :: f64
|
||||
v2 :: [2]f32
|
||||
v3 :: [3]f32
|
||||
v4 :: [4]f32
|
||||
Color :: [4]byte
|
||||
|
||||
System :: struct {
|
||||
particle_number: int,
|
||||
index: int,
|
||||
tpage_size: int,
|
||||
vertices: [^]Vertex,
|
||||
instances: [^]Instance,
|
||||
}
|
||||
|
||||
Instance :: struct {
|
||||
life: int,
|
||||
image_uv_width: f32,
|
||||
image_index, image_speed, image_number: f32,
|
||||
position, speed, gravity: v3,
|
||||
image_blend, image_blend_add: v4,
|
||||
scale, grow: v2,
|
||||
image_angle, image_angle_speed: f32,
|
||||
hsv, hsv_add: v3,
|
||||
}
|
||||
|
||||
Vertex :: struct {
|
||||
position: v3,
|
||||
color: Color,
|
||||
texcoord: v2,
|
||||
offset: v3,
|
||||
scale: v2,
|
||||
angle: f32,
|
||||
rotation_direction: v3,
|
||||
animation: f32,
|
||||
hsv: v3,
|
||||
}
|
||||
|
||||
system_current: ^System
|
||||
|
||||
pem_show_error :: proc(message: string, loc: runtime.Source_Code_Location) {
|
||||
context = context
|
||||
fmt.println("Error (", loc.procedure, ") L", loc.line, ": ", message, sep = "")
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_get_size :: proc "c" (number: double) -> double {
|
||||
number := int(number)
|
||||
system := size_of(System)
|
||||
vertices := _projectile_system_get_vertex_buffer_size(number)
|
||||
instances := size_of(Instance) * number
|
||||
return double(system + vertices + instances)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_get_vertex_buffer_size :: proc "c" (number: double) -> double {
|
||||
return double(_projectile_system_get_vertex_buffer_size(int(number)))
|
||||
}
|
||||
|
||||
_projectile_system_get_vertex_buffer_size :: proc "c" (number: int) -> int {
|
||||
return size_of(Vertex) * 6 * number
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_get_vertex_buffer_offset :: proc "c" () -> double {
|
||||
return double(_projectile_system_get_vertex_buffer_offset())
|
||||
}
|
||||
|
||||
_projectile_system_get_vertex_buffer_offset :: proc "c" () -> int {
|
||||
return size_of(System)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_init :: proc "c" (memory: [^]byte, particle_number, tpage_size: double) {
|
||||
context = runtime.default_context()
|
||||
particle_number := int(particle_number)
|
||||
system := cast(^System)memory
|
||||
system.particle_number = particle_number
|
||||
system.tpage_size = int(tpage_size)
|
||||
system.index = 0
|
||||
vertex_buffer_offset := _projectile_system_get_vertex_buffer_offset()
|
||||
system.vertices = cast([^]Vertex)&memory[vertex_buffer_offset]
|
||||
instance_buffer_offset := vertex_buffer_offset + _projectile_system_get_vertex_buffer_size(particle_number)
|
||||
system.instances = cast([^]Instance)&memory[instance_buffer_offset]
|
||||
}
|
||||
|
||||
@(export)
|
||||
_pem_update :: proc "c" (system: ^System) {
|
||||
vertices := system.vertices
|
||||
instances := system.instances
|
||||
for i in 0 ..< system.particle_number {
|
||||
instances[i].life = max(instances[i].life - 1, -1)
|
||||
if instances[i].life == 0 {
|
||||
instances[i].grow = v2{0.0, 0.0}
|
||||
instances[i].image_blend.a = 0.0
|
||||
instances[i].image_blend_add.a = 0.0
|
||||
}
|
||||
|
||||
instances[i].speed += instances[i].gravity
|
||||
instances[i].position += instances[i].speed
|
||||
instances[i].image_blend += instances[i].image_blend_add
|
||||
instances[i].scale += instances[i].grow
|
||||
instances[i].image_angle += instances[i].image_angle_speed
|
||||
instances[i].image_index = math.wrap(instances[i].image_index + instances[i].image_speed, instances[i].image_number)
|
||||
instances[i].hsv = v3 {
|
||||
instances[i].hsv.x + instances[i].hsv_add.x,
|
||||
clamp(instances[i].hsv.y + instances[i].hsv_add.y, 0.0, 2.0),
|
||||
clamp(instances[i].hsv.z + instances[i].hsv_add.z, 0.0, 2.0),
|
||||
}
|
||||
offset := i * 6
|
||||
#unroll for j in 0 ..< 6 {
|
||||
vertices[offset + j].color = {
|
||||
u8(clamp(instances[i].image_blend.r, 0, 255)),
|
||||
u8(clamp(instances[i].image_blend.g, 0, 255)),
|
||||
u8(clamp(instances[i].image_blend.b, 0, 255)),
|
||||
u8(clamp(instances[i].image_blend.a, 0, 255)),
|
||||
}
|
||||
vertices[offset + j].offset = instances[i].position
|
||||
vertices[offset + j].scale = instances[i].scale
|
||||
vertices[offset + j].angle = instances[i].image_angle
|
||||
vertices[offset + j].animation = math.floor(instances[i].image_index) * instances[i].image_uv_width
|
||||
vertices[offset + j].hsv = instances[i].hsv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@(export)
|
||||
_pem_set :: proc "c" (system: ^System) {
|
||||
system_current = system
|
||||
}
|
||||
|
||||
Origin :: enum {
|
||||
TopLeft,
|
||||
TopMiddle,
|
||||
TopRight,
|
||||
MiddleLeft,
|
||||
Middle,
|
||||
MiddleRight,
|
||||
BottomLeft,
|
||||
BottomMiddle,
|
||||
BottomRight,
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_create_origin :: proc "c" (x, y, w, h, origin, uv_left, uv_top, uv_right, uv_bottom, image_number: double) -> double {
|
||||
xorigin, yorigin: double
|
||||
origin := Origin(int(origin))
|
||||
switch origin {
|
||||
case .TopLeft:
|
||||
xorigin = 0.0; yorigin = 0.0
|
||||
case .TopMiddle:
|
||||
xorigin = w / 2.0; yorigin = 0.0
|
||||
case .TopRight:
|
||||
xorigin = w; yorigin = 0.0
|
||||
case .MiddleLeft:
|
||||
xorigin = 0.0; yorigin = h / 2.0
|
||||
case .Middle:
|
||||
xorigin = w / 2.0; yorigin = h / 2.0
|
||||
case .MiddleRight:
|
||||
xorigin = w; yorigin = h / 2.0
|
||||
case .BottomLeft:
|
||||
xorigin = 0.0; yorigin = h
|
||||
case .BottomMiddle:
|
||||
xorigin = w; yorigin = h
|
||||
case .BottomRight:
|
||||
xorigin = w / 2.0; yorigin = h
|
||||
}
|
||||
return pem_instance_create(x, y, w, h, xorigin, yorigin, uv_left, uv_top, uv_right, uv_bottom, image_number)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_create :: proc "c" (x, y, w, h, xorigin, yorigin, uv_left, uv_top, uv_right, uv_bottom, image_number: double) -> double {
|
||||
position := v3{f32(x), f32(y), 1.0}
|
||||
size := v3{f32(w), f32(h), 1.0}
|
||||
origin := v3{f32(xorigin), f32(yorigin), 0.0}
|
||||
uv_left := f32(uv_left)
|
||||
uv_right := f32(uv_right)
|
||||
uv_top := f32(uv_top)
|
||||
uv_bottom := f32(uv_bottom)
|
||||
image_number := f32(max(0.0, image_number))
|
||||
|
||||
uv_tl := v2{uv_left, uv_top}
|
||||
uv_br := v2{uv_left + (uv_right - uv_left) / image_number, uv_bottom}
|
||||
|
||||
index := system_current.index
|
||||
offset := system_current.index * 6
|
||||
system_current.index = (system_current.index + 1) % system_current.particle_number
|
||||
system_current.instances[index] = {
|
||||
life = -1,
|
||||
image_uv_width = (uv_right - uv_left) / image_number,
|
||||
image_index = 0.0,
|
||||
image_number = image_number,
|
||||
image_speed = 1.0,
|
||||
position = position,
|
||||
image_blend = {255.0, 255.0, 255.0, 255.0},
|
||||
scale = {1.0, 1.0},
|
||||
image_angle = 0.0,
|
||||
hsv = {0.0, 1.0, 1.0},
|
||||
}
|
||||
|
||||
tl := v3{0.0, 0.0, 1.0}
|
||||
tr := v3{1.0, 0.0, 1.0}
|
||||
bl := v3{0.0, 1.0, 1.0}
|
||||
br := v3{1.0, 1.0, 1.0}
|
||||
pos := [6]v3{tl, bl, tr, tr, bl, br}
|
||||
#unroll for i in 0 ..< 6 {
|
||||
system_current.vertices[offset + i] = {
|
||||
position = pos[i] * size - origin,
|
||||
color = {255, 255, 255, 255},
|
||||
texcoord = math.lerp(uv_tl, uv_br, pos[i].xy),
|
||||
offset = system_current.instances[index].position,
|
||||
scale = system_current.instances[index].scale,
|
||||
angle = system_current.instances[index].image_angle,
|
||||
rotation_direction = v3{0.0, 0.0, -1.0},
|
||||
hsv = system_current.instances[index].hsv,
|
||||
}
|
||||
}
|
||||
return double(index)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_life :: proc "c" (id, life: double) {
|
||||
system_current.instances[int(id)].life = int(life)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_life_to_animation :: proc "c" (id, animation_count: double) {
|
||||
id := int(id)
|
||||
image_number_from_index := system_current.instances[id].image_number - system_current.instances[id].image_index
|
||||
if image_number_from_index <= 0.0 {
|
||||
context = runtime.default_context()
|
||||
pem_show_error("image number left is 0", #location())
|
||||
system_current.instances[id].life = -1
|
||||
return
|
||||
}
|
||||
system_current.instances[id].life = int(image_number_from_index / system_current.instances[id].image_speed) * int(animation_count)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_life_to_alpha_fade :: proc "c" (id: double) {
|
||||
id := int(id)
|
||||
a := system_current.instances[id].image_blend.a
|
||||
a_add := system_current.instances[id].image_blend_add.a
|
||||
if a <= 0.0 {
|
||||
context = runtime.default_context()
|
||||
pem_show_error("alpha started at 0.0 or lower", #location())
|
||||
system_current.instances[id].life = -1
|
||||
return
|
||||
}
|
||||
frames := int((a / a_add) * -1.0)
|
||||
if frames <= 0 {
|
||||
context = runtime.default_context()
|
||||
pem_show_error("alpha never reaches 0.0", #location())
|
||||
system_current.instances[id].life = -1
|
||||
return
|
||||
}
|
||||
system_current.instances[id].life = frames
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_life_to_shrink :: proc "c" (id: double) {
|
||||
id := int(id)
|
||||
scale := v2{system_current.instances[id].scale.x, system_current.instances[id].scale.y}
|
||||
grow := v2{system_current.instances[id].grow.x, system_current.instances[id].grow.y}
|
||||
frames := v2{scale.x / grow.x * -1.0, scale.y / grow.y * -1.0}
|
||||
frames_max := max(frames.x, frames.y)
|
||||
if frames_max <= 0.0 {
|
||||
context = runtime.default_context()
|
||||
pem_show_error("instance never shrinks in on itself", #location())
|
||||
system_current.instances[id].life = -1
|
||||
return
|
||||
}
|
||||
system_current.instances[id].life = int(frames_max)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_image_blend :: proc "c" (id, r, g, b, a: double) {
|
||||
system_current.instances[int(id)].image_blend = {f32(r), f32(g), f32(b), f32(a)} * 255.0
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_image_blend_add :: proc "c" (id, r, g, b, a: double) {
|
||||
system_current.instances[int(id)].image_blend_add = {f32(r), f32(g), f32(b), f32(a)} * 255.0
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_speed :: proc "c" (id, hspeed, vspeed: double) {
|
||||
system_current.instances[int(id)].speed = {f32(hspeed), f32(vspeed), 0.0}
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_gravity :: proc "c" (id, x, y: double) {
|
||||
system_current.instances[int(id)].gravity = {f32(x), f32(y), 0.0}
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_scale :: proc "c" (id, xscale, yscale: double) {
|
||||
system_current.instances[int(id)].scale = {f32(xscale), f32(yscale)}
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_grow :: proc "c" (id, xgrow, ygrow: double) {
|
||||
system_current.instances[int(id)].grow = {f32(xgrow), f32(ygrow)}
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_image_angle :: proc "c" (id, angle: double) {
|
||||
system_current.instances[int(id)].image_angle = f32(angle) * math.RAD_PER_DEG
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_image_angle_speed :: proc "c" (id, angular_velocity: double) {
|
||||
system_current.instances[int(id)].image_angle_speed = f32(angular_velocity) * math.RAD_PER_DEG
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_image_angle_direction :: proc "c" (id, x, y, z: double) {
|
||||
offset := int(id) * 6
|
||||
#unroll for i in 0 ..< 6 {
|
||||
system_current.vertices[offset + i].rotation_direction = {f32(x), f32(y), f32(z)}
|
||||
}
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_image_index :: proc "c" (id, index: double) {
|
||||
system_current.instances[int(id)].image_index = f32(index)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_image_speed :: proc "c" (id, speed: double) {
|
||||
system_current.instances[int(id)].image_speed = f32(speed)
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_hsv :: proc "c" (id, h, s, v: double) {
|
||||
system_current.instances[int(id)].hsv = v3{f32(h) / 360.0, f32(s) / 100.0, f32(v) / 100.0}
|
||||
}
|
||||
|
||||
@(export)
|
||||
pem_instance_set_hsv_add :: proc "c" (id, h, s, v: double) {
|
||||
system_current.instances[int(id)].hsv_add = v3{f32(h) / 360.0, f32(s) / 100.0, f32(v) / 100.0}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue