我有一个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测试版
谢谢!
您是否期望rift SDK将神奇的视频转变为立体视频?它不会。 – derhass
我对两只眼睛使用相同的纹理,但设置不同的视口。我不知道如何解释看到图像中稍微不同的部分。我明白这不会是真正的3D,但我想知道如何修改单电脑游戏图像,以显示左眼与右眼的细微差别。 – Anshul
你已经设置了你的垫子的方式应该有双眼的总宽度,是这样吗?如果是这样,你应该在每一半的垫子上有两份文本,每只眼睛一份。您可以使用文本的相对水平坐标来播放文本的观察深度。为了进行更有用的调整,您需要使用CV摄像头参数。 –