Guest User

Oculus/Cinder

a guest
Oct 7th, 2014
626
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.78 KB | None | 0 0
  1. #include "cinder/app/AppNative.h"
  2. #include "cinder/gl/gl.h"
  3.  
  4. #include "cinder/Camera.h"
  5. #include "cinder/gl/Fbo.h"
  6. #include "cinder/Utilities.h"
  7.  
  8. #define OVR_OS_WIN32
  9. #include "OVR_CAPI.h"
  10. #include "OVR_CAPI_GL.h"
  11.  
  12. using namespace ci;
  13. using namespace ci::app;
  14. using namespace std;
  15.  
  16. class OculusTestApp : public AppNative {
  17.     public:
  18.         void prepareSettings(Settings *settings);
  19.         void setup();
  20.         void mouseDown(MouseEvent event);  
  21.         void keyDown(KeyEvent event);
  22.         void update();
  23.         void draw();
  24.  
  25.     private:
  26.         CameraStereo mCamera;
  27.         gl::Fbo mFbo;
  28.  
  29.         ovrHmd mHmd;
  30.         ovrSizei mEyeRes[2];
  31.         ovrGLTexture mEyeTex[2];
  32.         ovrEyeRenderDesc mEyeRdesc[2];
  33.         ovrPosef mEyePose[2];
  34.  
  35.     private:
  36.         void createFbo(int width, int height);
  37.         void render();
  38. };
  39.  
  40. void OculusTestApp::prepareSettings(Settings *settings)
  41. {
  42.     settings->setWindowSize(1280, 800);
  43.     settings->setTitle("Stereoscopic Rendering");
  44.     settings->setFrameRate(300.0f);
  45. }
  46.  
  47. void OculusTestApp::setup()
  48. {
  49.     // setup the camera
  50.     mCamera.setEyePoint(Vec3f(0.2f, 1.3f, -11.5f));
  51.     mCamera.setCenterOfInterestPoint(Vec3f(0.5f, 1.5f, -0.1f));
  52.     mCamera.setWorldUp(Vec3f(0.0f, -1.0f, 0.0f));
  53.     mCamera.setFov(60.0f);
  54.  
  55.     ovr_Initialize();
  56.     mHmd = ovrHmd_Create(0);
  57.  
  58.     if (!mHmd)
  59.     {
  60.         mHmd = ovrHmd_CreateDebug(ovrHmd_DK2);
  61.     }
  62.  
  63.     if (mHmd)
  64.     {
  65.         OutputDebugString(L"Got HMD: ");
  66.         switch (mHmd->Type) {
  67.         case ovrHmd_None:
  68.             OutputDebugString(L"None\n");
  69.             break;
  70.         case ovrHmd_DK1:
  71.             OutputDebugString(L"DK1\n");
  72.             break;
  73.         case ovrHmd_DKHD:
  74.             OutputDebugString(L"DKHD\n");
  75.             break;
  76.         case ovrHmd_DK2:
  77.             OutputDebugString(L"DK2\n");
  78.             break;
  79.         case ovrHmd_Other:
  80.             OutputDebugString(L"Other\n");
  81.             break;
  82.         default:
  83.             OutputDebugString(L"Unknown\n");
  84.             break;
  85.         }
  86.     }
  87.  
  88.     setWindowSize(mHmd->Resolution.w, mHmd->Resolution.h);
  89.     setWindowPos(mHmd->WindowsPos.x, mHmd->WindowsPos.y);
  90.  
  91.     ovrHmd_ConfigureTracking(mHmd, ovrTrackingCap_Orientation |
  92.                                    ovrTrackingCap_Position |
  93.                                    ovrTrackingCap_MagYawCorrection, 0);
  94.    
  95.     ovrSizei eyeRes[2];
  96.     eyeRes[0] = ovrHmd_GetFovTextureSize(mHmd, ovrEye_Left, mHmd->DefaultEyeFov[0], 1.0);
  97.     eyeRes[1] = ovrHmd_GetFovTextureSize(mHmd, ovrEye_Right, mHmd->DefaultEyeFov[1], 1.0);
  98.  
  99.     createFbo(eyeRes[0].w + eyeRes[1].w, ci::math<int>::max(eyeRes[0].h, eyeRes[1].h));
  100.    
  101.     for (int i = 0; i < 2; i++)
  102.     {
  103.         mEyeTex[i].OGL.Header.API = ovrRenderAPI_OpenGL;
  104.         mEyeTex[i].OGL.Header.TextureSize.w = mFbo.getSize().x;
  105.         mEyeTex[i].OGL.Header.TextureSize.h = mFbo.getSize().y;
  106.         mEyeTex[i].OGL.Header.RenderViewport.Pos.x = i == 0 ? 0 : mFbo.getSize().x / 2.0;
  107.         mEyeTex[i].OGL.Header.RenderViewport.Pos.y = 0;
  108.         mEyeTex[i].OGL.Header.RenderViewport.Size.w = mFbo.getSize().x / 2.0;
  109.         mEyeTex[i].OGL.Header.RenderViewport.Size.h = mFbo.getSize().y;
  110.        
  111.         mEyeTex[i].OGL.TexId = mFbo.getTexture(0).getId();
  112.     }
  113.    
  114.     ovrGLConfig cfg;
  115.     memset(&cfg, 0, sizeof cfg);
  116.     cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
  117.     cfg.OGL.Header.RTSize = mHmd->Resolution;
  118.     cfg.OGL.Header.Multisample = 1;
  119.     if (mHmd->HmdCaps & ovrHmdCap_ExtendDesktop) {
  120.         console() << "running in \"extended desktop\" mode" << endl;
  121.     }
  122.     else
  123.     {
  124.         HWND sys_win = GetActiveWindow();
  125.  
  126.         cfg.OGL.Window = sys_win;
  127.         cfg.OGL.DC = NULL;
  128.         cfg.OGL.Window = sys_win;
  129.         ovrHmd_AttachToWindow(mHmd, sys_win, NULL, NULL);
  130.         console() << "could not initialize" << endl;
  131.         console() << "running in \"direct-hmd\" moden" << endl;
  132.     }
  133.    
  134.     // enable low-persistence display and dynamic prediction for lattency compensation
  135.     ovrHmd_SetEnabledCaps(mHmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);
  136.  
  137.     ovrEyeRenderDesc eyeRenderDescOut[2];
  138.     unsigned int dcaps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette | ovrDistortionCap_TimeWarp |
  139.                          ovrDistortionCap_Overdrive;
  140.  
  141.     if (!ovrHmd_ConfigureRendering(mHmd, &cfg.Config, dcaps, mHmd->DefaultEyeFov, eyeRenderDescOut)) {
  142.         console() << "failed to configure distortion renderer" << endl;
  143.     }
  144.  
  145. }
  146.  
  147. void OculusTestApp::createFbo(int width, int height)
  148. {
  149.     gl::Fbo::Format fmt;
  150.     fmt.setMagFilter(GL_LINEAR);
  151.     fmt.setMinFilter(GL_LINEAR);
  152.     fmt.enableColorBuffer();
  153.     fmt.enableDepthBuffer();
  154.     fmt.setSamples(16);
  155.     fmt.setCoverageSamples(16);
  156.  
  157.     mFbo = gl::Fbo(width, height, fmt);
  158. }
  159.  
  160. void OculusTestApp::mouseDown( MouseEvent event )
  161. {
  162. }
  163.  
  164. void OculusTestApp::keyDown(KeyEvent event)
  165. {
  166.     switch (event.getCode())
  167.     {
  168.     case KeyEvent::KEY_ESCAPE:
  169.         if (mHmd) {
  170.             ovrHmd_Destroy(mHmd);
  171.         }
  172.         ovr_Shutdown();
  173.         quit();
  174.         break;
  175.     default:
  176.         ovrHSWDisplayState state;
  177.         ovrHmd_GetHSWDisplayState(mHmd, &state);
  178.         if (state.Displayed)
  179.         {
  180.             ovrHmd_DismissHSWDisplay(mHmd);
  181.         }
  182.         break;
  183.     }
  184. }
  185.  
  186. void OculusTestApp::update()
  187. {
  188.     // Extract Oculus Orientation and Update Camera
  189.     ovrTrackingState ts = ovrHmd_GetTrackingState(mHmd, ovr_GetTimeInSeconds());
  190.     ovrPosef pose = ts.HeadPose.ThePose;
  191.  
  192.     ovrQuatf orientation = pose.Orientation;
  193.     Quatf ci_quat(orientation.w, orientation.x, orientation.y, orientation.z);
  194.     mCamera.setOrientation(ci_quat * Quatf(Vec3f(0, 1, 0), M_PI));
  195. }
  196.  
  197. void OculusTestApp::draw()
  198. {
  199.     Vec2i size = mFbo.getSize();
  200.     ovrHmd_BeginFrame(mHmd, 0);
  201.     mFbo.bindFramebuffer();
  202.  
  203.     // clear out the window with black
  204.     gl::clear(Color(0, 0.4, 0));
  205.  
  206.     // store current viewport
  207.     glPushAttrib(GL_VIEWPORT_BIT);
  208.  
  209.     for (int i = 0; i < 2; i++)
  210.     {
  211.         ovrEyeType eye = mHmd->EyeRenderOrder[i];
  212.         if (eye == ovrEye_Left)
  213.         {
  214.             // draw to left half of window only
  215.             gl::setViewport(Area(0, 0, size.x / 2, size.y));
  216.  
  217.             // render left camera
  218.             mCamera.enableStereoLeft();
  219.         }
  220.         else
  221.         {
  222.             // draw to right half of window only
  223.             gl::setViewport(Area(size.x / 2, 0, size.x, size.y));
  224.  
  225.             // render right camera
  226.             mCamera.enableStereoRight();
  227.         }
  228.         mEyePose[eye] = ovrHmd_GetEyePose(mHmd, eye);
  229.        
  230.         render();
  231.     }
  232.    
  233.     // restore viewport
  234.     glPopAttrib();
  235.     mFbo.unbindFramebuffer();
  236.  
  237.     ovrHmd_EndFrame(mHmd, mEyePose, &mEyeTex[0].Texture);
  238.    
  239.     gl::setMatricesWindow(getWindowSize());
  240.     gl::draw(mFbo.getTexture(0), Rectf(0, 0, getWindowSize().x, getWindowSize().y));
  241. }
  242.  
  243. void OculusTestApp::render()
  244. {
  245.     // enable 3D rendering
  246.     gl::enableDepthRead();
  247.     gl::enableDepthWrite();
  248.  
  249.     // set 3D camera matrices
  250.     gl::pushMatrices();
  251.     gl::setMatrices(mCamera);
  252.  
  253.     // draw grid
  254.     gl::color(Color(0.8f, 0.8f, 0.8f));
  255.     for (int i = -100; i <= 100; ++i) {
  256.         gl::drawLine(Vec3f((float)i, 0, -100), Vec3f((float)i, 0, 100));
  257.         gl::drawLine(Vec3f(-100, 0, (float)i), Vec3f(100, 0, (float)i));
  258.     }
  259.  
  260.     // draw floor
  261.     gl::enableAlphaBlending();
  262.     gl::color(ColorA(1, 1, 1, 0.75f));
  263.     gl::drawCube(Vec3f(0.0f, -0.5f, 0.0f), Vec3f(200.0f, 1.0f, 200.0f));
  264.  
  265.     gl::color(ColorA(1, 0.5, 0, 0.75f));
  266.     gl::drawTorus(2.0f, 1.0f);
  267.     gl::disableAlphaBlending();
  268.  
  269.  
  270.     // restore 2D rendering
  271.     gl::popMatrices();
  272.     gl::disableDepthWrite();
  273.     gl::disableDepthRead();
  274. }
  275.  
  276. CINDER_APP_NATIVE( OculusTestApp, RendererGl )
Advertisement
Add Comment
Please, Sign In to add comment