added support for render models subsystem

This commit is contained in:
Rene Eichhorn
2016-05-04 18:57:01 +02:00
parent ff9743f9cf
commit a5598243bb
7 changed files with 268 additions and 88 deletions

3
examples/opengl.rs Normal file
View File

@ -0,0 +1,3 @@
pub fn main() {
// init vr system
}

View File

@ -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!");
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!("\tis vsync = {}", comp.get_vsync());
println!("\tcan render scene = {}", comp.can_render_scene());
println!("\tgamma value = {}", comp.get_gamma());
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/");

View File

@ -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,

View File

@ -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(),

View File

@ -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
View 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
View 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);
}
}
}