mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-12-16 17:08:48 +00:00
fixed some render_model bugs, added opengl/glium sample that renders sample rendermodel
This commit is contained in:
@@ -9,6 +9,7 @@ use subsystems::render_models;
|
||||
pub struct IVRRenderModels(*const ());
|
||||
|
||||
pub struct RenderModel(*mut openvr_sys::RenderModel_t);
|
||||
pub struct RenderModelTexture(*mut openvr_sys::RenderModel_TextureMap_t);
|
||||
|
||||
impl Drop for RenderModel {
|
||||
/// will inform openvr that the memory for the render model is no longer required
|
||||
@@ -22,6 +23,18 @@ impl Drop for RenderModel {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RenderModelTexture {
|
||||
/// 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.FreeTexture.unwrap()(
|
||||
self.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderModel {
|
||||
/// Returns an iterator that iterates over vertices
|
||||
pub fn vertex_iter(&self) -> slice::Iter<openvr_sys::RenderModel_Vertex_t> {
|
||||
@@ -34,15 +47,77 @@ impl RenderModel {
|
||||
/// 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);
|
||||
let slice = slice::from_raw_parts((*self.0).rIndexData, (*self.0).unTriangleCount as usize * 3);
|
||||
slice.iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// returns the unique identifier for the texture that the models uses
|
||||
pub fn texture_identifier(&self) -> usize {
|
||||
/// asynchronosly loads the texture for the current render model
|
||||
/// see IVRRenderModels::load_async for info how openvr async work
|
||||
pub fn load_texture_async(&self) -> Result<RenderModelTexture, openvr_sys::Enum_EVRRenderModelError> {
|
||||
unsafe {
|
||||
(*self.0).diffuseTextureId as usize
|
||||
let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
|
||||
let mut resp: *mut openvr_sys::RenderModel_TextureMap_t = null_mut();
|
||||
|
||||
let err = models.LoadTexture_Async.unwrap()(
|
||||
(*self.0).diffuseTextureId,
|
||||
&mut resp
|
||||
);
|
||||
|
||||
match err {
|
||||
EVRRenderModelError_VRRenderModelError_None => {
|
||||
Ok(RenderModelTexture (resp))
|
||||
},
|
||||
_ => {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// loads the texture for current model
|
||||
pub fn load_texture(&self) -> Result<RenderModelTexture, openvr_sys::Enum_EVRRenderModelError> {
|
||||
use std;
|
||||
|
||||
loop {
|
||||
let result = self.load_texture_async();
|
||||
match result {
|
||||
Ok(texture) => {
|
||||
return Ok(texture);
|
||||
},
|
||||
Err(err) => {
|
||||
match err {
|
||||
EVRRenderModelError_VRRenderModelError_Loading => {
|
||||
// ask again later
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderModelTexture {
|
||||
/// Returns the dimension from the texture (width, height)
|
||||
pub fn dimension(&self) -> (usize, usize) {
|
||||
unsafe {
|
||||
((*self.0).unWidth as usize, (*self.0).unHeight as usize)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a 1 dimensional vector of pixels, format: rgba@32
|
||||
pub fn to_vec(&self) -> Vec<u8> {
|
||||
unsafe {
|
||||
let dimension = self.dimension();
|
||||
let slice = slice::from_raw_parts((*self.0).rubTextureMapData, dimension.0 * dimension.1 * 4);
|
||||
let mut vec = Vec::new();
|
||||
vec.extend_from_slice(slice);
|
||||
vec
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,16 +157,51 @@ impl IVRRenderModels {
|
||||
}
|
||||
|
||||
/// Loads an render model into local memory
|
||||
/// blocks the thread and waits until driver responds with model
|
||||
pub fn load(&self, name: String) -> Result<RenderModel, openvr_sys::EVRRenderModelError> {
|
||||
use std;
|
||||
|
||||
loop {
|
||||
let result = self.load_async(name.clone());
|
||||
match result {
|
||||
Ok(model) => {
|
||||
return Ok(model);
|
||||
},
|
||||
Err(err) => {
|
||||
match err {
|
||||
EVRRenderModelError_VRRenderModelError_Loading => {
|
||||
// ask again later
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads an render model into local memory
|
||||
/// When called for the first time openvr will start to load the model into memory
|
||||
/// In the mean time this call will respond with EVRRenderModelError_VRRenderModelError_Loading
|
||||
/// It is designed to be used wihtin the render loop as it won't block the user, for sync usage use load()
|
||||
pub fn load_async(&self, name: String) -> Result<RenderModel, openvr_sys::EVRRenderModelError> {
|
||||
use std;
|
||||
|
||||
unsafe {
|
||||
let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
|
||||
let mut resp: *mut openvr_sys::RenderModel_t = null_mut();
|
||||
let cname = std::ffi::CString::new(name.as_str()).unwrap();
|
||||
let rawname = cname.into_raw();
|
||||
|
||||
let err = models.LoadRenderModel_Async.unwrap()(
|
||||
name.as_ptr() as *mut i8,
|
||||
rawname,
|
||||
&mut resp
|
||||
);
|
||||
|
||||
let _ = std::ffi::CString::from_raw(rawname);
|
||||
|
||||
match err {
|
||||
EVRRenderModelError_VRRenderModelError_None => {
|
||||
Ok(RenderModel ( resp ))
|
||||
|
||||
@@ -635,7 +635,7 @@ pub enum Enum_EOverlayDirection {
|
||||
EOverlayDirection_OverlayDirection_Count = 4,
|
||||
}
|
||||
pub type EOverlayDirection = Enum_EOverlayDirection;
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(u32)]
|
||||
pub enum Enum_EVRRenderModelError {
|
||||
EVRRenderModelError_VRRenderModelError_None = 0,
|
||||
|
||||
Reference in New Issue
Block a user