| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #include "CoinRiftWidget.h" |
| |
|
| | #include <Base/Console.h> |
| |
|
| | #if BUILD_VR |
| |
|
| |
|
| | # undef max |
| |
|
| |
|
| | CoinRiftWidget::CoinRiftWidget() |
| | : QGLWidget() |
| | { |
| | for (int eye = 0; eye < 2; eye++) { |
| | reinterpret_cast<ovrGLTextureData*>(&eyeTexture[eye])->TexId = 0; |
| | # ifdef USE_FRAMEBUFFER |
| | frameBufferID[eye] = 0; |
| | depthBufferID[eye] = 0; |
| | # endif |
| | } |
| |
|
| | |
| | setAutoBufferSwap(false); |
| |
|
| | hmd = ovrHmd_Create(0); |
| | if (!hmd) { |
| | qDebug() << "Could not find Rift device."; |
| | throw; |
| | } |
| |
|
| | if (!ovrHmd_ConfigureTracking( |
| | hmd, |
| | ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, |
| | ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position |
| | )) { |
| | qDebug() << "Could not start Rift motion sensor."; |
| | throw; |
| | } |
| |
|
| | resize(hmd->Resolution.w, hmd->Resolution.h); |
| |
|
| | |
| | ovrSizei recommenedTex0Size |
| | = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left, hmd->DefaultEyeFov[0], 1.0f); |
| | ovrSizei recommenedTex1Size |
| | = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right, hmd->DefaultEyeFov[1], 1.0f); |
| |
|
| | # ifdef USE_SO_OFFSCREEN_RENDERER |
| | renderer = new SoOffscreenRenderer(SbViewportRegion( |
| | std::max(recommenedTex0Size.w, recommenedTex0Size.w), |
| | std::max(recommenedTex1Size.h, recommenedTex1Size.h) |
| | )); |
| | renderer->setComponents(SoOffscreenRenderer::RGB_TRANSPARENCY); |
| | BackgroundColor = SbColor(.0f, .0f, .8f); |
| | renderer->setBackgroundColor(BackgroundColor); |
| | # endif |
| | # ifdef USE_FRAMEBUFFER |
| | m_sceneManager = new SoSceneManager(); |
| | m_sceneManager->setViewportRegion(SbViewportRegion( |
| | std::max(recommenedTex0Size.w, recommenedTex0Size.w), |
| | std::max(recommenedTex1Size.h, recommenedTex1Size.h) |
| | )); |
| | m_sceneManager->setBackgroundColor(SbColor(.0f, .0f, .8f)); |
| | # endif |
| | basePosition = SbVec3f(0.0f, 0.0f, -2.0f); |
| |
|
| | |
| | SoDirectionalLight* light = new SoDirectionalLight(); |
| | light->direction.setValue(1, -1, -1); |
| |
|
| | SoDirectionalLight* light2 = new SoDirectionalLight(); |
| | light2->direction.setValue(-1, -1, -1); |
| | light2->intensity.setValue(0.6); |
| | light2->color.setValue(0.8, 0.8, 1); |
| |
|
| |
|
| | scene = new SoSeparator(0); |
| | for (int eye = 0; eye < 2; eye++) { |
| | rootScene[eye] = new SoSeparator(); |
| | rootScene[eye]->ref(); |
| | camera[eye] = new SoFrustumCamera(); |
| | camera[eye]->position.setValue(basePosition); |
| | camera[eye]->focalDistance.setValue(5.0f); |
| | camera[eye]->viewportMapping.setValue(SoCamera::LEAVE_ALONE); |
| | rootScene[eye]->addChild(camera[eye]); |
| | rootScene[eye]->addChild(light); |
| | rootScene[eye]->addChild(light2); |
| | rootScene[eye]->addChild(scene); |
| | } |
| |
|
| | |
| | eyeRenderDesc[0].Eye = ovrEye_Left; |
| | eyeRenderDesc[1].Eye = ovrEye_Right; |
| | eyeRenderDesc[0].Fov = hmd->DefaultEyeFov[0]; |
| | eyeRenderDesc[1].Fov = hmd->DefaultEyeFov[1]; |
| | # ifdef USE_SO_OFFSCREEN_RENDERER |
| | eyeTexture[0].Header.TextureSize.w |
| | = renderer->getViewportRegion().getViewportSizePixels().getValue()[0]; |
| | eyeTexture[0].Header.TextureSize.h |
| | = renderer->getViewportRegion().getViewportSizePixels().getValue()[1]; |
| | eyeTexture[1].Header.TextureSize = eyeTexture[0].Header.TextureSize; |
| | # endif |
| | # ifdef USE_FRAMEBUFFER |
| | eyeTexture[0].Header.TextureSize = recommenedTex0Size; |
| | eyeTexture[1].Header.TextureSize = recommenedTex1Size; |
| | # endif |
| | eyeTexture[0].Header.RenderViewport.Pos.x = 0; |
| | eyeTexture[0].Header.RenderViewport.Pos.y = 0; |
| | eyeTexture[0].Header.RenderViewport.Size = eyeTexture[0].Header.TextureSize; |
| | eyeTexture[1].Header.RenderViewport.Pos = eyeTexture[0].Header.RenderViewport.Pos; |
| | eyeTexture[1].Header.RenderViewport.Size = eyeTexture[1].Header.TextureSize; |
| |
|
| | const int backBufferMultisample = 0; |
| | ovrGLConfig cfg; |
| | cfg.OGL.Header.API = ovrRenderAPI_OpenGL; |
| | cfg.OGL.Header.RTSize = hmd->Resolution; |
| | cfg.OGL.Header.Multisample = backBufferMultisample; |
| | cfg.OGL.Window = reinterpret_cast<HWND>(winId()); |
| | makeCurrent(); |
| | |
| | |
| | cfg.OGL.DC = wglGetCurrentDC(); |
| | qDebug() << "Window:" << cfg.OGL.Window; |
| | |
| | qDebug() << "DC:" << cfg.OGL.DC; |
| |
|
| | int DistortionCaps = 0; |
| | DistortionCaps |= ovrDistortionCap_Chromatic; |
| | |
| | DistortionCaps |= ovrDistortionCap_Vignette; |
| | DistortionCaps |= ovrDistortionCap_HqDistortion; |
| |
|
| | bool VSyncEnabled(false); |
| | if (!ovrHmd_ConfigureRendering( |
| | hmd, |
| | &cfg.Config, |
| | |
| | DistortionCaps, |
| | hmd->DefaultEyeFov, |
| | eyeRenderDesc |
| | )) { |
| | qDebug() << "Could not configure OVR rendering."; |
| | throw; |
| | } |
| | static const float nearPlane = 0.01; |
| |
|
| | for (int eye = 0; eye < 2; eye++) { |
| | camera[eye]->aspectRatio.setValue( |
| | (eyeRenderDesc[eye].Fov.LeftTan + eyeRenderDesc[eye].Fov.RightTan) |
| | / (eyeRenderDesc[eye].Fov.UpTan + eyeRenderDesc[eye].Fov.DownTan) |
| | ); |
| | camera[eye]->nearDistance.setValue(nearPlane); |
| | camera[eye]->farDistance.setValue(10000.0f); |
| | camera[eye]->left.setValue(-eyeRenderDesc[eye].Fov.LeftTan * nearPlane); |
| | camera[eye]->right.setValue(eyeRenderDesc[eye].Fov.RightTan * nearPlane); |
| | camera[eye]->top.setValue(eyeRenderDesc[eye].Fov.UpTan * nearPlane); |
| | camera[eye]->bottom.setValue(-eyeRenderDesc[eye].Fov.DownTan * nearPlane); |
| | } |
| | } |
| |
|
| |
|
| | CoinRiftWidget::~CoinRiftWidget() |
| | { |
| | # ifdef USE_SO_OFFSCREEN_RENDERER |
| | delete renderer; |
| | # endif |
| | for (int eye = 0; eye < 2; eye++) { |
| | rootScene[eye]->unref(); |
| | ovrGLTextureData* texData = reinterpret_cast<ovrGLTextureData*>(&eyeTexture[eye]); |
| | if (texData->TexId) { |
| | glDeleteTextures(1, &texData->TexId); |
| | texData->TexId = 0; |
| | } |
| | # ifdef USE_FRAMEBUFFER |
| | if (frameBufferID[eye] != 0) { |
| | |
| | frameBufferID[eye] = 0; |
| | } |
| | if (depthBufferID[eye] != 0) { |
| | |
| | depthBufferID[eye] = 0; |
| | } |
| | # endif |
| | } |
| | scene = 0; |
| | |
| | ovrHmd_Destroy(hmd); |
| | } |
| |
|
| |
|
| | void CoinRiftWidget::setBackgroundColor(const SbColor& Col) |
| | { |
| | BackgroundColor = Col; |
| | renderer->setBackgroundColor(BackgroundColor); |
| | } |
| |
|
| |
|
| | void CoinRiftWidget::setSceneGraph(SoNode* sceneGraph) |
| | { |
| | rootScene[0]->replaceChild(scene, sceneGraph); |
| | rootScene[1]->replaceChild(scene, sceneGraph); |
| | scene = sceneGraph; |
| | } |
| |
|
| |
|
| | void CoinRiftWidget::resizeGL(int width, int height) |
| | { |
| | int side = qMin(width, height); |
| | glViewport((width - side) / 2, (height - side) / 2, side, side); |
| |
|
| | glMatrixMode(GL_PROJECTION); |
| | glLoadIdentity(); |
| | glOrtho(-1.0, 1.0, -1.0, 1.0, 0.0, 1000.0); |
| | glMatrixMode(GL_MODELVIEW); |
| | } |
| |
|
| | void CoinRiftWidget::initializeGL() |
| | { |
| | makeCurrent(); |
| | |
| | # ifdef USE_FRAMEBUFFER |
| | OVR::CAPI::GL::InitGLExtensions(); |
| | if (OVR::CAPI::GL::glBindFramebuffer == NULL) { |
| | qDebug() << "No GL extensions found."; |
| | exit(4); |
| | } |
| |
|
| | |
| | GLint oldfb; |
| | glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &oldfb); |
| | # endif |
| |
|
| | |
| | glEnable(GL_TEXTURE_2D); |
| | for (int eye = 0; eye < 2; eye++) { |
| | # ifdef USE_FRAMEBUFFER |
| | OVR::CAPI::GL::glGenFramebuffers(1, &frameBufferID[eye]); |
| | OVR::CAPI::GL::glBindFramebuffer(GL_FRAMEBUFFER_EXT, frameBufferID[eye]); |
| | |
| | |
| | glGenRenderbuffers(1, &depthBufferID[eye]); |
| | glBindRenderbuffer(GL_RENDERBUFFER_EXT, depthBufferID[eye]); |
| | glRenderbufferStorage( |
| | GL_RENDERBUFFER_EXT, |
| | GL_DEPTH_COMPONENT16, |
| | eyeTexture[eye].Header.TextureSize.w, |
| | eyeTexture[eye].Header.TextureSize.h |
| | ); |
| | |
| | OVR::CAPI::GL::glFramebufferRenderbuffer( |
| | GL_FRAMEBUFFER_EXT, |
| | GL_DEPTH_ATTACHMENT_EXT, |
| | GL_RENDERBUFFER_EXT, |
| | depthBufferID[eye] |
| | ); |
| | # endif |
| | ovrGLTextureData* texData = reinterpret_cast<ovrGLTextureData*>(&eyeTexture[eye]); |
| | texData->Header.API = ovrRenderAPI_OpenGL; |
| | texData->Header.TextureSize = eyeTexture[eye].Header.TextureSize; |
| | texData->Header.RenderViewport = eyeTexture[eye].Header.RenderViewport; |
| | glGenTextures(1, &texData->TexId); |
| | glBindTexture(GL_TEXTURE_2D, texData->TexId); |
| | Q_ASSERT(!glGetError()); |
| | |
| | glTexImage2D( |
| | GL_TEXTURE_2D, |
| | 0, |
| | GL_RGBA, |
| | eyeTexture[eye].Header.TextureSize.w, |
| | eyeTexture[eye].Header.TextureSize.h, |
| | 0, |
| | GL_BGRA, |
| | GL_UNSIGNED_BYTE, |
| | NULL |
| | ); |
| | |
| | |
| | |
| | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| | |
| | Q_ASSERT(!glGetError()); |
| | # ifdef USE_FRAMEBUFFER |
| | |
| | OVR::CAPI::GL::glFramebufferTexture2D( |
| | GL_FRAMEBUFFER_EXT, |
| | GL_COLOR_ATTACHMENT0_EXT, |
| | GL_TEXTURE_2D, |
| | texData->TexId, |
| | 0 |
| | ); |
| | if (OVR::CAPI::GL::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { |
| | qDebug() << "ERROR: FrameBuffer is not operational!"; |
| | } |
| | # endif |
| | } |
| | glBindTexture(GL_TEXTURE_2D, 0); |
| | glDisable(GL_TEXTURE_2D); |
| |
|
| | # ifdef USE_FRAMEBUFFER |
| | |
| | OVR::CAPI::GL::glBindFramebuffer(GL_FRAMEBUFFER_EXT, oldfb); |
| | # endif |
| | doneCurrent(); |
| | } |
| |
|
| |
|
| | void CoinRiftWidget::paintGL() |
| | { |
| | const int ms(1000 / 75 ); |
| | QTimer::singleShot(ms, this, &CoinRiftWidget::updateGL); |
| |
|
| | |
| | handlingSafetyWarning(); |
| |
|
| | makeCurrent(); |
| |
|
| | ovrPosef eyePose[2]; |
| |
|
| | glEnable(GL_TEXTURE_2D); |
| |
|
| | ovrFrameTiming hmdFrameTiming = ovrHmd_BeginFrame(hmd, 0); |
| | for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) { |
| | ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex]; |
| | eyePose[eye] = ovrHmd_GetEyePose(hmd, eye); |
| |
|
| |
|
| | SbRotation riftOrientation( |
| | eyePose[eye].Orientation.x, |
| | eyePose[eye].Orientation.y, |
| | eyePose[eye].Orientation.z, |
| | eyePose[eye].Orientation.w |
| | ); |
| |
|
| | camera[eye]->orientation.setValue(riftOrientation); |
| |
|
| | SbVec3f riftPosition |
| | = SbVec3f(eyePose[eye].Position.x, eyePose[eye].Position.y, eyePose[eye].Position.z); |
| |
|
| |
|
| | |
| | SbVec3f viewAdjust( |
| | eyeRenderDesc[eye].ViewAdjust.x, |
| | eyeRenderDesc[eye].ViewAdjust.y, |
| | eyeRenderDesc[eye].ViewAdjust.z |
| | ); |
| |
|
| | riftOrientation.multVec(viewAdjust, viewAdjust); |
| |
|
| | camera[eye]->position.setValue(basePosition - viewAdjust + riftPosition); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | # ifdef USE_SO_OFFSCREEN_RENDERER |
| | ovrGLTextureData* texData = reinterpret_cast<ovrGLTextureData*>(&eyeTexture[eye]); |
| | glBindTexture(GL_TEXTURE_2D, texData->TexId); |
| | renderer->render(rootScene[eye]); |
| | Q_ASSERT(!glGetError()); |
| | glTexImage2D( |
| | GL_TEXTURE_2D, |
| | 0, |
| | GL_RGBA, |
| | eyeTexture[eye].Header.TextureSize.w, |
| | eyeTexture[eye].Header.TextureSize.h, |
| | 0, |
| | GL_RGBA , |
| | GL_UNSIGNED_BYTE, |
| | renderer->getBuffer() |
| | ); |
| | Q_ASSERT(!glGetError()); |
| | glBindTexture(GL_TEXTURE_2D, 0); |
| | # endif |
| | # ifdef USE_FRAMEBUFFER |
| | |
| | glBindTexture(GL_TEXTURE_2D, 0); |
| | |
| | OVR::CAPI::GL::glUseProgram(0); |
| |
|
| | GLint oldfb; |
| | glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &oldfb); |
| | |
| | OVR::CAPI::GL::glBindFramebuffer(GL_FRAMEBUFFER_EXT, frameBufferID[eye]); |
| |
|
| | m_sceneManager->setSceneGraph(rootScene[eye]); |
| | |
| | m_sceneManager->render(); |
| |
|
| | |
| | OVR::CAPI::GL::glBindFramebuffer(GL_FRAMEBUFFER_EXT, oldfb); |
| | Q_ASSERT(!glGetError()); |
| | # endif |
| |
|
| | |
| | } |
| |
|
| | |
| | ovrHmd_EndFrame(hmd, eyePose, eyeTexture); |
| |
|
| | |
| | glDisable(GL_CULL_FACE); |
| | glDisable(GL_DEPTH_TEST); |
| | |
| | glEnable(GL_CULL_FACE); |
| | glEnable(GL_DEPTH_TEST); |
| | glClearDepth(1.0); |
| |
|
| | doneCurrent(); |
| | } |
| |
|
| | void CoinRiftWidget::handlingSafetyWarning(void) |
| | { |
| | |
| | ovrHSWDisplayState hswDisplayState; |
| | ovrHmd_GetHSWDisplayState(hmd, &hswDisplayState); |
| | if (hswDisplayState.Displayed) { |
| | |
| | |
| | |
| | |
| | ovrHmd_DismissHSWDisplay(hmd); |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | } |
| | } |
| |
|
| |
|
| | # ifdef BUILD_RIFT_TEST_MAIN |
| |
|
| | int main(int argc, char* argv[]) |
| | { |
| | SoDB::init(); |
| |
|
| | QApplication app(argc, argv); |
| | qAddPostRoutine(cleanup); |
| |
|
| | |
| | |
| | if (!ovr_Initialize()) { |
| | qDebug() << "Could not initialize Oculus SDK."; |
| | exit(1); |
| | } |
| |
|
| | CoinRiftWidget window; |
| | window.show(); |
| |
|
| | |
| | static const char* inlineSceneGraph[] = { |
| | "#Inventor V2.1 ascii\n", |
| | "\n", |
| | "Separator {\n", |
| | " Rotation { rotation 1 0 0 0.3 }\n", |
| | " Cone { }\n", |
| | " BaseColor { rgb 1 0 0 }\n", |
| | " Scale { scaleFactor .7 .7 .7 }\n", |
| | " Cube { }\n", |
| | "\n", |
| | " DrawStyle { style LINES }\n", |
| | " ShapeHints { vertexOrdering COUNTERCLOCKWISE }\n", |
| | " Coordinate3 {\n", |
| | " point [\n", |
| | " -2 -2 1.1, -2 -1 1.1, -2 1 1.1, -2 2 1.1,\n", |
| | " -1 -2 1.1, -1 -1 1.1, -1 1 1.1, -1 2 1.1\n", |
| | " 1 -2 1.1, 1 -1 1.1, 1 1 1.1, 1 2 1.1\n", |
| | " 2 -2 1.1, 2 -1 1.1, 2 1 1.1, 2 2 1.1\n", |
| | " ]\n", |
| | " }\n", |
| | "\n", |
| | " Complexity { value 0.7 }\n", |
| | " NurbsSurface {\n", |
| | " numUControlPoints 4\n", |
| | " numVControlPoints 4\n", |
| | " uKnotVector [ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ]\n", |
| | " vKnotVector [ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ]\n", |
| | " }\n", |
| | "}\n", |
| | NULL |
| | }; |
| |
|
| | SoInput in; |
| | in.setStringArray(inlineSceneGraph); |
| |
|
| | window.setSceneGraph(SoDB::readAll(&in)); |
| |
|
| | return app.exec(); |
| | } |
| |
|
| | # endif |
| |
|
| | #endif |
| |
|