Heresy 之前已經在《HTC Vive Pre 使用感想》裡,針對 HTC Vive Pre 的開箱文、到使用感想,做了一定的整理。而中間也有提過,Heresy 也有試著用 Valve 提供的 SDK、OpenVR 來開發程式了;這篇基本上算是紀錄一下 Heresy 目前對 OpenVR 的感想。
首先,OpenVR 目前支援 Windows、Linux 以及 Mac OS X 32,相關的檔案都放在 GitHub 上了,他的連結是:
而在要開始之前,要先講一下一件最重要的事,那就是:
OpenVR 雖然掛著「open」這個字,但是他並不是開放原始碼的專案!
他基本上,只是提供一個 API,然後提供自己針對 SteamVR 的實作(這部分只有 binary),所以,一般人沒辦法知道它的內部是怎麼做的,也沒辦法自己 debug。
相較之下,由 Razer 主導的 OSVR(Open Source Virtual Reality、官網)才算是真正「open」的環境…
另外他目前的版本編號,個人覺得有點混亂…
官方號稱是 1.0.0(連結)了,但是根據 GitHub 的紀錄,最新的卻應該是 0.9.21(兩邊的檔案都一樣、修改紀錄還一樣…);所以,看來應該是直接跳到 1.0 了吧…
不過,雖然官方號稱是 1.0 的正式版了,但是應該還有不少問題還沒修,至少 Heresy 自己也採到的問題(參考),並沒有修掉…文件也還不算完整。
總之,還是大概來看一下。官方的文件是:https://github.com/ValveSoftware/openvr/wiki/API-Documentation,基本上並沒有 tutorial 似的教學,所以還是得參考範例程式來看。(而且內容和實際的 API 還有不一樣的地方… orz)
OpenVR 所提供的基本上是 C++ 的 API,使用時須要引入「openvr.h」這個檔案,而裡面的東西使用的 namespace 是「vr」;在建置的時候,則是要連結 openvr_api.lib 這個 Lib 檔。
而他主要的介面(Interface),則包括了:
-
IVRSystem(文件)
IVRSystem 算是 OpenVR 環境下最基本的東西,要撰寫 OpenVR 的程式,一定要去初始化他;之後要取得控制器的狀態、以及其他相關的系統資訊,也都是要透過這個介面。
實際要使用的時候,基本上就是先透過 vr::VR_Init() 這個函式來做初始化、並取得 vr::IVRSystem 的指標,之後再做後續的操作(話說,實際上的界面和官方文件的已經不同了…);而最後結束時,再呼叫 vr::VR_Shutdown() 來把整個環境關閉。
-
IVRCompositor(文件)
輸出 OpenGL 或 Direct3D 所繪製的 3D 內容的介面,透過texture 接受繪製好的左右兩眼的畫面,並顯示在頭戴顯示器內。
它的操作邏輯,基本上就是在主迴圈中:
- 呼叫 WaitGetPoses() 來取得 VR 相關裝置的位置資訊
- 根據現有的資料繪製左右兩眼的畫面
- 修正鏡片造成的影響(distortion)
- Submit 左右兩眼的畫面給 IVRCompositor
針對這部分,官方有提供「hello_opengl」這個範例(連結)可以作為參考。他這邊是使用 SDL 來作為 OpenGL 的框架;其中對於 OpenGL 初學者來說比較麻煩的,應該會是他計算 distortion 的部分一定得用到 shader 才行…
-
IVROverlay(文件)
2D 內容的控制,可以想成浮在空中的一個平面;這個平面的位置,可以是絕對位置,或是相對於控制器/頭戴顯示器的位置。它的用途主要應該是用來呈現圖形介面、或是簡單的資訊。
在使用時,則是先要透過 CreateOverlay() 這個函式,來建立一個 overlay,並使用 VROverlayHandle_t 來做之後的操作、管理;而在建立好之後,必要的動作基本上還包括了設定他的大小、設定他在空間中的位置、設定內容、顯示狀態。之後,如果有更新,就在去更新圖片的內容即可。
另外, IVROverlay 也提供了簡單的事件管理,可以把控制器當作滑鼠來操作。
這部分的範例程式,可以參考官方的「helloworldoverlay」(連結),它裡面是使用 QT5 作為圖形介面,並透過 OpenGL Texture 的形式、來更新 OpenVR overlay 的內容。
-
IVRChaperone(文件)
存取 Chaperone、也就是環境的空間資訊。不過 Heresy 還沒研究過,官方似乎也沒對應的範例。
-
IVRRenderModels(文件)
取得用來繪製的 VR 裝置 3D 模型,在「hello_opengl」這個範例(連結)中也有用到。
當然,實際上 OpenVR 裡面還有很多其他的介面,但是不要說範例了,有的連官方都不見得有文件了,看來要用可能也只能看 Header 檔的註解了…
而目前 Heresy 也已經算是寫了幾個範例、並把本來的 OpenGL 程式成功地加入 OpenVR 的功能了;不過,都還只是顯示的部分而已,不包含控制和介面的部分。
至於目前的感想呢…這邊大概列一下:
-
官方資源不足,不管是文件還是範例,都相當不足,而且內容甚至有錯誤;再加上沒有導引式的教學,要上手應該相對有點難度。
-
某方面來說,SDK 本身是給開發 3D Graphics 的人用的,所以如果對 shader-based 的 OpenGL 或 Direct 3D 不熟的人來說,應該很難上手。
-
像是在計算 distortion 的時候,由於他除了計算形變之外,還會去計算 RGB 三色個別的位移,不用 shader 寫、而用 CPU 算的話,應該會對效能造成一定的影響…
-
-
程式要很重視效能、FPS 絕對要夠高,否則視覺效果會非常地糟糕;而如果 FPS 低到一定程度,甚至會沒辦法顯示。
-
由於透過 OpenVR 取得的攝影機位置,基本上包含了「預估」的成分在裡面,所以如果繪製的速度太慢,繪製的角度和頭真正的角度會有不同,甚至會造成畫面感覺是在抖動/跳動,感覺會很糟。
-
Heresy 這邊用於科學視算的程式,由於資料量太大,基本上也只能勉強在效能底線內了…說實話,體驗不算好。
-
簡單講,Heresy 不認為現在的 OpenGL / Direct 3D 會是一般的開發者會去直接碰的東西,連帶的 OpenVR 也不是很合適…因為,他們都相對太低階了、太底層了。
真要開發,或許還是直接用 Unreal 或 Unity 這類的遊戲引擎,會比較合適吧?
會不會有後續的文章?Heresy 只能說,應該不會去寫像是 OpenNI 或 Kinect for Windows SDK v2 這類的完整教學了,頂多零星地寫一些個別的東西吧…畢竟,真要寫下去,應該得花一堆時間弄 OpenGL 了…
[…] HTC Vive 後,Heresy 這邊一直有在研究怎麼用 OpenVR 這個 SDK 來開發 C++ 搭配 OpenGL […]
讚讚
[…] OpenVR 這類的 SDK,其實是有提供對應的函式、可以用來讀取控制器的 3D […]
讚讚
[…] 就有在試著用 Qt 搭配 OpenVR,開發支援 SteamVR 的虛擬實境的程式。當時在寫的時候,一部分是參考 GitHub […]
讚讚
[…] 這邊之前在取得 HTC Vive 後,有透過 OpenVR […]
讚讚
[…] OpenVR 撰寫的程式,系統也會同時去自動執行 SteamVR […]
讚讚
[…] 有寫了一篇《HTC Vive 開發方案:OpenVR 簡介》,大概介紹過 OpenVR(GitHub)粗略的架構了;當時 OpenVR 的版本還是 […]
讚讚
想請教一下,我如果用GLFW或glut建立出來的視窗,能否放到OpenVR場景裡, 要如何放進去呢?
我都只能顯示在桌面螢幕, 因為我要在VR場景裡建立視窗, 把圖片嵌在視窗裡
讚讚
你如果是要在 VR 環境顯示一個視窗,就需要自己把該視窗的畫面擷取下來,當作 overlay 來顯示。
讚讚
抱歉,上面的留言輸入錯了,刪不掉,可忽略或刪掉它,
Overlay它只有提供QT的範例, 那我一定要用QT才可顯示嗎?
我能否在Visual Studio的範例建個視窗,嵌到overlay裡,
就像QT overlay範例一樣,用Setwidget把QT widget放入VR場景裡,
另個問題是,我可執行QT overlay範例,在VR場景看到widget視窗,
請問那個widget視窗能否同時在桌面的電腦螢幕上顯示,
我想同時在VR場景和桌面電腦螢幕同時播出畫面,
就像Visual studio的 hellovr_opengl範例一樣,可同時播出
讚讚
1. 沒有限制一定要用 Qt,只要你能把視窗的畫面擷取下來、再以 OpenGL / Direct3D Texture 的形式傳給 OpenVR 就可以了。
2. 理論上可以,不過 Heresy 沒是過去改他。
建議請參考範例程式的註解
https://github.com/ValveSoftware/openvr/blob/master/samples/helloworldoverlay/main.cpp
讚讚
謝謝你的回覆,
我最近用Overlay發現一個問題, 它是把2D視窗放到3D場景裡,只要我頭向旁邊轉,那個2D視窗就會遠離我的視野了,請問2D視窗有沒有辦法固定住,無論我怎麼轉,它都固定嵌在我的眼前?
不知你有沒有做過2D固定的視窗
讚讚
個人會建議你先看一下官方的文件,確認一下他有那些函式。
https://github.com/ValveSoftware/openvr/wiki/IVROverlay_Overview
讚讚
請問若是要將一張照片分別顯示在左右眼
應該用IVROverlay還是IVRCompositor?
讚讚
要看你希望怎麼顯示,你的「分別顯示在左右眼」是什麼意思?
IVROverlay 就是在你指定的位置放一張圖,他會幫你處理好其他東西。
IVRCompositor 基本上則是全部自己控制,也可以做到上面的事情。
讚讚
感謝Heresy
我是有一對立體視覺拍攝的左右眼圖(jpg)
我想把這兩張分別顯示在HMD左右眼鏡頭上。
讚讚
如果是這個狀況,要使用 IVRCompositor
讚讚
讓人很納悶阿,說要相容於各種頭盔,api 卻又綁定了 SteamVR…
讚讚
用 OpenVR 訂好的介面,重新寫裡面的內容、去呼叫其他家 VR SDK 的函式庫…
很蠢。
讚讚
您好,想請問一下OpenVR中有沒有提供鏡片中間距離感應器的控制方法呢?
最近剛要開始碰VIVE應用開發,看到你這幾篇文章受益良多,感謝。
讚讚
如果你指的是要讀取瞳距的話,應該是「Prop_UserIpdMeters_Float」這個屬性值。
而在 IVRSettings 中,也有定義 k_pch_SteamVR_IPD_Float 這個 key。
至於要怎麼用,可能得自己摸了。
讚讚