2016-01-04 38 views
0

我有一个Oculus Rift装有一个眼动仪,用于根据眼动仪输入显示实时图像。我想就我处理展示给Rift的方式发表你的看法(是吗?)。Oculus Rift上简单的视频流DK2

我有一个使用基于目光从眼动仪坐标OpenCV的修改简单的文本的基本形象。因此,每次眼动仪输出凝视坐标(60Hz)时,我都会看到一个新图像,就好像我正在使用网络摄像头流一样。我有一个工作程序,但由于我是OpenGL的新手,我希望有人可以通过以下步骤来查看我是否没有错过任何东西。我只包含的代码的主要块下面的书面意见:

1)首先,我创建和绑定纹理。 matToTexture是一个将cv :: mat图像转换为纹理的函数。

tex = matToTexture(result, GL_NEAREST, GL_NEAREST, GL_CLAMP); 
    glBindTexture(GL_TEXTURE_2D, tex)   

2)然后,我使眼睛渲染缓冲区和设置VR组件,让眼姿势,等:

 for (int eye=0; eye<2; eye++) 
{ 
    idealSize = ovrHmd_GetFovTextureSize(hmd, (ovrEyeType)eye, hmd->DefaultEyeFov[eye], 1.0f); 
    EyeRenderTexture[eye] = tex; 
    //EyeRenderViewport[eye].Pos.x = 0; 
    EyeRenderViewport[0].Pos.x =0; 
    EyeRenderViewport[1].Pos.x = idealSize.w/2; 
    EyeRenderViewport[eye].Pos.y = 0; 
    EyeRenderViewport[eye].Size = idealSize; 
} 

//Setup VR components 
ovrGLConfig oglcfg; 
oglcfg.OGL.Header.API    = ovrRenderAPI_OpenGL; 
oglcfg.OGL.Header.BackBufferSize.w = hmd->Resolution.w; 
oglcfg.OGL.Header.BackBufferSize.h = hmd->Resolution.h; 
oglcfg.OGL.Header.Multisample  = 1; 
oglcfg.OGL.Window     = handle; 
oglcfg.OGL.DC      = GetDC(handle); 

if (!ovrHmd_ConfigureRendering(hmd, &oglcfg.Config, 
           ovrDistortionCap_Vignette | 
           ovrDistortionCap_TimeWarp | ovrDistortionCap_Overdrive, 
           hmd->DefaultEyeFov, EyeRenderDesc)) 
    return(1); 

//Getting eye pose outside the loop since our pose will remain static 
ovrVector3f useHmdToEyeViewOffset[2]= {EyeRenderDesc[0].HmdToEyeViewOffset, EyeRenderDesc[1].HmdToEyeViewOffset}; 
ovrHmd_GetEyePoses(hmd, 0, useHmdToEyeViewOffset, EyeRenderPose, NULL); 

glGenTextures(1, &textureID); 

//Changing eye tracking location from 1920-1080 to 2364-1461 since that is 
//optimal buffer size 
float x_scale = static_cast<float>(image.cols)/static_cast<float>(hmd->Resolution.w); 
float y_scale = static_cast<float>(image.rows)/static_cast<float>(hmd->Resolution.h); 

//x_adjusted and y_adjusted store the new adjusted x,y values 
float x_adjusted, y_adjusted; 

最后,我有渲染while循环

while(1) 
{ 
      //Changing the texture dynamically because the result image is changing 
    //with eye tracker input 
    tex = matToTexture(result, GL_NEAREST, GL_NEAREST, GL_CLAMP); 
    glBindTexture(GL_TEXTURE_2D, tex); 

    for (int eye = 0; eye<2; eye++) 
    { 
     projection[eye] = ovrMatrix4f_Projection(EyeRenderDesc[eye].Fov, 1, 1000, 1); 
     glMatrixMode(GL_PROJECTION); 
     glLoadTransposeMatrixf(projection[eye].M[0]); 
     EyeRenderTexture[eye] = tex; 
     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 
     glTranslatef(EyeRenderDesc[eye].HmdToEyeViewOffset.x,-EyeRenderDesc[eye].HmdToEyeViewOffset.y, EyeRenderDesc[eye].HmdToEyeViewOffset.z); 


     //Distortion Rendering 
     eyeTexture[eye].OGL.Header.API    = ovrRenderAPI_OpenGL; 
     //eyeTexture[eye].OGL.Header.TextureSize = idealSize; 
     eyeTexture[eye].OGL.Header.TextureSize.h = idealSize.h; 
     eyeTexture[eye].OGL.Header.TextureSize.w = 2*idealSize.w; 
     eyeTexture[eye].OGL.Header.RenderViewport.Size = idealSize; 
     eyeTexture[0].OGL.Header.RenderViewport.Pos.x = 0; 
     eyeTexture[1].OGL.Header.RenderViewport.Pos.x = idealSize.w; 
     eyeTexture[eye].OGL.Header.RenderViewport.Pos.y = 0; 
     eyeTexture[eye].OGL.TexId     = EyeRenderTexture[eye]; 
    } 


    ovrHmd_EndFrame(hmd, EyeRenderPose, &eyeTexture[0].Texture); 

    //restoring result back to original so that new scotoma position 
    //can be added onto it 
    image.copyTo(result); 

    // Clear the screen to black 
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 

    //Exiting loop if 'q' is pressed 
    if (quit == 1) break; 

} 

glDeleteTextures(1, &tex); 

所以我只有一个OpenGL纹理,我修改每个帧。我已经阅读了关于帧缓冲区以及它们如何被使用的方法,但是即使在阅读了一些源代码之后,我也很困惑它们是否应该用于这个特定的应用程序。我做得好吗?如果有一个源可以推荐学习更多关于这个2D应用程序的OpenGL,我将不胜感激。

问题:两个屏幕当前都看到相同的确切图像。这是为什么?双眼不应该看到稍微不同的图像?我没有正确设置眼睛纹理/视口吗?如果需要,我可以上传整个代码。

当我写了这个代码,我用裂谷0.5.0,但现在我已经升级到0.8.0测试版

谢谢!

+0

您是否期望rift SDK将神奇的视频转变为立体视频?它不会。 – derhass

+0

我对两只眼睛使用相同的纹理,但设置不同的视口。我不知道如何解释看到图像中稍微不同的部分。我明白这不会是真正的3D,但我想知道如何修改单电脑游戏图像,以显示左眼与右眼的细微差别。 – Anshul

+0

你已经设置了你的垫子的方式应该有双眼的总宽度,是这样吗?如果是这样,你应该在每一半的垫子上有两份文本,每只眼睛一份。您可以使用文本的相对水平坐标来播放文本的观察深度。为了进行更有用的调整,您需要使用CV摄像头参数。 –

回答

1

问题:无论是屏幕目前看到的完全相同的图像。这是为什么?双眼不应该看到稍微不同的图像?

occulus SDK不会为您创建立体图像对。它只是将两件事这里是关注的:

  1. 为您提供正确的投影参数,以及为视点/方向

  2. 后处理上的裂痕显示的图像对(翘曲,校正色差)。

从SDK中查询投影矩阵和视点位置时,实际上并没有对它做任何事情。您只需将它们设置为OpenGL投影和模型视图矩阵,而无需渲染任何东西

的代码应该呈现纹理,提供了不同的视角为3D世界,最后用ovrHmd_EndFrame做就可以了后处理和渲染,以实际的窗口。

但是,您只需提供您的单色输入纹理作为输入,完全跳过渲染步骤并直接对其进行后处理。

您无法自动推测出单个单像图像中的立体图像对。

从您的评论:

我明白,不会是真正的3D,但我想知道,例如单视电脑游戏图像如何可以修改显示左与slighlty不同的看法右眼。

这取决于你如何定义“单像游戏”。这些游戏中的大多数实际使用3D数据表示并将其渲染到屏幕上,从而创建2D投影。在这种情况下,对于立体输出,渲染必须进行两次,使用不同的投影和视图矩阵。

另一种方法是使用平面图像和深度缓冲区,通过基本重新投影点(我们通过深度缓冲区获得)到不同的视图配置并填充所有的孔来创建另一个视图。

但是,没有一个适用于

我有一个新的图像,这是因为如果我有一个摄像头流工作。

如果您只有一个平面镜头摄像头,则无法直接获取渲染场景的不同视角所需的3D信息。有一些方法可以使用视频流的时间一致性来重建这种信息,参见structure from motion wikipedia artice。但这是非常有限的,不适用于任何实时使用。