FreeCAD-VR: First succesfull render on the Rift!

This commit is contained in:
jriegel 2014-09-13 20:03:57 +02:00
parent c0152eeb68
commit ad2406a763
2 changed files with 57 additions and 35 deletions

View File

@ -78,7 +78,7 @@
class CoinRiftWidget : public QGLWidget class CoinRiftWidget : public QGLWidget
{ {
ovrHmd hmd; ovrHmd hmd;
ovrHmdDesc hmdDesc; //ovrHmdDesc hmdDesc;
//ovrEyeType eyes[2]; //ovrEyeType eyes[2];
ovrEyeRenderDesc eyeRenderDesc[2]; ovrEyeRenderDesc eyeRenderDesc[2];
ovrTexture eyeTexture[2]; ovrTexture eyeTexture[2];
@ -132,23 +132,24 @@ CoinRiftWidget::CoinRiftWidget() : QGLWidget()
hmd = ovrHmd_Create(0); hmd = ovrHmd_Create(0);
if (!hmd) { if (!hmd) {
qDebug() << "Could not find Rift device."; qDebug() << "Could not find Rift device.";
exit(2); throw;
} }
if (!ovrHmd_ConfigureTracking (hmd, ovrTrackingCap_Orientation | if (!ovrHmd_ConfigureTracking (hmd, ovrTrackingCap_Orientation |
ovrTrackingCap_MagYawCorrection |
ovrTrackingCap_Position, ovrTrackingCap_Position,
ovrTrackingCap_Orientation)) { // Capabilities we require. ovrTrackingCap_Orientation)) { // Capabilities we require.
qDebug() << "Could not start Rift motion sensor."; qDebug() << "Could not start Rift motion sensor.";
exit(3); throw;
} }
resize(hmdDesc.Resolution.w, hmdDesc.Resolution.h); resize(hmd->Resolution.w, hmd->Resolution.h);
// Configure stereo settings. // Configure stereo settings.
ovrSizei recommenedTex0Size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, ovrSizei recommenedTex0Size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left,
hmdDesc.DefaultEyeFov[0], 1.0f); hmd->DefaultEyeFov[0], 1.0f);
ovrSizei recommenedTex1Size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, ovrSizei recommenedTex1Size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right,
hmdDesc.DefaultEyeFov[1], 1.0f); hmd->DefaultEyeFov[1], 1.0f);
#ifdef USE_SO_OFFSCREEN_RENDERER #ifdef USE_SO_OFFSCREEN_RENDERER
renderer = new SoOffscreenRenderer(SbViewportRegion(std::max(recommenedTex0Size.w, recommenedTex0Size.w), renderer = new SoOffscreenRenderer(SbViewportRegion(std::max(recommenedTex0Size.w, recommenedTex0Size.w),
@ -179,8 +180,8 @@ CoinRiftWidget::CoinRiftWidget() : QGLWidget()
// Populate ovrEyeDesc[2]. // Populate ovrEyeDesc[2].
eyeRenderDesc[0].Eye = ovrEye_Left; eyeRenderDesc[0].Eye = ovrEye_Left;
eyeRenderDesc[1].Eye = ovrEye_Right; eyeRenderDesc[1].Eye = ovrEye_Right;
eyeRenderDesc[0].Fov = hmdDesc.DefaultEyeFov[0]; eyeRenderDesc[0].Fov = hmd->DefaultEyeFov[0];
eyeRenderDesc[1].Fov = hmdDesc.DefaultEyeFov[1]; eyeRenderDesc[1].Fov = hmd->DefaultEyeFov[1];
#ifdef USE_SO_OFFSCREEN_RENDERER #ifdef USE_SO_OFFSCREEN_RENDERER
eyeTexture[0].Header.TextureSize.w = renderer->getViewportRegion().getViewportSizePixels().getValue()[0]; eyeTexture[0].Header.TextureSize.w = renderer->getViewportRegion().getViewportSizePixels().getValue()[0];
eyeTexture[0].Header.TextureSize.h = renderer->getViewportRegion().getViewportSizePixels().getValue()[1]; eyeTexture[0].Header.TextureSize.h = renderer->getViewportRegion().getViewportSizePixels().getValue()[1];
@ -192,14 +193,14 @@ CoinRiftWidget::CoinRiftWidget() : QGLWidget()
#endif #endif
eyeTexture[0].Header.RenderViewport.Pos.x = 0; eyeTexture[0].Header.RenderViewport.Pos.x = 0;
eyeTexture[0].Header.RenderViewport.Pos.y = 0; eyeTexture[0].Header.RenderViewport.Pos.y = 0;
eyeTexture[0].Header.RenderViewport.Size = eyeTexture[1].Header.TextureSize; eyeTexture[0].Header.RenderViewport.Size = eyeTexture[0].Header.TextureSize;
eyeTexture[0].Header.RenderViewport.Pos = eyeTexture[0].Header.RenderViewport.Pos; eyeTexture[1].Header.RenderViewport.Pos = eyeTexture[0].Header.RenderViewport.Pos;
eyeTexture[0].Header.RenderViewport.Size = eyeTexture[1].Header.TextureSize; eyeTexture[1].Header.RenderViewport.Size = eyeTexture[1].Header.TextureSize;
const int backBufferMultisample = 0; // TODO This is a guess? const int backBufferMultisample = 0; // TODO This is a guess?
ovrGLConfig cfg; ovrGLConfig cfg;
cfg.OGL.Header.API = ovrRenderAPI_OpenGL; cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
cfg.OGL.Header.RTSize = hmdDesc.Resolution; cfg.OGL.Header.RTSize = hmd->Resolution;
cfg.OGL.Header.Multisample = backBufferMultisample; cfg.OGL.Header.Multisample = backBufferMultisample;
cfg.OGL.Window = reinterpret_cast<HWND>(winId()); cfg.OGL.Window = reinterpret_cast<HWND>(winId());
makeCurrent(); makeCurrent();
@ -209,17 +210,17 @@ CoinRiftWidget::CoinRiftWidget() : QGLWidget()
//qDebug() << "Context:" << cfg.OGL.WglContext; //qDebug() << "Context:" << cfg.OGL.WglContext;
qDebug() << "DC:" << cfg.OGL.DC; qDebug() << "DC:" << cfg.OGL.DC;
hmdDesc.DistortionCaps = 0; int DistortionCaps = 0;
hmdDesc.DistortionCaps |= ovrDistortionCap_Chromatic; DistortionCaps |= ovrDistortionCap_Chromatic;
// hmdDesc.DistortionCaps |= ovrDistortionCap_TimeWarp; // Produces black screen... // DistortionCaps |= ovrDistortionCap_TimeWarp; // Produces black screen...
hmdDesc.DistortionCaps |= ovrDistortionCap_Vignette; DistortionCaps |= ovrDistortionCap_Vignette;
bool VSyncEnabled(false); // TODO This is a guess. bool VSyncEnabled(false); // TODO This is a guess.
if (!ovrHmd_ConfigureRendering( hmd, if (!ovrHmd_ConfigureRendering( hmd,
&cfg.Config, &cfg.Config,
/*(VSyncEnabled ? 0 : ovrHmdCap_NoVSync),*/ /*(VSyncEnabled ? 0 : ovrHmdCap_NoVSync),*/
hmdDesc.DistortionCaps, DistortionCaps,
hmdDesc.DefaultEyeFov,//eyes, hmd->DefaultEyeFov,//eyes,
eyeRenderDesc)) { eyeRenderDesc)) {
qDebug() << "Could not configure OVR rendering."; qDebug() << "Could not configure OVR rendering.";
exit(3); exit(3);
@ -348,22 +349,24 @@ void CoinRiftWidget::initializeGL()
void CoinRiftWidget::paintGL() void CoinRiftWidget::paintGL()
{ {
const int ms(1000 / 60 /*fps*/); const int ms(1000 / 60 /*fps*/);
QTimer::singleShot(ms, this, SLOT(updateGL())); QTimer::singleShot(ms, this, SLOT(updateGL()));
makeCurrent(); makeCurrent();
ovrPosef eyePose[2];
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
/*ovrFrameTiming hmdFrameTiming =*/ ovrHmd_BeginFrame(hmd, 0); /*ovrFrameTiming hmdFrameTiming =*/ ovrHmd_BeginFrame(hmd, 0);
for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) { for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) {
ovrEyeType eye = hmdDesc.EyeRenderOrder[eyeIndex]; ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex];
ovrPosef eyePose = ovrHmd_GetEyePose(hmd, eye); eyePose[eye] = ovrHmd_GetEyePose(hmd, eye);
camera[eye]->orientation.setValue(eyePose.Orientation.x, camera[eye]->orientation.setValue(eyePose[eye].Orientation.x,
eyePose.Orientation.y, eyePose[eye].Orientation.y,
eyePose.Orientation.z, eyePose[eye].Orientation.z,
eyePose.Orientation.w); eyePose[eye].Orientation.w);
SbVec3f originalPosition(camera[eye]->position.getValue()); SbVec3f originalPosition(camera[eye]->position.getValue());
camera[eye]->position.setValue(originalPosition - SbVec3f(eyeRenderDesc[eye].ViewAdjust.x, camera[eye]->position.setValue(originalPosition - SbVec3f(eyeRenderDesc[eye].ViewAdjust.x,
@ -403,9 +406,10 @@ void CoinRiftWidget::paintGL()
camera[eye]->position.setValue(originalPosition); camera[eye]->position.setValue(originalPosition);
// Submit the texture for distortion.
ovrHmd_EndFrame(hmd, &eyePose, &eyeTexture[eye]);
} }
// Submit the texture for distortion.
ovrHmd_EndFrame(hmd, eyePose, eyeTexture);
// Swap buffers. // Swap buffers.
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@ -419,19 +423,31 @@ void CoinRiftWidget::paintGL()
} }
static void cleanup() static CoinRiftWidget *window=0;
void oculusStop()
{ {
//SoDB::finish(); //SoDB::finish();
if(window){
delete window;
window = 0;
}
ovr_Shutdown(); ovr_Shutdown();
} }
bool oculusUp(void)
{
return window!=0;
}
int oculusTest(void) int oculusStart(void)
{ {
//SoDB::init(); //SoDB::init();
//QApplication app(argc, argv); //QApplication app(argc, argv);
qAddPostRoutine(cleanup); //qAddPostRoutine(cleanup);
// Moved here because of https://developer.oculusvr.com/forums/viewtopic.php?f=17&t=7915&p=108503#p108503 // Moved here because of https://developer.oculusvr.com/forums/viewtopic.php?f=17&t=7915&p=108503#p108503
// Init libovr. // Init libovr.
@ -440,8 +456,8 @@ int oculusTest(void)
return 0; return 0;
} }
CoinRiftWidget window; window = new CoinRiftWidget;
window.show(); window->show();
// An example scene. // An example scene.
static const char * inlineSceneGraph[] = { static const char * inlineSceneGraph[] = {
@ -479,8 +495,9 @@ int oculusTest(void)
SoInput in; SoInput in;
in.setStringArray(inlineSceneGraph); in.setStringArray(inlineSceneGraph);
window.setSceneGraph(SoDB::readAll(&in)); window->setSceneGraph(SoDB::readAll(&in));
return 1;
//return app.exec(); //return app.exec();
} }

View File

@ -1637,13 +1637,18 @@ void View3DInventorViewer::animatedViewAll(int steps, int ms)
} }
#if BUILD_VR #if BUILD_VR
extern int oculusTest(void); extern int oculusStart(void);
extern bool oculusUp (void);
extern void oculusStop (void);
#endif #endif
void View3DInventorViewer::viewVR(void) void View3DInventorViewer::viewVR(void)
{ {
#if BUILD_VR #if BUILD_VR
oculusTest(); if(oculusUp())
oculusStop();
else
oculusStart();
#endif #endif
} }