瀏覽代碼

Implemented virtual file system

raster
Bergmann89 5 年之前
父節點
當前提交
05b0414267
共有 14 個檔案被更改,包括 269 行新增33 行删除
  1. +92
    -0
      Cargo.lock
  2. +19
    -7
      glc/src/shader.rs
  3. +2
    -0
      space-crush/Cargo.toml
  4. +0
    -0
      space-crush/resources/shader/noise.frag
  5. +0
    -0
      space-crush/resources/shader/noise.vert
  6. +0
    -0
      space-crush/resources/shader/quad.frag
  7. +0
    -0
      space-crush/resources/shader/quad.vert
  8. +21
    -0
      space-crush/src/app/misc/mod.rs
  9. +72
    -0
      space-crush/src/app/misc/vfs.rs
  10. +1
    -1
      space-crush/src/app/misc/window.rs
  11. +4
    -3
      space-crush/src/app/mod.rs
  12. +11
    -11
      space-crush/src/app/render/init.rs
  13. +12
    -10
      space-crush/src/app/render/test.rs
  14. +35
    -1
      space-crush/src/error.rs

+ 92
- 0
Cargo.lock 查看文件

@@ -6,6 +6,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9fe5e32de01730eb1f6b7f5b51c17e03e2325bf40a74f754f04f130043affff"

[[package]]
name = "adler32"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"

[[package]]
name = "ahash"
version = "0.3.8"
@@ -87,6 +93,27 @@ version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"

[[package]]
name = "bzip2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b"
dependencies = [
"bzip2-sys",
"libc",
]

[[package]]
name = "bzip2-sys"
version = "0.1.9+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad3b39a260062fca31f7b0b12f207e8f2590a67d32ec7d59c20484b07ea7285e"
dependencies = [
"cc",
"libc",
"pkg-config",
]

[[package]]
name = "calloop"
version = "0.6.5"
@@ -252,6 +279,15 @@ dependencies = [
"objc",
]

[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if 1.0.0",
]

[[package]]
name = "crossbeam-channel"
version = "0.5.0"
@@ -406,6 +442,18 @@ dependencies = [
"termcolor",
]

[[package]]
name = "flate2"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42"
dependencies = [
"cfg-if 0.1.10",
"crc32fast",
"libc",
"miniz_oxide",
]

[[package]]
name = "fnv"
version = "1.0.7"
@@ -817,6 +865,15 @@ dependencies = [
"autocfg",
]

[[package]]
name = "miniz_oxide"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
dependencies = [
"adler32",
]

[[package]]
name = "mio"
version = "0.6.22"
@@ -1348,6 +1405,8 @@ dependencies = [
"specs",
"thiserror",
"tokio",
"vfs",
"vfs-zip",
]

[[package]]
@@ -1473,6 +1532,26 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"

[[package]]
name = "vfs"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cc382cffc2f8d6f9490b96d42a7408d6aa719c2db86491b8b31780208ac9d86"
dependencies = [
"thiserror",
]

[[package]]
name = "vfs-zip"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68a369614cd12ca384ca6e75ab0a5ac3a5acbfe8003622e20808a322b9bb652"
dependencies = [
"flate2",
"vfs",
"zip",
]

[[package]]
name = "walkdir"
version = "2.3.1"
@@ -1689,3 +1768,16 @@ name = "xml-rs"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a"

[[package]]
name = "zip"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "543adf038106b64cfca4711c82c917d785e3540e04f7996554488f988ec43124"
dependencies = [
"byteorder",
"bzip2",
"crc32fast",
"flate2",
"thiserror",
]

+ 19
- 7
glc/src/shader.rs 查看文件

@@ -1,4 +1,5 @@
use std::fs::read_to_string;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::ptr::{null, null_mut};
use std::str::from_utf8;
@@ -24,9 +25,10 @@ impl Program {
Self::from_shaders_result(iter.into_iter().map(Ok))
}

pub fn from_shaders_result<I>(iter: I) -> Result<Self, Error>
pub fn from_shaders_result<I, E>(iter: I) -> Result<Self, E>
where
I: IntoIterator<Item = Result<Shader, Error>>,
I: IntoIterator<Item = Result<Shader, E>>,
E: From<Error>,
{
let id = gl::create_program();
let id = Error::err_if(&0, id)?;
@@ -59,9 +61,9 @@ impl Program {
buffer.as_mut_ptr() as *mut gl::types::GLchar,
);

let msg = from_utf8(&buffer)?;
let msg = from_utf8(&buffer).map_err(Error::Utf8Error)?;

return Err(Error::ShaderLink(msg.into()));
return Err(Error::ShaderLink(msg.into()).into());
}

Ok(Program { id })
@@ -140,13 +142,23 @@ impl Shader {
Ok(Self { id })
}

