Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic FFI library target, API version 1 #174

Merged
merged 15 commits into from
Jan 10, 2022
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ publish = false

[workspace]
members = [
"lib/ffi",
"lib/m3d",
"lib/splay",
"lib/tiff",
Expand Down
4 changes: 2 additions & 2 deletions bin/convert/layers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ impl LevelLayers {

LevelData {
size: (self.size.0 as i32, self.size.1 as i32),
meta,
height,
meta: meta.into_boxed_slice(),
height: height.into_boxed_slice(),
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions bin/level/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum Input {

pub struct LevelView {
render: Render,
_level: level::Level,
level: level::Level,
cam: space::Camera,
input: Input,

Expand Down Expand Up @@ -123,7 +123,7 @@ impl LevelView {

LevelView {
render,
_level: level,
level,
cam: space::Camera {
loc: cgmath::vec3(0.0, 0.0, 400.0),
rot: cgmath::Quaternion::new(1.0, 0.0, 0.0, 0.0),
Expand Down Expand Up @@ -372,6 +372,7 @@ impl Application for LevelView {
self.render.draw_world(
&mut encoder,
&mut Batcher::new(),
&self.level,
&self.cam,
targets,
device,
Expand Down
10 changes: 8 additions & 2 deletions bin/road/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,8 +923,14 @@ impl Application for Game {
label: Some("Draw"),
});

self.render
.draw_world(&mut encoder, &mut self.batcher, &self.cam, targets, device);
self.render.draw_world(
&mut encoder,
&mut self.batcher,
&self.level,
&self.cam,
targets,
device,
);

/*
self.render.debug.draw_lines(
Expand Down
2 changes: 1 addition & 1 deletion config/settings-macos-topdown.ron
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
height: 300,
target_overhead: 200,
speed: 1,
depth_range: (10, 1000),
depth_range: (10, 2000),
),
other: (
count: 10, // number of NPC vangers
Expand Down
2 changes: 1 addition & 1 deletion config/settings.template.ron
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
height: 300,
target_overhead: 200,
speed: 1,
depth_range: (10, 1000),
depth_range: (10, 2000),
),
other: (
count: 10, // number of NPC vangers
Expand Down
14 changes: 14 additions & 0 deletions lib/ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "vangers-ffi"
version = "0.1.0"
workspace = "../.."
authors = ["Dzmitry Malyshau <kvarkus@gmail.com>"]
edition = "2021"

[lib]
crate-type = ["staticlib"]

[dependencies]
vangers = { path = "../.." }
futures = "0.3"
wgpu = { git = "https://github.com/gfx-rs/wgpu", rev = "c8d572a", features = [] }
203 changes: 203 additions & 0 deletions lib/ffi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
//! Rusty Vangers FFI bindings.
//! Matches "lib/renderer/src/renderer/scene/rust/vange_rs.h"
//! See https://github.com/KranX/Vangers/pull/517

use futures::executor::LocalPool;
use std::ptr;

#[repr(C)]
#[derive(Default)]
pub struct Vector3 {
x: f32,
y: f32,
z: f32,
}

#[repr(C)]
#[derive(Default)]
pub struct Quaternion {
x: f32,
y: f32,
z: f32,
w: f32,
}

#[repr(C)]
#[derive(Default)]
pub struct Transform {
position: Vector3,
rotation: Quaternion,
}

#[repr(C)]
pub struct Rect {
x: i32,
y: i32,
width: i32,
height: i32,
}

#[repr(C)]
#[derive(Default)]
pub struct CameraDescription {
fov: f32,
aspect: f32,
near: f32,
far: f32,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct MapDescription {
width: i32,
height: i32,
lines: *const *const u8,
material_begin_offsets: *const u8,
material_end_offsets: *const u8,
material_count: i32,
}

#[derive(Default)]
struct Camera {
desc: CameraDescription,
transform: Transform,
}

struct LevelContext {
desc: MapDescription,
render: vangers::render::Render,
level: vangers::level::Level,
}

pub struct Context {
level: Option<LevelContext>,
render_config: vangers::config::settings::Render,
color_format: wgpu::TextureFormat,
queue: wgpu::Queue,
device: wgpu::Device,
downlevel_caps: wgpu::DownlevelCapabilities,
_instance: wgpu::Instance,
camera: Camera,
}

#[no_mangle]
pub extern "C" fn rv_init() -> Option<ptr::NonNull<Context>> {
use vangers::config::settings as st;

let mut task_pool = LocalPool::new();
kvark marked this conversation as resolved.
Show resolved Hide resolved

let instance = wgpu::Instance::new(wgpu::Backends::all());
let adapter = task_pool.run_until(instance.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: None, //TODO
force_fallback_adapter: false,
}))?;
let (device, queue) = task_pool
.run_until(adapter.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
limits: wgpu::Limits::default(),
},
None,
))
.ok()?;

let ctx = Context {
level: None,
render_config: st::Render {
wgpu_trace_path: String::new(),
light: st::Light {
pos: [1.0, 2.0, 4.0, 0.0],
color: [1.0, 1.0, 1.0, 1.0],
shadow: st::Shadow {
size: 0,
terrain: st::ShadowTerrain::RayTraced,
},
},
terrain: st::Terrain::RayTraced,
fog: st::Fog {
color: [0.1, 0.2, 0.3, 1.0],
depth: 50.0,
},
debug: st::DebugRender::default(),
},
color_format: wgpu::TextureFormat::Rgba8UnormSrgb,
queue,
device,
downlevel_caps: adapter.get_downlevel_properties(),
_instance: instance,
camera: Default::default(),
};
let ptr = Box::into_raw(Box::new(ctx));
ptr::NonNull::new(ptr)
}

#[no_mangle]
pub unsafe extern "C" fn rv_exit(ctx: *mut Context) {
let _ctx = Box::from_raw(ctx);
}

#[no_mangle]
pub extern "C" fn rv_camera_init(ctx: &mut Context, desc: CameraDescription) {
ctx.camera.desc = desc;
}

#[no_mangle]
pub extern "C" fn rv_camera_set_transform(ctx: &mut Context, transform: Transform) {
ctx.camera.transform = transform;
}

#[no_mangle]
pub extern "C" fn rv_map_init(ctx: &mut Context, desc: MapDescription) {
let terrains = (0..desc.material_count)
.map(|i| unsafe {
let mut tc = vangers::level::TerrainConfig::default();
tc.colors.start = *desc.material_begin_offsets.offset(i as isize);
tc.colors.end = *desc.material_end_offsets.offset(i as isize);
tc
})
.collect::<Box<[_]>>();

let total = (desc.width * desc.height) as usize;
let level = vangers::level::Level {
size: (desc.width, desc.height),
flood_map: vec![].into_boxed_slice(),
flood_section_power: 0, //TODO
height: vec![0; total].into_boxed_slice(),
meta: vec![0; total].into_boxed_slice(),
palette: [[0; 4]; 0x100], //TODO
terrains,
};

let render = vangers::render::Render::new(
&ctx.device,
&ctx.queue,
&ctx.downlevel_caps,
&level,
&[[0; 4]; 0x100], //TODO: objects palette
&ctx.render_config,
ctx.color_format,
// extent only matters for "scatter" style rendering
wgpu::Extent3d {
width: 0,
height: 0,
depth_or_array_layers: 0,
},
);
ctx.level = Some(LevelContext {
desc,
render,
level,
});
}

#[no_mangle]
pub extern "C" fn rv_map_exit(ctx: &mut Context) {
ctx.level = None;
}

#[no_mangle]
pub extern "C" fn rv_map_request_update(ctx: &mut Context, region: Rect) {
//TODO
}
2 changes: 1 addition & 1 deletion src/config/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl Backend {
}
}

#[derive(Copy, Clone, Deserialize)]
#[derive(Copy, Clone, Default, Deserialize)]
pub struct DebugRender {
pub max_vertices: usize,
pub collision_shapes: bool,
Expand Down
8 changes: 2 additions & 6 deletions src/level/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl Power {
}
}

#[derive(Clone)]
#[derive(Clone, Default)]
pub struct TerrainConfig {
pub shadow_offset: u8,
pub height_shift: u8,
Expand Down Expand Up @@ -45,11 +45,7 @@ impl LevelConfig {
.get("Terrain Max")
.map_or(8, |value| value.parse::<usize>().unwrap());
let mut terrains = (0..terra_count)
.map(|_| TerrainConfig {
shadow_offset: 0,
height_shift: 0,
colors: 0..0,
})
.map(|_| TerrainConfig::default())
.collect::<Box<[_]>>();

for (t, val) in terrains
Expand Down
Loading