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!("\nIVRExtendedDisplay was created");
|
||||||
println!("\tbounds: {:?}", ext.window_bounds());
|
println!("\tbounds: {:?}", ext.window_bounds());
|
||||||
println!("\teye output: {:?} {:?}", ext.eye_viewport(openvr::Eye::Left), ext.eye_viewport(openvr::Eye::Right));
|
println!("\teye output: {:?} {:?}", ext.eye_viewport(openvr::Eye::Left), ext.eye_viewport(openvr::Eye::Right));
|
||||||
/*
|
|
||||||
println!("Trying to create a compositor");
|
let comp = match openvr::compositor() {
|
||||||
match ivr.compositor() {
|
Ok(ext) => ext,
|
||||||
Err(err) => println!("Could not create compositor {:?}", err),
|
Err(err) => {
|
||||||
Ok(comp) => {
|
println!("Failed to create IVRCompositor subsystem {:?}", err);
|
||||||
println!("\tCreated one!");
|
return;
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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();
|
openvr::shutdown();
|
||||||
println!("Done! \\o/");
|
println!("Done! \\o/");
|
||||||
|
@ -51,7 +51,7 @@ pub struct TextureBounds {
|
|||||||
|
|
||||||
impl TextureBounds {
|
impl TextureBounds {
|
||||||
/// Convert a bounds to a openvr_bounds
|
/// 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{
|
openvr_sys::VRTextureBounds_t{
|
||||||
uMin: self.u_min,
|
uMin: self.u_min,
|
||||||
uMax: self.u_max,
|
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
|
/// 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
|
/// Check to see if the compositor is fullscreen
|
||||||
pub fn is_fullscreen(&self) -> bool {
|
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
|
/// Check if compositor can render a scene
|
||||||
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
|
|
||||||
pub fn can_render_scene(&self) -> bool {
|
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
|
/// Submits an opengl framebuffer as an eye to the render
|
||||||
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
|
|
||||||
pub fn submit(&self, eye: Eye, texture: usize, bounds: TextureBounds) {
|
pub fn submit(&self, eye: Eye, texture: usize, bounds: TextureBounds) {
|
||||||
let mut b = bounds.to_raw();
|
let mut b = bounds.to_raw();
|
||||||
let e = eye.to_raw();
|
let e = eye.to_raw();
|
||||||
unsafe {
|
|
||||||
use std::mem;
|
|
||||||
let t = mem::transmute(texture);
|
|
||||||
|
|
||||||
openvr_sys::VR_IVRCompositor_Submit(
|
unsafe {
|
||||||
self.0,
|
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,
|
e,
|
||||||
openvr_sys::GraphicsAPIConvention::OpenGL,
|
&mut t,
|
||||||
t,
|
|
||||||
&mut b as *mut openvr_sys::VRTextureBounds_t,
|
&mut b as *mut openvr_sys::VRTextureBounds_t,
|
||||||
openvr_sys::VRSubmitFlags_t::Default
|
EVRSubmitFlags_Submit_GlRenderBuffer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the poses
|
/// Get the poses
|
||||||
pub fn wait_get_poses(&self) -> TrackedDevicePoses {
|
pub fn wait_get_poses(&self) -> TrackedDevicePoses {
|
||||||
|
use std;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
|
||||||
let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed();
|
let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed();
|
||||||
openvr_sys::VR_IVRCompositor_WaitGetPoses(
|
|
||||||
self.0,
|
comp.WaitGetPoses.unwrap()(
|
||||||
&mut data[0],
|
&mut data[0],
|
||||||
16,
|
16,
|
||||||
std::ptr::null_mut(),
|
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 common;
|
||||||
pub mod system;
|
pub mod system;
|
||||||
pub mod extended_display;
|
pub mod extended_display;
|
||||||
|
pub mod compositor;
|
||||||
|
pub mod render_models;
|
||||||
|
pub mod subsystems;
|
||||||
|
|
||||||
pub use system::IVRSystem;
|
pub use system::IVRSystem;
|
||||||
pub use extended_display::IVRExtendedDisplay;
|
pub use extended_display::IVRExtendedDisplay;
|
||||||
|
pub use compositor::IVRCompositor;
|
||||||
|
pub use render_models::IVRRenderModels;
|
||||||
|
|
||||||
|
pub use subsystems::*;
|
||||||
|
|
||||||
pub use common::Eye;
|
pub use common::Eye;
|
||||||
|
|
||||||
@ -47,43 +54,3 @@ pub fn shutdown() {
|
|||||||
openvr_sys::VR_ShutdownInternal();
|
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