/// <summary> /// I really, really want to make this asynchronous so that we can load render models on the fly without interupting the experience. /// I need to look more into how we can accomplish this without casuing errors in OpenGL. /// </summary> /// <returns></returns> public static GLRenderModels Create(OpenVRScene scene) { const int retryInterval = 10; var models = new Dictionary <int, GLRenderModel>(); foreach (int trackedDeviceIndex in OpenVRUtil.DeviceIndexes) { if (trackedDeviceIndex == OpenVR.k_unTrackedDeviceIndex_Hmd) { continue; // dont want to render the actual HMD! it would block your face! (yep i did that) } if (!scene.IsConnected(trackedDeviceIndex)) { continue; } string renderModelName = scene.DeviceInfo(trackedDeviceIndex, ETrackedDeviceProperty.Prop_RenderModelName_String) .Validate(propErr => new InvalidOperationException($"Failed to retrieve prop name for connected tracked device: {propErr}")); // load render model async IntPtr renderModelPtr = IntPtr.Zero; EVRRenderModelError rmErr = EVRRenderModelError.Loading; while (rmErr == EVRRenderModelError.Loading) // is this seriously how im supposed to do this? no callback? { rmErr = OpenVR.RenderModels.LoadRenderModel_Async(renderModelName, ref renderModelPtr); Thread.Sleep(retryInterval); // async seems to be breaking opengl!? //await Task.Delay(retryInterval); // try again every 0.1 seconds } if (rmErr != EVRRenderModelError.None || renderModelPtr == IntPtr.Zero) { throw new InvalidOperationException($"Failed to load Render Model: {renderModelName}"); } var renderModel = (RenderModel_t)Marshal.PtrToStructure(renderModelPtr, typeof(RenderModel_t)); // load the render texture async IntPtr texturePtr = IntPtr.Zero; rmErr = EVRRenderModelError.Loading; while (rmErr == EVRRenderModelError.Loading) // is this seriously how im supposed to do this? no callback? { rmErr = OpenVR.RenderModels.LoadTexture_Async(renderModel.diffuseTextureId, ref texturePtr); Thread.Sleep(retryInterval); // async seems to be breaking opengl? //await Task.Delay(retryInterval); // try again every 0.1 seconds } if (rmErr != EVRRenderModelError.None || texturePtr == IntPtr.Zero) { throw new InvalidOperationException($"Failed to load texture for Render Model: {renderModelName}"); } var diffuseTexture = (RenderModel_TextureMap_t)Marshal.PtrToStructure(texturePtr, typeof(RenderModel_TextureMap_t)); models[trackedDeviceIndex] = GLRenderModel.Create(renderModelName, renderModel, diffuseTexture); OpenVR.RenderModels.FreeRenderModel(renderModelPtr); OpenVR.RenderModels.FreeTexture(texturePtr); } return(new GLRenderModels(scene, models)); }
/// <summary> /// I really, really want to make this asynchronous so that we can load render models on the fly without interupting the experience. /// I need to look more into how we can accomplish this without casuing errors in OpenGL. /// </summary> /// <returns></returns> public static GLRenderModels Create(OpenVRScene scene) { const int retryInterval = 10; var models = new Dictionary<int, GLRenderModel>(); foreach (int trackedDeviceIndex in OpenVRUtil.DeviceIndexes) { if (trackedDeviceIndex == OpenVR.k_unTrackedDeviceIndex_Hmd) continue; // dont want to render the actual HMD! it would block your face! (yep i did that) if (!scene.IsConnected(trackedDeviceIndex)) continue; string renderModelName = scene.DeviceInfo(trackedDeviceIndex, ETrackedDeviceProperty.Prop_RenderModelName_String) .Validate(propErr => new InvalidOperationException($"Failed to retrieve prop name for connected tracked device: {propErr}")); // load render model async IntPtr renderModelPtr = IntPtr.Zero; EVRRenderModelError rmErr = EVRRenderModelError.Loading; while (rmErr == EVRRenderModelError.Loading) // is this seriously how im supposed to do this? no callback? { rmErr = OpenVR.RenderModels.LoadRenderModel_Async(renderModelName, ref renderModelPtr); Thread.Sleep(retryInterval); // async seems to be breaking opengl!? //await Task.Delay(retryInterval); // try again every 0.1 seconds } if (rmErr != EVRRenderModelError.None || renderModelPtr == IntPtr.Zero) throw new InvalidOperationException($"Failed to load Render Model: {renderModelName}"); var renderModel = (RenderModel_t)Marshal.PtrToStructure(renderModelPtr, typeof(RenderModel_t)); // load the render texture async IntPtr texturePtr = IntPtr.Zero; rmErr = EVRRenderModelError.Loading; while (rmErr == EVRRenderModelError.Loading) // is this seriously how im supposed to do this? no callback? { rmErr = OpenVR.RenderModels.LoadTexture_Async(renderModel.diffuseTextureId, ref texturePtr); Thread.Sleep(retryInterval); // async seems to be breaking opengl? //await Task.Delay(retryInterval); // try again every 0.1 seconds } if (rmErr != EVRRenderModelError.None || texturePtr == IntPtr.Zero) throw new InvalidOperationException($"Failed to load texture for Render Model: {renderModelName}"); var diffuseTexture = (RenderModel_TextureMap_t)Marshal.PtrToStructure(texturePtr, typeof(RenderModel_TextureMap_t)); models[trackedDeviceIndex] = GLRenderModel.Create(renderModelName, renderModel, diffuseTexture); OpenVR.RenderModels.FreeRenderModel(renderModelPtr); OpenVR.RenderModels.FreeTexture(texturePtr); } return new GLRenderModels(scene, models); }