123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223 |
- #ifdef BT_ENABLE_VR
- //#define BT_USE_CUSTOM_PROFILER
- //========= Copyright Valve Corporation ============//
- #include "../OpenGLWindow/SimpleOpenGL3App.h"
- #include "../OpenGLWindow/OpenGLInclude.h"
- #include "Bullet3Common/b3Quaternion.h"
- #include "Bullet3Common/b3Transform.h"
- #include "../ExampleBrowser/OpenGLGuiHelper.h"
- #include "../CommonInterfaces/CommonExampleInterface.h"
- #include "../CommonInterfaces/CommonGUIHelperInterface.h"
- #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
- #include "BulletCollision/CollisionShapes/btCollisionShape.h"
- #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
- #include "LinearMath/btIDebugDraw.h"
- int gSharedMemoryKey = -1;
- int gDebugDrawFlags = 0;
- //how can you try typing on a keyboard, without seeing it?
- //it is pretty funny, to see the desktop in VR!
- #include <stdio.h>
- #include <string>
- #include <cstdlib>
- #include <openvr.h>
- #include "lodepng.h"
- #include "Matrices.h"
- #include "pathtools.h"
- CommonExampleInterface* sExample;
- int sPrevPacketNum=0;
- OpenGLGuiHelper* sGuiPtr = 0;
- static vr::VRControllerState_t sPrevStates[vr::k_unMaxTrackedDeviceCount] = { 0 };
- #if defined(POSIX)
- #include "unistd.h"
- #endif
- #ifdef _WIN32
- #include <Windows.h>
- #endif
- void ThreadSleep( unsigned long nMilliseconds )
- {
- #if defined(_WIN32)
- ::Sleep( nMilliseconds );
- #elif defined(POSIX)
- usleep( nMilliseconds * 1000 );
- #endif
- }
- class CGLRenderModel
- {
- public:
- CGLRenderModel( const std::string & sRenderModelName );
- ~CGLRenderModel();
- bool BInit( const vr::RenderModel_t & vrModel, const vr::RenderModel_TextureMap_t & vrDiffuseTexture );
- void Cleanup();
- void Draw();
- const std::string & GetName() const { return m_sModelName; }
- private:
- GLuint m_glVertBuffer;
- GLuint m_glIndexBuffer;
- GLuint m_glVertArray;
- GLuint m_glTexture;
- GLsizei m_unVertexCount;
- std::string m_sModelName;
- };
- static bool g_bPrintf = true;
- //-----------------------------------------------------------------------------
- // Purpose:
- //------------------------------------------------------------------------------
- class CMainApplication
- {
- public:
- CMainApplication( int argc, char *argv[] );
- virtual ~CMainApplication();
- bool BInit();
- bool BInitGL();
- bool BInitCompositor();
- void getControllerTransform(int unDevice, b3Transform& tr);
- void SetupRenderModels();
- void Shutdown();
- void RunMainLoop();
- bool HandleInput();
- void ProcessVREvent( const vr::VREvent_t & event );
- void RenderFrame();
- bool SetupTexturemaps();
- void SetupScene();
- void AddCubeToScene( Matrix4 mat, std::vector<float> &vertdata );
- void AddCubeVertex( float fl0, float fl1, float fl2, float fl3, float fl4, std::vector<float> &vertdata );
- void DrawControllers();
- bool SetupStereoRenderTargets();
- void SetupDistortion();
- void SetupCameras();
- void RenderStereoTargets();
- void RenderDistortion();
- void RenderScene( vr::Hmd_Eye nEye );
- Matrix4 GetHMDMatrixProjectionEye( vr::Hmd_Eye nEye );
- Matrix4 GetHMDMatrixPoseEye( vr::Hmd_Eye nEye );
- Matrix4 GetCurrentViewProjectionMatrix( vr::Hmd_Eye nEye );
- void UpdateHMDMatrixPose();
- Matrix4 ConvertSteamVRMatrixToMatrix4( const vr::HmdMatrix34_t &matPose );
- GLuint CompileGLShader( const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader );
- bool CreateAllShaders();
- void SetupRenderModelForTrackedDevice( vr::TrackedDeviceIndex_t unTrackedDeviceIndex );
- CGLRenderModel *FindOrLoadRenderModel( const char *pchRenderModelName );
- private:
- bool m_bDebugOpenGL;
- bool m_bVerbose;
- bool m_bPerf;
- bool m_bVblank;
- bool m_bGlFinishHack;
- vr::IVRSystem *m_pHMD;
- vr::IVRRenderModels *m_pRenderModels;
- std::string m_strDriver;
- std::string m_strDisplay;
- vr::TrackedDevicePose_t m_rTrackedDevicePose[ vr::k_unMaxTrackedDeviceCount ];
- Matrix4 m_rmat4DevicePose[ vr::k_unMaxTrackedDeviceCount ];
- bool m_rbShowTrackedDevice[ vr::k_unMaxTrackedDeviceCount ];
- private:
- SimpleOpenGL3App* m_app;
- uint32_t m_nWindowWidth;
- uint32_t m_nWindowHeight;
- bool m_hasContext;
- private: // OpenGL bookkeeping
- int m_iTrackedControllerCount;
- int m_iTrackedControllerCount_Last;
- int m_iValidPoseCount;
- int m_iValidPoseCount_Last;
- bool m_bShowCubes;
- std::string m_strPoseClasses; // what classes we saw poses for this frame
- char m_rDevClassChar[ vr::k_unMaxTrackedDeviceCount ]; // for each device, a character representing its class
- int m_iSceneVolumeWidth;
- int m_iSceneVolumeHeight;
- int m_iSceneVolumeDepth;
- float m_fScaleSpacing;
- float m_fScale;
-
- int m_iSceneVolumeInit; // if you want something other than the default 20x20x20
-
- float m_fNearClip;
- float m_fFarClip;
- GLuint m_iTexture;
- unsigned int m_uiVertcount;
- GLuint m_glSceneVertBuffer;
- GLuint m_unSceneVAO;
- GLuint m_unLensVAO;
- GLuint m_glIDVertBuffer;
- GLuint m_glIDIndexBuffer;
- unsigned int m_uiIndexSize;
- GLuint m_glControllerVertBuffer;
- GLuint m_unControllerVAO;
- unsigned int m_uiControllerVertcount;
- Matrix4 m_mat4HMDPose;
- Matrix4 m_mat4eyePosLeft;
- Matrix4 m_mat4eyePosRight;
- Matrix4 m_mat4ProjectionCenter;
- Matrix4 m_mat4ProjectionLeft;
- Matrix4 m_mat4ProjectionRight;
- struct VertexDataScene
- {
- Vector3 position;
- Vector2 texCoord;
- };
- struct VertexDataLens
- {
- Vector2 position;
- Vector2 texCoordRed;
- Vector2 texCoordGreen;
- Vector2 texCoordBlue;
- };
- GLuint m_unSceneProgramID;
- GLuint m_unLensProgramID;
- GLuint m_unControllerTransformProgramID;
- GLuint m_unRenderModelProgramID;
- GLint m_nSceneMatrixLocation;
- GLint m_nControllerMatrixLocation;
- GLint m_nRenderModelMatrixLocation;
- struct FramebufferDesc
- {
- GLuint m_nDepthBufferId;
- GLuint m_nRenderTextureId;
- GLuint m_nRenderFramebufferId;
- GLuint m_nResolveTextureId;
- GLuint m_nResolveFramebufferId;
- };
- FramebufferDesc leftEyeDesc;
- FramebufferDesc rightEyeDesc;
- bool CreateFrameBuffer( int nWidth, int nHeight, FramebufferDesc &framebufferDesc );
-
- uint32_t m_nRenderWidth;
- uint32_t m_nRenderHeight;
- std::vector< CGLRenderModel * > m_vecRenderModels;
- CGLRenderModel *m_rTrackedDeviceToRenderModel[ vr::k_unMaxTrackedDeviceCount ];
- };
- //-----------------------------------------------------------------------------
- // Purpose: Constructor
- //-----------------------------------------------------------------------------
- CMainApplication::CMainApplication( int argc, char *argv[] )
- : m_app(NULL)
- , m_hasContext(false)
- , m_nWindowWidth( 1280 )
- , m_nWindowHeight( 720 )
- , m_unSceneProgramID( 0 )
- , m_unLensProgramID( 0 )
- , m_unControllerTransformProgramID( 0 )
- , m_unRenderModelProgramID( 0 )
- , m_pHMD( NULL )
- , m_pRenderModels( NULL )
- , m_bDebugOpenGL( false )
- , m_bVerbose( false )
- , m_bPerf( false )
- , m_bVblank( false )
- , m_bGlFinishHack( true )
- , m_glControllerVertBuffer( 0 )
- , m_unControllerVAO( 0 )
- , m_unLensVAO( 0 )
- , m_unSceneVAO( 0 )
- , m_nSceneMatrixLocation( -1 )
- , m_nControllerMatrixLocation( -1 )
- , m_nRenderModelMatrixLocation( -1 )
- , m_iTrackedControllerCount( 0 )
- , m_iTrackedControllerCount_Last( -1 )
- , m_iValidPoseCount( 0 )
- , m_iValidPoseCount_Last( -1 )
- , m_iSceneVolumeInit( 20 )
- , m_strPoseClasses("")
- , m_bShowCubes( false )
- {
- for( int i = 1; i < argc; i++ )
- {
- if( !stricmp( argv[i], "-gldebug" ) )
- {
- m_bDebugOpenGL = true;
- }
- else if( !stricmp( argv[i], "-verbose" ) )
- {
- m_bVerbose = true;
- }
- else if( !stricmp( argv[i], "-novblank" ) )
- {
- m_bVblank = false;
- }
- else if( !stricmp( argv[i], "-noglfinishhack" ) )
- {
- m_bGlFinishHack = false;
- }
- else if( !stricmp( argv[i], "-noprintf" ) )
- {
- g_bPrintf = false;
- }
- else if ( !stricmp( argv[i], "-cubevolume" ) && ( argc > i + 1 ) && ( *argv[ i + 1 ] != '-' ) )
- {
- m_iSceneVolumeInit = atoi( argv[ i + 1 ] );
- i++;
- }
- }
- // other initialization tasks are done in BInit
- memset(m_rDevClassChar, 0, sizeof(m_rDevClassChar));
- };
- //-----------------------------------------------------------------------------
- // Purpose: Destructor
- //-----------------------------------------------------------------------------
- CMainApplication::~CMainApplication()
- {
- // work is done in Shutdown
- b3Printf( "Shutdown" );
- }
- //-----------------------------------------------------------------------------
- // Purpose: Helper to get a string from a tracked device property and turn it
- // into a std::string
- //-----------------------------------------------------------------------------
- std::string GetTrackedDeviceString( vr::IVRSystem *pHmd, vr::TrackedDeviceIndex_t unDevice, vr::TrackedDeviceProperty prop, vr::TrackedPropertyError *peError = NULL )
- {
- uint32_t unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty( unDevice, prop, NULL, 0, peError );
- if( unRequiredBufferLen == 0 )
- return "";
- char *pchBuffer = new char[ unRequiredBufferLen ];
- unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty( unDevice, prop, pchBuffer, unRequiredBufferLen, peError );
- std::string sResult = pchBuffer;
- delete [] pchBuffer;
- return sResult;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- bool CMainApplication::BInit()
- {
-
- // Loading the SteamVR Runtime
- vr::EVRInitError eError = vr::VRInitError_None;
- m_pHMD = vr::VR_Init( &eError, vr::VRApplication_Scene );
- if ( eError != vr::VRInitError_None )
- {
- m_pHMD = NULL;
- char buf[1024];
- sprintf_s( buf, sizeof( buf ), "Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription( eError ) );
- b3Warning( "VR_Init Failed %s", buf);
- return false;
- }
- m_pRenderModels = (vr::IVRRenderModels *)vr::VR_GetGenericInterface( vr::IVRRenderModels_Version, &eError );
- if( !m_pRenderModels )
- {
- m_pHMD = NULL;
- vr::VR_Shutdown();
- char buf[1024];
- sprintf_s( buf, sizeof( buf ), "Unable to get render model interface: %s", vr::VR_GetVRInitErrorAsEnglishDescription( eError ) );
- b3Warning( "VR_Init Failed %s", buf);
- return false;
- }
- // int nWindowPosX = 700;
- // int nWindowPosY = 100;
- m_nWindowWidth = 1280;
- m_nWindowHeight = 720;
- /*
-
- //SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY );
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
- SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 );
- SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 );
- if( m_bDebugOpenGL )
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG );
- */
- m_app = new SimpleOpenGL3App("SimpleOpenGL3App",m_nWindowWidth,m_nWindowHeight,true);
-
- sGuiPtr = new OpenGLGuiHelper(m_app,false);
- sGuiPtr->setVRMode(true);
- //sGuiPtr = new DummyGUIHelper;
-
- CommonExampleOptions options(sGuiPtr);
- sExample = StandaloneExampleCreateFunc(options);
- sExample->initPhysics();
- sExample->resetCamera();
- #if 0
- int cubeIndex = m_app->registerCubeShape(1,1,1);
-
- b3Quaternion orn(0,0,0,1);
-
- {
- b3Vector3 color=b3MakeVector3(0.3,0.3,0.6);
- b3Vector3 pos = b3MakeVector3(0,0,0);
- b3Vector3 scaling=b3MakeVector3 (1,.1,1);
- m_app->m_renderer->registerGraphicsInstance(cubeIndex,pos,orn,color,scaling);
- }
- {
- b3Vector3 color=b3MakeVector3(0.3,0.6,0.3);
- b3Vector3 pos = b3MakeVector3(0,0.3,0);
- b3Vector3 scaling=b3MakeVector3 (.1,.1,.1);
- m_app->m_renderer->registerGraphicsInstance(cubeIndex,pos,orn,color,scaling);
- }
- #endif
-
- m_app->m_renderer->writeTransforms();
- /* if (m_pWindow == NULL)
- {
- printf( "%s - Window could not be created! SDL Error: %s\n", __FUNCTION__, SDL_GetError() );
- return false;
- }
- */
- /*m_pContext = SDL_GL_CreateContext(m_pWindow);
- if (m_pContext == NULL)
- {
- printf( "%s - OpenGL context could not be created! SDL Error: %s\n", __FUNCTION__, SDL_GetError() );
- return false;
- }
- glewExperimental = GL_TRUE;
- GLenum nGlewError = glewInit();
- if (nGlewError != GLEW_OK)
- {
- printf( "%s - Error initializing GLEW! %s\n", __FUNCTION__, glewGetErrorString( nGlewError ) );
- return false;
- }
- glGetError(); // to clear the error caused deep in GLEW
- if ( SDL_GL_SetSwapInterval( m_bVblank ? 1 : 0 ) < 0 )
- {
- printf( "%s - Warning: Unable to set VSync! SDL Error: %s\n", __FUNCTION__, SDL_GetError() );
- return false;
- }
- */
- m_strDriver = "No Driver";
- m_strDisplay = "No Display";
- m_strDriver = GetTrackedDeviceString( m_pHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_TrackingSystemName_String );
- m_strDisplay = GetTrackedDeviceString( m_pHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SerialNumber_String );
- std::string strWindowTitle = "hellovr_bullet - " + m_strDriver + " " + m_strDisplay;
- m_app->m_window->setWindowTitle(strWindowTitle.c_str() );
-
- // cube array
- m_iSceneVolumeWidth = m_iSceneVolumeInit;
- m_iSceneVolumeHeight = m_iSceneVolumeInit;
- m_iSceneVolumeDepth = m_iSceneVolumeInit;
-
- m_fScale = 0.3f;
- m_fScaleSpacing = 4.0f;
-
- m_fNearClip = 0.1f;
- m_fFarClip = 3000.0f;
-
- m_iTexture = 0;
- m_uiVertcount = 0;
-
- // m_MillisecondsTimer.start(1, this);
- // m_SecondsTimer.start(1000, this);
-
- if (!BInitGL())
- {
- printf("%s - Unable to initialize OpenGL!\n", __FUNCTION__);
- return false;
- }
- if (!BInitCompositor())
- {
- printf("%s - Failed to initialize VR Compositor!\n", __FUNCTION__);
- return false;
- }
- return true;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- /*void APIENTRY DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam)
- {
- b3Printf( "GL Error: %s\n", message );
- }
- */
- static void APIENTRY DebugCallback (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam)
- {
- b3Printf( "GL Error: %s\n", message );
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- bool CMainApplication::BInitGL()
- {
- if( m_bDebugOpenGL )
- {
- const GLvoid *userParam=0;
- glDebugMessageCallback(DebugCallback, userParam);
- glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE );
- glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
- }
- if( !CreateAllShaders() )
- return false;
- SetupTexturemaps();
- SetupScene();
- SetupCameras();
- SetupStereoRenderTargets();
- SetupDistortion();
- SetupRenderModels();
- return true;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- bool CMainApplication::BInitCompositor()
- {
- vr::EVRInitError peError = vr::VRInitError_None;
- if ( !vr::VRCompositor() )
- {
- printf( "Compositor initialization failed. See log file for details\n" );
- return false;
- }
- return true;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::Shutdown()
- {
- if( m_pHMD )
- {
- vr::VR_Shutdown();
- m_pHMD = NULL;
- }
- for( std::vector< CGLRenderModel * >::iterator i = m_vecRenderModels.begin(); i != m_vecRenderModels.end(); i++ )
- {
- delete (*i);
- }
- m_vecRenderModels.clear();
-
- if( m_hasContext)
- {
- if (m_glSceneVertBuffer)
- {
- glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE );
- glDebugMessageCallback(nullptr, nullptr);
- glDeleteBuffers(1, &m_glSceneVertBuffer);
- glDeleteBuffers(1, &m_glIDVertBuffer);
- glDeleteBuffers(1, &m_glIDIndexBuffer);
- }
- if ( m_unSceneProgramID )
- {
- glDeleteProgram( m_unSceneProgramID );
- }
- if ( m_unControllerTransformProgramID )
- {
- glDeleteProgram( m_unControllerTransformProgramID );
- }
- if ( m_unRenderModelProgramID )
- {
- glDeleteProgram( m_unRenderModelProgramID );
- }
- if ( m_unLensProgramID )
- {
- glDeleteProgram( m_unLensProgramID );
- }
- glDeleteRenderbuffers( 1, &leftEyeDesc.m_nDepthBufferId );
- glDeleteTextures( 1, &leftEyeDesc.m_nRenderTextureId );
- glDeleteFramebuffers( 1, &leftEyeDesc.m_nRenderFramebufferId );
- glDeleteTextures( 1, &leftEyeDesc.m_nResolveTextureId );
- glDeleteFramebuffers( 1, &leftEyeDesc.m_nResolveFramebufferId );
- glDeleteRenderbuffers( 1, &rightEyeDesc.m_nDepthBufferId );
- glDeleteTextures( 1, &rightEyeDesc.m_nRenderTextureId );
- glDeleteFramebuffers( 1, &rightEyeDesc.m_nRenderFramebufferId );
- glDeleteTextures( 1, &rightEyeDesc.m_nResolveTextureId );
- glDeleteFramebuffers( 1, &rightEyeDesc.m_nResolveFramebufferId );
- if( m_unLensVAO != 0 )
- {
- glDeleteVertexArrays( 1, &m_unLensVAO );
- }
- if( m_unSceneVAO != 0 )
- {
- glDeleteVertexArrays( 1, &m_unSceneVAO );
- }
- if( m_unControllerVAO != 0 )
- {
- glDeleteVertexArrays( 1, &m_unControllerVAO );
- }
- }
- sExample->exitPhysics();
- delete sExample;
- delete m_app;
- m_app=0;
-
- }
- void CMainApplication::getControllerTransform(int unDevice, b3Transform& tr)
- {
- const Matrix4 & matOrg = m_rmat4DevicePose[unDevice];
- tr.setIdentity();
- tr.setOrigin(b3MakeVector3(matOrg[12],matOrg[13],matOrg[14]));//pos[1]));
- b3Matrix3x3 bmat;
- for (int i=0;i<3;i++)
- {
- for (int j=0;j<3;j++)
- {
- bmat[i][j] = matOrg[i+4*j];
- }
- }
- tr.setBasis(bmat);
- b3Transform y2z;
- y2z.setIdentity();
- y2z.setRotation(b3Quaternion(0,B3_HALF_PI,0));
- tr = y2z*tr;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- bool CMainApplication::HandleInput()
- {
- bool bRet = false;
-
- // Process SteamVR events
- vr::VREvent_t event;
- while( m_pHMD->PollNextEvent( &event, sizeof( event ) ) )
- {
- ProcessVREvent( event );
- }
- // Process SteamVR controller state
- for( vr::TrackedDeviceIndex_t unDevice = 0; unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++ )
- {
- vr::VRControllerState_t state;
- if( m_pHMD->GetControllerState( unDevice, &state ) )
- {
- //we need to have the 'move' events, so no early out here
- //if (sPrevStates[unDevice].unPacketNum != state.unPacketNum)
- if( m_pHMD->GetTrackedDeviceClass( unDevice) == vr::TrackedDeviceClass_Controller )
- {
- sPrevStates[unDevice].unPacketNum = state.unPacketNum;
- for (int button = 0; button < vr::k_EButton_Max; button++)
- {
- uint64_t trigger = vr::ButtonMaskFromId((vr::EVRButtonId)button);
- bool isTrigger = (state.ulButtonPressed&trigger) != 0;
- if (isTrigger)
- {
- b3Transform tr;
- getControllerTransform(unDevice, tr);
- float pos[3] = { tr.getOrigin()[0], tr.getOrigin()[1], tr.getOrigin()[2] };
- b3Quaternion born = tr.getRotation();
- float orn[4] = { born[0], born[1], born[2], born[3] };
- //pressed now, not pressed before -> raise a button down event
- if ((sPrevStates[unDevice].ulButtonPressed&trigger)==0)
- {
- // printf("Device PRESSED: %d, button %d\n", unDevice, button);
- if (button==2)
- {
- glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
- ///todo(erwincoumans) can't use reguar debug drawer, because physics/graphics are not in sync
- ///so it can (and likely will) cause crashes
- ///add a special debug drawer that deals with this
- //gDebugDrawFlags = btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints+
- //btIDebugDraw::DBG_DrawConstraintLimits+
- //btIDebugDraw::DBG_DrawConstraints
- //;
- //gDebugDrawFlags = btIDebugDraw::DBG_DrawFrames;
-
- }
- sExample->vrControllerButtonCallback(unDevice, button, 1, pos, orn);
- }
- else
- {
-
- // printf("Device MOVED: %d\n", unDevice);
- sExample->vrControllerMoveCallback(unDevice, pos, orn, state.rAxis[1].x);
- }
- }
- else
- {
- if( m_pHMD->GetTrackedDeviceClass( unDevice) == vr::TrackedDeviceClass_Controller )
- {
-
- b3Transform tr;
- getControllerTransform(unDevice, tr);
- float pos[3] = { tr.getOrigin()[0], tr.getOrigin()[1], tr.getOrigin()[2] };
- b3Quaternion born = tr.getRotation();
- float orn[4] = { born[0], born[1], born[2], born[3] };
- // printf("Device RELEASED: %d, button %d\n", unDevice,button);
-
- //not pressed now, but pressed before -> raise a button up event
- if ((sPrevStates[unDevice].ulButtonPressed&trigger) != 0)
- {
- if (button==2)
- {
- gDebugDrawFlags = 0;
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
- }
-
- sExample->vrControllerButtonCallback(unDevice, button, 0, pos, orn);
- } else
- {
- sExample->vrControllerMoveCallback(unDevice, pos, orn, state.rAxis[1].x);
- }
- }
- }
- }
- }
- // m_rbShowTrackedDevice[ unDevice ] = state.ulButtonPressed == 0;
- }
- sPrevStates[unDevice] = state;
- }
- return bRet;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::RunMainLoop()
- {
- bool bQuit = false;
- while ( !bQuit && !m_app->m_window->requestedExit())
- {
- B3_PROFILE("main");
- bQuit = HandleInput();
- RenderFrame();
- }
- }
- //-----------------------------------------------------------------------------
- // Purpose: Processes a single VR event
- //-----------------------------------------------------------------------------
- void CMainApplication::ProcessVREvent( const vr::VREvent_t & event )
- {
- switch( event.eventType )
- {
- case vr::VREvent_TrackedDeviceActivated:
- {
- SetupRenderModelForTrackedDevice( event.trackedDeviceIndex );
- b3Printf( "Device %u attached. Setting up render model.\n", event.trackedDeviceIndex );
- }
- break;
- case vr::VREvent_TrackedDeviceDeactivated:
- {
- b3Printf( "Device %u detached.\n", event.trackedDeviceIndex );
- }
- break;
- case vr::VREvent_TrackedDeviceUpdated:
- {
- b3Printf( "Device %u updated.\n", event.trackedDeviceIndex );
- }
- break;
- }
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::RenderFrame()
- {
- // for now as fast as possible
- if ( m_pHMD )
- {
- {
- B3_PROFILE("DrawControllers");
- DrawControllers();
- }
- RenderStereoTargets();
- {
- B3_PROFILE("RenderDistortion");
- RenderDistortion();
- }
- vr::Texture_t leftEyeTexture = {(void*)leftEyeDesc.m_nResolveTextureId, vr::API_OpenGL, vr::ColorSpace_Gamma };
- vr::VRCompositor()->Submit(vr::Eye_Left, &leftEyeTexture );
- vr::Texture_t rightEyeTexture = {(void*)rightEyeDesc.m_nResolveTextureId, vr::API_OpenGL, vr::ColorSpace_Gamma };
- vr::VRCompositor()->Submit(vr::Eye_Right, &rightEyeTexture );
- }
- if ( m_bVblank && m_bGlFinishHack )
- {
- B3_PROFILE("bGlFinishHack");
- //$ HACKHACK. From gpuview profiling, it looks like there is a bug where two renders and a present
- // happen right before and after the vsync causing all kinds of jittering issues. This glFinish()
- // appears to clear that up. Temporary fix while I try to get nvidia to investigate this problem.
- // 1/29/2014 mikesart
- glFinish();
- }
- // SwapWindow
- {
- B3_PROFILE("m_app->swapBuffer");
- m_app->swapBuffer();
- //SDL_GL_SwapWindow( m_pWindow );
-
- }
- // Clear
- {
- B3_PROFILE("glClearColor");
- // We want to make sure the glFinish waits for the entire present to complete, not just the submission
- // of the command. So, we do a clear here right here so the glFinish will wait fully for the swap.
- glClearColor( 0, 0, 0, 1 );
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- }
- // Flush and wait for swap.
- if ( m_bVblank )
- {
- B3_PROFILE("glFlushglFinish");
- glFlush();
- glFinish();
- }
- // Spew out the controller and pose count whenever they change.
- if ( m_iTrackedControllerCount != m_iTrackedControllerCount_Last || m_iValidPoseCount != m_iValidPoseCount_Last )
- {
- B3_PROFILE("debug pose");
- m_iValidPoseCount_Last = m_iValidPoseCount;
- m_iTrackedControllerCount_Last = m_iTrackedControllerCount;
-
- b3Printf( "PoseCount:%d(%s) Controllers:%d\n", m_iValidPoseCount, m_strPoseClasses.c_str(), m_iTrackedControllerCount );
- }
- {
- B3_PROFILE("UpdateHMDMatrixPose");
- UpdateHMDMatrixPose();
- }
- }
- //-----------------------------------------------------------------------------
- // Purpose: Compiles a GL shader program and returns the handle. Returns 0 if
- // the shader couldn't be compiled for some reason.
- //-----------------------------------------------------------------------------
- GLuint CMainApplication::CompileGLShader( const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader )
- {
- GLuint unProgramID = glCreateProgram();
- GLuint nSceneVertexShader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource( nSceneVertexShader, 1, &pchVertexShader, NULL);
- glCompileShader( nSceneVertexShader );
- GLint vShaderCompiled = GL_FALSE;
- glGetShaderiv( nSceneVertexShader, GL_COMPILE_STATUS, &vShaderCompiled);
- if ( vShaderCompiled != GL_TRUE)
- {
- b3Printf("%s - Unable to compile vertex shader %d!\n", pchShaderName, nSceneVertexShader);
- glDeleteProgram( unProgramID );
- glDeleteShader( nSceneVertexShader );
- return 0;
- }
- glAttachShader( unProgramID, nSceneVertexShader);
- glDeleteShader( nSceneVertexShader ); // the program hangs onto this once it's attached
- GLuint nSceneFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource( nSceneFragmentShader, 1, &pchFragmentShader, NULL);
- glCompileShader( nSceneFragmentShader );
- GLint fShaderCompiled = GL_FALSE;
- glGetShaderiv( nSceneFragmentShader, GL_COMPILE_STATUS, &fShaderCompiled);
- if (fShaderCompiled != GL_TRUE)
- {
- b3Printf("%s - Unable to compile fragment shader %d!\n", pchShaderName, nSceneFragmentShader );
- glDeleteProgram( unProgramID );
- glDeleteShader( nSceneFragmentShader );
- return 0;
- }
- glAttachShader( unProgramID, nSceneFragmentShader );
- glDeleteShader( nSceneFragmentShader ); // the program hangs onto this once it's attached
- glLinkProgram( unProgramID );
- GLint programSuccess = GL_TRUE;
- glGetProgramiv( unProgramID, GL_LINK_STATUS, &programSuccess);
- if ( programSuccess != GL_TRUE )
- {
- b3Printf("%s - Error linking program %d!\n", pchShaderName, unProgramID);
- glDeleteProgram( unProgramID );
- return 0;
- }
- glUseProgram( unProgramID );
- glUseProgram( 0 );
- return unProgramID;
- }
- //-----------------------------------------------------------------------------
- // Purpose: Creates all the shaders used by HelloVR SDL
- //-----------------------------------------------------------------------------
- bool CMainApplication::CreateAllShaders()
- {
- m_unSceneProgramID = CompileGLShader(
- "Scene",
- // Vertex Shader
- "#version 410\n"
- "uniform mat4 matrix;\n"
- "layout(location = 0) in vec4 position;\n"
- "layout(location = 1) in vec2 v2UVcoordsIn;\n"
- "layout(location = 2) in vec3 v3NormalIn;\n"
- "out vec2 v2UVcoords;\n"
- "void main()\n"
- "{\n"
- " v2UVcoords = v2UVcoordsIn;\n"
- " gl_Position = matrix * position;\n"
- "}\n",
- // Fragment Shader
- "#version 410 core\n"
- "uniform sampler2D mytexture;\n"
- "in vec2 v2UVcoords;\n"
- "out vec4 outputColor;\n"
- "void main()\n"
- "{\n"
- " outputColor = texture(mytexture, v2UVcoords);\n"
- "}\n"
- );
- m_nSceneMatrixLocation = glGetUniformLocation( m_unSceneProgramID, "matrix" );
- if( m_nSceneMatrixLocation == -1 )
- {
- b3Printf( "Unable to find matrix uniform in scene shader\n" );
- return false;
- }
- m_unControllerTransformProgramID = CompileGLShader(
- "Controller",
- // vertex shader
- "#version 410\n"
- "uniform mat4 matrix;\n"
- "layout(location = 0) in vec4 position;\n"
- "layout(location = 1) in vec3 v3ColorIn;\n"
- "out vec4 v4Color;\n"
- "void main()\n"
- "{\n"
- " v4Color.xyz = v3ColorIn; v4Color.a = 1.0;\n"
- " gl_Position = matrix * position;\n"
- "}\n",
- // fragment shader
- "#version 410\n"
- "in vec4 v4Color;\n"
- "out vec4 outputColor;\n"
- "void main()\n"
- "{\n"
- " outputColor = v4Color;\n"
- "}\n"
- );
- m_nControllerMatrixLocation = glGetUniformLocation( m_unControllerTransformProgramID, "matrix" );
- if( m_nControllerMatrixLocation == -1 )
- {
- b3Printf( "Unable to find matrix uniform in controller shader\n" );
- return false;
- }
- m_unRenderModelProgramID = CompileGLShader(
- "render model",
- // vertex shader
- "#version 410\n"
- "uniform mat4 matrix;\n"
- "layout(location = 0) in vec4 position;\n"
- "layout(location = 1) in vec3 v3NormalIn;\n"
- "layout(location = 2) in vec2 v2TexCoordsIn;\n"
- "out vec2 v2TexCoord;\n"
- "void main()\n"
- "{\n"
- " v2TexCoord = v2TexCoordsIn;\n"
- " gl_Position = matrix * vec4(position.xyz, 1);\n"
- "}\n",
- //fragment shader
- "#version 410 core\n"
- "uniform sampler2D diffuse;\n"
- "in vec2 v2TexCoord;\n"
- "out vec4 outputColor;\n"
- "void main()\n"
- "{\n"
- " outputColor = texture( diffuse, v2TexCoord);\n"
- "}\n"
- );
- m_nRenderModelMatrixLocation = glGetUniformLocation( m_unRenderModelProgramID, "matrix" );
- if( m_nRenderModelMatrixLocation == -1 )
- {
- b3Printf( "Unable to find matrix uniform in render model shader\n" );
- return false;
- }
- m_unLensProgramID = CompileGLShader(
- "Distortion",
- // vertex shader
- "#version 410 core\n"
- "layout(location = 0) in vec4 position;\n"
- "layout(location = 1) in vec2 v2UVredIn;\n"
- "layout(location = 2) in vec2 v2UVGreenIn;\n"
- "layout(location = 3) in vec2 v2UVblueIn;\n"
- "noperspective out vec2 v2UVred;\n"
- "noperspective out vec2 v2UVgreen;\n"
- "noperspective out vec2 v2UVblue;\n"
- "void main()\n"
- "{\n"
- " v2UVred = v2UVredIn;\n"
- " v2UVgreen = v2UVGreenIn;\n"
- " v2UVblue = v2UVblueIn;\n"
- " gl_Position = position;\n"
- "}\n",
- // fragment shader
- "#version 410 core\n"
- "uniform sampler2D mytexture;\n"
- "noperspective in vec2 v2UVred;\n"
- "noperspective in vec2 v2UVgreen;\n"
- "noperspective in vec2 v2UVblue;\n"
- "out vec4 outputColor;\n"
- "void main()\n"
- "{\n"
- " float fBoundsCheck = ( (dot( vec2( lessThan( v2UVgreen.xy, vec2(0.05, 0.05)) ), vec2(1.0, 1.0))+dot( vec2( greaterThan( v2UVgreen.xy, vec2( 0.95, 0.95)) ), vec2(1.0, 1.0))) );\n"
- " if( fBoundsCheck > 1.0 )\n"
- " { outputColor = vec4( 0, 0, 0, 1.0 ); }\n"
- " else\n"
- " {\n"
- " float red = texture(mytexture, v2UVred).x;\n"
- " float green = texture(mytexture, v2UVgreen).y;\n"
- " float blue = texture(mytexture, v2UVblue).z;\n"
- " outputColor = vec4( red, green, blue, 1.0 ); }\n"
- "}\n"
- );
- return m_unSceneProgramID != 0
- && m_unControllerTransformProgramID != 0
- && m_unRenderModelProgramID != 0
- && m_unLensProgramID != 0;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- bool CMainApplication::SetupTexturemaps()
- {
- std::string sExecutableDirectory = Path_StripFilename( Path_GetExecutablePath() );
- std::string strFullPath = Path_MakeAbsolute( "../cube_texture.png", sExecutableDirectory );
-
- std::vector<unsigned char> imageRGBA;
- unsigned nImageWidth, nImageHeight;
- unsigned nError = lodepng::decode( imageRGBA, nImageWidth, nImageHeight, strFullPath.c_str() );
-
- if ( nError != 0 )
- return false;
- glGenTextures(1, &m_iTexture );
- glBindTexture( GL_TEXTURE_2D, m_iTexture );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nImageWidth, nImageHeight,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, &imageRGBA[0] );
- glGenerateMipmap(GL_TEXTURE_2D);
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
- GLfloat fLargest;
- glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
-
- glBindTexture( GL_TEXTURE_2D, 0 );
- return ( m_iTexture != 0 );
- }
- //-----------------------------------------------------------------------------
- // Purpose: create a sea of cubes
- //-----------------------------------------------------------------------------
- void CMainApplication::SetupScene()
- {
- if ( !m_pHMD )
- return;
- std::vector<float> vertdataarray;
- Matrix4 matScale;
- matScale.scale( m_fScale, m_fScale, m_fScale );
- Matrix4 matTransform;
- matTransform.translate(
- -( (float)m_iSceneVolumeWidth * m_fScaleSpacing ) / 2.f,
- -( (float)m_iSceneVolumeHeight * m_fScaleSpacing ) / 2.f,
- -( (float)m_iSceneVolumeDepth * m_fScaleSpacing ) / 2.f);
-
- Matrix4 mat = matScale * matTransform;
- for( int z = 0; z< m_iSceneVolumeDepth; z++ )
- {
- for( int y = 0; y< m_iSceneVolumeHeight; y++ )
- {
- for( int x = 0; x< m_iSceneVolumeWidth; x++ )
- {
- AddCubeToScene( mat, vertdataarray );
- mat = mat * Matrix4().translate( m_fScaleSpacing, 0, 0 );
- }
- mat = mat * Matrix4().translate( -((float)m_iSceneVolumeWidth) * m_fScaleSpacing, m_fScaleSpacing, 0 );
- }
- mat = mat * Matrix4().translate( 0, -((float)m_iSceneVolumeHeight) * m_fScaleSpacing, m_fScaleSpacing );
- }
- m_uiVertcount = vertdataarray.size()/5;
-
- glGenVertexArrays( 1, &m_unSceneVAO );
- glBindVertexArray( m_unSceneVAO );
- glGenBuffers( 1, &m_glSceneVertBuffer );
- glBindBuffer( GL_ARRAY_BUFFER, m_glSceneVertBuffer );
- glBufferData( GL_ARRAY_BUFFER, sizeof(float) * vertdataarray.size(), &vertdataarray[0], GL_STATIC_DRAW);
- glBindBuffer( GL_ARRAY_BUFFER, m_glSceneVertBuffer );
- GLsizei stride = sizeof(VertexDataScene);
- uintptr_t offset = 0;
- glEnableVertexAttribArray( 0 );
- glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride , (const void *)offset);
- offset += sizeof(Vector3);
- glEnableVertexAttribArray( 1 );
- glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, stride, (const void *)offset);
- glBindVertexArray( 0 );
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
- m_hasContext = true;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::AddCubeVertex( float fl0, float fl1, float fl2, float fl3, float fl4, std::vector<float> &vertdata )
- {
- vertdata.push_back( fl0 );
- vertdata.push_back( fl1 );
- vertdata.push_back( fl2 );
- vertdata.push_back( fl3 );
- vertdata.push_back( fl4 );
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::AddCubeToScene( Matrix4 mat, std::vector<float> &vertdata )
- {
- // Matrix4 mat( outermat.data() );
- Vector4 A = mat * Vector4( 0, 0, 0, 1 );
- Vector4 B = mat * Vector4( 1, 0, 0, 1 );
- Vector4 C = mat * Vector4( 1, 1, 0, 1 );
- Vector4 D = mat * Vector4( 0, 1, 0, 1 );
- Vector4 E = mat * Vector4( 0, 0, 1, 1 );
- Vector4 F = mat * Vector4( 1, 0, 1, 1 );
- Vector4 G = mat * Vector4( 1, 1, 1, 1 );
- Vector4 H = mat * Vector4( 0, 1, 1, 1 );
- // triangles instead of quads
- AddCubeVertex( E.x, E.y, E.z, 0, 1, vertdata ); //Front
- AddCubeVertex( F.x, F.y, F.z, 1, 1, vertdata );
- AddCubeVertex( G.x, G.y, G.z, 1, 0, vertdata );
- AddCubeVertex( G.x, G.y, G.z, 1, 0, vertdata );
- AddCubeVertex( H.x, H.y, H.z, 0, 0, vertdata );
- AddCubeVertex( E.x, E.y, E.z, 0, 1, vertdata );
-
- AddCubeVertex( B.x, B.y, B.z, 0, 1, vertdata ); //Back
- AddCubeVertex( A.x, A.y, A.z, 1, 1, vertdata );
- AddCubeVertex( D.x, D.y, D.z, 1, 0, vertdata );
- AddCubeVertex( D.x, D.y, D.z, 1, 0, vertdata );
- AddCubeVertex( C.x, C.y, C.z, 0, 0, vertdata );
- AddCubeVertex( B.x, B.y, B.z, 0, 1, vertdata );
-
- AddCubeVertex( H.x, H.y, H.z, 0, 1, vertdata ); //Top
- AddCubeVertex( G.x, G.y, G.z, 1, 1, vertdata );
- AddCubeVertex( C.x, C.y, C.z, 1, 0, vertdata );
- AddCubeVertex( C.x, C.y, C.z, 1, 0, vertdata );
- AddCubeVertex( D.x, D.y, D.z, 0, 0, vertdata );
- AddCubeVertex( H.x, H.y, H.z, 0, 1, vertdata );
-
- AddCubeVertex( A.x, A.y, A.z, 0, 1, vertdata ); //Bottom
- AddCubeVertex( B.x, B.y, B.z, 1, 1, vertdata );
- AddCubeVertex( F.x, F.y, F.z, 1, 0, vertdata );
- AddCubeVertex( F.x, F.y, F.z, 1, 0, vertdata );
- AddCubeVertex( E.x, E.y, E.z, 0, 0, vertdata );
- AddCubeVertex( A.x, A.y, A.z, 0, 1, vertdata );
-
- AddCubeVertex( A.x, A.y, A.z, 0, 1, vertdata ); //Left
- AddCubeVertex( E.x, E.y, E.z, 1, 1, vertdata );
- AddCubeVertex( H.x, H.y, H.z, 1, 0, vertdata );
- AddCubeVertex( H.x, H.y, H.z, 1, 0, vertdata );
- AddCubeVertex( D.x, D.y, D.z, 0, 0, vertdata );
- AddCubeVertex( A.x, A.y, A.z, 0, 1, vertdata );
- AddCubeVertex( F.x, F.y, F.z, 0, 1, vertdata ); //Right
- AddCubeVertex( B.x, B.y, B.z, 1, 1, vertdata );
- AddCubeVertex( C.x, C.y, C.z, 1, 0, vertdata );
- AddCubeVertex( C.x, C.y, C.z, 1, 0, vertdata );
- AddCubeVertex( G.x, G.y, G.z, 0, 0, vertdata );
- AddCubeVertex( F.x, F.y, F.z, 0, 1, vertdata );
- }
- //-----------------------------------------------------------------------------
- // Purpose: Draw all of the controllers as X/Y/Z lines
- //-----------------------------------------------------------------------------
- void CMainApplication::DrawControllers()
- {
- // don't draw controllers if somebody else has input focus
- if( m_pHMD->IsInputFocusCapturedByAnotherProcess() )
- return;
- std::vector<float> vertdataarray;
- m_uiControllerVertcount = 0;
- m_iTrackedControllerCount = 0;
- for ( vr::TrackedDeviceIndex_t unTrackedDevice = vr::k_unTrackedDeviceIndex_Hmd + 1; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; ++unTrackedDevice )
- {
- if ( !m_pHMD->IsTrackedDeviceConnected( unTrackedDevice ) )
- continue;
- if( m_pHMD->GetTrackedDeviceClass( unTrackedDevice ) != vr::TrackedDeviceClass_Controller )
- continue;
- m_iTrackedControllerCount += 1;
- if( !m_rTrackedDevicePose[ unTrackedDevice ].bPoseIsValid )
- continue;
- const Matrix4 & mat = m_rmat4DevicePose[unTrackedDevice];
- Vector4 center = mat * Vector4( 0, 0, 0, 1 );
- for ( int i = 0; i < 3; ++i )
- {
- Vector3 color( 0, 0, 0 );
- Vector4 point( 0, 0, 0, 1 );
- point[i] += 0.05f; // offset in X, Y, Z
- color[i] = 1.0; // R, G, B
- point = mat * point;
- vertdataarray.push_back( center.x );
- vertdataarray.push_back( center.y );
- vertdataarray.push_back( center.z );
- vertdataarray.push_back( color.x );
- vertdataarray.push_back( color.y );
- vertdataarray.push_back( color.z );
-
- vertdataarray.push_back( point.x );
- vertdataarray.push_back( point.y );
- vertdataarray.push_back( point.z );
-
- vertdataarray.push_back( color.x );
- vertdataarray.push_back( color.y );
- vertdataarray.push_back( color.z );
-
- m_uiControllerVertcount += 2;
- }
- Vector4 start = mat * Vector4( 0, 0, -0.02f, 1 );
- Vector4 end = mat * Vector4( 0, 0, -39.f, 1 );
- Vector3 color( .92f, .92f, .71f );
- vertdataarray.push_back( start.x );vertdataarray.push_back( start.y );vertdataarray.push_back( start.z );
- vertdataarray.push_back( color.x );vertdataarray.push_back( color.y );vertdataarray.push_back( color.z );
- vertdataarray.push_back( end.x );vertdataarray.push_back( end.y );vertdataarray.push_back( end.z );
- vertdataarray.push_back( color.x );vertdataarray.push_back( color.y );vertdataarray.push_back( color.z );
- m_uiControllerVertcount += 2;
- }
- // Setup the VAO the first time through.
- if ( m_unControllerVAO == 0 )
- {
- glGenVertexArrays( 1, &m_unControllerVAO );
- glBindVertexArray( m_unControllerVAO );
- glGenBuffers( 1, &m_glControllerVertBuffer );
- glBindBuffer( GL_ARRAY_BUFFER, m_glControllerVertBuffer );
- GLuint stride = 2 * 3 * sizeof( float );
- GLuint offset = 0;
- glEnableVertexAttribArray( 0 );
- glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, (const void *)offset);
- offset += sizeof( Vector3 );
- glEnableVertexAttribArray( 1 );
- glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, stride, (const void *)offset);
- glBindVertexArray( 0 );
- }
- glBindBuffer( GL_ARRAY_BUFFER, m_glControllerVertBuffer );
- // set vertex data if we have some
- if( vertdataarray.size() > 0 )
- {
- //$ TODO: Use glBufferSubData for this...
- glBufferData( GL_ARRAY_BUFFER, sizeof(float) * vertdataarray.size(), &vertdataarray[0], GL_STREAM_DRAW );
- }
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::SetupCameras()
- {
- m_mat4ProjectionLeft = GetHMDMatrixProjectionEye( vr::Eye_Left );
- m_mat4ProjectionRight = GetHMDMatrixProjectionEye( vr::Eye_Right );
- m_mat4eyePosLeft = GetHMDMatrixPoseEye( vr::Eye_Left );
- m_mat4eyePosRight = GetHMDMatrixPoseEye( vr::Eye_Right );
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- bool CMainApplication::CreateFrameBuffer( int nWidth, int nHeight, FramebufferDesc &framebufferDesc )
- {
- glGenFramebuffers(1, &framebufferDesc.m_nRenderFramebufferId );
- glBindFramebuffer(GL_FRAMEBUFFER, framebufferDesc.m_nRenderFramebufferId);
- glGenRenderbuffers(1, &framebufferDesc.m_nDepthBufferId);
- glBindRenderbuffer(GL_RENDERBUFFER, framebufferDesc.m_nDepthBufferId);
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT, nWidth, nHeight );
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, framebufferDesc.m_nDepthBufferId );
- glGenTextures(1, &framebufferDesc.m_nRenderTextureId );
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, framebufferDesc.m_nRenderTextureId );
- glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, nWidth, nHeight, true);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, framebufferDesc.m_nRenderTextureId, 0);
- glGenFramebuffers(1, &framebufferDesc.m_nResolveFramebufferId );
- glBindFramebuffer(GL_FRAMEBUFFER, framebufferDesc.m_nResolveFramebufferId);
- glGenTextures(1, &framebufferDesc.m_nResolveTextureId );
- glBindTexture(GL_TEXTURE_2D, framebufferDesc.m_nResolveTextureId );
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferDesc.m_nResolveTextureId, 0);
- // check FBO status
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE)
- {
- return false;
- }
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- return true;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- bool CMainApplication::SetupStereoRenderTargets()
- {
- if ( !m_pHMD )
- return false;
- m_pHMD->GetRecommendedRenderTargetSize( &m_nRenderWidth, &m_nRenderHeight );
- CreateFrameBuffer( m_nRenderWidth, m_nRenderHeight, leftEyeDesc );
- CreateFrameBuffer( m_nRenderWidth, m_nRenderHeight, rightEyeDesc );
-
- return true;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::SetupDistortion()
- {
- if ( !m_pHMD )
- return;
- GLushort m_iLensGridSegmentCountH = 43;
- GLushort m_iLensGridSegmentCountV = 43;
- float w = (float)( 1.0/float(m_iLensGridSegmentCountH-1));
- float h = (float)( 1.0/float(m_iLensGridSegmentCountV-1));
- float u, v = 0;
- std::vector<VertexDataLens> vVerts(0);
- VertexDataLens vert;
- //left eye distortion verts
- float Xoffset = -1;
- for( int y=0; y<m_iLensGridSegmentCountV; y++ )
- {
- for( int x=0; x<m_iLensGridSegmentCountH; x++ )
- {
- u = x*w; v = 1-y*h;
- vert.position = Vector2( Xoffset+u, -1+2*y*h );
- vr::DistortionCoordinates_t dc0 = m_pHMD->ComputeDistortion(vr::Eye_Left, u, v);
- vert.texCoordRed = Vector2(dc0.rfRed[0], 1 - dc0.rfRed[1]);
- vert.texCoordGreen = Vector2(dc0.rfGreen[0], 1 - dc0.rfGreen[1]);
- vert.texCoordBlue = Vector2(dc0.rfBlue[0], 1 - dc0.rfBlue[1]);
- vVerts.push_back( vert );
- }
- }
- //right eye distortion verts
- Xoffset = 0;
- for( int y=0; y<m_iLensGridSegmentCountV; y++ )
- {
- for( int x=0; x<m_iLensGridSegmentCountH; x++ )
- {
- u = x*w; v = 1-y*h;
- vert.position = Vector2( Xoffset+u, -1+2*y*h );
- vr::DistortionCoordinates_t dc0 = m_pHMD->ComputeDistortion( vr::Eye_Right, u, v );
- vert.texCoordRed = Vector2(dc0.rfRed[0], 1 - dc0.rfRed[1]);
- vert.texCoordGreen = Vector2(dc0.rfGreen[0], 1 - dc0.rfGreen[1]);
- vert.texCoordBlue = Vector2(dc0.rfBlue[0], 1 - dc0.rfBlue[1]);
- vVerts.push_back( vert );
- }
- }
- std::vector<GLushort> vIndices;
- GLushort a,b,c,d;
- GLushort offset = 0;
- for( GLushort y=0; y<m_iLensGridSegmentCountV-1; y++ )
- {
- for( GLushort x=0; x<m_iLensGridSegmentCountH-1; x++ )
- {
- a = m_iLensGridSegmentCountH*y+x +offset;
- b = m_iLensGridSegmentCountH*y+x+1 +offset;
- c = (y+1)*m_iLensGridSegmentCountH+x+1 +offset;
- d = (y+1)*m_iLensGridSegmentCountH+x +offset;
- vIndices.push_back( a );
- vIndices.push_back( b );
- vIndices.push_back( c );
- vIndices.push_back( a );
- vIndices.push_back( c );
- vIndices.push_back( d );
- }
- }
- offset = (m_iLensGridSegmentCountH)*(m_iLensGridSegmentCountV);
- for( GLushort y=0; y<m_iLensGridSegmentCountV-1; y++ )
- {
- for( GLushort x=0; x<m_iLensGridSegmentCountH-1; x++ )
- {
- a = m_iLensGridSegmentCountH*y+x +offset;
- b = m_iLensGridSegmentCountH*y+x+1 +offset;
- c = (y+1)*m_iLensGridSegmentCountH+x+1 +offset;
- d = (y+1)*m_iLensGridSegmentCountH+x +offset;
- vIndices.push_back( a );
- vIndices.push_back( b );
- vIndices.push_back( c );
- vIndices.push_back( a );
- vIndices.push_back( c );
- vIndices.push_back( d );
- }
- }
- m_uiIndexSize = vIndices.size();
- glGenVertexArrays( 1, &m_unLensVAO );
- glBindVertexArray( m_unLensVAO );
- glGenBuffers( 1, &m_glIDVertBuffer );
- glBindBuffer( GL_ARRAY_BUFFER, m_glIDVertBuffer );
- glBufferData( GL_ARRAY_BUFFER, vVerts.size()*sizeof(VertexDataLens), &vVerts[0], GL_STATIC_DRAW );
- glGenBuffers( 1, &m_glIDIndexBuffer );
- glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_glIDIndexBuffer );
- glBufferData( GL_ELEMENT_ARRAY_BUFFER, vIndices.size()*sizeof(GLushort), &vIndices[0], GL_STATIC_DRAW );
- glEnableVertexAttribArray( 0 );
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexDataLens), (void *)offsetof( VertexDataLens, position ) );
- glEnableVertexAttribArray( 1 );
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexDataLens), (void *)offsetof( VertexDataLens, texCoordRed ) );
- glEnableVertexAttribArray(2);
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexDataLens), (void *)offsetof( VertexDataLens, texCoordGreen ) );
- glEnableVertexAttribArray(3);
- glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexDataLens), (void *)offsetof( VertexDataLens, texCoordBlue ) );
- glBindVertexArray( 0 );
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
- glDisableVertexAttribArray(2);
- glDisableVertexAttribArray(3);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::RenderStereoTargets()
- {
- B3_PROFILE("CMainApplication::RenderStereoTargets");
- sExample->stepSimulation(1./60.);
- glClearColor( 0.15f, 0.15f, 0.18f, 1.0f ); // nice background color, but not black
- glEnable( GL_MULTISAMPLE );
- m_app->m_instancingRenderer->init();
-
-
- Matrix4 rotYtoZ = rotYtoZ.identity();
-
- //some Bullet apps (especially robotics related) require Z as up-axis)
- if (m_app->getUpAxis()==2)
- {
- rotYtoZ.rotateX(-90);
- }
-
-
- // Left Eye
- {
-
- Matrix4 viewMatLeft = m_mat4eyePosLeft * m_mat4HMDPose * rotYtoZ;
- Matrix4 viewMatCenter = m_mat4HMDPose * rotYtoZ;
- //0,1,2,3
- //4,5,6,7,
- //8,9,10,11
- //12,13,14,15
-
- //m_mat4eyePosLeft.get()[10]
- //m_app->m_instancingRenderer->getActiveCamera()->setCameraTargetPosition(
- // m_mat4eyePosLeft.get()[3],
- // m_mat4eyePosLeft.get()[7],
- // m_mat4eyePosLeft.get()[11]);
- Matrix4 m;
- m = viewMatCenter;
- const float* mat = m.invertAffine().get();
-
- /*printf("camera:\n,%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f",
- mat[0],mat[1],mat[2],mat[3],
- mat[4],mat[5],mat[6],mat[7],
- mat[8],mat[9],mat[10],mat[11],
- mat[12],mat[13],mat[14],mat[15]);
- */
- float dist=1;
- m_app->m_instancingRenderer->getActiveCamera()->setCameraTargetPosition(
- mat[12]-dist*mat[8],
- mat[13]-dist*mat[9],
- mat[14]-dist*mat[10]
- );
- m_app->m_instancingRenderer->getActiveCamera()->setCameraUpVector(mat[0],mat[1],mat[2]);
- m_app->m_instancingRenderer->getActiveCamera()->setVRCamera(viewMatLeft.get(),m_mat4ProjectionLeft.get());
- m_app->m_instancingRenderer->updateCamera(m_app->getUpAxis());
- }
- glBindFramebuffer( GL_FRAMEBUFFER, leftEyeDesc.m_nRenderFramebufferId );
- glViewport(0, 0, m_nRenderWidth, m_nRenderHeight );
-
-
-
- m_app->m_window->startRendering();
-
- RenderScene( vr::Eye_Left );
-
-
-
- m_app->m_instancingRenderer->setRenderFrameBuffer((unsigned int)leftEyeDesc.m_nRenderFramebufferId);
- if (gDebugDrawFlags)
- {
- sExample->physicsDebugDraw(gDebugDrawFlags);
- }
- //else
- {
- sExample->renderScene();
- }
- //m_app->m_instancingRenderer->renderScene();
- DrawGridData gridUp;
- gridUp.upAxis = m_app->getUpAxis();
- // m_app->drawGrid(gridUp);
-
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-
- glDisable( GL_MULTISAMPLE );
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, leftEyeDesc.m_nRenderFramebufferId);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, leftEyeDesc.m_nResolveFramebufferId );
- glBlitFramebuffer( 0, 0, m_nRenderWidth, m_nRenderHeight, 0, 0, m_nRenderWidth, m_nRenderHeight,
- GL_COLOR_BUFFER_BIT,
- GL_LINEAR );
- glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 );
- glEnable( GL_MULTISAMPLE );
- // Right Eye
-
-
- {
- Matrix4 viewMatRight = m_mat4eyePosRight * m_mat4HMDPose * rotYtoZ;
- m_app->m_instancingRenderer->getActiveCamera()->setVRCamera(viewMatRight.get(),m_mat4ProjectionRight.get());
- m_app->m_instancingRenderer->updateCamera(m_app->getUpAxis());
- }
-
- glBindFramebuffer( GL_FRAMEBUFFER, rightEyeDesc.m_nRenderFramebufferId );
- glViewport(0, 0, m_nRenderWidth, m_nRenderHeight );
-
- m_app->m_window->startRendering();
-
- RenderScene( vr::Eye_Right );
-
- m_app->m_instancingRenderer->setRenderFrameBuffer((unsigned int)rightEyeDesc.m_nRenderFramebufferId);
- //m_app->m_renderer->renderScene();
-
- if (gDebugDrawFlags)
- {
- sExample->physicsDebugDraw(gDebugDrawFlags);
- }
- //else
- {
- sExample->renderScene();
- }
- //m_app->drawGrid(gridUp);
-
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-
- glDisable( GL_MULTISAMPLE );
- glBindFramebuffer(GL_READ_FRAMEBUFFER, rightEyeDesc.m_nRenderFramebufferId );
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rightEyeDesc.m_nResolveFramebufferId );
-
- glBlitFramebuffer( 0, 0, m_nRenderWidth, m_nRenderHeight, 0, 0, m_nRenderWidth, m_nRenderHeight,
- GL_COLOR_BUFFER_BIT,
- GL_LINEAR );
- glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 );
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::RenderScene( vr::Hmd_Eye nEye )
- {
- B3_PROFILE("RenderScene");
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
- if( m_bShowCubes )
- {
- glUseProgram( m_unSceneProgramID );
- glUniformMatrix4fv( m_nSceneMatrixLocation, 1, GL_FALSE, GetCurrentViewProjectionMatrix( nEye ).get() );
- glBindVertexArray( m_unSceneVAO );
- glBindTexture( GL_TEXTURE_2D, m_iTexture );
- glDrawArrays( GL_TRIANGLES, 0, m_uiVertcount );
- glBindVertexArray( 0 );
- }
- bool bIsInputCapturedByAnotherProcess = m_pHMD->IsInputFocusCapturedByAnotherProcess();
- if( !bIsInputCapturedByAnotherProcess )
- {
- // draw the controller axis lines
- glUseProgram( m_unControllerTransformProgramID );
- glUniformMatrix4fv( m_nControllerMatrixLocation, 1, GL_FALSE, GetCurrentViewProjectionMatrix( nEye ).get() );
- glBindVertexArray( m_unControllerVAO );
- glDrawArrays( GL_LINES, 0, m_uiControllerVertcount );
- glBindVertexArray( 0 );
- }
- // ----- Render Model rendering -----
- glUseProgram( m_unRenderModelProgramID );
- for( uint32_t unTrackedDevice = 0; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; unTrackedDevice++ )
- {
- if( !m_rTrackedDeviceToRenderModel[ unTrackedDevice ] || !m_rbShowTrackedDevice[ unTrackedDevice ] )
- continue;
- const vr::TrackedDevicePose_t & pose = m_rTrackedDevicePose[ unTrackedDevice ];
- if( !pose.bPoseIsValid )
- continue;
- if( bIsInputCapturedByAnotherProcess && m_pHMD->GetTrackedDeviceClass( unTrackedDevice ) == vr::TrackedDeviceClass_Controller )
- continue;
- const Matrix4 & matDeviceToTracking = m_rmat4DevicePose[ unTrackedDevice ];
- Matrix4 matMVP = GetCurrentViewProjectionMatrix( nEye ) * matDeviceToTracking;
- glUniformMatrix4fv( m_nRenderModelMatrixLocation, 1, GL_FALSE, matMVP.get() );
- m_rTrackedDeviceToRenderModel[ unTrackedDevice ]->Draw();
- }
- glUseProgram( 0 );
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::RenderDistortion()
- {
- glDisable(GL_DEPTH_TEST);
- glViewport( 0, 0, m_nWindowWidth, m_nWindowHeight );
- glBindVertexArray( m_unLensVAO );
- glUseProgram( m_unLensProgramID );
- //render left lens (first half of index array )
- glBindTexture(GL_TEXTURE_2D, leftEyeDesc.m_nResolveTextureId );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
- glDrawElements( GL_TRIANGLES, m_uiIndexSize/2, GL_UNSIGNED_SHORT, 0 );
- //render right lens (second half of index array )
- glBindTexture(GL_TEXTURE_2D, rightEyeDesc.m_nResolveTextureId );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
- glDrawElements( GL_TRIANGLES, m_uiIndexSize/2, GL_UNSIGNED_SHORT, (const void *)(m_uiIndexSize) );
- glBindVertexArray( 0 );
- glUseProgram( 0 );
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- Matrix4 CMainApplication::GetHMDMatrixProjectionEye( vr::Hmd_Eye nEye )
- {
- if ( !m_pHMD )
- return Matrix4();
- vr::HmdMatrix44_t mat = m_pHMD->GetProjectionMatrix( nEye, m_fNearClip, m_fFarClip, vr::API_OpenGL);
- return Matrix4(
- mat.m[0][0], mat.m[1][0], mat.m[2][0], mat.m[3][0],
- mat.m[0][1], mat.m[1][1], mat.m[2][1], mat.m[3][1],
- mat.m[0][2], mat.m[1][2], mat.m[2][2], mat.m[3][2],
- mat.m[0][3], mat.m[1][3], mat.m[2][3], mat.m[3][3]
- );
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- Matrix4 CMainApplication::GetHMDMatrixPoseEye( vr::Hmd_Eye nEye )
- {
- if ( !m_pHMD )
- return Matrix4();
- vr::HmdMatrix34_t matEyeRight = m_pHMD->GetEyeToHeadTransform( nEye );
- Matrix4 matrixObj(
- matEyeRight.m[0][0], matEyeRight.m[1][0], matEyeRight.m[2][0], 0.0,
- matEyeRight.m[0][1], matEyeRight.m[1][1], matEyeRight.m[2][1], 0.0,
- matEyeRight.m[0][2], matEyeRight.m[1][2], matEyeRight.m[2][2], 0.0,
- matEyeRight.m[0][3], matEyeRight.m[1][3], matEyeRight.m[2][3], 1.0f
- );
- return matrixObj.invert();
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- Matrix4 CMainApplication::GetCurrentViewProjectionMatrix( vr::Hmd_Eye nEye )
- {
- Matrix4 matMVP;
- if( nEye == vr::Eye_Left )
- {
- matMVP = m_mat4ProjectionLeft * m_mat4eyePosLeft * m_mat4HMDPose;
- }
- else if( nEye == vr::Eye_Right )
- {
- matMVP = m_mat4ProjectionRight * m_mat4eyePosRight * m_mat4HMDPose;
- }
- return matMVP;
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- void CMainApplication::UpdateHMDMatrixPose()
- {
- if (!m_pHMD)
- return;
- {
- B3_PROFILE("WaitGetPoses");
- vr::VRCompositor()->WaitGetPoses(m_rTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, NULL, 0);
- }
- m_iValidPoseCount = 0;
- m_strPoseClasses = "";
- {
- B3_PROFILE("for loop");
- for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice)
- {
- if (m_rTrackedDevicePose[nDevice].bPoseIsValid)
- {
- m_iValidPoseCount++;
- m_rmat4DevicePose[nDevice] = ConvertSteamVRMatrixToMatrix4(m_rTrackedDevicePose[nDevice].mDeviceToAbsoluteTracking);
- if (m_rDevClassChar[nDevice] == 0)
- {
- switch (m_pHMD->GetTrackedDeviceClass(nDevice))
- {
- case vr::TrackedDeviceClass_Controller: m_rDevClassChar[nDevice] = 'C'; break;
- case vr::TrackedDeviceClass_HMD: m_rDevClassChar[nDevice] = 'H'; break;
- case vr::TrackedDeviceClass_Invalid: m_rDevClassChar[nDevice] = 'I'; break;
- case vr::TrackedDeviceClass_Other: m_rDevClassChar[nDevice] = 'O'; break;
- case vr::TrackedDeviceClass_TrackingReference: m_rDevClassChar[nDevice] = 'T'; break;
- default: m_rDevClassChar[nDevice] = '?'; break;
- }
- }
- m_strPoseClasses += m_rDevClassChar[nDevice];
- }
- }
- }
- {
- B3_PROFILE("m_mat4HMDPose invert");
- if (m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid)
- {
- m_mat4HMDPose = m_rmat4DevicePose[vr::k_unTrackedDeviceIndex_Hmd].invert();
- }
- }
- }
- //-----------------------------------------------------------------------------
- // Purpose: Finds a render model we've already loaded or loads a new one
- //-----------------------------------------------------------------------------
- CGLRenderModel *CMainApplication::FindOrLoadRenderModel( const char *pchRenderModelName )
- {
- CGLRenderModel *pRenderModel = NULL;
- for( std::vector< CGLRenderModel * >::iterator i = m_vecRenderModels.begin(); i != m_vecRenderModels.end(); i++ )
- {
- if( !stricmp( (*i)->GetName().c_str(), pchRenderModelName ) )
- {
- pRenderModel = *i;
- break;
- }
- }
- // load the model if we didn't find one
- if( !pRenderModel )
- {
- vr::RenderModel_t *pModel;
- vr::EVRRenderModelError error;
- while ( 1 )
- {
- error = vr::VRRenderModels()->LoadRenderModel_Async( pchRenderModelName, &pModel );
- if ( error != vr::VRRenderModelError_Loading )
- break;
- ThreadSleep( 1 );
- }
- if ( error != vr::VRRenderModelError_None )
- {
- b3Printf( "Unable to load render model %s - %s\n", pchRenderModelName, vr::VRRenderModels()->GetRenderModelErrorNameFromEnum( error ) );
- return NULL; // move on to the next tracked device
- }
- vr::RenderModel_TextureMap_t *pTexture;
- while ( 1 )
- {
- error = vr::VRRenderModels()->LoadTexture_Async( pModel->diffuseTextureId, &pTexture );
- if ( error != vr::VRRenderModelError_Loading )
- break;
- ThreadSleep( 1 );
- }
- if ( error != vr::VRRenderModelError_None )
- {
- b3Printf( "Unable to load render texture id:%d for render model %s\n", pModel->diffuseTextureId, pchRenderModelName );
- vr::VRRenderModels()->FreeRenderModel( pModel );
- return NULL; // move on to the next tracked device
- }
- pRenderModel = new CGLRenderModel( pchRenderModelName );
- if ( !pRenderModel->BInit( *pModel, *pTexture ) )
- {
- b3Printf( "Unable to create GL model from render model %s\n", pchRenderModelName );
- delete pRenderModel;
- pRenderModel = NULL;
- }
- else
- {
- m_vecRenderModels.push_back( pRenderModel );
- }
- vr::VRRenderModels()->FreeRenderModel( pModel );
- vr::VRRenderModels()->FreeTexture( pTexture );
- }
- return pRenderModel;
- }
- //-----------------------------------------------------------------------------
- // Purpose: Create/destroy GL a Render Model for a single tracked device
- //-----------------------------------------------------------------------------
- void CMainApplication::SetupRenderModelForTrackedDevice( vr::TrackedDeviceIndex_t unTrackedDeviceIndex )
- {
- if( unTrackedDeviceIndex >= vr::k_unMaxTrackedDeviceCount )
- return;
- // try to find a model we've already set up
- std::string sRenderModelName = GetTrackedDeviceString( m_pHMD, unTrackedDeviceIndex, vr::Prop_RenderModelName_String );
- CGLRenderModel *pRenderModel = FindOrLoadRenderModel( sRenderModelName.c_str() );
- if( !pRenderModel )
- {
- std::string sTrackingSystemName = GetTrackedDeviceString( m_pHMD, unTrackedDeviceIndex, vr::Prop_TrackingSystemName_String );
- b3Printf( "Unable to load render model for tracked device %d (%s.%s)", unTrackedDeviceIndex, sTrackingSystemName.c_str(), sRenderModelName.c_str() );
- }
- else
- {
- m_rTrackedDeviceToRenderModel[ unTrackedDeviceIndex ] = pRenderModel;
- m_rbShowTrackedDevice[ unTrackedDeviceIndex ] = true;
- }
- }
- //-----------------------------------------------------------------------------
- // Purpose: Create/destroy GL Render Models
- //-----------------------------------------------------------------------------
- void CMainApplication::SetupRenderModels()
- {
- memset( m_rTrackedDeviceToRenderModel, 0, sizeof( m_rTrackedDeviceToRenderModel ) );
- if( !m_pHMD )
- return;
- for( uint32_t unTrackedDevice = vr::k_unTrackedDeviceIndex_Hmd + 1; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; unTrackedDevice++ )
- {
- if( !m_pHMD->IsTrackedDeviceConnected( unTrackedDevice ) )
- continue;
- SetupRenderModelForTrackedDevice( unTrackedDevice );
- }
- }
- //-----------------------------------------------------------------------------
- // Purpose: Converts a SteamVR matrix to our local matrix class
- //-----------------------------------------------------------------------------
- Matrix4 CMainApplication::ConvertSteamVRMatrixToMatrix4( const vr::HmdMatrix34_t &matPose )
- {
- Matrix4 matrixObj(
- matPose.m[0][0], matPose.m[1][0], matPose.m[2][0], 0.0,
- matPose.m[0][1], matPose.m[1][1], matPose.m[2][1], 0.0,
- matPose.m[0][2], matPose.m[1][2], matPose.m[2][2], 0.0,
- matPose.m[0][3], matPose.m[1][3], matPose.m[2][3], 1.0f
- );
- return matrixObj;
- }
- //-----------------------------------------------------------------------------
- // Purpose: Create/destroy GL Render Models
- //-----------------------------------------------------------------------------
- CGLRenderModel::CGLRenderModel( const std::string & sRenderModelName )
- : m_sModelName( sRenderModelName )
- {
- m_glIndexBuffer = 0;
- m_glVertArray = 0;
- m_glVertBuffer = 0;
- m_glTexture = 0;
- }
- CGLRenderModel::~CGLRenderModel()
- {
- Cleanup();
- }
- //-----------------------------------------------------------------------------
- // Purpose: Allocates and populates the GL resources for a render model
- //-----------------------------------------------------------------------------
- bool CGLRenderModel::BInit( const vr::RenderModel_t & vrModel, const vr::RenderModel_TextureMap_t & vrDiffuseTexture )
- {
- // create and bind a VAO to hold state for this model
- glGenVertexArrays( 1, &m_glVertArray );
- glBindVertexArray( m_glVertArray );
- // Populate a vertex buffer
- glGenBuffers( 1, &m_glVertBuffer );
- glBindBuffer( GL_ARRAY_BUFFER, m_glVertBuffer );
- glBufferData( GL_ARRAY_BUFFER, sizeof( vr::RenderModel_Vertex_t ) * vrModel.unVertexCount, vrModel.rVertexData, GL_STATIC_DRAW );
- // Identify the components in the vertex buffer
- glEnableVertexAttribArray( 0 );
- glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof( vr::RenderModel_Vertex_t ), (void *)offsetof( vr::RenderModel_Vertex_t, vPosition ) );
- glEnableVertexAttribArray( 1 );
- glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, sizeof( vr::RenderModel_Vertex_t ), (void *)offsetof( vr::RenderModel_Vertex_t, vNormal ) );
- glEnableVertexAttribArray( 2 );
- glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, sizeof( vr::RenderModel_Vertex_t ), (void *)offsetof( vr::RenderModel_Vertex_t, rfTextureCoord ) );
- // Create and populate the index buffer
- glGenBuffers( 1, &m_glIndexBuffer );
- glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_glIndexBuffer );
- glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( uint16_t ) * vrModel.unTriangleCount * 3, vrModel.rIndexData, GL_STATIC_DRAW );
- glBindVertexArray( 0 );
- // create and populate the texture
- glGenTextures(1, &m_glTexture );
- glBindTexture( GL_TEXTURE_2D, m_glTexture );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, vrDiffuseTexture.unWidth, vrDiffuseTexture.unHeight,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, vrDiffuseTexture.rubTextureMapData );
- // If this renders black ask McJohn what's wrong.
- glGenerateMipmap(GL_TEXTURE_2D);
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
- GLfloat fLargest;
- glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest );
- glBindTexture( GL_TEXTURE_2D, 0 );
- m_unVertexCount = vrModel.unTriangleCount * 3;
- return true;
- }
- //-----------------------------------------------------------------------------
- // Purpose: Frees the GL resources for a render model
- //-----------------------------------------------------------------------------
- void CGLRenderModel::Cleanup()
- {
- if( m_glVertBuffer )
- {
- glDeleteBuffers(1, &m_glIndexBuffer);
- glDeleteVertexArrays( 1, &m_glVertArray );
- glDeleteBuffers(1, &m_glVertBuffer);
- m_glIndexBuffer = 0;
- m_glVertArray = 0;
- m_glVertBuffer = 0;
- }
- }
- //-----------------------------------------------------------------------------
- // Purpose: Draws the render model
- //-----------------------------------------------------------------------------
- void CGLRenderModel::Draw()
- {
- glBindVertexArray( m_glVertArray );
- glActiveTexture( GL_TEXTURE0 );
- glBindTexture( GL_TEXTURE_2D, m_glTexture );
- glDrawElements( GL_TRIANGLES, m_unVertexCount, GL_UNSIGNED_SHORT, 0 );
- glBindVertexArray( 0 );
- }
- //-----------------------------------------------------------------------------
- // Purpose:
- //-----------------------------------------------------------------------------
- int main(int argc, char *argv[])
- {
- #ifdef BT_USE_CUSTOM_PROFILER
- //b3SetCustomEnterProfileZoneFunc(...);
- //b3SetCustomLeaveProfileZoneFunc(...);
- #endif
- CMainApplication *pMainApplication = new CMainApplication( argc, argv );
- if (!pMainApplication->BInit())
- {
- pMainApplication->Shutdown();
- return 1;
- }
-
- if (sExample)
- {
- sExample->processCommandLineArgs(argc,argv);
- }
- //request disable VSYNC
- typedef bool (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int);
- PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;
- wglSwapIntervalEXT =
- (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress("wglSwapIntervalEXT");
- if (wglSwapIntervalEXT)
- wglSwapIntervalEXT(0);
-
- pMainApplication->RunMainLoop();
- pMainApplication->Shutdown();
- #ifdef BT_USE_CUSTOM_PROFILER
- //...
- #endif
- return 0;
- }
- #endif //BT_ENABLE_VR
|