This commit is contained in:
griffi-gh 2023-07-12 17:24:07 +02:00
parent 37ccbfb1ba
commit 098c168639
23 changed files with 169 additions and 208 deletions

7
Cargo.lock generated
View file

@ -908,6 +908,7 @@ dependencies = [
"log",
"lz4_flex",
"nohash-hasher",
"pollster",
"postcard",
"rayon",
"serde_json",
@ -1486,6 +1487,12 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "pollster"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
[[package]]
name = "postcard"
version = "1.0.4"

View file

@ -26,9 +26,10 @@ flume = "0.10"
gilrs = { version = "0.10", default_features = false, features = ["xinput"] }
uflow = "0.7"
postcard = { version = "1.0", features = ["alloc"] }
serde_json = { version = "1.0", optional = true } #only used for `generate_visualizer_data`
lz4_flex = { version = "0.11", default-features = false, features = ["std"] }
tinyset = "0.4"
serde_json = { version = "1.0", optional = true } #only used for `generate_visualizer_data`
pollster = "0.3"
[target.'cfg(target_os = "android")'.dependencies]
android-activity = { version = "0.4", features = ["native-activity"] }
@ -43,6 +44,7 @@ generate_visualizer_data = ["dep:serde_json", "shipyard/serde1"]
safe_lz4 = ["lz4_flex/safe-encode", "lz4_flex/safe-decode"]
parallel = ["shipyard/parallel"] # causes some serious issues!
nightly = ["hashbrown/nightly", "glam/core-simd", "lz4_flex/nightly", "kubi-shared/nightly"]
dx12-dxc = [] #Requires dlls from https://github.com/microsoft/DirectXShaderCompiler
#part of wip android support
[package.metadata.android]

View file

@ -1,5 +1,5 @@
use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut, Workload, IntoWorkload};
use glium::glutin::event::VirtualKeyCode;
use winit::event::VirtualKeyCode;
use kubi_shared::{
block::Block,
queue::QueuedBlock,

View file

@ -1,6 +1,6 @@
use glam::{Vec3, Mat4};
use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track, UniqueView, SystemModificator};
use crate::{transform::Transform, rendering::WindowSize, events::WindowResizedEvent};
use crate::{transform::Transform, events::WindowResizedEvent, rendering::Renderer};
use super::Camera;
//maybe parallelize these two?
@ -18,14 +18,14 @@ fn update_view_matrix(
fn update_perspective_matrix(
mut vm_camera: ViewMut<Camera>,
size: UniqueView<WindowSize>,
renderer: UniqueView<Renderer>
) {
let size = renderer.size;
for mut camera in (&mut vm_camera).iter() {
camera.perspective_matrix = Mat4::perspective_rh_gl(
camera.fov,
size.0.x as f32 / size.0.y as f32,
camera.z_near,
camera.z_far,
size.width as f32 / size.height as f32,
camera.z_near, camera.z_far
)
}
}

View file

@ -1,5 +1,5 @@
use shipyard::{UniqueView, UniqueViewMut, Unique, AllStoragesView};
use glium::glutin::{event::VirtualKeyCode, event_loop::ControlFlow};
use winit::{event::VirtualKeyCode, event_loop::ControlFlow};
use crate::input::RawKbmInputState;
#[derive(Unique)]

View file

@ -1,6 +1,6 @@
use shipyard::{AllStoragesView, Unique, NonSendSync, UniqueView, UniqueViewMut};
use crate::rendering::Renderer;
use glium::glutin::window::CursorGrabMode;
use winit::window::CursorGrabMode;
#[derive(Unique)]
pub struct CursorLock(pub bool);
@ -13,13 +13,11 @@ pub fn update_cursor_lock_state(
return
}
if lock.is_inserted_or_modified() {
let gl_window = display.display.gl_window();
let window = gl_window.window();
window.set_cursor_grab(match lock.0 {
display.window.set_cursor_grab(match lock.0 {
true => CursorGrabMode::Confined,
false => CursorGrabMode::None,
}).expect("Failed to change cursor grab state");
window.set_cursor_visible(!lock.0);
display.window.set_cursor_visible(!lock.0);
}
}

View file

@ -1,6 +1,6 @@
use glam::UVec2;
use shipyard::{World, Component, AllStoragesViewMut, SparseSet, NonSendSync, UniqueView};
use glium::glutin::event::{Event, DeviceEvent, DeviceId, WindowEvent, Touch};
use winit::event::{Event, DeviceEvent, DeviceId, WindowEvent, Touch};
use crate::rendering::Renderer;
pub mod player_actions;
@ -81,13 +81,10 @@ pub fn process_glutin_events(world: &mut World, event: &Event<'_, ()>) {
pub fn initial_resize_event(
mut storages: AllStoragesViewMut,
) {
let (w, h) = {
let renderer = storages.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
renderer.display.get_framebuffer_dimensions()
};
storages.add_entity((
EventComponent,
WindowResizedEvent(UVec2::new(w, h))
WindowResizedEvent(UVec2::new(renderer.size.width, renderer.size.height))
));
}

View file

@ -2,7 +2,6 @@ use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, View,
use glam::{Vec4, Mat4};
use crate::{color::color_hex, events::WindowResizedEvent};
pub mod text_widget;
pub mod progressbar;
use progressbar::render_progressbars;
@ -41,18 +40,24 @@ fn update_gui_view(
view.0 = Mat4::orthographic_rh_gl(0.0, w as f32, h as f32, 0.0, -1.0, 1.0);
}
#[deprecated="will be replaced by an immediate-mode ui soon, currently a no-op"]
#[allow(deprecated)]
pub fn init_gui(
storages: AllStoragesView
) {
storages.add_unique(GuiView::default());
}
#[deprecated="will be replaced by an immediate-mode ui soon, currently a no-op"]
#[allow(deprecated)]
pub fn update_gui() -> Workload {
(
update_gui_view
).into_sequential_workload()
}
#[deprecated="will be replaced by an immediate-mode ui soon, currently a no-op"]
#[allow(deprecated)]
pub fn render_gui() -> Workload {
(
render_progressbars

View file

@ -1,5 +1,4 @@
use shipyard::{UniqueView, UniqueViewMut, NonSendSync, View, Component, IntoIter, IntoWithId, Get, track};
use glium::{Surface, uniform, DrawParameters};
use crate::{
prefabs::ProgressbarShaderPrefab,
rendering::{
@ -29,18 +28,18 @@ pub fn render_progressbars(
for (eid, (_, transform, progress)) in (&components, &transforms, &progressbars).iter().with_id() {
let primary_color = primary.get(eid).copied().unwrap_or_default();
let secondary_color = secondary.get(eid).copied().unwrap_or_default();
target.0.draw(
&rect.0,
&rect.1,
&program.0,
&uniform! {
transform: transform.0.to_cols_array_2d(),
ui_view: view.0.to_cols_array_2d(),
progress: progress.progress,
color: primary_color.0.to_array(),
bg_color: secondary_color.0.to_array(),
},
&DrawParameters::default()
).unwrap();
// target.0.draw(
// &rect.0,
// &rect.1,
// &program.0,
// &uniform! {
// transform: transform.0.to_cols_array_2d(),
// ui_view: view.0.to_cols_array_2d(),
// progress: progress.progress,
// color: primary_color.0.to_array(),
// bg_color: secondary_color.0.to_array(),
// },
// &DrawParameters::default()
// ).unwrap();
}
}

View file

@ -1 +0,0 @@
//TODO text widget

View file

@ -1,13 +1,13 @@
use gilrs::{Gilrs, GamepadId, Button, Event, Axis};
use glam::{Vec2, DVec2, vec2, dvec2};
use glium::glutin::event::{DeviceEvent, DeviceId, VirtualKeyCode, ElementState, TouchPhase};
use winit::event::{DeviceEvent, DeviceId, VirtualKeyCode, ElementState, TouchPhase};
use hashbrown::HashMap;
use tinyset::{SetU32, SetU64};
use nohash_hasher::BuildNoHashHasher;
use shipyard::{AllStoragesView, Unique, View, IntoIter, UniqueViewMut, Workload, IntoWorkload, UniqueView, NonSendSync};
use crate::{
events::{InputDeviceEvent, TouchEvent},
rendering::WindowSize
rendering::Renderer
};
#[derive(Unique, Clone, Copy, Default, Debug)]
@ -202,10 +202,10 @@ fn update_input_state_gamepad (
fn update_input_state_touch (
touch_state: UniqueView<RawTouchState>,
win_size: UniqueView<WindowSize>,
renderer: UniqueView<Renderer>,
mut inputs: UniqueViewMut<Inputs>,
) {
let w = win_size.0.as_dvec2();
let w = dvec2(renderer.size.width as _, renderer.size.height as _);
//Movement
if let Some(finger) = touch_state.query_area(

View file

@ -6,11 +6,9 @@ use shipyard::{
NonSendSync, WorkloadModificator,
SystemModificator
};
use glium::{
glutin::{
use winit::{
event_loop::{EventLoop, ControlFlow},
event::{Event, WindowEvent}
}
};
use glam::vec3;
use std::time::Instant;
@ -31,6 +29,8 @@ pub(crate) mod delta_time;
pub(crate) mod cursor_lock;
pub(crate) mod control_flow;
pub(crate) mod state;
#[deprecated="will be replaced by an immediate-mode ui soon, currently a no-op"]
#[allow(deprecated)]
pub(crate) mod gui;
pub(crate) mod networking;
pub(crate) mod init;
@ -45,7 +45,7 @@ use world::{
loading::update_loaded_world_around_player,
raycast::update_raycasts,
queue::apply_queued_blocks,
tasks::{ChunkTaskManager},
tasks::ChunkTaskManager,
};
use player::{spawn_player, MainPlayer};
use prefabs::load_prefabs;
@ -64,8 +64,6 @@ use rendering::{
RenderTarget,
BackgroundColor,
clear_background,
init_window_size,
update_window_size,
primitives::init_primitives,
world::{draw_world, draw_current_chunk_border},
selection_box::render_selection_box,
@ -94,7 +92,6 @@ fn startup() -> Workload {
(
init_fixed_timestamp_storage,
initial_resize_event,
init_window_size,
load_prefabs,
init_primitives,
insert_lock_state,
@ -110,7 +107,6 @@ fn startup() -> Workload {
fn update() -> Workload {
(
update_window_size,
update_cursor_lock_state,
process_inputs,
(
@ -170,8 +166,12 @@ fn attach_console() {
unsafe { AttachConsole(ATTACH_PARENT_PROCESS); }
}
#[cfg(target_os = "android")]
#[no_mangle]
#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
pub fn android_main(app: AndroidApp) {
kubi_main()
}
pub fn kubi_main() {
//Attach console on release builds on windows
#[cfg(all(windows, not(debug_assertions)))] attach_console();
@ -201,7 +201,7 @@ pub fn kubi_main() {
//Initialize renderer
{
let settings = world.borrow::<UniqueView<GameSettings>>().unwrap();
world.add_unique_non_send_sync(Renderer::init(&event_loop, &settings));
world.add_unique_non_send_sync(Renderer::init_blocking(&event_loop, &settings));
}
world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.)));

View file

@ -1,5 +1,5 @@
use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload, EntityId, Unique, AllStoragesViewMut, ViewMut, Get, SystemModificator, track};
use glium::glutin::event::VirtualKeyCode;
use winit::event::VirtualKeyCode;
use glam::{Mat3, vec2};
use crate::{
world::ChunkStorage,

View file

@ -1,5 +1,5 @@
use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator, View, IntoIter, WorkloadModificator};
use glium::glutin::event_loop::ControlFlow;
use winit::event_loop::ControlFlow;
use std::net::SocketAddr;
use uflow::{
client::{Client, Config as ClientConfig, Event as ClientEvent},

View file

@ -1,5 +1,4 @@
use shipyard::{NonSendSync, UniqueView, Unique, AllStoragesView};
use glium::{texture::{SrgbTexture2dArray, MipmapsOption}, Program};
use kubi_shared::block::BlockTexture;
use crate::rendering::Renderer;

View file

@ -1,19 +1,6 @@
macro_rules! include_shader_prefab {
($name: literal, $vert: literal, $frag: literal, $facade: expr) => {
{
use ::glium::{Program, program::ProgramCreationInput};
log::info!("compiling shader {}", $name);
Program::new(&*$facade, ProgramCreationInput::SourceCode {
vertex_shader: include_str!($vert),
fragment_shader: include_str!($frag),
geometry_shader: None,
tessellation_control_shader: None,
tessellation_evaluation_shader: None,
transform_feedback_varyings: None,
outputs_srgb: false,
uses_point_size: false,
}).expect("Failed to compile gpu program")
compile_error!("`include_shader_prefab` is not implemented yet")
}
};
}
pub(crate) use include_shader_prefab;

View file

@ -1,7 +1,6 @@
use strum::IntoEnumIterator;
use rayon::prelude::*;
use std::{path::PathBuf, io::BufReader};
use glium::{texture::{SrgbTexture2dArray, RawImage2d, MipmapsOption}, backend::Facade};
use crate::filesystem::open_asset;
use super::AssetPaths;

View file

@ -1,14 +1,11 @@
use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut, View, IntoIter, AllStoragesView};
use glium::{
Display, Surface,
Version, Api,
glutin::{
use winit::{
event_loop::EventLoop,
window::{WindowBuilder, Fullscreen},
ContextBuilder, GlProfile, GlRequest, dpi::PhysicalSize
},
window::{Window, WindowBuilder, Fullscreen},
dpi::PhysicalSize,
};
use glam::{Vec3, UVec2};
use pollster::FutureExt as _;
use crate::{events::WindowResizedEvent, settings::{GameSettings, FullscreenMode}};
pub mod primitives;
@ -18,93 +15,104 @@ pub mod entities;
#[derive(Unique)]
#[repr(transparent)]
pub struct RenderTarget(pub glium::Frame);
pub struct RenderTarget(pub ());
impl Drop for RenderTarget {
}
#[derive(Unique)]
#[repr(transparent)]
pub struct BackgroundColor(pub Vec3);
#[derive(Unique, Clone, Copy)]
#[repr(transparent)]
pub struct WindowSize(pub UVec2);
#[derive(Unique)]
pub struct Renderer {
pub display: Display
pub window: Window,
pub instance: wgpu::Instance,
pub surface: wgpu::Surface,
pub adapter: wgpu::Adapter,
pub device: wgpu::Device,
pub queue: wgpu::Queue,
pub size: PhysicalSize<u32>,
}
impl Renderer {
pub fn init(event_loop: &EventLoop<()>, settings: &GameSettings) -> Self {
pub async fn init(event_loop: &EventLoop<()>, settings: &GameSettings) -> Self {
log::info!("initializing display");
let wb = WindowBuilder::new()
//Build window
let window = WindowBuilder::new()
.with_title("kubi")
.with_maximized(true)
.with_min_inner_size(PhysicalSize::new(640, 480))
.with_fullscreen({
//this has no effect on android, so skip this pointless stuff
#[cfg(target_os = "android")] {
None
}
.build(event_loop)
.expect("Window creation failed");
//Enable fullscreen (on supported platforms; if enabled in settings)
#[cfg(not(target_os = "android"))]
if let Some(fs_settings) = &settings.fullscreen {
let monitor = event_loop.primary_monitor().or_else(|| {
event_loop.available_monitors().next()
});
if let Some(monitor) = monitor {
log::info!("monitor: {}", monitor.name().unwrap_or_else(|| "generic".into()));
match fs_settings.mode {
FullscreenMode::Borderless => {
log::info!("starting in borderless fullscreen mode");
Some(Fullscreen::Borderless(Some(monitor)))
},
window.set_fullscreen(settings.fullscreen.as_ref().and_then(|fullscreen| {
match fullscreen.mode {
FullscreenMode::Exclusive => {
log::warn!("exclusive fullscreen mode is experimental");
log::info!("starting in exclusive fullscreen mode");
//TODO: grabbing the first video mode is probably not the best idea...
monitor.video_modes().next()
.map(|vmode| {
log::info!("video mode: {}", vmode.to_string());
Some(Fullscreen::Exclusive(vmode))
Some(Fullscreen::Borderless(window.current_monitor()))
}
FullscreenMode::Borderless => {
window.current_monitor().and_then(|monitor| {
monitor.video_modes().next().map(|video_mode| {
Fullscreen::Exclusive(video_mode)
})
.unwrap_or_else(|| {
log::warn!("no valid video modes found, falling back to windowed mode instead");
None
})
}
}
}));
//Create wgpu stuff
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::all(),
dx12_shader_compiler: if cfg!(all(windows, feature = "dx12-dxc")) {
wgpu::Dx12Compiler::Dxc { dxil_path: None, dxc_path: None }
} else {
log::warn!("no monitors found, falling back to windowed mode");
None
}
} else {
log::info!("starting in windowed mode");
None
wgpu::Dx12Compiler::Fxc
}
});
let cb = ContextBuilder::new()
.with_srgb(false)
.with_depth_buffer(24)
.with_multisampling(settings.msaa.unwrap_or_default())
.with_vsync(settings.vsync)
.with_gl_profile(GlProfile::Core)
.with_gl(GlRequest::Latest);
let surface = unsafe {
instance.create_surface(&window)
}.expect("Failed to create a Surface");
let display = Display::new(wb, cb, event_loop)
.expect("Failed to create a glium Display");
let adapter = instance.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: Some(&surface),
force_fallback_adapter: false,
},
).await.expect("Failed to create wgpu adapter");
log::info!("Vendor: {}", display.get_opengl_vendor_string());
log::info!("Renderer: {}", display.get_opengl_renderer_string());
log::info!("OpenGL: {}", display.get_opengl_version_string());
log::info!("Supports GLSL: {:?}", display.get_supported_glsl_version());
log::info!("Framebuffer dimensions: {:?}", display.get_framebuffer_dimensions());
if display.is_context_loss_possible() { log::warn!("OpenGL context loss possible") }
if display.is_robust() { log::warn!("OpenGL implementation is not robust") }
if display.is_debug() { log::info!("OpenGL context is in debug mode") }
let (device, queue) = adapter.request_device(
&wgpu::DeviceDescriptor {
features: wgpu::Features::empty(),
limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else if cfg!(target_arch = "android") {
wgpu::Limits::downlevel_defaults()
} else {
wgpu::Limits::default()
},
label: None,
},
None,
).await.unwrap();
assert!(display.is_glsl_version_supported(&Version(Api::GlEs, 3, 0)), "GLSL ES 3.0 is not supported");
log::info!("Adapter: {:?}", adapter.get_info());
Self { window, instance, surface, adapter, device, queue, size: PhysicalSize::default() }
}
/// do not call from async functions
pub fn init_blocking(event_loop: &EventLoop<()>, settings: &GameSettings) -> Self {
Self::init(event_loop, settings).block_on()
}
/// Start a new frame
pub fn render() -> RenderTarget {
Self { display }
}
}
@ -112,27 +120,10 @@ pub fn clear_background(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
color: UniqueView<BackgroundColor>,
) {
target.0.clear_color_srgb_and_depth((color.0.x, color.0.y, color.0.z, 1.), 1.);
}
//not sure if this belongs here
pub fn init_window_size(
storages: AllStoragesView,
) {
let size = storages.borrow::<View<WindowResizedEvent>>().unwrap().iter().next().unwrap().0;
storages.add_unique(WindowSize(size))
}
pub fn update_window_size(
mut win_size: UniqueViewMut<WindowSize>,
resize: View<WindowResizedEvent>,
) {
if let Some(resize) = resize.iter().next() {
win_size.0 = resize.0;
}
}
#[deprecated]
pub fn if_resized (
resize: View<WindowResizedEvent>,
) -> bool {

View file

@ -1,5 +1,4 @@
use shipyard::{NonSendSync, UniqueViewMut, UniqueView, View, IntoIter, IntoWithId};
use glium::{DepthTest, Depth, PolygonMode, BackfaceCullingMode, DrawParameters, Surface, uniform};
use kubi_shared::{entity::Entity, transform::Transform};
use crate::{
prefabs::ColoredShaderPrefab,
@ -42,17 +41,17 @@ pub fn render_entities(
if entity_id == camera_id { continue }
//render entity
target.0.draw(
&buffers.0,
&buffers.1,
&program.0,
&uniform! {
color: [1.0, 1.0, 1.0, 1.0_f32],
model: trans.0.to_cols_array_2d(),
view: view,
perspective: perspective,
},
&draw_parameters
).unwrap();
// target.0.draw(
// &buffers.0,
// &buffers.1,
// &program.0,
// &uniform! {
// color: [1.0, 1.0, 1.0, 1.0_f32],
// model: trans.0.to_cols_array_2d(),
// view: view,
// perspective: perspective,
// },
// &draw_parameters
// ).unwrap();
}
}

View file

@ -1,5 +1,4 @@
use shipyard::{Workload, IntoWorkload};
use glium::implement_vertex;
pub mod cube;
pub mod rect;
@ -7,17 +6,17 @@ pub mod rect;
use cube::init_cube_primitive;
use rect::init_rect_primitive;
#[repr(C)]
#[derive(Clone, Copy, Default)]
pub struct PositionOnlyVertex {
pub position: [f32; 3],
}
implement_vertex!(PositionOnlyVertex, position);
#[repr(C)]
#[derive(Clone, Copy, Default)]
pub struct PositionOnlyVertex2d {
pub position: [f32; 2],
}
implement_vertex!(PositionOnlyVertex2d, position);
pub fn init_primitives() -> Workload {
(

View file

@ -1,5 +1,4 @@
use shipyard::{Unique, AllStoragesView, NonSendSync, UniqueView};
use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType};
use crate::rendering::Renderer;
use super::PositionOnlyVertex2d;

View file

@ -1,22 +1,5 @@
use glam::{Vec3, Mat4, Quat, ivec3};
use shipyard::{NonSendSync, UniqueView, UniqueViewMut, View, IntoIter, track};
use glium::{
implement_vertex, uniform,
Surface, DrawParameters,
uniforms::{
Sampler,
SamplerBehavior,
MinifySamplerFilter,
MagnifySamplerFilter,
SamplerWrapFunction
},
draw_parameters::{
Depth,
DepthTest,
PolygonMode,
BackfaceCullingMode,
}, Blend
};
use crate::{
camera::Camera,
player::MainPlayer,
@ -34,15 +17,14 @@ use crate::{
};
use super::{RenderTarget, primitives::cube::CubePrimitive};
#[derive(Clone, Copy)]
#[repr(C)]
#[derive(Clone, Copy)]
pub struct ChunkVertex {
pub position: [f32; 3],
pub normal: [f32; 3],
pub uv: [f32; 2],
pub tex_index: u8,
}
implement_vertex!(ChunkVertex, position, normal, uv, tex_index);
pub fn draw_world(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,

View file

@ -1,5 +1,4 @@
use glam::{IVec3, ivec3};
use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType};
use kubi_shared::networking::messages::ClientToServerMessage;
use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload, NonSendSync, track};
use uflow::SendMode;