Separate input component
This commit is contained in:
parent
29e7b5e499
commit
705f498daa
9 changed files with 318 additions and 178 deletions
56
ecs/camera_system.odin
Normal file
56
ecs/camera_system.odin
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import "core:math"
|
||||||
|
import "core:math/linalg"
|
||||||
|
|
||||||
|
import sa "../sokol/app"
|
||||||
|
|
||||||
|
CameraSystem :: struct {
|
||||||
|
using base: SystemBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
camera_system_init :: proc(camera_system: ^CameraSystem) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
camera_system_update :: proc(camera_system: ^CameraSystem, coordinator: ^Coordinator, dt: f32) {
|
||||||
|
for entity in camera_system.entities {
|
||||||
|
camera := coordinator_get_component(CameraComponent, coordinator, entity)
|
||||||
|
input := coordinator_get_component(InputComponent, coordinator, entity)
|
||||||
|
|
||||||
|
if input.key_down[.ESCAPE] do sa.quit()
|
||||||
|
|
||||||
|
move_input: Vec3
|
||||||
|
if input.key_down[.W] do move_input.y = 1
|
||||||
|
else if input.key_down[.S] do move_input.y = -1
|
||||||
|
|
||||||
|
if input.key_down[.D] do move_input.x = 1
|
||||||
|
else if input.key_down[.A] do move_input.x = -1
|
||||||
|
|
||||||
|
if input.key_down[.SPACE] do move_input.z = 1
|
||||||
|
else if input.key_down[.LEFT_SHIFT] do move_input.z = -1
|
||||||
|
|
||||||
|
look_input: Vec2 = -input.mouse_movement * camera.look_sensitivity
|
||||||
|
camera.look += look_input
|
||||||
|
camera.look.x = math.wrap(camera.look.x, 360)
|
||||||
|
camera.look.y = math.clamp(camera.look.y, -89.5, 89.5)
|
||||||
|
|
||||||
|
look_mat := linalg.matrix4_from_yaw_pitch_roll_f32(
|
||||||
|
linalg.to_radians(camera.look.x),
|
||||||
|
linalg.to_radians(camera.look.y),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
|
||||||
|
forward := (look_mat * Vec4{0, 0, -1, 1}).xyz
|
||||||
|
right := (look_mat * Vec4{1, 0, 0, 1}).xyz
|
||||||
|
up := (look_mat * Vec4{0, 1, 0, 1}).xyz
|
||||||
|
|
||||||
|
move_dir := forward * move_input.y + right * move_input.x + up * move_input.z
|
||||||
|
motion := linalg.normalize0(move_dir) * camera.movement_speed * dt
|
||||||
|
camera.position += motion
|
||||||
|
|
||||||
|
camera.target = camera.position + forward
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package ecs
|
package ecs
|
||||||
|
|
||||||
|
import sa "../sokol/app"
|
||||||
import sg "../sokol/gfx"
|
import sg "../sokol/gfx"
|
||||||
|
|
||||||
Mat4 :: matrix[4, 4]f32
|
Mat4 :: matrix[4, 4]f32
|
||||||
|
|
@ -8,38 +9,51 @@ Vec2 :: [2]f32
|
||||||
Vec3 :: [3]f32
|
Vec3 :: [3]f32
|
||||||
Vec4 :: [4]f32
|
Vec4 :: [4]f32
|
||||||
|
|
||||||
Gravity :: struct {
|
GravityComponent :: struct {
|
||||||
force: Vec3
|
force: Vec3
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBody :: struct {
|
RigidBodyComponent :: struct {
|
||||||
velocity: Vec3,
|
velocity: Vec3,
|
||||||
acceleration: Vec3,
|
acceleration: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform :: struct {
|
TransformComponent :: struct {
|
||||||
position: Vec3,
|
position: Vec3,
|
||||||
rotation: Vec3,
|
rotation: Vec3,
|
||||||
scale: Vec3,
|
scale: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
Color :: struct {
|
ColorComponent :: struct {
|
||||||
color: Vec4,
|
color: Vec4,
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh :: struct {
|
MeshID :: enum {
|
||||||
vertex_buffer: sg.Buffer,
|
CubeMesh,
|
||||||
index_buffer: sg.Buffer,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Material :: struct {
|
MeshComponent :: struct {
|
||||||
shader: sg.Shader,
|
mesh_id: MeshID
|
||||||
image: sg.Image,
|
|
||||||
sampler: sg.Sampler,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera :: struct {
|
MaterialID :: enum {
|
||||||
|
GridTexture,
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialComponent :: struct {
|
||||||
|
material_id: MaterialID
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraComponent :: struct {
|
||||||
position: Vec3,
|
position: Vec3,
|
||||||
target: Vec3,
|
target: Vec3,
|
||||||
look: Vec2
|
look: Vec2,
|
||||||
|
|
||||||
|
look_sensitivity: f32,
|
||||||
|
movement_speed: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
InputComponent :: struct {
|
||||||
|
mouse_movement: Vec2,
|
||||||
|
key_down: #sparse[sa.Keycode]bool,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
30
ecs/input_system.odin
Normal file
30
ecs/input_system.odin
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import sa "../sokol/app"
|
||||||
|
|
||||||
|
InputSystem :: struct {
|
||||||
|
using base: SystemBase,
|
||||||
|
}
|
||||||
|
|
||||||
|
input_system_update :: proc(input_system: ^InputSystem, coordinator: ^Coordinator, event: ^sa.Event) {
|
||||||
|
for entity in input_system.entities {
|
||||||
|
input := coordinator_get_component(InputComponent, coordinator, entity)
|
||||||
|
|
||||||
|
#partial switch event.type {
|
||||||
|
case .MOUSE_MOVE:
|
||||||
|
input.mouse_movement += {event.mouse_dx, event.mouse_dy}
|
||||||
|
case .KEY_DOWN:
|
||||||
|
input.key_down[event.key_code] = true
|
||||||
|
case .KEY_UP:
|
||||||
|
input.key_down[event.key_code] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input_system_mouse_reset :: proc(input_system: ^InputSystem, coordinator: ^Coordinator) {
|
||||||
|
for entity in input_system.entities {
|
||||||
|
input := coordinator_get_component(InputComponent, coordinator, entity)
|
||||||
|
|
||||||
|
input.mouse_movement = { 0, 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,9 +6,9 @@ PhysicsSystem :: struct {
|
||||||
|
|
||||||
physics_system_update :: proc(physics_system: ^PhysicsSystem, coordinator: ^Coordinator, dt: f32) {
|
physics_system_update :: proc(physics_system: ^PhysicsSystem, coordinator: ^Coordinator, dt: f32) {
|
||||||
for entity in physics_system.entities {
|
for entity in physics_system.entities {
|
||||||
rigid_body := coordinator_get_component(RigidBody, coordinator, entity)
|
rigid_body := coordinator_get_component(RigidBodyComponent, coordinator, entity)
|
||||||
transform := coordinator_get_component(Transform, coordinator, entity)
|
transform := coordinator_get_component(TransformComponent, coordinator, entity)
|
||||||
gravity := coordinator_get_component(Gravity, coordinator, entity)
|
gravity := coordinator_get_component(GravityComponent, coordinator, entity)
|
||||||
|
|
||||||
transform.position += rigid_body.velocity * dt
|
transform.position += rigid_body.velocity * dt
|
||||||
rigid_body.velocity += gravity.force * dt
|
rigid_body.velocity += gravity.force * dt
|
||||||
|
|
|
||||||
|
|
@ -27,32 +27,28 @@ VertexData :: struct {
|
||||||
uv: Vec2,
|
uv: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderSystem :: struct {
|
Mesh :: struct {
|
||||||
using base: SystemBase,
|
|
||||||
|
|
||||||
shader: sg.Shader,
|
|
||||||
pipeline: sg.Pipeline,
|
|
||||||
vertex_buffer: sg.Buffer,
|
vertex_buffer: sg.Buffer,
|
||||||
index_buffer: sg.Buffer,
|
index_buffer: sg.Buffer,
|
||||||
image: sg.Image,
|
|
||||||
sampler: sg.Sampler,
|
|
||||||
|
|
||||||
camera: struct {
|
|
||||||
pos: Vec3,
|
|
||||||
target: Vec3,
|
|
||||||
look: Vec2,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init_render_system :: proc(render_system: ^RenderSystem) {
|
Material :: struct {
|
||||||
default_context := runtime.default_context()
|
pipeline: sg.Pipeline,
|
||||||
|
shader: sg.Shader,
|
||||||
|
image: sg.Image,
|
||||||
|
sampler: sg.Sampler,
|
||||||
|
}
|
||||||
|
|
||||||
sg.setup({
|
RenderSystem :: struct {
|
||||||
environment = sh.glue_environment(),
|
using base: SystemBase,
|
||||||
allocator = sg.Allocator(sh.allocator(&default_context)),
|
camera_entity: EntityID,
|
||||||
logger = sg.Logger(sh.logger(&default_context)),
|
|
||||||
})
|
|
||||||
|
|
||||||
|
materials: map[MaterialID]Material,
|
||||||
|
meshes : map[MeshID]Mesh,
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
init_grid_material :: proc(render_system: ^RenderSystem) {
|
||||||
shader := sg.make_shader(shaders.main_shader_desc(sg.query_backend()))
|
shader := sg.make_shader(shaders.main_shader_desc(sg.query_backend()))
|
||||||
pipeline := sg.make_pipeline({
|
pipeline := sg.make_pipeline({
|
||||||
shader = shader,
|
shader = shader,
|
||||||
|
|
@ -74,7 +70,40 @@ init_render_system :: proc(render_system: ^RenderSystem) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
vertices := []VertexData {
|
w, h: i32
|
||||||
|
pixels := stbi.load("res/white.png", &w, &h, nil, 4)
|
||||||
|
assert(pixels != nil)
|
||||||
|
defer(stbi.image_free(pixels))
|
||||||
|
|
||||||
|
image := sg.make_image({
|
||||||
|
width = w,
|
||||||
|
height = h,
|
||||||
|
pixel_format = .RGBA8,
|
||||||
|
data = {
|
||||||
|
subimage = {
|
||||||
|
0 = {
|
||||||
|
0 = {
|
||||||
|
ptr = pixels,
|
||||||
|
size = uint(w * h * 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
sampler := sg.make_sampler({})
|
||||||
|
|
||||||
|
render_system.materials[.GridTexture] = Material{
|
||||||
|
shader = shader,
|
||||||
|
pipeline = pipeline,
|
||||||
|
image = image,
|
||||||
|
sampler = sampler,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
init_cube_mesh :: proc (render_system: ^RenderSystem) {
|
||||||
|
cube_vertices := []VertexData {
|
||||||
{ pos = { -0.5, -0.5, 0.5 }, uv = { 0, 0 } },
|
{ pos = { -0.5, -0.5, 0.5 }, uv = { 0, 0 } },
|
||||||
{ pos = { 0.5, -0.5, 0.5 }, uv = { 1, 0 } },
|
{ pos = { 0.5, -0.5, 0.5 }, uv = { 1, 0 } },
|
||||||
{ pos = { 0.5, 0.5, 0.5 }, uv = { 1, 1 } },
|
{ pos = { 0.5, 0.5, 0.5 }, uv = { 1, 1 } },
|
||||||
|
|
@ -106,10 +135,10 @@ init_render_system :: proc(render_system: ^RenderSystem) {
|
||||||
{ pos = { -0.5, 0.5, 0.5 }, uv = { 1, 1 } },
|
{ pos = { -0.5, 0.5, 0.5 }, uv = { 1, 1 } },
|
||||||
}
|
}
|
||||||
vertex_buffer := sg.make_buffer({
|
vertex_buffer := sg.make_buffer({
|
||||||
data = sg_range(vertices)
|
data = sg_range(cube_vertices)
|
||||||
})
|
})
|
||||||
|
|
||||||
indices := []u16 {
|
cube_indices := []u16 {
|
||||||
1, 0, 2,
|
1, 0, 2,
|
||||||
3, 2, 0,
|
3, 2, 0,
|
||||||
7, 4, 6,
|
7, 4, 6,
|
||||||
|
|
@ -126,78 +155,80 @@ init_render_system :: proc(render_system: ^RenderSystem) {
|
||||||
|
|
||||||
index_buffer := sg.make_buffer({
|
index_buffer := sg.make_buffer({
|
||||||
usage = { index_buffer = true },
|
usage = { index_buffer = true },
|
||||||
data = sg_range(indices),
|
data = sg_range(cube_indices),
|
||||||
})
|
})
|
||||||
|
|
||||||
w, h: i32
|
render_system.meshes[.CubeMesh] = Mesh{
|
||||||
pixels := stbi.load("res/white.png", &w, &h, nil, 4)
|
vertex_buffer = vertex_buffer,
|
||||||
assert(pixels != nil)
|
index_buffer = index_buffer,
|
||||||
defer(stbi.image_free(pixels))
|
|
||||||
|
|
||||||
image := sg.make_image({
|
|
||||||
width = w,
|
|
||||||
height = h,
|
|
||||||
pixel_format = .RGBA8,
|
|
||||||
data = {
|
|
||||||
subimage = {
|
|
||||||
0 = {
|
|
||||||
0 = {
|
|
||||||
ptr = pixels,
|
|
||||||
size = uint(w * h * 4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
sampler := sg.make_sampler({})
|
|
||||||
|
|
||||||
render_system.sampler = sampler
|
|
||||||
render_system.shader = shader
|
|
||||||
render_system.image = image
|
|
||||||
render_system.pipeline = pipeline
|
|
||||||
render_system.vertex_buffer = vertex_buffer
|
|
||||||
render_system.index_buffer = index_buffer
|
|
||||||
render_system.camera = {
|
|
||||||
pos = { 30, 0, 60 },
|
|
||||||
target = { 0, 0, 1 },
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_render_system :: proc(render_system: ^RenderSystem) {
|
render_system_init :: proc(render_system: ^RenderSystem, camera_entity: EntityID) {
|
||||||
sg.destroy_buffer(render_system.index_buffer)
|
default_context := runtime.default_context()
|
||||||
sg.destroy_buffer(render_system.vertex_buffer)
|
|
||||||
sg.destroy_image(render_system.image)
|
sg.setup({
|
||||||
sg.destroy_sampler(render_system.sampler)
|
environment = sh.glue_environment(),
|
||||||
sg.destroy_pipeline(render_system.pipeline)
|
allocator = sg.Allocator(sh.allocator(&default_context)),
|
||||||
sg.destroy_shader(render_system.shader)
|
logger = sg.Logger(sh.logger(&default_context)),
|
||||||
|
})
|
||||||
|
|
||||||
|
render_system.materials = make(map[MaterialID]Material)
|
||||||
|
render_system.meshes = make(map[MeshID]Mesh)
|
||||||
|
render_system.camera_entity = camera_entity
|
||||||
|
|
||||||
|
init_cube_mesh(render_system)
|
||||||
|
init_grid_material(render_system)
|
||||||
|
}
|
||||||
|
|
||||||
|
render_system_delete :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator) {
|
||||||
|
cube_mesh := render_system.meshes[.CubeMesh]
|
||||||
|
sg.destroy_buffer(cube_mesh.index_buffer)
|
||||||
|
sg.destroy_buffer(cube_mesh.vertex_buffer)
|
||||||
|
|
||||||
|
grid_material := render_system.materials[.GridTexture]
|
||||||
|
sg.destroy_image(grid_material.image)
|
||||||
|
sg.destroy_sampler(grid_material.sampler)
|
||||||
|
sg.destroy_pipeline(grid_material.pipeline)
|
||||||
|
sg.destroy_shader(grid_material.shader)
|
||||||
|
|
||||||
|
delete(render_system.materials)
|
||||||
|
delete(render_system.meshes)
|
||||||
|
|
||||||
sg.shutdown()
|
sg.shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, dt: f32, key_down: #sparse[sa.Keycode]bool, mouse_move: Vec2) {
|
render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordinator, dt: f32) {
|
||||||
update_camera(render_system, dt, key_down, mouse_move)
|
camera := coordinator_get_component(CameraComponent, coordinator, render_system.camera_entity)
|
||||||
|
|
||||||
proj := linalg.matrix4_perspective_f32(70, sa.widthf() / sa.heightf(), 0.001, 1000)
|
proj := linalg.matrix4_perspective_f32(70, sa.widthf() / sa.heightf(), 0.001, 1000)
|
||||||
view := linalg.matrix4_look_at_f32(render_system.camera.pos, render_system.camera.target, { 0, 1, 0 } )
|
view := linalg.matrix4_look_at_f32(camera.position, camera.target, { 0, 1, 0 } )
|
||||||
|
|
||||||
sg.begin_pass({ swapchain = sh.glue_swapchain() })
|
sg.begin_pass({ swapchain = sh.glue_swapchain() })
|
||||||
|
|
||||||
sg.apply_pipeline(render_system.pipeline)
|
|
||||||
sg.apply_bindings({
|
|
||||||
vertex_buffers = { 0 = render_system.vertex_buffer },
|
|
||||||
index_buffer = render_system.index_buffer,
|
|
||||||
images = { shaders.IMG_tex = render_system.image },
|
|
||||||
samplers = { shaders.SMP_smp = render_system.sampler },
|
|
||||||
})
|
|
||||||
|
|
||||||
for entity in render_system.entities {
|
for entity in render_system.entities {
|
||||||
transform := coordinator_get_component(Transform, coordinator, entity)
|
transform := coordinator_get_component(TransformComponent, coordinator, entity)
|
||||||
color := coordinator_get_component(Color, coordinator, entity)
|
color := coordinator_get_component(ColorComponent, coordinator, entity)
|
||||||
|
|
||||||
|
mesh_id := coordinator_get_component(MeshComponent, coordinator, entity).mesh_id
|
||||||
|
mesh := render_system.meshes[mesh_id]
|
||||||
|
|
||||||
|
material_id := coordinator_get_component(MaterialComponent, coordinator, entity).material_id
|
||||||
|
material := render_system.materials[material_id]
|
||||||
|
|
||||||
pos_mat := linalg.matrix4_translate_f32(transform.position)
|
pos_mat := linalg.matrix4_translate_f32(transform.position)
|
||||||
rot_mat := linalg.matrix4_from_yaw_pitch_roll_f32(transform.rotation.y, transform.rotation.x, transform.rotation.z)
|
rot_mat := linalg.matrix4_from_yaw_pitch_roll_f32(transform.rotation.y, transform.rotation.x, transform.rotation.z)
|
||||||
model := pos_mat * rot_mat
|
model := pos_mat * rot_mat
|
||||||
|
|
||||||
|
sg.apply_pipeline(material.pipeline)
|
||||||
|
sg.apply_bindings({
|
||||||
|
images = { shaders.IMG_tex = material.image },
|
||||||
|
samplers = { shaders.SMP_smp = material.sampler },
|
||||||
|
|
||||||
|
vertex_buffers = { 0 = mesh.vertex_buffer },
|
||||||
|
index_buffer = mesh.index_buffer,
|
||||||
|
})
|
||||||
|
|
||||||
sg.apply_uniforms(shaders.UB_VsParams, sg_range(&shaders.Vsparams{
|
sg.apply_uniforms(shaders.UB_VsParams, sg_range(&shaders.Vsparams{
|
||||||
mvp = proj * view * model,
|
mvp = proj * view * model,
|
||||||
col = color.color
|
col = color.color
|
||||||
|
|
@ -210,44 +241,6 @@ render_system_update :: proc(render_system: ^RenderSystem, coordinator: ^Coordin
|
||||||
sg.commit()
|
sg.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
|
||||||
update_camera :: proc(render_system: ^RenderSystem, dt: f32, key_down: #sparse[sa.Keycode]bool, mouse_move: Vec2) {
|
|
||||||
MOVE_SPEED :: 3
|
|
||||||
LOOK_SENSITIVITY :: 0.15
|
|
||||||
|
|
||||||
move_input: Vec3
|
|
||||||
if key_down[.W] do move_input.y = 1
|
|
||||||
else if key_down[.S] do move_input.y = -1
|
|
||||||
|
|
||||||
if key_down[.D] do move_input.x = 1
|
|
||||||
else if key_down[.A] do move_input.x = -1
|
|
||||||
|
|
||||||
if key_down[.SPACE] do move_input.z = 1
|
|
||||||
else if key_down[.LEFT_SHIFT] do move_input.z = -1
|
|
||||||
|
|
||||||
look_input: Vec2 = -mouse_move * LOOK_SENSITIVITY
|
|
||||||
render_system.camera.look += look_input
|
|
||||||
render_system.camera.look.x = math.wrap(render_system.camera.look.x, 360)
|
|
||||||
render_system.camera.look.y = math.clamp(render_system.camera.look.y, -89.5, 89.5)
|
|
||||||
|
|
||||||
look_mat := linalg.matrix4_from_yaw_pitch_roll_f32(
|
|
||||||
linalg.to_radians(render_system.camera.look.x),
|
|
||||||
linalg.to_radians(render_system.camera.look.y),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
forward := (look_mat * Vec4{0, 0, -1, 1}).xyz
|
|
||||||
right := (look_mat * Vec4{1, 0, 0, 1}).xyz
|
|
||||||
up := (look_mat * Vec4{0, 1, 0, 1}).xyz
|
|
||||||
|
|
||||||
move_dir := forward * move_input.y + right * move_input.x + up * move_input.z
|
|
||||||
motion := linalg.normalize0(move_dir) * MOVE_SPEED * dt
|
|
||||||
render_system.camera.pos += motion
|
|
||||||
|
|
||||||
render_system.camera.target = render_system.camera.pos + forward
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sg_range :: proc {
|
sg_range :: proc {
|
||||||
sg_range_from_slice,
|
sg_range_from_slice,
|
||||||
sg_range_from_struct,
|
sg_range_from_struct,
|
||||||
|
|
|
||||||
126
main.odin
126
main.odin
|
|
@ -28,15 +28,14 @@ Vec4 :: [4]f32
|
||||||
|
|
||||||
Globals :: struct {
|
Globals :: struct {
|
||||||
coordinator: ecs.Coordinator,
|
coordinator: ecs.Coordinator,
|
||||||
|
input_system: ^ecs.InputSystem,
|
||||||
physics_system: ^ecs.PhysicsSystem,
|
physics_system: ^ecs.PhysicsSystem,
|
||||||
|
camera_system: ^ecs.CameraSystem,
|
||||||
render_system: ^ecs.RenderSystem,
|
render_system: ^ecs.RenderSystem,
|
||||||
entities: []ecs.EntityID,
|
entities: []ecs.EntityID,
|
||||||
}
|
}
|
||||||
g: ^Globals
|
g: ^Globals
|
||||||
|
|
||||||
mouse_move: Vec2
|
|
||||||
key_down: #sparse[sa.Keycode]bool
|
|
||||||
|
|
||||||
default_context: runtime.Context
|
default_context: runtime.Context
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
|
|
@ -50,7 +49,7 @@ main :: proc() {
|
||||||
default_context = context
|
default_context = context
|
||||||
|
|
||||||
sa.run({
|
sa.run({
|
||||||
window_title = "Ecs Test",
|
window_title = "ECS",
|
||||||
|
|
||||||
allocator = sa.Allocator(sh.allocator(&default_context)),
|
allocator = sa.Allocator(sh.allocator(&default_context)),
|
||||||
logger = sa.Logger(sh.logger(&default_context)),
|
logger = sa.Logger(sh.logger(&default_context)),
|
||||||
|
|
@ -77,23 +76,19 @@ init_cb :: proc "c" () {
|
||||||
frame_cb:: proc "c" () {
|
frame_cb:: proc "c" () {
|
||||||
context = default_context
|
context = default_context
|
||||||
|
|
||||||
if key_down[.ESCAPE] {
|
|
||||||
sa.quit()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dt := f32(sa.frame_duration())
|
dt := f32(sa.frame_duration())
|
||||||
|
|
||||||
ecs.physics_system_update(g.physics_system, &g.coordinator, dt)
|
ecs.physics_system_update(g.physics_system, &g.coordinator, dt)
|
||||||
ecs.render_system_update(g.render_system, &g.coordinator, dt, key_down, mouse_move)
|
ecs.camera_system_update(g.camera_system, &g.coordinator, dt)
|
||||||
|
ecs.render_system_update(g.render_system, &g.coordinator, dt)
|
||||||
|
|
||||||
mouse_move = {}
|
ecs.input_system_mouse_reset(g.input_system, &g.coordinator)
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_cb :: proc "c" () {
|
cleanup_cb :: proc "c" () {
|
||||||
context = default_context
|
context = default_context
|
||||||
|
|
||||||
ecs.delete_render_system(g.render_system)
|
ecs.render_system_delete(g.render_system, &g.coordinator)
|
||||||
|
|
||||||
delete(g.entities)
|
delete(g.entities)
|
||||||
ecs.coordinator_destroy(&g.coordinator)
|
ecs.coordinator_destroy(&g.coordinator)
|
||||||
|
|
@ -103,61 +98,94 @@ cleanup_cb :: proc "c" () {
|
||||||
event_cb :: proc "c" (event: ^sa.Event) {
|
event_cb :: proc "c" (event: ^sa.Event) {
|
||||||
context = default_context
|
context = default_context
|
||||||
|
|
||||||
#partial switch event.type {
|
ecs.input_system_update(g.input_system, &g.coordinator, event)
|
||||||
case .MOUSE_MOVE:
|
|
||||||
mouse_move += {event.mouse_dx, event.mouse_dy}
|
|
||||||
case .KEY_DOWN:
|
|
||||||
key_down[event.key_code] = true
|
|
||||||
case .KEY_UP:
|
|
||||||
key_down[event.key_code] = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create_scene :: proc() {
|
create_scene :: proc() {
|
||||||
ecs.coordinator_register_component(ecs.Gravity, &g.coordinator)
|
ecs.coordinator_register_component(ecs.GravityComponent, &g.coordinator)
|
||||||
ecs.coordinator_register_component(ecs.RigidBody, &g.coordinator)
|
ecs.coordinator_register_component(ecs.RigidBodyComponent, &g.coordinator)
|
||||||
ecs.coordinator_register_component(ecs.Transform, &g.coordinator)
|
ecs.coordinator_register_component(ecs.TransformComponent, &g.coordinator)
|
||||||
ecs.coordinator_register_component(ecs.Color, &g.coordinator)
|
ecs.coordinator_register_component(ecs.ColorComponent, &g.coordinator)
|
||||||
|
ecs.coordinator_register_component(ecs.CameraComponent, &g.coordinator)
|
||||||
|
ecs.coordinator_register_component(ecs.MaterialComponent, &g.coordinator)
|
||||||
|
ecs.coordinator_register_component(ecs.MeshComponent, &g.coordinator)
|
||||||
|
ecs.coordinator_register_component(ecs.InputComponent, &g.coordinator)
|
||||||
|
|
||||||
g.physics_system = ecs.coordinator_register_system(ecs.PhysicsSystem, &g.coordinator)
|
g.physics_system = ecs.coordinator_register_system(ecs.PhysicsSystem, &g.coordinator)
|
||||||
g.render_system = ecs.coordinator_register_system(ecs.RenderSystem, &g.coordinator)
|
|
||||||
ecs.init_render_system(g.render_system)
|
|
||||||
|
|
||||||
signature := ecs.signature_create()
|
signature := ecs.signature_create()
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.Gravity, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.GravityComponent, &g.coordinator))
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.RigidBody, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.RigidBodyComponent, &g.coordinator))
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.Transform, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.TransformComponent, &g.coordinator))
|
||||||
ecs.coordinator_set_system_signature(ecs.PhysicsSystem, &g.coordinator, signature)
|
ecs.coordinator_set_system_signature(ecs.PhysicsSystem, &g.coordinator, signature)
|
||||||
|
|
||||||
signature = ecs.signature_create()
|
g.render_system = ecs.coordinator_register_system(ecs.RenderSystem, &g.coordinator)
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.Transform, &g.coordinator))
|
ecs.signature_clear(&signature)
|
||||||
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.Color, &g.coordinator))
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.TransformComponent, &g.coordinator))
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.ColorComponent, &g.coordinator))
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.MeshComponent, &g.coordinator))
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.MaterialComponent, &g.coordinator))
|
||||||
ecs.coordinator_set_system_signature(ecs.RenderSystem, &g.coordinator, signature)
|
ecs.coordinator_set_system_signature(ecs.RenderSystem, &g.coordinator, signature)
|
||||||
|
|
||||||
g.entities = make([]ecs.EntityID, ecs.ENTITY_MAX)
|
g.camera_system = ecs.coordinator_register_system(ecs.CameraSystem, &g.coordinator)
|
||||||
|
ecs.signature_clear(&signature)
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.CameraComponent, &g.coordinator))
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.InputComponent, &g.coordinator))
|
||||||
|
ecs.coordinator_set_system_signature(ecs.CameraSystem, &g.coordinator, signature)
|
||||||
|
|
||||||
|
g.input_system = ecs.coordinator_register_system(ecs.InputSystem, &g.coordinator)
|
||||||
|
ecs.signature_clear(&signature)
|
||||||
|
ecs.signature_set(&signature, ecs.coordinator_get_component_type(ecs.InputComponent, &g.coordinator))
|
||||||
|
ecs.coordinator_set_system_signature(ecs.InputSystem, &g.coordinator, signature)
|
||||||
|
|
||||||
|
camera_entity := ecs.coordinator_create_entity(&g.coordinator)
|
||||||
|
ecs.coordinator_add_component(
|
||||||
|
ecs.CameraComponent,
|
||||||
|
&g.coordinator,
|
||||||
|
camera_entity,
|
||||||
|
ecs.CameraComponent{
|
||||||
|
position = { 30, 0, 60 },
|
||||||
|
target = { 0, 0, 1 },
|
||||||
|
look = { 0, 0 },
|
||||||
|
|
||||||
|
movement_speed = 3.0,
|
||||||
|
look_sensitivity = 0.15,
|
||||||
|
})
|
||||||
|
|
||||||
|
ecs.coordinator_add_component(
|
||||||
|
ecs.InputComponent,
|
||||||
|
&g.coordinator,
|
||||||
|
camera_entity,
|
||||||
|
ecs.InputComponent{
|
||||||
|
key_down = {},
|
||||||
|
mouse_movement = Vec2{ 0, 0 }
|
||||||
|
})
|
||||||
|
|
||||||
|
ecs.render_system_init(g.render_system, camera_entity)
|
||||||
|
|
||||||
|
g.entities = make([]ecs.EntityID, 1000)
|
||||||
for &entity in g.entities {
|
for &entity in g.entities {
|
||||||
entity = ecs.coordinator_create_entity(&g.coordinator)
|
entity = ecs.coordinator_create_entity(&g.coordinator)
|
||||||
|
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.Gravity,
|
ecs.GravityComponent,
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
entity,
|
||||||
ecs.Gravity{
|
ecs.GravityComponent{
|
||||||
ecs.Vec3{0.0, -2.82, 0.0}
|
ecs.Vec3{0.0, -2.82, 0.0}
|
||||||
})
|
})
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.RigidBody,
|
ecs.RigidBodyComponent,
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
entity,
|
||||||
ecs.RigidBody{
|
ecs.RigidBodyComponent{
|
||||||
velocity = ecs.Vec3{0.0, 0.0, 0.0},
|
velocity = ecs.Vec3{0.0, 0.0, 0.0},
|
||||||
acceleration = ecs.Vec3{0.0, 0.0, 0.0},
|
acceleration = ecs.Vec3{0.0, 0.0, 0.0},
|
||||||
})
|
})
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.Transform,
|
ecs.TransformComponent,
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
entity,
|
||||||
ecs.Transform{
|
ecs.TransformComponent{
|
||||||
position = Vec3{
|
position = Vec3{
|
||||||
f32(rand.int_max(50)),
|
f32(rand.int_max(50)),
|
||||||
f32(rand.int_max(10)),
|
f32(rand.int_max(10)),
|
||||||
|
|
@ -167,10 +195,10 @@ create_scene :: proc() {
|
||||||
scale = ecs.Vec3{1.0, 1.0, 1.0},
|
scale = ecs.Vec3{1.0, 1.0, 1.0},
|
||||||
})
|
})
|
||||||
ecs.coordinator_add_component(
|
ecs.coordinator_add_component(
|
||||||
ecs.Color,
|
ecs.ColorComponent,
|
||||||
&g.coordinator,
|
&g.coordinator,
|
||||||
entity,
|
entity,
|
||||||
ecs.Color{
|
ecs.ColorComponent{
|
||||||
color = Vec4{
|
color = Vec4{
|
||||||
rand.float32_uniform(0,1),
|
rand.float32_uniform(0,1),
|
||||||
rand.float32_uniform(0,1),
|
rand.float32_uniform(0,1),
|
||||||
|
|
@ -178,6 +206,20 @@ create_scene :: proc() {
|
||||||
rand.float32_uniform(0,1),
|
rand.float32_uniform(0,1),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
ecs.coordinator_add_component(
|
||||||
|
ecs.MeshComponent,
|
||||||
|
&g.coordinator,
|
||||||
|
entity,
|
||||||
|
ecs.MeshComponent{
|
||||||
|
mesh_id = .CubeMesh
|
||||||
|
})
|
||||||
|
ecs.coordinator_add_component(
|
||||||
|
ecs.MaterialComponent,
|
||||||
|
&g.coordinator,
|
||||||
|
entity,
|
||||||
|
ecs.MaterialComponent{
|
||||||
|
material_id = .GridTexture
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package shader
|
package shaders
|
||||||
import sg "../../sokol/gfx"
|
import sg "../../sokol/gfx"
|
||||||
import ecs "../../types"
|
|
||||||
/*
|
/*
|
||||||
#version:1# (machine generated, don't edit!)
|
#version:1# (machine generated, don't edit!)
|
||||||
|
|
||||||
|
|
@ -38,7 +37,7 @@ IMG_tex :: 0
|
||||||
SMP_smp :: 0
|
SMP_smp :: 0
|
||||||
Vsparams :: struct #align(16) {
|
Vsparams :: struct #align(16) {
|
||||||
using _: struct #packed {
|
using _: struct #packed {
|
||||||
mvp: ecs.Mat4,
|
mvp: Mat4,
|
||||||
col: [4]f32,
|
col: [4]f32,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
shaders/out/types.odin
Normal file
7
shaders/out/types.odin
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package shaders
|
||||||
|
|
||||||
|
Mat4 :: matrix[4, 4]f32
|
||||||
|
|
||||||
|
Vec2 :: [2]f32
|
||||||
|
Vec3 :: [3]f32
|
||||||
|
Vec4 :: [4]f32
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
@header package shader
|
@header package shaders
|
||||||
@header import sg "../../sokol/gfx"
|
@header import sg "../../sokol/gfx"
|
||||||
@header import ecs "../../types"
|
|
||||||
|
|
||||||
@ctype mat4 ecs.Mat4
|
@ctype mat4 Mat4
|
||||||
|
|
||||||
@vs vs
|
@vs vs
|
||||||
in vec3 pos;
|
in vec3 pos;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue