2014-11-05 34 views
0

背景克隆呈現給窗口/屏幕上的圖像,用於處理

予有發展汽車控制系統的程序,它使用的TCL腳本語言和OpenGL的組合來附加地呈現行駛的汽車的行爲一條路。

我正在做的是實現OculusRift對它的支持,到目前爲止設法解決sesor部分,並右鍵單擊汽車駕駛的窗口,我可以將它發送到oculus裂谷。到目前爲止,它看起來像這樣:Youtube-Video

程序的可視部分有大量的已經功能包括瞭如調整FOV,魚眼鏡頭,攝像頭的方向,汽車內部視圖等

環視後選項軟件文件夾,我發現如下的TCL文件:

// ... cut here 

gl pushmatrix 
gl loadidentity 
gl translate $x $y $z 
gl rotate $xrot 1 0 0 
gl rotate $yrot 0 1 0 
gl rotate $zrot 0 0 1 
gl translate $offx $offy $offz 
lassign [lrange [OGL get modelviewmatrix] 12 14] tx ty tz 
gl popmatrix 


dict set ::View($view) CameraMode FixedToBodyA 
dict set ::View($view) xrot $xrot 
dict set ::View($view) yrot $yrot 
dict set ::View($view) zrot [expr $zrot + $zrot_eyeAngle] 
dict set ::View($view) dist $conf(dist) 
dict set ::View($view) VPtOffset_x $tx 
dict set ::View($view) VPtOffset_y $ty 
dict set ::View($view) VPtOffset_z $tz 
dict set ::View($view) FieldOfView $conf(fov) 
dict set ::View($view) AspectRatio $conf(AspectRatio) 

return; 
} 

我沒有發現,處理渲染本身,而是「GL」 - 命令就足以讓我明白,這TCL文件將被直接運行的任何行附加到渲染過程。所以我擴展了上面這樣的:

// load a self written DLL that wraps OVR functionality (Github link bellow) 

# now run tclovrGetData() from the loaded DLL to get sensor data 
set data [tclovrGetData] 
// data = x y z xrot yrot zrot 

gl pushmatrix 
gl loadidentity 
gl translate $x $y $z 
gl rotate $xrot 1 0 0 
... 

Github link to the DLL

正如你可以在視頻中看到,它看起來在監視器上不錯,但我們知道裂谷的鏡頭失真帶來的(這只是對我來說很輕微),還有一些色差。

我的想法

我要的是搶的是,在視頻「圖像/紋理/幀」屏幕上的每個10-20ms(我還是新來的術語),並做一些color-過濾(我想看看我是否可以減少色差)。然後或許(爲了使獨立)使用修改過的圖像創建一個新窗口並將其發送給Rift。基本上以所需的「格式」獲取圖像以便能夠對其執行計算。

我的想法是(因爲我們連接到渲染過程)添加一些額外的線路上面調用我的DLL中的附加功能,可以做以下TCL文件:

// Begin Oculus rendering loop 
//1. get frame that is currently being rendered (in this process) 
//2. copy this frame to memory 
//3. perform some operations (color filtering) on this frame in memory 
//4. send this frame to a new window 

現在我的問題:

  • 會是這樣的事情嗎?
  • 有人能指引我進入正確的方向嗎?即我可以使用一些gl函數?
  • 也許Direct3D的工作原理?

我看過This職位上計算器,但無法理解:/

+0

顯示器硬件不應該爲你處理那種事情嗎?必須在軟件中完成硬件應該處理的事情永遠不會是有效的或合理的...... – 2014-11-05 16:33:00

+0

是的,它應該。那麼OculusRift仍處於開發狀態。我也不知道是否在使用Oculus軟件進行渲染時進行某種後處理,以儘量減少這種情況。但至少我沒有看到來自鏡頭的色差校正。 我的第一個計劃實際上是使用Oculus渲染功能。但是我真的感到不知所措,特別是因爲我對模擬器軟件的訪問有限,因此不知道如何獲取紋理/幀信息以將它們重新路由到Oculus渲染引擎。 – Skavee 2014-11-06 10:27:38

回答

0

將這樣的可能嗎?

是的。但它可能不是最好的解決方案,因爲將數據複製回cpu內存並在那裏處理它可能對於實時應用程序來說不夠快。

難道有人指着我走向正確的方向嗎?即我可以使用一些gl函數?

如果你真的想這樣做,你首先必須渲染你的圖像幀緩衝區(或更好地說,附加到framebuffer紋理)。這個紋理然後可以通過你已經在相關文章(glGetTexImage)中找到的函數複製到cpu內存中。還有其他選項,如像素緩衝區,這可能是有點快(see here)

更快的解決方案

所有這些方法都需要你從GPU MEM的數據複製到CPU的紀念品,工藝也有和複製一切背部。這需要gpu和cpu之間的很多同步,並且另外處理cpu上的映像會很慢。

根據您可以使用的可用OpenGL功能,有方法可以在GPU上執行整個圖像處理。一個可能是最容易使用的着色器:

  1. 渲染場景的幀緩衝
  2. 繪製紋理四,其中來自 紋理(1),在片段着色器操作所有 必要的。

在這種方法中,也不需要第二個窗口,因爲後處理的四邊形可以顯示在第一個窗口中。有關GPU上的後處理的更多信息,您可以看看here

+0

感謝您的回覆。如果我沒有正確閱讀[this](http://en.wikibooks.org/wiki/OpenGL_Programming/Post-Processing#Drawing),我基本上必須將目標FB綁定到我們自己的FB,執行處理,然後綁定我們的FB返回到屏幕緩衝區(0)。有一點還是有點不清楚。我假設每個進程只能有一個目標FB,因此'glBindFramebuffer(GL_FRAMEBUFFER,fbo);'會將正確的圖像(在一個窗口中)綁定到我們的FB,假設我在同一個進程內執行該調用。 – Skavee 2014-11-05 13:52:42

+0

應用程序只能有一個backbuffer,但有多個framebuffer對象。 – BDL 2014-11-05 17:48:50

+0

好吧,我想我已經開始明白了。基本上,如果我執行以下操作: 'glBindFramebuffer(GL_FRAMEBUFFER,FBO);'' //現在做fbo' 操作'glBindFramebuffer(GL_FRAMEBUFFER,0);' 我會有效地選擇'fbo'作爲目標渲染到,然後我會處理'fbo'內的內容,並且一旦我在第三行中打破邊界。 'fbo'中的內容會呈現在屏幕上嗎? – Skavee 2014-11-05 19:16:09