mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-22 16:25:36 +00:00
added support for render models subsystem
This commit is contained in:
3
examples/opengl.rs
Normal file
3
examples/opengl.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub fn main() {
|
||||
// init vr system
|
||||
}
|
@ -63,19 +63,31 @@ fn main() {
|
||||
println!("\nIVRExtendedDisplay was created");
|
||||
println!("\tbounds: {:?}", ext.window_bounds());
|
||||
println!("\teye output: {:?} {:?}", ext.eye_viewport(openvr::Eye::Left), ext.eye_viewport(openvr::Eye::Right));
|
||||
/*
|
||||
println!("Trying to create a compositor");
|
||||
match ivr.compositor() {
|
||||
Err(err) => println!("Could not create compositor {:?}", err),
|
||||
Ok(comp) => {
|
||||
println!("\tCreated one!");
|
||||
println!("\tis fullscreen = {}", comp.is_fullscreen());
|
||||
println!("\tis vsync = {}", comp.get_vsync());
|
||||
println!("\tcan render scene = {}", comp.can_render_scene());
|
||||
println!("\tgamma value = {}", comp.get_gamma());
|
||||
|
||||
let comp = match openvr::compositor() {
|
||||
Ok(ext) => ext,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRCompositor subsystem {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("\nIVRCompositor was created");
|
||||
println!("\tis fullscreen = {}", comp.is_fullscreen());
|
||||
println!("\tcan render scene = {}", comp.can_render_scene());
|
||||
|
||||
let model = match openvr::render_models() {
|
||||
Ok(ext) => ext,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRRenderModels subsystem {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("\nIVRRenderModels was created\n Count: {}", model.get_count());
|
||||
for i in 0..model.get_count() {
|
||||
println!("\t{}", model.get_name(i));
|
||||
}
|
||||
*/
|
||||
|
||||
openvr::shutdown();
|
||||
println!("Done! \\o/");
|
||||
|
@ -51,7 +51,7 @@ pub struct TextureBounds {
|
||||
|
||||
impl TextureBounds {
|
||||
/// Convert a bounds to a openvr_bounds
|
||||
fn to_raw(self) -> openvr_sys::VRTextureBounds_t {
|
||||
pub fn to_raw(self) -> openvr_sys::VRTextureBounds_t {
|
||||
openvr_sys::VRTextureBounds_t{
|
||||
uMin: self.u_min,
|
||||
uMax: self.u_max,
|
||||
|
@ -1,63 +1,66 @@
|
||||
use openvr_sys;
|
||||
use openvr_sys::Enum_EGraphicsAPIConvention::*;
|
||||
use openvr_sys::Enum_EVRSubmitFlags::*;
|
||||
use openvr_sys::Enum_EColorSpace::*;
|
||||
use common::*;
|
||||
|
||||
/// A VR compositor
|
||||
pub struct Compositor(*const ());
|
||||
pub struct IVRCompositor(*const ());
|
||||
|
||||
impl IVRCompositor {
|
||||
pub unsafe fn from_raw(ptr: *const ()) -> Self {
|
||||
IVRCompositor(ptr as *mut ())
|
||||
}
|
||||
|
||||
impl Compositor {
|
||||
/// Check to see if the compositor is fullscreen
|
||||
pub fn is_fullscreen(&self) -> bool {
|
||||
unsafe { openvr_sys::VR_IVRCompositor_IsFullscreen(self.0) }
|
||||
unsafe {
|
||||
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
|
||||
comp.IsFullscreen.unwrap()() > 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if vsync in enabled
|
||||
pub fn get_vsync(&self) -> Option<u64> {
|
||||
unsafe { openvr_sys::VR_IVRCompositor_GetVSync(self.0) }
|
||||
}
|
||||
|
||||
/// Set the vsync value
|
||||
pub fn set_vsync(&self, v: bool) {
|
||||
unsafe { openvr_sys::VR_IVRCompositor_SetVSync(self.0, v) }
|
||||
}
|
||||
|
||||
/// Check if vsync in enabled
|
||||
/// Check if compositor can render a scene
|
||||
pub fn can_render_scene(&self) -> bool {
|
||||
unsafe { openvr_sys::VR_IVRCompositor_CanRenderScene(self.0) }
|
||||
unsafe {
|
||||
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
|
||||
comp.CanRenderScene.unwrap()() > 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the gamma value
|
||||
pub fn get_gamma(&self) -> f32 {
|
||||
unsafe { openvr_sys::VR_IVRCompositor_GetGamma(self.0) }
|
||||
}
|
||||
|
||||
/// Get the gamma value
|
||||
pub fn set_gamma(&self, v: f32) {
|
||||
unsafe { openvr_sys::VR_IVRCompositor_SetGamma(self.0, v) }
|
||||
}
|
||||
|
||||
/// Submit an eye to the render
|
||||
/// Submits an opengl framebuffer as an eye to the render
|
||||
pub fn submit(&self, eye: Eye, texture: usize, bounds: TextureBounds) {
|
||||
let mut b = bounds.to_raw();
|
||||
let e = eye.to_raw();
|
||||
unsafe {
|
||||
use std::mem;
|
||||
let t = mem::transmute(texture);
|
||||
|
||||
openvr_sys::VR_IVRCompositor_Submit(
|
||||
self.0,
|
||||
unsafe {
|
||||
use std;
|
||||
|
||||
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
|
||||
let mut t = openvr_sys::Texture_t {
|
||||
eType: EGraphicsAPIConvention_API_OpenGL,
|
||||
eColorSpace: EColorSpace_ColorSpace_Auto,
|
||||
handle: texture as *mut std::os::raw::c_void,
|
||||
};
|
||||
|
||||
comp.Submit.unwrap()(
|
||||
e,
|
||||
openvr_sys::GraphicsAPIConvention::OpenGL,
|
||||
t,
|
||||
&mut t,
|
||||
&mut b as *mut openvr_sys::VRTextureBounds_t,
|
||||
openvr_sys::VRSubmitFlags_t::Default
|
||||
EVRSubmitFlags_Submit_GlRenderBuffer
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the poses
|
||||
pub fn wait_get_poses(&self) -> TrackedDevicePoses {
|
||||
use std;
|
||||
|
||||
unsafe {
|
||||
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
|
||||
let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed();
|
||||
openvr_sys::VR_IVRCompositor_WaitGetPoses(
|
||||
self.0,
|
||||
|
||||
comp.WaitGetPoses.unwrap()(
|
||||
&mut data[0],
|
||||
16,
|
||||
std::ptr::null_mut(),
|
||||
|
47
src/lib.rs
47
src/lib.rs
@ -5,9 +5,16 @@ use openvr_sys::Enum_EVRApplicationType::*;
|
||||
pub mod common;
|
||||
pub mod system;
|
||||
pub mod extended_display;
|
||||
pub mod compositor;
|
||||
pub mod render_models;
|
||||
pub mod subsystems;
|
||||
|
||||
pub use system::IVRSystem;
|
||||
pub use extended_display::IVRExtendedDisplay;
|
||||
pub use compositor::IVRCompositor;
|
||||
pub use render_models::IVRRenderModels;
|
||||
|
||||
pub use subsystems::*;
|
||||
|
||||
pub use common::Eye;
|
||||
|
||||
@ -47,43 +54,3 @@ pub fn shutdown() {
|
||||
openvr_sys::VR_ShutdownInternal();
|
||||
}
|
||||
}
|
||||
|
||||
/// gets the current vr system interface (initialization is required beforehand)
|
||||
pub fn system() -> Result<system::IVRSystem, openvr_sys::HmdError> {
|
||||
let mut err = EVRInitError_VRInitError_None;
|
||||
let name = std::ffi::CString::new("FnTable:IVRSystem_012").unwrap();
|
||||
let ptr = unsafe {
|
||||
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
|
||||
};
|
||||
|
||||
match err {
|
||||
EVRInitError_VRInitError_None => {
|
||||
unsafe {
|
||||
return Ok(IVRSystem::from_raw(ptr as *const ()));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// gets the current vr extended display interface (initialization is required beforehand)
|
||||
pub fn extended_display() -> Result<IVRExtendedDisplay, openvr_sys::HmdError> {
|
||||
let mut err = EVRInitError_VRInitError_None;
|
||||
let name = std::ffi::CString::new("FnTable:IVRExtendedDisplay_001").unwrap();
|
||||
let ptr = unsafe {
|
||||
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
|
||||
};
|
||||
|
||||
match err {
|
||||
EVRInitError_VRInitError_None => {
|
||||
unsafe {
|
||||
return Ok(IVRExtendedDisplay::from_raw(ptr as *const ()));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
106
src/render_models.rs
Normal file
106
src/render_models.rs
Normal file
@ -0,0 +1,106 @@
|
||||
use openvr_sys;
|
||||
use openvr_sys::Enum_EVRRenderModelError::*;
|
||||
|
||||
use std::string::String;
|
||||
use std::ptr::null_mut;
|
||||
use std::slice;
|
||||
use subsystems::render_models;
|
||||
|
||||
pub struct IVRRenderModels(*const ());
|
||||
|
||||
pub struct RenderModel(*mut openvr_sys::RenderModel_t);
|
||||
|
||||
impl Drop for RenderModel {
|
||||
/// will inform openvr that the memory for the render model is no longer required
|
||||
fn drop (&mut self) {
|
||||
unsafe {
|
||||
let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
|
||||
models.FreeRenderModel.unwrap()(
|
||||
self.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderModel {
|
||||
/// Returns an iterator that iterates over vertices
|
||||
pub fn vertex_iter(&self) -> slice::Iter<openvr_sys::RenderModel_Vertex_t> {
|
||||
unsafe {
|
||||
let slice = slice::from_raw_parts((*self.0).rVertexData, (*self.0).unVertexCount as usize);
|
||||
slice.iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator that iterates over indices
|
||||
pub fn index_iter(&self) -> slice::Iter<u16> {
|
||||
unsafe {
|
||||
let slice = slice::from_raw_parts((*self.0).rIndexData, (*self.0).unTriangleCount as usize);
|
||||
slice.iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// returns the unique identifier for the texture that the models uses
|
||||
pub fn texture_identifier(&self) -> usize {
|
||||
unsafe {
|
||||
(*self.0).diffuseTextureId as usize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IVRRenderModels {
|
||||
pub unsafe fn from_raw(ptr: *const ()) -> Self {
|
||||
IVRRenderModels(ptr as *mut ())
|
||||
}
|
||||
|
||||
/// Returns the amount of render models available
|
||||
pub fn get_count(&self) -> u32 {
|
||||
unsafe {
|
||||
let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
|
||||
|
||||
models.GetRenderModelCount.unwrap()()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the name of an available render model
|
||||
pub fn get_name(&self, index: u32) -> String {
|
||||
unsafe {
|
||||
let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
|
||||
let name_out = String::with_capacity(256);
|
||||
|
||||
let size = models.GetRenderModelName.unwrap()(
|
||||
index,
|
||||
name_out.as_ptr() as *mut i8,
|
||||
256
|
||||
);
|
||||
|
||||
if size > 0 {
|
||||
return String::from_raw_parts(name_out.as_ptr() as *mut _, (size - 1) as usize, (size - 1) as usize);
|
||||
} else {
|
||||
return String::from("");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Loads an render model into local memory
|
||||
pub fn load(&self, name: String) -> Result<RenderModel, openvr_sys::EVRRenderModelError> {
|
||||
unsafe {
|
||||
let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
|
||||
let mut resp: *mut openvr_sys::RenderModel_t = null_mut();
|
||||
|
||||
let err = models.LoadRenderModel_Async.unwrap()(
|
||||
name.as_ptr() as *mut i8,
|
||||
&mut resp
|
||||
);
|
||||
|
||||
match err {
|
||||
EVRRenderModelError_VRRenderModelError_None => {
|
||||
Ok(RenderModel ( resp ))
|
||||
},
|
||||
_ => {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
89
src/subsystems.rs
Normal file
89
src/subsystems.rs
Normal file
@ -0,0 +1,89 @@
|
||||
extern crate openvr_sys;
|
||||
use openvr_sys::Enum_EVRInitError::*;
|
||||
|
||||
use system::IVRSystem;
|
||||
use extended_display::IVRExtendedDisplay;
|
||||
use compositor::IVRCompositor;
|
||||
use render_models::IVRRenderModels;
|
||||
|
||||
use std;
|
||||
|
||||
/// gets the current vr system interface (initialization is required beforehand)
|
||||
pub fn system() -> Result<IVRSystem, openvr_sys::HmdError> {
|
||||
let mut err = EVRInitError_VRInitError_None;
|
||||
let name = std::ffi::CString::new("FnTable:IVRSystem_012").unwrap();
|
||||
let ptr = unsafe {
|
||||
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
|
||||
};
|
||||
|
||||
match err {
|
||||
EVRInitError_VRInitError_None => {
|
||||
unsafe {
|
||||
return Ok(IVRSystem::from_raw(ptr as *const ()));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// gets the current vr extended display interface (initialization is required beforehand)
|
||||
pub fn extended_display() -> Result<IVRExtendedDisplay, openvr_sys::HmdError> {
|
||||
let mut err = EVRInitError_VRInitError_None;
|
||||
let name = std::ffi::CString::new("FnTable:IVRExtendedDisplay_001").unwrap();
|
||||
let ptr = unsafe {
|
||||
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
|
||||
};
|
||||
|
||||
match err {
|
||||
EVRInitError_VRInitError_None => {
|
||||
unsafe {
|
||||
return Ok(IVRExtendedDisplay::from_raw(ptr as *const ()));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// gets the current vr extended display interface (initialization is required beforehand)
|
||||
pub fn compositor() -> Result<IVRCompositor, openvr_sys::HmdError> {
|
||||
let mut err = EVRInitError_VRInitError_None;
|
||||
let name = std::ffi::CString::new("FnTable:IVRCompositor_013").unwrap();
|
||||
let ptr = unsafe {
|
||||
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
|
||||
};
|
||||
|
||||
match err {
|
||||
EVRInitError_VRInitError_None => {
|
||||
unsafe {
|
||||
return Ok(IVRCompositor::from_raw(ptr as *const ()));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// gets the current vr extended display interface (initialization is required beforehand)
|
||||
pub fn render_models() -> Result<IVRRenderModels, openvr_sys::HmdError> {
|
||||
let mut err = EVRInitError_VRInitError_None;
|
||||
let name = std::ffi::CString::new("FnTable:IVRRenderModels_005").unwrap();
|
||||
let ptr = unsafe {
|
||||
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
|
||||
};
|
||||
|
||||
match err {
|
||||
EVRInitError_VRInitError_None => {
|
||||
unsafe {
|
||||
return Ok(IVRRenderModels::from_raw(ptr as *const ()));
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user