pub fn from_reader<R>(type_: Type, mut reader: R) -> Result<Self, Error>
where
R: Read,
{
let mut source = String::new();
reader.read_to_string(&mut source)?;

Self::from_string(type_, source)
}

pub fn from_file<P>(type_: Type, path: P) -> Result<Self, Error>
where
P: AsRef<Path>,
{
let source = read_to_string(&path)?;
let source = File::open(&path)?;

match Self::from_string(type_, source) {
match Self::from_reader(type_, source) {
Ok(v) => Ok(v),
Err(Error::ShaderCompile { code, error }) => Err(Error::ShaderCompile {
code: format!("{}\n{}", path.as_ref().display(), code),


+ 2
- 0
space-crush/Cargo.toml 查看文件

@@ -17,3 +17,5 @@ shrev = "1.1"
specs = "0.16"
thiserror = "1.0"
tokio = "0.3"
vfs = "0.4"
vfs-zip = "0.2"

space-crush/src/app/render/shader/noise.frag → space-crush/resources/shader/noise.frag 查看文件


space-crush/src/app/render/shader/noise.vert → space-crush/resources/shader/noise.vert 查看文件


space-crush/src/app/render/shader/quad.frag → space-crush/resources/shader/quad.frag 查看文件


space-crush/src/app/render/shader/quad.vert → space-crush/resources/shader/quad.vert 查看文件


+ 21
- 0
space-crush/src/app/misc/mod.rs 查看文件

@@ -2,4 +2,25 @@ pub mod camera;
pub mod events;
pub mod frame_counter;
pub mod geometry;
pub mod vfs;
pub mod window;

use std::iter::Iterator;
use std::ops::Deref;

use self::vfs::Vfs;
use glc::shader::{Program, Shader, Type};

use crate::Error;

pub fn load_program<I>(vfs: &Vfs, iter: I) -> Result<Program, Error>
where
I: IntoIterator<Item = (Type, &'static str)>,
{
Program::from_shaders_result(iter.into_iter().map(|(t, p)| {
let file = vfs.deref().join(p)?.open_file()?;
let shader = Shader::from_reader(t, file)?;

Ok(shader)
}))
}

+ 72
- 0
space-crush/src/app/misc/vfs.rs 查看文件

@@ -0,0 +1,72 @@
use std::collections::HashSet;
use std::env::{current_dir, current_exe};
use std::fs::File;
use std::ops::Deref;

use log::info;

use vfs::{
impls::{overlay::OverlayFS, physical::PhysicalFS},
VfsPath,
};
use vfs_zip::ZipReadOnly as ZipFS;

use crate::Error;

pub struct Vfs(pub VfsPath);

impl Vfs {
pub fn new() -> Result<Self, Error> {
let dirs = vec![
current_exe()
.ok()
.as_ref()
.and_then(|p| p.parent())
.map(|p| p.to_owned()),
current_exe()
.ok()
.as_ref()
.and_then(|p| p.parent())
.map(|p| p.join("space-crush")),
current_dir().ok(),
current_dir().ok().map(|p| p.join("space-crush")),
]
.into_iter()
.filter_map(|d| d);

let mut paths = HashSet::new();
let mut layers = Vec::new();

for dir in dirs.clone() {
if paths.insert(dir.clone()) {
info!("Adding layer to VFS: {}", dir.display());

let layer = VfsPath::new(PhysicalFS::new(dir));

layers.push(layer);
}
}

for dir in dirs {
let path = dir.join("resources.bin");
if path.is_file() && paths.insert(path.to_owned()) {
info!("Adding layer to VFS: {}", dir.display());

let zip = File::open(path)?;
let layer = VfsPath::new(ZipFS::new_relaxed(zip)?);

layers.push(layer);
}
}

Ok(Self(VfsPath::new(OverlayFS::new(&layers))))
}
}

impl Deref for Vfs {
type Target = VfsPath;

fn deref(&self) -> &Self::Target {
&self.0
}
}

+ 1
- 1
space-crush/src/app/misc/window.rs 查看文件

@@ -19,7 +19,7 @@ impl Window {
let context = loop {
let multisampling = match multisampling.next() {
Some(multisampling) => multisampling,
None => return Err(Error::UnableToCreateContext),
None => return Err(Error::CreateContext),
};

info!("Create OpenGL context (multisampling={})", multisampling);


+ 4
- 3
space-crush/src/app/mod.rs 查看文件

@@ -6,7 +6,7 @@ use specs::{Dispatcher, DispatcherBuilder, World};

use crate::Error;

use misc::{events::Events, geometry::Geometry, window::Window};
use misc::{events::Events, geometry::Geometry, vfs::Vfs, window::Window};
use render::{Init, Test};
use systems::{State, StateUpdate};

@@ -22,6 +22,9 @@ impl<'a, 'b> App<'a, 'b> {
let events = Events::new(world);
let window = Window::new(events.handle())?;

world.insert(Vfs::new()?);
world.insert(Geometry::new()?);

let mut dispatcher = DispatcherBuilder::new()
.with(StateUpdate::new(world), "state_update", &[])
.with_thread_local(Init::new(world)?)
@@ -29,8 +32,6 @@ impl<'a, 'b> App<'a, 'b> {
.build();
dispatcher.setup(world);

world.insert(Geometry::new()?);

Ok(Self {
is_running: true,
events,


+ 11
- 11
space-crush/src/app/render/init.rs 查看文件

@@ -1,6 +1,6 @@
use glc::{
misc::Bindable,
shader::{Program, Shader, Type},
shader::{Program, Type},
};
use log::{error, info};
use shrev::{EventChannel, ReaderId};
@@ -10,6 +10,7 @@ use crate::Error;

use super::super::misc::{
camera::Camera, events::WindowEvent, frame_counter::FrameCounter, geometry::Geometry,
load_program, vfs::Vfs,
};

/* Global */
@@ -37,21 +38,20 @@ pub struct Init {

impl Init {
pub fn new(world: &mut World) -> Result<Self, Error> {
let shaders = vec![
(Type::Vertex, include_str!("shader/noise.vert")),
(Type::Fragment, include_str!("shader/noise.frag")),
];
let program = Program::from_shaders_result(
shaders
.into_iter()
.map(|(t, s)| Shader::from_string(t, s.into())),
world.insert(Global::new()?);

let vfs = world.fetch::<Vfs>();
let program = load_program(
&vfs,
vec![
(Type::Vertex, "resources/shader/noise.vert"),
(Type::Fragment, "resources/shader/noise.frag"),
],
)?;
let window_events_id = world
.fetch_mut::<EventChannel<WindowEvent>>()
.register_reader();

world.insert(Global::new()?);

Ok(Self {
program,
window_events_id,


+ 12
- 10
space-crush/src/app/render/test.rs 查看文件

@@ -1,14 +1,17 @@
use glc::{
matrix::{Angle, Matrix4f},
misc::Bindable,
shader::{Program, Shader, Type, Uniform},
shader::{Program, Type, Uniform},
vector::Vector3f,
};
use specs::{ReadExpect, System, World};

use crate::Error;

use super::{super::misc::geometry::Geometry, init::Global};
use super::{
super::misc::{geometry::Geometry, load_program, vfs::Vfs},
init::Global,
};

pub struct Test {
program: Program,
@@ -17,14 +20,13 @@ pub struct Test {

impl Test {
pub fn new(world: &World) -> Result<Self, Error> {
let shaders = vec![
(Type::Vertex, include_str!("shader/quad.vert")),
(Type::Fragment, include_str!("shader/quad.frag")),
];
let program = Program::from_shaders_result(
shaders
.into_iter()
.map(|(t, s)| Shader::from_string(t, s.into())),
let vfs = world.fetch::<Vfs>();
let program = load_program(
&vfs,
vec![
(Type::Vertex, "resources/shader/quad.vert"),
(Type::Fragment, "resources/shader/quad.frag"),
],
)?;

let global = world.fetch::<Global>();


+ 35
- 1
space-crush/src/error.rs 查看文件

@@ -1,9 +1,22 @@
use std::io::Error as IoError;

use glc::error::Error as GlcError;
use glutin::{ContextError as GlutinContextError, CreationError as GlutinCreationError};
use thiserror::Error;
use vfs::VfsError;
use vfs_zip::Error as VfsZipError;

#[derive(Debug, Error)]
pub enum Error {
#[error("IO Error: {0}")]
IoError(IoError),

#[error("VFS Error: {0}")]
VfsError(VfsError),

#[error("VFS ZIP Error: {0}")]
VfsZipError(VfsZipError),

#[error("GLC Error: {0}")]
GlcError(GlcError),

@@ -14,7 +27,28 @@ pub enum Error {
GlutinCreationError(GlutinCreationError),

#[error("Unable to create OpenGL context")]
UnableToCreateContext,
CreateContext,

#[error("Unable to initialize VFS")]
InitVFS,
}

impl From<IoError> for Error {
fn from(err: IoError) -> Self {
Self::IoError(err)
}
}

impl From<VfsError> for Error {
fn from(err: VfsError) -> Self {
Self::VfsError(err)
}
}

impl From<VfsZipError> for Error {
fn from(err: VfsZipError) -> Self {
Self::VfsZipError(err)
}
}

impl From<GlcError> for Error {


Loading…
取消
儲存