"problemMatcher": "$onyx",
"options": {
"cwd": "${workspaceFolder}/run_tree",
+ "shell": {
+ "executable": "/bin/sh",
+ }
},
"presentation": {
"echo": true,
uniform sampler2D u_sampler;
-uniform vec3 u_fog_color;
-uniform float u_fog_start;
-uniform float u_fog_range;
+layout(std140) uniform u_game_fog_block {
+ uniform vec3 u_fog_color;
+ uniform float u_fog_start;
+ uniform float u_fog_range;
+};
out vec4 fragColor;
void main() {
--- /dev/null
+precision mediump float;
+
+COMM vec4 v_col;
+COMM float v_dist;
+
+#ifdef VERTEX_SHADER
+
+layout(location = 0) in vec3 a_pos;
+layout(location = 1) in vec4 a_col;
+
+layout(std140) uniform u_world_matrix_block {
+ mat4 u_view;
+ mat4 u_world;
+ mat4 u_model;
+};
+
+void main() {
+ vec4 pos = u_world * u_model * vec4(a_pos, 1);
+ v_dist = length(pos);
+ gl_Position = u_view * pos;
+ v_col = a_col;
+}
+
+#endif
+
+#ifdef FRAGMENT_SHADER
+
+layout(std140) uniform u_game_fog_block {
+ uniform vec3 u_fog_color;
+ uniform float u_fog_start;
+ uniform float u_fog_range;
+};
+
+uniform vec4 color;
+out vec4 fragColor;
+
+void main() {
+ vec4 output_color = v_col * color;
+
+ // Not going to rely on clamp() existing.
+ float fog = min(1.0f, max(0.0f, (v_dist - u_fog_start) / u_fog_range));
+
+ fragColor = mix(output_color, vec4(u_fog_color, 1), fog);
+}
+
+#endif
selected_block: Vector3i;
player_shader: Shader;
+world_fog_block: Shader_Block;
+
+World_Fog :: struct {
+ u_fog_color: Vector3;
+ u_fog_start: f32;
+ u_fog_range: f32;
+}
Game_State :: struct {
init :: game_init;
game_init :: (_: rawptr) {
world_shader = shader_make("assets/shaders/world.glsl");
- player_shader = shader_make("assets/shaders/basic.glsl");
+ player_shader = shader_make("assets/shaders/world_object.glsl");
shader_link_world_matrix_block(world_shader);
shader_link_world_matrix_block(player_shader);
- shader_set_uniform(world_shader, #cstr "u_fog_start", 50.0f);
- shader_set_uniform(world_shader, #cstr "u_fog_range", 10.0f);
+ shader_block_link(^world_fog_block, world_shader, #cstr "u_game_fog_block");
+ shader_block_link(^world_fog_block, player_shader, #cstr "u_game_fog_block");
+
+ world_fog_block = shader_block_create(World_Fog);
+ shader_block_update(^world_fog_block, "u_fog_start", 50.0f);
+ shader_block_update(^world_fog_block, "u_fog_range", 10.0f);
font = font_lookup(.{"./assets/fonts/calibri.ttf", 32});
chat_font = font_lookup(.{"./assets/fonts/calibri.ttf", 16});
send_movement_timeout -= dt;
if send_movement_timeout < 0 {
- send_movement_timeout = 0.05f;
- net_send_movement_update(player.body.pos, player.body.vel, .{1,0,0});
+ send_movement_timeout = 0.1f;
+ net_send_movement_update(player.body.pos, player.body.vel, .{1,0,0}, player.body.on_ground);
+ }
+
+ for ^other_players.entries {
+ if it.value.on_ground do it.value.velocity.y = 0;
+ it.value.position += it.value.velocity * dt;
}
if is_key_just_down(GLFW_KEY_F7) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader_use(world_shader);
- shader_set_uniform(world_shader, #cstr "u_fog_color", fog_color);
+ shader_block_update(^world_fog_block, "u_fog_color", fog_color);
shader_set_uniform(world_shader, #cstr "u_texture", 0);
glEnable(GL_DEPTH_TEST);
world_draw(world);
shader_use(player_shader);
shader_set_uniform(player_shader, #cstr "color", Color.{1,0,0});
for^ other_players.entries {
+ if (it.value.position - player.body.pos)->square_mag() >= 70 * 70 do continue;
+
update_model_matrix(it.value.position - .{0,0.8,0}, .{0.3, 1, 0.3});
mesh_draw(Meshes.white_box);
}
}
}
+
+
+Shader_Block :: struct {
+ block_buffer: GLuint;
+ uniform_block: u32;
+ type: type_expr;
+}
+
+shader_block_create :: (T: type_expr) -> Shader_Block {
+ #persist next_block_id := 0;
+
+ block: Shader_Block;
+ block.type = T;
+ glGenBuffers(1, ^block.block_buffer);
+
+ size := type_info.size_of(T);
+
+ glBindBuffer(GL_UNIFORM_BUFFER, block.block_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, size, null, GL_DYNAMIC_DRAW);
+
+ block.uniform_block = next_block_id;
+ next_block_id += 1;
+
+ glBindBufferBase(GL_UNIFORM_BUFFER, block.uniform_block, block.block_buffer);
+
+ return block;
+}
+
+shader_block_link :: (s: ^Shader_Block, use shader: Shader, field_name: cstr) {
+ index := glGetUniformBlockIndex(prog, field_name);
+ glUniformBlockBinding(prog, index, s.uniform_block);
+}
+
+shader_block_update :: (s: ^Shader_Block, field: str, value: $T) {
+ glBindBuffer(GL_UNIFORM_BUFFER, s.block_buffer);
+ defer glBindBuffer(GL_UNIFORM_BUFFER, -1);
+
+ v := value;
+
+ s_info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(s.type);
+ for^ s_info.members {
+ if it.name == field {
+ if it.type != T do return;
+ glBufferSubData(GL_UNIFORM_BUFFER, it.offset, sizeof T, ^v);
+ break;
+ }
+ }
+}
\ No newline at end of file
other_players[~~ joined_packet.player_id] = .{
name,
- .{0, 0, 0}, .{0, 0, 0}, .{0, 0, 0}
+ .{0, 0, 0}, .{0, 0, 0}, .{0, 0, 0},
+ false
};
if joined_packet.player_id != player_id {
if moved.player_id == player_id do return;
player := ^other_players[~~ moved.player_id];
- player.position = moved.position;
- player.velocity = moved.velocity;
- player.facing = moved.facing;
+ player.position = moved.position;
+ player.velocity = moved.velocity;
+ player.facing = moved.facing;
+ player.on_ground = moved.on_ground;
}
case .Block_Updates {
onet.peer_send(peer, 0, p);
}
-net_send_movement_update :: (position: Vector3, velocity: Vector3, facing: Vector3) {
+net_send_movement_update :: (position: Vector3, velocity: Vector3, facing: Vector3, on_ground: bool) {
movement := new(packets.Player_Moved);
movement.player_id = player_id;
movement.position = position;
movement.velocity = velocity;
movement.facing = facing;
+ movement.on_ground = on_ground;
p := new(onet.Packet);
p.data = .{ ~~movement, sizeof typeof *movement };
Remote_Player :: struct {
name: str;
- position: Vector3;
- velocity: Vector3;
- facing: Vector3;
+ position: Vector3;
+ velocity: Vector3;
+ facing: Vector3;
+ on_ground: bool;
}
@TEMPORARY
mag :: macro (v: Vector3) => math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
+ square_mag :: macro (v: Vector3) => v.x * v.x + v.y * v.y + v.z * v.z;
+
neg :: macro (v: Vector3) => Vector3.{ -v.x, -v.y, -v.z };
dot :: macro (v1, v2: Vector3) -> f32 {
#operator + macro (v1, v2: Vector3) => Vector3.{ v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
#operator - macro (v1, v2: Vector3) => Vector3.{ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
#operator * macro (v: Vector3, s: f32) => Vector3.{ v.x * s, v.y * s, v.z * s };
-#operator * macro (v1, v2: Vector3) => (typeof v1).{ v1.x * v2.x, v1.y * v2.y, v1.z * v3.z };
+#operator * macro (v1, v2: Vector3) => (typeof v1).{ v1.x * v2.x, v1.y * v2.y, v1.z * v2.z };
#operator == macro (v1, v2: Vector3) => v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;
#operator + macro (v1, v2: Vector3i) => Vector3i.{ v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
#operator - macro (v1, v2: Vector3i) => Vector3i.{ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
#operator * macro (v: Vector3i, s: i32) => Vector3i.{ v.x * s, v.y * s, v.z * s };
-#operator * macro (v1, v2: Vector3i) => (typeof v1).{ v1.x * v2.x, v1.y * v2.y, v1.z * v3.z };
+#operator * macro (v1, v2: Vector3i) => (typeof v1).{ v1.x * v2.x, v1.y * v2.y, v1.z * v2.z };
#operator == macro (v1, v2: Vector3i) => v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;
#local {
&& a1.z0 < a2.z1 && a1.z1 > a2.z0;
}
+ overlap :: (a1, a2: AABB) -> Vector3 {
+ ox, oy, oz: f32;
+ if a1.x0 < a2.x1 && a1.x1 > a2.x0 {
+ dx1 := a1.x0 - a2.x1;
+ dx2 := a1.x1 - a2.x0;
+ if math.abs(dx1) < math.abs(dx2) do ox = dx1;
+ else do ox = dx2;
+ }
+
+ if a1.y0 < a2.y1 && a1.y1 > a2.y0 {
+ dy1 := a1.y0 - a2.y1;
+ dy2 := a1.y1 - a2.y0;
+ if math.abs(dy1) < math.abs(dy2) do oy = dy1;
+ else do oy = dy2;
+ }
+
+ if a1.z0 < a2.z1 && a1.z1 > a2.z0 {
+ dz1 := a1.z0 - a2.z1;
+ dz2 := a1.z1 - a2.z0;
+ if math.abs(dz1) < math.abs(dz2) do oz = dz1;
+ else do oz = dz2;
+ }
+
+ return .{ox, oy, oz};
+ }
+
contains :: (a: AABB, v: Vector3) -> bool {
return a.x0 < v.x && v.x < a.x1
&& a.y0 < v.y && v.y < a.y1
vel: Vector3;
acc: Vector3;
+ collied := false;
on_ground := false;
get_collision_object: (pos: Vector3) -> AABB; // This will get expanded on when other collision objects are defined
}
physics_simulate :: (use body: ^PhysicsBody, dt: f32, world: ^World) {
- aabb_buffer := (cast(^AABB) alloc.from_stack(sizeof [256] AABB))[0..256];
+ aabb_buffer := alloc.array_from_stack(AABB, 256);
aabbs := world_get_aabbs(world, pos, 3, aabb_buffer);
- try_move :: macro (delta: Vector3) -> f32 {
+ try_move :: macro (d: f32, dir: Vector3) -> (f32, f32) {
+ delta := dir * d;
new_pos := body.pos + delta;
body_aabb := get_collision_object(new_pos);
for^ aabbs {
- if body_aabb->intersects(*it) {
+ if body_aabb->intersects(*it) {
if delta.y < 0 do on_ground = true;
- return 0;
+
+ overlap := body_aabb->overlap(*it);
+ overlap *= 1.1f;
+ change := delta - overlap;
+
+ return 0, change->dot(dir);
}
}
- return 1;
+ return 1, 0;
}
on_ground = false;
- move_x := try_move(.{acc.x*0.5*dt*dt + vel.x * dt, 0, 0});
- move_y := try_move(.{0, acc.y*0.5*dt*dt + vel.y * dt, 0});
- move_z := try_move(.{0, 0, acc.z*0.5*dt*dt + vel.z * dt});
+ move_x, overlap_x := try_move(acc.x*0.5*dt*dt + vel.x*dt, .{1,0,0});
+ move_y, overlap_y := try_move(acc.y*0.5*dt*dt + vel.y*dt, .{0,1,0});
+ move_z, overlap_z := try_move(acc.z*0.5*dt*dt + vel.z*dt, .{0,0,1});
- pos.x += vel.x * dt * move_x;
- pos.y += vel.y * dt * move_y;
- pos.z += vel.z * dt * move_z;
+ pos.x += vel.x * dt * move_x + overlap_x;
+ pos.y += vel.y * dt * move_y + overlap_y;
+ pos.z += vel.z * dt * move_z + overlap_z;
vel += acc * dt;
+ vel *= .{ move_x, move_y, move_z };
- if on_ground do vel.y = 0;
+ // if on_ground do vel.y = 0;
}
position: Vector3 = .{0,0,0};
velocity: Vector3 = .{0,0,0};
facing: Vector3 = .{0,0,0};
+ on_ground := false;
}
max_connected_players := 8;
player := ^connected_players[~~ moved.player_id];
if player == null do return;
- player.position = moved.position;
- player.velocity = moved.velocity;
- player.facing = moved.facing;
+ player.position = moved.position;
+ player.velocity = moved.velocity;
+ player.facing = moved.facing;
+ player.on_ground = moved.on_ground;
packet := new(onet.Packet);
packet.data = memory.copy_slice(packet_data);
position: Vector3;
velocity: Vector3;
facing: Vector3;
+ on_ground: bool;
}
Chat_Message :: struct #pack {