engine/util: rework file::resource api
parent
193ead1eb7
commit
05dd81fa4f
|
@ -107,8 +107,8 @@ impl Main {
|
|||
};
|
||||
|
||||
let material = renderer.add_resource(PBRMaterialBuilder {
|
||||
diffuse: Texture::from_image(String::from("assets/test-128px.png")),
|
||||
roughness: Texture::from_image(String::from("assets/test-128px-roughness.png")),
|
||||
diffuse: Texture::from_image(String::from("//assets/test-128px.png")),
|
||||
roughness: Texture::from_image(String::from("//assets/test-128px-roughness.png")),
|
||||
}.build());
|
||||
|
||||
for x in -20..20 {
|
||||
|
|
|
@ -38,8 +38,9 @@ impl<T: ChannelLayoutVulkan> Texture<T> {
|
|||
match self {
|
||||
Texture::<T>::Color(c) => c.vulkan_from_value(graphics_queue),
|
||||
Texture::<T>::ImageRef(r) => {
|
||||
let path = &file::resource_path(r.clone());
|
||||
let img = Arc::new(image::open(path).unwrap());
|
||||
let format = image::ImageFormat::from_path(r).unwrap();
|
||||
let r = file::resource(r.clone()).unwrap();
|
||||
let img = Arc::new(image::load(r, format).unwrap());
|
||||
T::vulkan_from_image(img, graphics_queue)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ impl Forward {
|
|||
render_pass: Arc<dyn vf::RenderPassAbstract + Send + Sync>,
|
||||
) -> Forward {
|
||||
let vertex_shader = shaders::ShaderDefinition {
|
||||
name: "engine/shaders/forward_vert.spv".to_string(),
|
||||
name: "//engine/shaders/forward_vert.spv".to_string(),
|
||||
ty: vps::GraphicsShaderType::Vertex,
|
||||
inputs: vec![
|
||||
vps::ShaderInterfaceDefEntry {
|
||||
|
@ -95,7 +95,7 @@ impl Forward {
|
|||
}.load_into(device.clone()).expect("could not load vertex shader");
|
||||
|
||||
let fragment_shader = shaders::ShaderDefinition {
|
||||
name: "engine/shaders/forward_frag.spv".to_string(),
|
||||
name: "//engine/shaders/forward_frag.spv".to_string(),
|
||||
ty: vps::GraphicsShaderType::Fragment,
|
||||
inputs: vec![
|
||||
vps::ShaderInterfaceDefEntry {
|
||||
|
|
|
@ -24,6 +24,8 @@ use vulkano::descriptor::pipeline_layout as vdp;
|
|||
use vulkano::device as vd;
|
||||
use vulkano::pipeline::shader as vps;
|
||||
|
||||
use crate::util::file;
|
||||
|
||||
pub struct ShaderDefinition {
|
||||
pub name: String,
|
||||
pub ty: vps::GraphicsShaderType,
|
||||
|
@ -33,14 +35,31 @@ pub struct ShaderDefinition {
|
|||
pub push_constants: Vec<vdp::PipelineLayoutDescPcRange>,
|
||||
}
|
||||
|
||||
impl ShaderDefinition {
|
||||
pub fn load_into(self, device: Arc<vd::Device>) -> Result<LoadedShader, String> {
|
||||
fn stringify(x: std::io::Error) -> String { format!("IO error: {}", x) }
|
||||
#[derive(Debug)]
|
||||
pub enum ShaderError {
|
||||
ResourceError(file::ResourceError),
|
||||
IOError(std::io::Error),
|
||||
}
|
||||
|
||||
let path = &crate::util::file::resource_path(self.name.clone());
|
||||
let mut f = File::open(path).map_err(stringify)?;
|
||||
impl From<file::ResourceError> for ShaderError {
|
||||
fn from(v: file::ResourceError) -> Self {
|
||||
ShaderError::ResourceError(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for ShaderError {
|
||||
fn from(v: std::io::Error) -> Self {
|
||||
ShaderError::IOError(v)
|
||||
}
|
||||
}
|
||||
|
||||
type Result<T> = std::result::Result<T, ShaderError>;
|
||||
|
||||
impl ShaderDefinition {
|
||||
pub fn load_into(self, device: Arc<vd::Device>) -> Result<LoadedShader> {
|
||||
let mut r = file::resource(self.name.clone())?;
|
||||
let mut v = vec![];
|
||||
f.read_to_end(&mut v).map_err(stringify)?;
|
||||
r.read_to_end(&mut v)?;
|
||||
|
||||
let module = unsafe {
|
||||
vps::ShaderModule::new(device.clone(), &v).unwrap()
|
||||
|
|
|
@ -18,23 +18,75 @@ use std::path;
|
|||
|
||||
use runfiles::Runfiles;
|
||||
|
||||
pub fn resource_path(name: String) -> path::PathBuf {
|
||||
fn stringify(x: std::io::Error) -> String { format!("IO error: {}", x) }
|
||||
#[derive(Debug)]
|
||||
pub enum ResourceError {
|
||||
InvalidPath,
|
||||
NotFound,
|
||||
NoRunfiles,
|
||||
Other(std::io::Error),
|
||||
}
|
||||
|
||||
match Runfiles::create().map_err(stringify) {
|
||||
Err(_) => {
|
||||
let exe = std::env::current_exe().unwrap();
|
||||
let p = exe.parent().unwrap().join("..").join(name.clone());
|
||||
//let p = path::Path::new(".").join(name.clone());
|
||||
if !p.exists() {
|
||||
panic!("Could not load resource '{}', not found in runfiles or bare files (at {:?})", name, p);
|
||||
}
|
||||
log::info!("Loaded resource from bare file: {}", name);
|
||||
p
|
||||
},
|
||||
Ok(r) => {
|
||||
log::info!("Loaded resource from runfiles: {}", name.clone());
|
||||
r.rlocation(format!("abrasion/{}", name))
|
||||
type Result<T> = std::result::Result<T, ResourceError>;
|
||||
|
||||
pub enum Resource {
|
||||
File(std::io::BufReader<std::fs::File>),
|
||||
}
|
||||
|
||||
impl std::io::Read for Resource {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
match self {
|
||||
Resource::File(r) => r.read(buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::io::BufRead for Resource {
|
||||
fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
|
||||
match self {
|
||||
Resource::File(r) => r.fill_buf()
|
||||
}
|
||||
}
|
||||
fn consume(&mut self, amt: usize) {
|
||||
match self {
|
||||
Resource::File(r) => r.consume(amt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::io::Seek for Resource {
|
||||
fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
|
||||
match self {
|
||||
Resource::File(r) => r.seek(pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resource(name: String) -> Result<Resource>
|
||||
{
|
||||
// Ensure name has //-prefix.
|
||||
let rel = name.strip_prefix("//").ok_or(ResourceError::InvalidPath)?;
|
||||
// Ensure no / prefix or suffix.
|
||||
if rel.starts_with("/") || rel.ends_with("/") {
|
||||
return Err(ResourceError::InvalidPath);
|
||||
}
|
||||
// Ensure no double slash elsewhere in the path.
|
||||
if rel.contains("//") {
|
||||
return Err(ResourceError::InvalidPath);
|
||||
}
|
||||
|
||||
if let Ok(r) = Runfiles::create() {
|
||||
// TODO(q3k): unhardcode workspace name?
|
||||
let workspace = format!("abrasion/{}", rel);
|
||||
let loc = r.rlocation(workspace);
|
||||
std::fs::File::open(loc).map_err(|e| {
|
||||
match e.kind() {
|
||||
std::io::ErrorKind::NotFound => ResourceError::NotFound,
|
||||
_ => ResourceError::Other(e),
|
||||
}
|
||||
}).map(|f| {
|
||||
Resource::File(std::io::BufReader::new(f))
|
||||
})
|
||||
} else {
|
||||
return Err(ResourceError::NoRunfiles);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue