首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Oculus Rift DK2上的简单视频流

Oculus Rift DK2上的简单视频流
EN

Stack Overflow用户
提问于 2016-01-04 22:27:40
回答 1查看 890关注 0票数 0

我有一个Oculus裂谷安装了一个眼睛跟踪器,我用来显示实时图像的基础上的眼睛跟踪器输入。我想听听你对我处理裂口显示器的方式的看法(对吗?)

我有一个简单文本的基本图像,它是基于眼睛跟踪器的凝视坐标使用OpenCV修改的。因此,每次眼睛跟踪输出凝视坐标(60赫兹),我有一个新的图像,所以它是我工作的一个网络摄像头流。我有一个工作程序,但是由于我是OpenGL新手,所以我希望有人能检查一下下面的步骤,看看我是否遗漏了什么。我将只包含主要代码块,并在下面给出书面评论:

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

代码语言:javascript
复制
    tex = matToTexture(result, GL_NEAREST, GL_NEAREST, GL_CLAMP);
    glBindTexture(GL_TEXTURE_2D, tex)        

2)然后让眼睛呈现缓冲器,安装VR组件,获取眼睛的姿势,等等:

代码语言:javascript
复制
        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循环。

代码语言:javascript
复制
    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的信息,我将不胜感激。

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

当我编写这段代码时,我使用的是Rift 0.5.0,但现在升级到0.8.0测试版

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2016-01-05 22:03:02

问:这两个屏幕目前都能看到相同的图像。为什么会这样呢?两只眼睛不应该看到稍微不同的图像吗?

occulus不会为您创建立体图像对。这里有两件事是值得关注的:

  1. 为您提供正确的投影参数以及视点/方向。
  2. 对图像对进行后处理,以便显示在裂缝上(翘曲,校正色差)。

当您从SDK查询投影矩阵和视点位置时,实际上您并没有对它做任何事情。您只需将它们设置为OpenGL投影和模型视图矩阵,而不使用它呈现任何内容。

代码应该呈现到纹理中,向3D世界提供不同的透视图,最后使用ovrHmd_EndFrame对其进行后处理,并将其呈现到实际窗口。

然而,您只是提供您的单目输入纹理作为输入,完全跳过渲染步骤,并直接后处理它。

您不能从单个单目图像自动推导出立体图像对。

根据你的评论:

我知道这不会是真实的3D,但我想知道,例如,一个单一的电脑游戏图像如何可以被修改,以显示轻巧的不同视图左眼与右眼。

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

另一种方法是使用单目图像和深度缓冲器创建另一个视图,方法是基本上重新投影3d点(我们通过深度缓冲区获得),以非常不同的视图配置,并填充所有的洞。

然而,所有这些都不适用于

我有一个新的形象,所以这是我工作的一个网络摄像头流。

如果你只有一个单一的摄像头,你没有直接的方式获得3D信息所需的渲染一个不同的视角的场景。有一些方法可以利用视频流的时间相干性来重建这些信息,参见结构从运动维基百科停战。但这是非常有限的,不适用于任何实时使用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34601009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档