hellovr_opengl_main.cpp 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223
  1. #ifdef BT_ENABLE_VR
  2. //#define BT_USE_CUSTOM_PROFILER
  3. //========= Copyright Valve Corporation ============//
  4. #include "../OpenGLWindow/SimpleOpenGL3App.h"
  5. #include "../OpenGLWindow/OpenGLInclude.h"
  6. #include "Bullet3Common/b3Quaternion.h"
  7. #include "Bullet3Common/b3Transform.h"
  8. #include "../ExampleBrowser/OpenGLGuiHelper.h"
  9. #include "../CommonInterfaces/CommonExampleInterface.h"
  10. #include "../CommonInterfaces/CommonGUIHelperInterface.h"
  11. #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
  12. #include "BulletCollision/CollisionShapes/btCollisionShape.h"
  13. #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
  14. #include "LinearMath/btIDebugDraw.h"
  15. int gSharedMemoryKey = -1;
  16. int gDebugDrawFlags = 0;
  17. //how can you try typing on a keyboard, without seeing it?
  18. //it is pretty funny, to see the desktop in VR!
  19. #include <stdio.h>
  20. #include <string>
  21. #include <cstdlib>
  22. #include <openvr.h>
  23. #include "lodepng.h"
  24. #include "Matrices.h"
  25. #include "pathtools.h"
  26. CommonExampleInterface* sExample;
  27. int sPrevPacketNum=0;
  28. OpenGLGuiHelper* sGuiPtr = 0;
  29. static vr::VRControllerState_t sPrevStates[vr::k_unMaxTrackedDeviceCount] = { 0 };
  30. #if defined(POSIX)
  31. #include "unistd.h"
  32. #endif
  33. #ifdef _WIN32
  34. #include <Windows.h>
  35. #endif
  36. void ThreadSleep( unsigned long nMilliseconds )
  37. {
  38. #if defined(_WIN32)
  39. ::Sleep( nMilliseconds );
  40. #elif defined(POSIX)
  41. usleep( nMilliseconds * 1000 );
  42. #endif
  43. }
  44. class CGLRenderModel
  45. {
  46. public:
  47. CGLRenderModel( const std::string & sRenderModelName );
  48. ~CGLRenderModel();
  49. bool BInit( const vr::RenderModel_t & vrModel, const vr::RenderModel_TextureMap_t & vrDiffuseTexture );
  50. void Cleanup();
  51. void Draw();
  52. const std::string & GetName() const { return m_sModelName; }
  53. private:
  54. GLuint m_glVertBuffer;
  55. GLuint m_glIndexBuffer;
  56. GLuint m_glVertArray;
  57. GLuint m_glTexture;
  58. GLsizei m_unVertexCount;
  59. std::string m_sModelName;
  60. };
  61. static bool g_bPrintf = true;
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. //------------------------------------------------------------------------------
  65. class CMainApplication
  66. {
  67. public:
  68. CMainApplication( int argc, char *argv[] );
  69. virtual ~CMainApplication();
  70. bool BInit();
  71. bool BInitGL();
  72. bool BInitCompositor();
  73. void getControllerTransform(int unDevice, b3Transform& tr);
  74. void SetupRenderModels();
  75. void Shutdown();
  76. void RunMainLoop();
  77. bool HandleInput();
  78. void ProcessVREvent( const vr::VREvent_t & event );
  79. void RenderFrame();
  80. bool SetupTexturemaps();
  81. void SetupScene();
  82. void AddCubeToScene( Matrix4 mat, std::vector<float> &vertdata );
  83. void AddCubeVertex( float fl0, float fl1, float fl2, float fl3, float fl4, std::vector<float> &vertdata );
  84. void DrawControllers();
  85. bool SetupStereoRenderTargets();
  86. void SetupDistortion();
  87. void SetupCameras();
  88. void RenderStereoTargets();
  89. void RenderDistortion();
  90. void RenderScene( vr::Hmd_Eye nEye );
  91. Matrix4 GetHMDMatrixProjectionEye( vr::Hmd_Eye nEye );
  92. Matrix4 GetHMDMatrixPoseEye( vr::Hmd_Eye nEye );
  93. Matrix4 GetCurrentViewProjectionMatrix( vr::Hmd_Eye nEye );
  94. void UpdateHMDMatrixPose();
  95. Matrix4 ConvertSteamVRMatrixToMatrix4( const vr::HmdMatrix34_t &matPose );
  96. GLuint CompileGLShader( const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader );
  97. bool CreateAllShaders();
  98. void SetupRenderModelForTrackedDevice( vr::TrackedDeviceIndex_t unTrackedDeviceIndex );
  99. CGLRenderModel *FindOrLoadRenderModel( const char *pchRenderModelName );
  100. private:
  101. bool m_bDebugOpenGL;
  102. bool m_bVerbose;
  103. bool m_bPerf;
  104. bool m_bVblank;
  105. bool m_bGlFinishHack;
  106. vr::IVRSystem *m_pHMD;
  107. vr::IVRRenderModels *m_pRenderModels;
  108. std::string m_strDriver;
  109. std::string m_strDisplay;
  110. vr::TrackedDevicePose_t m_rTrackedDevicePose[ vr::k_unMaxTrackedDeviceCount ];
  111. Matrix4 m_rmat4DevicePose[ vr::k_unMaxTrackedDeviceCount ];
  112. bool m_rbShowTrackedDevice[ vr::k_unMaxTrackedDeviceCount ];
  113. private:
  114. SimpleOpenGL3App* m_app;
  115. uint32_t m_nWindowWidth;
  116. uint32_t m_nWindowHeight;
  117. bool m_hasContext;
  118. private: // OpenGL bookkeeping
  119. int m_iTrackedControllerCount;
  120. int m_iTrackedControllerCount_Last;
  121. int m_iValidPoseCount;
  122. int m_iValidPoseCount_Last;
  123. bool m_bShowCubes;
  124. std::string m_strPoseClasses; // what classes we saw poses for this frame
  125. char m_rDevClassChar[ vr::k_unMaxTrackedDeviceCount ]; // for each device, a character representing its class
  126. int m_iSceneVolumeWidth;
  127. int m_iSceneVolumeHeight;
  128. int m_iSceneVolumeDepth;
  129. float m_fScaleSpacing;
  130. float m_fScale;
  131. int m_iSceneVolumeInit; // if you want something other than the default 20x20x20
  132. float m_fNearClip;
  133. float m_fFarClip;
  134. GLuint m_iTexture;
  135. unsigned int m_uiVertcount;
  136. GLuint m_glSceneVertBuffer;
  137. GLuint m_unSceneVAO;
  138. GLuint m_unLensVAO;
  139. GLuint m_glIDVertBuffer;
  140. GLuint m_glIDIndexBuffer;
  141. unsigned int m_uiIndexSize;
  142. GLuint m_glControllerVertBuffer;
  143. GLuint m_unControllerVAO;
  144. unsigned int m_uiControllerVertcount;
  145. Matrix4 m_mat4HMDPose;
  146. Matrix4 m_mat4eyePosLeft;
  147. Matrix4 m_mat4eyePosRight;
  148. Matrix4 m_mat4ProjectionCenter;
  149. Matrix4 m_mat4ProjectionLeft;
  150. Matrix4 m_mat4ProjectionRight;
  151. struct VertexDataScene
  152. {
  153. Vector3 position;
  154. Vector2 texCoord;
  155. };
  156. struct VertexDataLens
  157. {
  158. Vector2 position;
  159. Vector2 texCoordRed;
  160. Vector2 texCoordGreen;
  161. Vector2 texCoordBlue;
  162. };
  163. GLuint m_unSceneProgramID;
  164. GLuint m_unLensProgramID;
  165. GLuint m_unControllerTransformProgramID;
  166. GLuint m_unRenderModelProgramID;
  167. GLint m_nSceneMatrixLocation;
  168. GLint m_nControllerMatrixLocation;
  169. GLint m_nRenderModelMatrixLocation;
  170. struct FramebufferDesc
  171. {
  172. GLuint m_nDepthBufferId;
  173. GLuint m_nRenderTextureId;
  174. GLuint m_nRenderFramebufferId;
  175. GLuint m_nResolveTextureId;
  176. GLuint m_nResolveFramebufferId;
  177. };
  178. FramebufferDesc leftEyeDesc;
  179. FramebufferDesc rightEyeDesc;
  180. bool CreateFrameBuffer( int nWidth, int nHeight, FramebufferDesc &framebufferDesc );
  181. uint32_t m_nRenderWidth;
  182. uint32_t m_nRenderHeight;
  183. std::vector< CGLRenderModel * > m_vecRenderModels;
  184. CGLRenderModel *m_rTrackedDeviceToRenderModel[ vr::k_unMaxTrackedDeviceCount ];
  185. };
  186. //-----------------------------------------------------------------------------
  187. // Purpose: Constructor
  188. //-----------------------------------------------------------------------------
  189. CMainApplication::CMainApplication( int argc, char *argv[] )
  190. : m_app(NULL)
  191. , m_hasContext(false)
  192. , m_nWindowWidth( 1280 )
  193. , m_nWindowHeight( 720 )
  194. , m_unSceneProgramID( 0 )
  195. , m_unLensProgramID( 0 )
  196. , m_unControllerTransformProgramID( 0 )
  197. , m_unRenderModelProgramID( 0 )
  198. , m_pHMD( NULL )
  199. , m_pRenderModels( NULL )
  200. , m_bDebugOpenGL( false )
  201. , m_bVerbose( false )
  202. , m_bPerf( false )
  203. , m_bVblank( false )
  204. , m_bGlFinishHack( true )
  205. , m_glControllerVertBuffer( 0 )
  206. , m_unControllerVAO( 0 )
  207. , m_unLensVAO( 0 )
  208. , m_unSceneVAO( 0 )
  209. , m_nSceneMatrixLocation( -1 )
  210. , m_nControllerMatrixLocation( -1 )
  211. , m_nRenderModelMatrixLocation( -1 )
  212. , m_iTrackedControllerCount( 0 )
  213. , m_iTrackedControllerCount_Last( -1 )
  214. , m_iValidPoseCount( 0 )
  215. , m_iValidPoseCount_Last( -1 )
  216. , m_iSceneVolumeInit( 20 )
  217. , m_strPoseClasses("")
  218. , m_bShowCubes( false )
  219. {
  220. for( int i = 1; i < argc; i++ )
  221. {
  222. if( !stricmp( argv[i], "-gldebug" ) )
  223. {
  224. m_bDebugOpenGL = true;
  225. }
  226. else if( !stricmp( argv[i], "-verbose" ) )
  227. {
  228. m_bVerbose = true;
  229. }
  230. else if( !stricmp( argv[i], "-novblank" ) )
  231. {
  232. m_bVblank = false;
  233. }
  234. else if( !stricmp( argv[i], "-noglfinishhack" ) )
  235. {
  236. m_bGlFinishHack = false;
  237. }
  238. else if( !stricmp( argv[i], "-noprintf" ) )
  239. {
  240. g_bPrintf = false;
  241. }
  242. else if ( !stricmp( argv[i], "-cubevolume" ) && ( argc > i + 1 ) && ( *argv[ i + 1 ] != '-' ) )
  243. {
  244. m_iSceneVolumeInit = atoi( argv[ i + 1 ] );
  245. i++;
  246. }
  247. }
  248. // other initialization tasks are done in BInit
  249. memset(m_rDevClassChar, 0, sizeof(m_rDevClassChar));
  250. };
  251. //-----------------------------------------------------------------------------
  252. // Purpose: Destructor
  253. //-----------------------------------------------------------------------------
  254. CMainApplication::~CMainApplication()
  255. {
  256. // work is done in Shutdown
  257. b3Printf( "Shutdown" );
  258. }
  259. //-----------------------------------------------------------------------------
  260. // Purpose: Helper to get a string from a tracked device property and turn it
  261. // into a std::string
  262. //-----------------------------------------------------------------------------
  263. std::string GetTrackedDeviceString( vr::IVRSystem *pHmd, vr::TrackedDeviceIndex_t unDevice, vr::TrackedDeviceProperty prop, vr::TrackedPropertyError *peError = NULL )
  264. {
  265. uint32_t unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty( unDevice, prop, NULL, 0, peError );
  266. if( unRequiredBufferLen == 0 )
  267. return "";
  268. char *pchBuffer = new char[ unRequiredBufferLen ];
  269. unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty( unDevice, prop, pchBuffer, unRequiredBufferLen, peError );
  270. std::string sResult = pchBuffer;
  271. delete [] pchBuffer;
  272. return sResult;
  273. }
  274. //-----------------------------------------------------------------------------
  275. // Purpose:
  276. //-----------------------------------------------------------------------------
  277. bool CMainApplication::BInit()
  278. {
  279. // Loading the SteamVR Runtime
  280. vr::EVRInitError eError = vr::VRInitError_None;
  281. m_pHMD = vr::VR_Init( &eError, vr::VRApplication_Scene );
  282. if ( eError != vr::VRInitError_None )
  283. {
  284. m_pHMD = NULL;
  285. char buf[1024];
  286. sprintf_s( buf, sizeof( buf ), "Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription( eError ) );
  287. b3Warning( "VR_Init Failed %s", buf);
  288. return false;
  289. }
  290. m_pRenderModels = (vr::IVRRenderModels *)vr::VR_GetGenericInterface( vr::IVRRenderModels_Version, &eError );
  291. if( !m_pRenderModels )
  292. {
  293. m_pHMD = NULL;
  294. vr::VR_Shutdown();
  295. char buf[1024];
  296. sprintf_s( buf, sizeof( buf ), "Unable to get render model interface: %s", vr::VR_GetVRInitErrorAsEnglishDescription( eError ) );
  297. b3Warning( "VR_Init Failed %s", buf);
  298. return false;
  299. }
  300. // int nWindowPosX = 700;
  301. // int nWindowPosY = 100;
  302. m_nWindowWidth = 1280;
  303. m_nWindowHeight = 720;
  304. /*
  305. //SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY );
  306. SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
  307. SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 );
  308. SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 );
  309. if( m_bDebugOpenGL )
  310. SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG );
  311. */
  312. m_app = new SimpleOpenGL3App("SimpleOpenGL3App",m_nWindowWidth,m_nWindowHeight,true);
  313. sGuiPtr = new OpenGLGuiHelper(m_app,false);
  314. sGuiPtr->setVRMode(true);
  315. //sGuiPtr = new DummyGUIHelper;
  316. CommonExampleOptions options(sGuiPtr);
  317. sExample = StandaloneExampleCreateFunc(options);
  318. sExample->initPhysics();
  319. sExample->resetCamera();
  320. #if 0
  321. int cubeIndex = m_app->registerCubeShape(1,1,1);
  322. b3Quaternion orn(0,0,0,1);
  323. {
  324. b3Vector3 color=b3MakeVector3(0.3,0.3,0.6);
  325. b3Vector3 pos = b3MakeVector3(0,0,0);
  326. b3Vector3 scaling=b3MakeVector3 (1,.1,1);
  327. m_app->m_renderer->registerGraphicsInstance(cubeIndex,pos,orn,color,scaling);
  328. }
  329. {
  330. b3Vector3 color=b3MakeVector3(0.3,0.6,0.3);
  331. b3Vector3 pos = b3MakeVector3(0,0.3,0);
  332. b3Vector3 scaling=b3MakeVector3 (.1,.1,.1);
  333. m_app->m_renderer->registerGraphicsInstance(cubeIndex,pos,orn,color,scaling);
  334. }
  335. #endif
  336. m_app->m_renderer->writeTransforms();
  337. /* if (m_pWindow == NULL)
  338. {
  339. printf( "%s - Window could not be created! SDL Error: %s\n", __FUNCTION__, SDL_GetError() );
  340. return false;
  341. }
  342. */
  343. /*m_pContext = SDL_GL_CreateContext(m_pWindow);
  344. if (m_pContext == NULL)
  345. {
  346. printf( "%s - OpenGL context could not be created! SDL Error: %s\n", __FUNCTION__, SDL_GetError() );
  347. return false;
  348. }
  349. glewExperimental = GL_TRUE;
  350. GLenum nGlewError = glewInit();
  351. if (nGlewError != GLEW_OK)
  352. {
  353. printf( "%s - Error initializing GLEW! %s\n", __FUNCTION__, glewGetErrorString( nGlewError ) );
  354. return false;
  355. }
  356. glGetError(); // to clear the error caused deep in GLEW
  357. if ( SDL_GL_SetSwapInterval( m_bVblank ? 1 : 0 ) < 0 )
  358. {
  359. printf( "%s - Warning: Unable to set VSync! SDL Error: %s\n", __FUNCTION__, SDL_GetError() );
  360. return false;
  361. }
  362. */
  363. m_strDriver = "No Driver";
  364. m_strDisplay = "No Display";
  365. m_strDriver = GetTrackedDeviceString( m_pHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_TrackingSystemName_String );
  366. m_strDisplay = GetTrackedDeviceString( m_pHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SerialNumber_String );
  367. std::string strWindowTitle = "hellovr_bullet - " + m_strDriver + " " + m_strDisplay;
  368. m_app->m_window->setWindowTitle(strWindowTitle.c_str() );
  369. // cube array
  370. m_iSceneVolumeWidth = m_iSceneVolumeInit;
  371. m_iSceneVolumeHeight = m_iSceneVolumeInit;
  372. m_iSceneVolumeDepth = m_iSceneVolumeInit;
  373. m_fScale = 0.3f;
  374. m_fScaleSpacing = 4.0f;
  375. m_fNearClip = 0.1f;
  376. m_fFarClip = 3000.0f;
  377. m_iTexture = 0;
  378. m_uiVertcount = 0;
  379. // m_MillisecondsTimer.start(1, this);
  380. // m_SecondsTimer.start(1000, this);
  381. if (!BInitGL())
  382. {
  383. printf("%s - Unable to initialize OpenGL!\n", __FUNCTION__);
  384. return false;
  385. }
  386. if (!BInitCompositor())
  387. {
  388. printf("%s - Failed to initialize VR Compositor!\n", __FUNCTION__);
  389. return false;
  390. }
  391. return true;
  392. }
  393. //-----------------------------------------------------------------------------
  394. // Purpose:
  395. //-----------------------------------------------------------------------------
  396. /*void APIENTRY DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam)
  397. {
  398. b3Printf( "GL Error: %s\n", message );
  399. }
  400. */
  401. static void APIENTRY DebugCallback (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam)
  402. {
  403. b3Printf( "GL Error: %s\n", message );
  404. }
  405. //-----------------------------------------------------------------------------
  406. // Purpose:
  407. //-----------------------------------------------------------------------------
  408. bool CMainApplication::BInitGL()
  409. {
  410. if( m_bDebugOpenGL )
  411. {
  412. const GLvoid *userParam=0;
  413. glDebugMessageCallback(DebugCallback, userParam);
  414. glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE );
  415. glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  416. }
  417. if( !CreateAllShaders() )
  418. return false;
  419. SetupTexturemaps();
  420. SetupScene();
  421. SetupCameras();
  422. SetupStereoRenderTargets();
  423. SetupDistortion();
  424. SetupRenderModels();
  425. return true;
  426. }
  427. //-----------------------------------------------------------------------------
  428. // Purpose:
  429. //-----------------------------------------------------------------------------
  430. bool CMainApplication::BInitCompositor()
  431. {
  432. vr::EVRInitError peError = vr::VRInitError_None;
  433. if ( !vr::VRCompositor() )
  434. {
  435. printf( "Compositor initialization failed. See log file for details\n" );
  436. return false;
  437. }
  438. return true;
  439. }
  440. //-----------------------------------------------------------------------------
  441. // Purpose:
  442. //-----------------------------------------------------------------------------
  443. void CMainApplication::Shutdown()
  444. {
  445. if( m_pHMD )
  446. {
  447. vr::VR_Shutdown();
  448. m_pHMD = NULL;
  449. }
  450. for( std::vector< CGLRenderModel * >::iterator i = m_vecRenderModels.begin(); i != m_vecRenderModels.end(); i++ )
  451. {
  452. delete (*i);
  453. }
  454. m_vecRenderModels.clear();
  455. if( m_hasContext)
  456. {
  457. if (m_glSceneVertBuffer)
  458. {
  459. glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE );
  460. glDebugMessageCallback(nullptr, nullptr);
  461. glDeleteBuffers(1, &m_glSceneVertBuffer);
  462. glDeleteBuffers(1, &m_glIDVertBuffer);
  463. glDeleteBuffers(1, &m_glIDIndexBuffer);
  464. }
  465. if ( m_unSceneProgramID )
  466. {
  467. glDeleteProgram( m_unSceneProgramID );
  468. }
  469. if ( m_unControllerTransformProgramID )
  470. {
  471. glDeleteProgram( m_unControllerTransformProgramID );
  472. }
  473. if ( m_unRenderModelProgramID )
  474. {
  475. glDeleteProgram( m_unRenderModelProgramID );
  476. }
  477. if ( m_unLensProgramID )
  478. {
  479. glDeleteProgram( m_unLensProgramID );
  480. }
  481. glDeleteRenderbuffers( 1, &leftEyeDesc.m_nDepthBufferId );
  482. glDeleteTextures( 1, &leftEyeDesc.m_nRenderTextureId );
  483. glDeleteFramebuffers( 1, &leftEyeDesc.m_nRenderFramebufferId );
  484. glDeleteTextures( 1, &leftEyeDesc.m_nResolveTextureId );
  485. glDeleteFramebuffers( 1, &leftEyeDesc.m_nResolveFramebufferId );
  486. glDeleteRenderbuffers( 1, &rightEyeDesc.m_nDepthBufferId );
  487. glDeleteTextures( 1, &rightEyeDesc.m_nRenderTextureId );
  488. glDeleteFramebuffers( 1, &rightEyeDesc.m_nRenderFramebufferId );
  489. glDeleteTextures( 1, &rightEyeDesc.m_nResolveTextureId );
  490. glDeleteFramebuffers( 1, &rightEyeDesc.m_nResolveFramebufferId );
  491. if( m_unLensVAO != 0 )
  492. {
  493. glDeleteVertexArrays( 1, &m_unLensVAO );
  494. }
  495. if( m_unSceneVAO != 0 )
  496. {
  497. glDeleteVertexArrays( 1, &m_unSceneVAO );
  498. }
  499. if( m_unControllerVAO != 0 )
  500. {
  501. glDeleteVertexArrays( 1, &m_unControllerVAO );
  502. }
  503. }
  504. sExample->exitPhysics();
  505. delete sExample;
  506. delete m_app;
  507. m_app=0;
  508. }
  509. void CMainApplication::getControllerTransform(int unDevice, b3Transform& tr)
  510. {
  511. const Matrix4 & matOrg = m_rmat4DevicePose[unDevice];
  512. tr.setIdentity();
  513. tr.setOrigin(b3MakeVector3(matOrg[12],matOrg[13],matOrg[14]));//pos[1]));
  514. b3Matrix3x3 bmat;
  515. for (int i=0;i<3;i++)
  516. {
  517. for (int j=0;j<3;j++)
  518. {
  519. bmat[i][j] = matOrg[i+4*j];
  520. }
  521. }
  522. tr.setBasis(bmat);
  523. b3Transform y2z;
  524. y2z.setIdentity();
  525. y2z.setRotation(b3Quaternion(0,B3_HALF_PI,0));
  526. tr = y2z*tr;
  527. }
  528. //-----------------------------------------------------------------------------
  529. // Purpose:
  530. //-----------------------------------------------------------------------------
  531. bool CMainApplication::HandleInput()
  532. {
  533. bool bRet = false;
  534. // Process SteamVR events
  535. vr::VREvent_t event;
  536. while( m_pHMD->PollNextEvent( &event, sizeof( event ) ) )
  537. {
  538. ProcessVREvent( event );
  539. }
  540. // Process SteamVR controller state
  541. for( vr::TrackedDeviceIndex_t unDevice = 0; unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++ )
  542. {
  543. vr::VRControllerState_t state;
  544. if( m_pHMD->GetControllerState( unDevice, &state ) )
  545. {
  546. //we need to have the 'move' events, so no early out here
  547. //if (sPrevStates[unDevice].unPacketNum != state.unPacketNum)
  548. if( m_pHMD->GetTrackedDeviceClass( unDevice) == vr::TrackedDeviceClass_Controller )
  549. {
  550. sPrevStates[unDevice].unPacketNum = state.unPacketNum;
  551. for (int button = 0; button < vr::k_EButton_Max; button++)
  552. {
  553. uint64_t trigger = vr::ButtonMaskFromId((vr::EVRButtonId)button);
  554. bool isTrigger = (state.ulButtonPressed&trigger) != 0;
  555. if (isTrigger)
  556. {
  557. b3Transform tr;
  558. getControllerTransform(unDevice, tr);
  559. float pos[3] = { tr.getOrigin()[0], tr.getOrigin()[1], tr.getOrigin()[2] };
  560. b3Quaternion born = tr.getRotation();
  561. float orn[4] = { born[0], born[1], born[2], born[3] };
  562. //pressed now, not pressed before -> raise a button down event
  563. if ((sPrevStates[unDevice].ulButtonPressed&trigger)==0)
  564. {
  565. // printf("Device PRESSED: %d, button %d\n", unDevice, button);
  566. if (button==2)
  567. {
  568. glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  569. ///todo(erwincoumans) can't use reguar debug drawer, because physics/graphics are not in sync
  570. ///so it can (and likely will) cause crashes
  571. ///add a special debug drawer that deals with this
  572. //gDebugDrawFlags = btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints+
  573. //btIDebugDraw::DBG_DrawConstraintLimits+
  574. //btIDebugDraw::DBG_DrawConstraints
  575. //;
  576. //gDebugDrawFlags = btIDebugDraw::DBG_DrawFrames;
  577. }
  578. sExample->vrControllerButtonCallback(unDevice, button, 1, pos, orn);
  579. }
  580. else
  581. {
  582. // printf("Device MOVED: %d\n", unDevice);
  583. sExample->vrControllerMoveCallback(unDevice, pos, orn, state.rAxis[1].x);
  584. }
  585. }
  586. else
  587. {
  588. if( m_pHMD->GetTrackedDeviceClass( unDevice) == vr::TrackedDeviceClass_Controller )
  589. {
  590. b3Transform tr;
  591. getControllerTransform(unDevice, tr);
  592. float pos[3] = { tr.getOrigin()[0], tr.getOrigin()[1], tr.getOrigin()[2] };
  593. b3Quaternion born = tr.getRotation();
  594. float orn[4] = { born[0], born[1], born[2], born[3] };
  595. // printf("Device RELEASED: %d, button %d\n", unDevice,button);
  596. //not pressed now, but pressed before -> raise a button up event
  597. if ((sPrevStates[unDevice].ulButtonPressed&trigger) != 0)
  598. {
  599. if (button==2)
  600. {
  601. gDebugDrawFlags = 0;
  602. glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
  603. }
  604. sExample->vrControllerButtonCallback(unDevice, button, 0, pos, orn);
  605. } else
  606. {
  607. sExample->vrControllerMoveCallback(unDevice, pos, orn, state.rAxis[1].x);
  608. }
  609. }
  610. }
  611. }
  612. }
  613. // m_rbShowTrackedDevice[ unDevice ] = state.ulButtonPressed == 0;
  614. }
  615. sPrevStates[unDevice] = state;
  616. }
  617. return bRet;
  618. }
  619. //-----------------------------------------------------------------------------
  620. // Purpose:
  621. //-----------------------------------------------------------------------------
  622. void CMainApplication::RunMainLoop()
  623. {
  624. bool bQuit = false;
  625. while ( !bQuit && !m_app->m_window->requestedExit())
  626. {
  627. B3_PROFILE("main");
  628. bQuit = HandleInput();
  629. RenderFrame();
  630. }
  631. }
  632. //-----------------------------------------------------------------------------
  633. // Purpose: Processes a single VR event
  634. //-----------------------------------------------------------------------------
  635. void CMainApplication::ProcessVREvent( const vr::VREvent_t & event )
  636. {
  637. switch( event.eventType )
  638. {
  639. case vr::VREvent_TrackedDeviceActivated:
  640. {
  641. SetupRenderModelForTrackedDevice( event.trackedDeviceIndex );
  642. b3Printf( "Device %u attached. Setting up render model.\n", event.trackedDeviceIndex );
  643. }
  644. break;
  645. case vr::VREvent_TrackedDeviceDeactivated:
  646. {
  647. b3Printf( "Device %u detached.\n", event.trackedDeviceIndex );
  648. }
  649. break;
  650. case vr::VREvent_TrackedDeviceUpdated:
  651. {
  652. b3Printf( "Device %u updated.\n", event.trackedDeviceIndex );
  653. }
  654. break;
  655. }
  656. }
  657. //-----------------------------------------------------------------------------
  658. // Purpose:
  659. //-----------------------------------------------------------------------------
  660. void CMainApplication::RenderFrame()
  661. {
  662. // for now as fast as possible
  663. if ( m_pHMD )
  664. {
  665. {
  666. B3_PROFILE("DrawControllers");
  667. DrawControllers();
  668. }
  669. RenderStereoTargets();
  670. {
  671. B3_PROFILE("RenderDistortion");
  672. RenderDistortion();
  673. }
  674. vr::Texture_t leftEyeTexture = {(void*)leftEyeDesc.m_nResolveTextureId, vr::API_OpenGL, vr::ColorSpace_Gamma };
  675. vr::VRCompositor()->Submit(vr::Eye_Left, &leftEyeTexture );
  676. vr::Texture_t rightEyeTexture = {(void*)rightEyeDesc.m_nResolveTextureId, vr::API_OpenGL, vr::ColorSpace_Gamma };
  677. vr::VRCompositor()->Submit(vr::Eye_Right, &rightEyeTexture );
  678. }
  679. if ( m_bVblank && m_bGlFinishHack )
  680. {
  681. B3_PROFILE("bGlFinishHack");
  682. //$ HACKHACK. From gpuview profiling, it looks like there is a bug where two renders and a present
  683. // happen right before and after the vsync causing all kinds of jittering issues. This glFinish()
  684. // appears to clear that up. Temporary fix while I try to get nvidia to investigate this problem.
  685. // 1/29/2014 mikesart
  686. glFinish();
  687. }
  688. // SwapWindow
  689. {
  690. B3_PROFILE("m_app->swapBuffer");
  691. m_app->swapBuffer();
  692. //SDL_GL_SwapWindow( m_pWindow );
  693. }
  694. // Clear
  695. {
  696. B3_PROFILE("glClearColor");
  697. // We want to make sure the glFinish waits for the entire present to complete, not just the submission
  698. // of the command. So, we do a clear here right here so the glFinish will wait fully for the swap.
  699. glClearColor( 0, 0, 0, 1 );
  700. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  701. }
  702. // Flush and wait for swap.
  703. if ( m_bVblank )
  704. {
  705. B3_PROFILE("glFlushglFinish");
  706. glFlush();
  707. glFinish();
  708. }
  709. // Spew out the controller and pose count whenever they change.
  710. if ( m_iTrackedControllerCount != m_iTrackedControllerCount_Last || m_iValidPoseCount != m_iValidPoseCount_Last )
  711. {
  712. B3_PROFILE("debug pose");
  713. m_iValidPoseCount_Last = m_iValidPoseCount;
  714. m_iTrackedControllerCount_Last = m_iTrackedControllerCount;
  715. b3Printf( "PoseCount:%d(%s) Controllers:%d\n", m_iValidPoseCount, m_strPoseClasses.c_str(), m_iTrackedControllerCount );
  716. }
  717. {
  718. B3_PROFILE("UpdateHMDMatrixPose");
  719. UpdateHMDMatrixPose();
  720. }
  721. }
  722. //-----------------------------------------------------------------------------
  723. // Purpose: Compiles a GL shader program and returns the handle. Returns 0 if
  724. // the shader couldn't be compiled for some reason.
  725. //-----------------------------------------------------------------------------
  726. GLuint CMainApplication::CompileGLShader( const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader )
  727. {
  728. GLuint unProgramID = glCreateProgram();
  729. GLuint nSceneVertexShader = glCreateShader(GL_VERTEX_SHADER);
  730. glShaderSource( nSceneVertexShader, 1, &pchVertexShader, NULL);
  731. glCompileShader( nSceneVertexShader );
  732. GLint vShaderCompiled = GL_FALSE;
  733. glGetShaderiv( nSceneVertexShader, GL_COMPILE_STATUS, &vShaderCompiled);
  734. if ( vShaderCompiled != GL_TRUE)
  735. {
  736. b3Printf("%s - Unable to compile vertex shader %d!\n", pchShaderName, nSceneVertexShader);
  737. glDeleteProgram( unProgramID );
  738. glDeleteShader( nSceneVertexShader );
  739. return 0;
  740. }
  741. glAttachShader( unProgramID, nSceneVertexShader);
  742. glDeleteShader( nSceneVertexShader ); // the program hangs onto this once it's attached
  743. GLuint nSceneFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  744. glShaderSource( nSceneFragmentShader, 1, &pchFragmentShader, NULL);
  745. glCompileShader( nSceneFragmentShader );
  746. GLint fShaderCompiled = GL_FALSE;
  747. glGetShaderiv( nSceneFragmentShader, GL_COMPILE_STATUS, &fShaderCompiled);
  748. if (fShaderCompiled != GL_TRUE)
  749. {
  750. b3Printf("%s - Unable to compile fragment shader %d!\n", pchShaderName, nSceneFragmentShader );
  751. glDeleteProgram( unProgramID );
  752. glDeleteShader( nSceneFragmentShader );
  753. return 0;
  754. }
  755. glAttachShader( unProgramID, nSceneFragmentShader );
  756. glDeleteShader( nSceneFragmentShader ); // the program hangs onto this once it's attached
  757. glLinkProgram( unProgramID );
  758. GLint programSuccess = GL_TRUE;
  759. glGetProgramiv( unProgramID, GL_LINK_STATUS, &programSuccess);
  760. if ( programSuccess != GL_TRUE )
  761. {
  762. b3Printf("%s - Error linking program %d!\n", pchShaderName, unProgramID);
  763. glDeleteProgram( unProgramID );
  764. return 0;
  765. }
  766. glUseProgram( unProgramID );
  767. glUseProgram( 0 );
  768. return unProgramID;
  769. }
  770. //-----------------------------------------------------------------------------
  771. // Purpose: Creates all the shaders used by HelloVR SDL
  772. //-----------------------------------------------------------------------------
  773. bool CMainApplication::CreateAllShaders()
  774. {
  775. m_unSceneProgramID = CompileGLShader(
  776. "Scene",
  777. // Vertex Shader
  778. "#version 410\n"
  779. "uniform mat4 matrix;\n"
  780. "layout(location = 0) in vec4 position;\n"
  781. "layout(location = 1) in vec2 v2UVcoordsIn;\n"
  782. "layout(location = 2) in vec3 v3NormalIn;\n"
  783. "out vec2 v2UVcoords;\n"
  784. "void main()\n"
  785. "{\n"
  786. " v2UVcoords = v2UVcoordsIn;\n"
  787. " gl_Position = matrix * position;\n"
  788. "}\n",
  789. // Fragment Shader
  790. "#version 410 core\n"
  791. "uniform sampler2D mytexture;\n"
  792. "in vec2 v2UVcoords;\n"
  793. "out vec4 outputColor;\n"
  794. "void main()\n"
  795. "{\n"
  796. " outputColor = texture(mytexture, v2UVcoords);\n"
  797. "}\n"
  798. );
  799. m_nSceneMatrixLocation = glGetUniformLocation( m_unSceneProgramID, "matrix" );
  800. if( m_nSceneMatrixLocation == -1 )
  801. {
  802. b3Printf( "Unable to find matrix uniform in scene shader\n" );
  803. return false;
  804. }
  805. m_unControllerTransformProgramID = CompileGLShader(
  806. "Controller",
  807. // vertex shader
  808. "#version 410\n"
  809. "uniform mat4 matrix;\n"
  810. "layout(location = 0) in vec4 position;\n"
  811. "layout(location = 1) in vec3 v3ColorIn;\n"
  812. "out vec4 v4Color;\n"
  813. "void main()\n"
  814. "{\n"
  815. " v4Color.xyz = v3ColorIn; v4Color.a = 1.0;\n"
  816. " gl_Position = matrix * position;\n"
  817. "}\n",
  818. // fragment shader
  819. "#version 410\n"
  820. "in vec4 v4Color;\n"
  821. "out vec4 outputColor;\n"
  822. "void main()\n"
  823. "{\n"
  824. " outputColor = v4Color;\n"
  825. "}\n"
  826. );
  827. m_nControllerMatrixLocation = glGetUniformLocation( m_unControllerTransformProgramID, "matrix" );
  828. if( m_nControllerMatrixLocation == -1 )
  829. {
  830. b3Printf( "Unable to find matrix uniform in controller shader\n" );
  831. return false;
  832. }
  833. m_unRenderModelProgramID = CompileGLShader(
  834. "render model",
  835. // vertex shader
  836. "#version 410\n"
  837. "uniform mat4 matrix;\n"
  838. "layout(location = 0) in vec4 position;\n"
  839. "layout(location = 1) in vec3 v3NormalIn;\n"
  840. "layout(location = 2) in vec2 v2TexCoordsIn;\n"
  841. "out vec2 v2TexCoord;\n"
  842. "void main()\n"
  843. "{\n"
  844. " v2TexCoord = v2TexCoordsIn;\n"
  845. " gl_Position = matrix * vec4(position.xyz, 1);\n"
  846. "}\n",
  847. //fragment shader
  848. "#version 410 core\n"
  849. "uniform sampler2D diffuse;\n"
  850. "in vec2 v2TexCoord;\n"
  851. "out vec4 outputColor;\n"
  852. "void main()\n"
  853. "{\n"
  854. " outputColor = texture( diffuse, v2TexCoord);\n"
  855. "}\n"
  856. );
  857. m_nRenderModelMatrixLocation = glGetUniformLocation( m_unRenderModelProgramID, "matrix" );
  858. if( m_nRenderModelMatrixLocation == -1 )
  859. {
  860. b3Printf( "Unable to find matrix uniform in render model shader\n" );
  861. return false;
  862. }
  863. m_unLensProgramID = CompileGLShader(
  864. "Distortion",
  865. // vertex shader
  866. "#version 410 core\n"
  867. "layout(location = 0) in vec4 position;\n"
  868. "layout(location = 1) in vec2 v2UVredIn;\n"
  869. "layout(location = 2) in vec2 v2UVGreenIn;\n"
  870. "layout(location = 3) in vec2 v2UVblueIn;\n"
  871. "noperspective out vec2 v2UVred;\n"
  872. "noperspective out vec2 v2UVgreen;\n"
  873. "noperspective out vec2 v2UVblue;\n"
  874. "void main()\n"
  875. "{\n"
  876. " v2UVred = v2UVredIn;\n"
  877. " v2UVgreen = v2UVGreenIn;\n"
  878. " v2UVblue = v2UVblueIn;\n"
  879. " gl_Position = position;\n"
  880. "}\n",
  881. // fragment shader
  882. "#version 410 core\n"
  883. "uniform sampler2D mytexture;\n"
  884. "noperspective in vec2 v2UVred;\n"
  885. "noperspective in vec2 v2UVgreen;\n"
  886. "noperspective in vec2 v2UVblue;\n"
  887. "out vec4 outputColor;\n"
  888. "void main()\n"
  889. "{\n"
  890. " 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"
  891. " if( fBoundsCheck > 1.0 )\n"
  892. " { outputColor = vec4( 0, 0, 0, 1.0 ); }\n"
  893. " else\n"
  894. " {\n"
  895. " float red = texture(mytexture, v2UVred).x;\n"
  896. " float green = texture(mytexture, v2UVgreen).y;\n"
  897. " float blue = texture(mytexture, v2UVblue).z;\n"
  898. " outputColor = vec4( red, green, blue, 1.0 ); }\n"
  899. "}\n"
  900. );
  901. return m_unSceneProgramID != 0
  902. && m_unControllerTransformProgramID != 0
  903. && m_unRenderModelProgramID != 0
  904. && m_unLensProgramID != 0;
  905. }
  906. //-----------------------------------------------------------------------------
  907. // Purpose:
  908. //-----------------------------------------------------------------------------
  909. bool CMainApplication::SetupTexturemaps()
  910. {
  911. std::string sExecutableDirectory = Path_StripFilename( Path_GetExecutablePath() );
  912. std::string strFullPath = Path_MakeAbsolute( "../cube_texture.png", sExecutableDirectory );
  913. std::vector<unsigned char> imageRGBA;
  914. unsigned nImageWidth, nImageHeight;
  915. unsigned nError = lodepng::decode( imageRGBA, nImageWidth, nImageHeight, strFullPath.c_str() );
  916. if ( nError != 0 )
  917. return false;
  918. glGenTextures(1, &m_iTexture );
  919. glBindTexture( GL_TEXTURE_2D, m_iTexture );
  920. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nImageWidth, nImageHeight,
  921. 0, GL_RGBA, GL_UNSIGNED_BYTE, &imageRGBA[0] );
  922. glGenerateMipmap(GL_TEXTURE_2D);
  923. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  924. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  925. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  926. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
  927. GLfloat fLargest;
  928. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
  929. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
  930. glBindTexture( GL_TEXTURE_2D, 0 );
  931. return ( m_iTexture != 0 );
  932. }
  933. //-----------------------------------------------------------------------------
  934. // Purpose: create a sea of cubes
  935. //-----------------------------------------------------------------------------
  936. void CMainApplication::SetupScene()
  937. {
  938. if ( !m_pHMD )
  939. return;
  940. std::vector<float> vertdataarray;
  941. Matrix4 matScale;
  942. matScale.scale( m_fScale, m_fScale, m_fScale );
  943. Matrix4 matTransform;
  944. matTransform.translate(
  945. -( (float)m_iSceneVolumeWidth * m_fScaleSpacing ) / 2.f,
  946. -( (float)m_iSceneVolumeHeight * m_fScaleSpacing ) / 2.f,
  947. -( (float)m_iSceneVolumeDepth * m_fScaleSpacing ) / 2.f);
  948. Matrix4 mat = matScale * matTransform;
  949. for( int z = 0; z< m_iSceneVolumeDepth; z++ )
  950. {
  951. for( int y = 0; y< m_iSceneVolumeHeight; y++ )
  952. {
  953. for( int x = 0; x< m_iSceneVolumeWidth; x++ )
  954. {
  955. AddCubeToScene( mat, vertdataarray );
  956. mat = mat * Matrix4().translate( m_fScaleSpacing, 0, 0 );
  957. }
  958. mat = mat * Matrix4().translate( -((float)m_iSceneVolumeWidth) * m_fScaleSpacing, m_fScaleSpacing, 0 );
  959. }
  960. mat = mat * Matrix4().translate( 0, -((float)m_iSceneVolumeHeight) * m_fScaleSpacing, m_fScaleSpacing );
  961. }
  962. m_uiVertcount = vertdataarray.size()/5;
  963. glGenVertexArrays( 1, &m_unSceneVAO );
  964. glBindVertexArray( m_unSceneVAO );
  965. glGenBuffers( 1, &m_glSceneVertBuffer );
  966. glBindBuffer( GL_ARRAY_BUFFER, m_glSceneVertBuffer );
  967. glBufferData( GL_ARRAY_BUFFER, sizeof(float) * vertdataarray.size(), &vertdataarray[0], GL_STATIC_DRAW);
  968. glBindBuffer( GL_ARRAY_BUFFER, m_glSceneVertBuffer );
  969. GLsizei stride = sizeof(VertexDataScene);
  970. uintptr_t offset = 0;
  971. glEnableVertexAttribArray( 0 );
  972. glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride , (const void *)offset);
  973. offset += sizeof(Vector3);
  974. glEnableVertexAttribArray( 1 );
  975. glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, stride, (const void *)offset);
  976. glBindVertexArray( 0 );
  977. glDisableVertexAttribArray(0);
  978. glDisableVertexAttribArray(1);
  979. m_hasContext = true;
  980. }
  981. //-----------------------------------------------------------------------------
  982. // Purpose:
  983. //-----------------------------------------------------------------------------
  984. void CMainApplication::AddCubeVertex( float fl0, float fl1, float fl2, float fl3, float fl4, std::vector<float> &vertdata )
  985. {
  986. vertdata.push_back( fl0 );
  987. vertdata.push_back( fl1 );
  988. vertdata.push_back( fl2 );
  989. vertdata.push_back( fl3 );
  990. vertdata.push_back( fl4 );
  991. }
  992. //-----------------------------------------------------------------------------
  993. // Purpose:
  994. //-----------------------------------------------------------------------------
  995. void CMainApplication::AddCubeToScene( Matrix4 mat, std::vector<float> &vertdata )
  996. {
  997. // Matrix4 mat( outermat.data() );
  998. Vector4 A = mat * Vector4( 0, 0, 0, 1 );
  999. Vector4 B = mat * Vector4( 1, 0, 0, 1 );
  1000. Vector4 C = mat * Vector4( 1, 1, 0, 1 );
  1001. Vector4 D = mat * Vector4( 0, 1, 0, 1 );
  1002. Vector4 E = mat * Vector4( 0, 0, 1, 1 );
  1003. Vector4 F = mat * Vector4( 1, 0, 1, 1 );
  1004. Vector4 G = mat * Vector4( 1, 1, 1, 1 );
  1005. Vector4 H = mat * Vector4( 0, 1, 1, 1 );
  1006. // triangles instead of quads
  1007. AddCubeVertex( E.x, E.y, E.z, 0, 1, vertdata ); //Front
  1008. AddCubeVertex( F.x, F.y, F.z, 1, 1, vertdata );
  1009. AddCubeVertex( G.x, G.y, G.z, 1, 0, vertdata );
  1010. AddCubeVertex( G.x, G.y, G.z, 1, 0, vertdata );
  1011. AddCubeVertex( H.x, H.y, H.z, 0, 0, vertdata );
  1012. AddCubeVertex( E.x, E.y, E.z, 0, 1, vertdata );
  1013. AddCubeVertex( B.x, B.y, B.z, 0, 1, vertdata ); //Back
  1014. AddCubeVertex( A.x, A.y, A.z, 1, 1, vertdata );
  1015. AddCubeVertex( D.x, D.y, D.z, 1, 0, vertdata );
  1016. AddCubeVertex( D.x, D.y, D.z, 1, 0, vertdata );
  1017. AddCubeVertex( C.x, C.y, C.z, 0, 0, vertdata );
  1018. AddCubeVertex( B.x, B.y, B.z, 0, 1, vertdata );
  1019. AddCubeVertex( H.x, H.y, H.z, 0, 1, vertdata ); //Top
  1020. AddCubeVertex( G.x, G.y, G.z, 1, 1, vertdata );
  1021. AddCubeVertex( C.x, C.y, C.z, 1, 0, vertdata );
  1022. AddCubeVertex( C.x, C.y, C.z, 1, 0, vertdata );
  1023. AddCubeVertex( D.x, D.y, D.z, 0, 0, vertdata );
  1024. AddCubeVertex( H.x, H.y, H.z, 0, 1, vertdata );
  1025. AddCubeVertex( A.x, A.y, A.z, 0, 1, vertdata ); //Bottom
  1026. AddCubeVertex( B.x, B.y, B.z, 1, 1, vertdata );
  1027. AddCubeVertex( F.x, F.y, F.z, 1, 0, vertdata );
  1028. AddCubeVertex( F.x, F.y, F.z, 1, 0, vertdata );
  1029. AddCubeVertex( E.x, E.y, E.z, 0, 0, vertdata );
  1030. AddCubeVertex( A.x, A.y, A.z, 0, 1, vertdata );
  1031. AddCubeVertex( A.x, A.y, A.z, 0, 1, vertdata ); //Left
  1032. AddCubeVertex( E.x, E.y, E.z, 1, 1, vertdata );
  1033. AddCubeVertex( H.x, H.y, H.z, 1, 0, vertdata );
  1034. AddCubeVertex( H.x, H.y, H.z, 1, 0, vertdata );
  1035. AddCubeVertex( D.x, D.y, D.z, 0, 0, vertdata );
  1036. AddCubeVertex( A.x, A.y, A.z, 0, 1, vertdata );
  1037. AddCubeVertex( F.x, F.y, F.z, 0, 1, vertdata ); //Right
  1038. AddCubeVertex( B.x, B.y, B.z, 1, 1, vertdata );
  1039. AddCubeVertex( C.x, C.y, C.z, 1, 0, vertdata );
  1040. AddCubeVertex( C.x, C.y, C.z, 1, 0, vertdata );
  1041. AddCubeVertex( G.x, G.y, G.z, 0, 0, vertdata );
  1042. AddCubeVertex( F.x, F.y, F.z, 0, 1, vertdata );
  1043. }
  1044. //-----------------------------------------------------------------------------
  1045. // Purpose: Draw all of the controllers as X/Y/Z lines
  1046. //-----------------------------------------------------------------------------
  1047. void CMainApplication::DrawControllers()
  1048. {
  1049. // don't draw controllers if somebody else has input focus
  1050. if( m_pHMD->IsInputFocusCapturedByAnotherProcess() )
  1051. return;
  1052. std::vector<float> vertdataarray;
  1053. m_uiControllerVertcount = 0;
  1054. m_iTrackedControllerCount = 0;
  1055. for ( vr::TrackedDeviceIndex_t unTrackedDevice = vr::k_unTrackedDeviceIndex_Hmd + 1; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; ++unTrackedDevice )
  1056. {
  1057. if ( !m_pHMD->IsTrackedDeviceConnected( unTrackedDevice ) )
  1058. continue;
  1059. if( m_pHMD->GetTrackedDeviceClass( unTrackedDevice ) != vr::TrackedDeviceClass_Controller )
  1060. continue;
  1061. m_iTrackedControllerCount += 1;
  1062. if( !m_rTrackedDevicePose[ unTrackedDevice ].bPoseIsValid )
  1063. continue;
  1064. const Matrix4 & mat = m_rmat4DevicePose[unTrackedDevice];
  1065. Vector4 center = mat * Vector4( 0, 0, 0, 1 );
  1066. for ( int i = 0; i < 3; ++i )
  1067. {
  1068. Vector3 color( 0, 0, 0 );
  1069. Vector4 point( 0, 0, 0, 1 );
  1070. point[i] += 0.05f; // offset in X, Y, Z
  1071. color[i] = 1.0; // R, G, B
  1072. point = mat * point;
  1073. vertdataarray.push_back( center.x );
  1074. vertdataarray.push_back( center.y );
  1075. vertdataarray.push_back( center.z );
  1076. vertdataarray.push_back( color.x );
  1077. vertdataarray.push_back( color.y );
  1078. vertdataarray.push_back( color.z );
  1079. vertdataarray.push_back( point.x );
  1080. vertdataarray.push_back( point.y );
  1081. vertdataarray.push_back( point.z );
  1082. vertdataarray.push_back( color.x );
  1083. vertdataarray.push_back( color.y );
  1084. vertdataarray.push_back( color.z );
  1085. m_uiControllerVertcount += 2;
  1086. }
  1087. Vector4 start = mat * Vector4( 0, 0, -0.02f, 1 );
  1088. Vector4 end = mat * Vector4( 0, 0, -39.f, 1 );
  1089. Vector3 color( .92f, .92f, .71f );
  1090. vertdataarray.push_back( start.x );vertdataarray.push_back( start.y );vertdataarray.push_back( start.z );
  1091. vertdataarray.push_back( color.x );vertdataarray.push_back( color.y );vertdataarray.push_back( color.z );
  1092. vertdataarray.push_back( end.x );vertdataarray.push_back( end.y );vertdataarray.push_back( end.z );
  1093. vertdataarray.push_back( color.x );vertdataarray.push_back( color.y );vertdataarray.push_back( color.z );
  1094. m_uiControllerVertcount += 2;
  1095. }
  1096. // Setup the VAO the first time through.
  1097. if ( m_unControllerVAO == 0 )
  1098. {
  1099. glGenVertexArrays( 1, &m_unControllerVAO );
  1100. glBindVertexArray( m_unControllerVAO );
  1101. glGenBuffers( 1, &m_glControllerVertBuffer );
  1102. glBindBuffer( GL_ARRAY_BUFFER, m_glControllerVertBuffer );
  1103. GLuint stride = 2 * 3 * sizeof( float );
  1104. GLuint offset = 0;
  1105. glEnableVertexAttribArray( 0 );
  1106. glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, (const void *)offset);
  1107. offset += sizeof( Vector3 );
  1108. glEnableVertexAttribArray( 1 );
  1109. glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, stride, (const void *)offset);
  1110. glBindVertexArray( 0 );
  1111. }
  1112. glBindBuffer( GL_ARRAY_BUFFER, m_glControllerVertBuffer );
  1113. // set vertex data if we have some
  1114. if( vertdataarray.size() > 0 )
  1115. {
  1116. //$ TODO: Use glBufferSubData for this...
  1117. glBufferData( GL_ARRAY_BUFFER, sizeof(float) * vertdataarray.size(), &vertdataarray[0], GL_STREAM_DRAW );
  1118. }
  1119. }
  1120. //-----------------------------------------------------------------------------
  1121. // Purpose:
  1122. //-----------------------------------------------------------------------------
  1123. void CMainApplication::SetupCameras()
  1124. {
  1125. m_mat4ProjectionLeft = GetHMDMatrixProjectionEye( vr::Eye_Left );
  1126. m_mat4ProjectionRight = GetHMDMatrixProjectionEye( vr::Eye_Right );
  1127. m_mat4eyePosLeft = GetHMDMatrixPoseEye( vr::Eye_Left );
  1128. m_mat4eyePosRight = GetHMDMatrixPoseEye( vr::Eye_Right );
  1129. }
  1130. //-----------------------------------------------------------------------------
  1131. // Purpose:
  1132. //-----------------------------------------------------------------------------
  1133. bool CMainApplication::CreateFrameBuffer( int nWidth, int nHeight, FramebufferDesc &framebufferDesc )
  1134. {
  1135. glGenFramebuffers(1, &framebufferDesc.m_nRenderFramebufferId );
  1136. glBindFramebuffer(GL_FRAMEBUFFER, framebufferDesc.m_nRenderFramebufferId);
  1137. glGenRenderbuffers(1, &framebufferDesc.m_nDepthBufferId);
  1138. glBindRenderbuffer(GL_RENDERBUFFER, framebufferDesc.m_nDepthBufferId);
  1139. glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT, nWidth, nHeight );
  1140. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, framebufferDesc.m_nDepthBufferId );
  1141. glGenTextures(1, &framebufferDesc.m_nRenderTextureId );
  1142. glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, framebufferDesc.m_nRenderTextureId );
  1143. glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, nWidth, nHeight, true);
  1144. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, framebufferDesc.m_nRenderTextureId, 0);
  1145. glGenFramebuffers(1, &framebufferDesc.m_nResolveFramebufferId );
  1146. glBindFramebuffer(GL_FRAMEBUFFER, framebufferDesc.m_nResolveFramebufferId);
  1147. glGenTextures(1, &framebufferDesc.m_nResolveTextureId );
  1148. glBindTexture(GL_TEXTURE_2D, framebufferDesc.m_nResolveTextureId );
  1149. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1150. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
  1151. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
  1152. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferDesc.m_nResolveTextureId, 0);
  1153. // check FBO status
  1154. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  1155. if (status != GL_FRAMEBUFFER_COMPLETE)
  1156. {
  1157. return false;
  1158. }
  1159. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  1160. return true;
  1161. }
  1162. //-----------------------------------------------------------------------------
  1163. // Purpose:
  1164. //-----------------------------------------------------------------------------
  1165. bool CMainApplication::SetupStereoRenderTargets()
  1166. {
  1167. if ( !m_pHMD )
  1168. return false;
  1169. m_pHMD->GetRecommendedRenderTargetSize( &m_nRenderWidth, &m_nRenderHeight );
  1170. CreateFrameBuffer( m_nRenderWidth, m_nRenderHeight, leftEyeDesc );
  1171. CreateFrameBuffer( m_nRenderWidth, m_nRenderHeight, rightEyeDesc );
  1172. return true;
  1173. }
  1174. //-----------------------------------------------------------------------------
  1175. // Purpose:
  1176. //-----------------------------------------------------------------------------
  1177. void CMainApplication::SetupDistortion()
  1178. {
  1179. if ( !m_pHMD )
  1180. return;
  1181. GLushort m_iLensGridSegmentCountH = 43;
  1182. GLushort m_iLensGridSegmentCountV = 43;
  1183. float w = (float)( 1.0/float(m_iLensGridSegmentCountH-1));
  1184. float h = (float)( 1.0/float(m_iLensGridSegmentCountV-1));
  1185. float u, v = 0;
  1186. std::vector<VertexDataLens> vVerts(0);
  1187. VertexDataLens vert;
  1188. //left eye distortion verts
  1189. float Xoffset = -1;
  1190. for( int y=0; y<m_iLensGridSegmentCountV; y++ )
  1191. {
  1192. for( int x=0; x<m_iLensGridSegmentCountH; x++ )
  1193. {
  1194. u = x*w; v = 1-y*h;
  1195. vert.position = Vector2( Xoffset+u, -1+2*y*h );
  1196. vr::DistortionCoordinates_t dc0 = m_pHMD->ComputeDistortion(vr::Eye_Left, u, v);
  1197. vert.texCoordRed = Vector2(dc0.rfRed[0], 1 - dc0.rfRed[1]);
  1198. vert.texCoordGreen = Vector2(dc0.rfGreen[0], 1 - dc0.rfGreen[1]);
  1199. vert.texCoordBlue = Vector2(dc0.rfBlue[0], 1 - dc0.rfBlue[1]);
  1200. vVerts.push_back( vert );
  1201. }
  1202. }
  1203. //right eye distortion verts
  1204. Xoffset = 0;
  1205. for( int y=0; y<m_iLensGridSegmentCountV; y++ )
  1206. {
  1207. for( int x=0; x<m_iLensGridSegmentCountH; x++ )
  1208. {
  1209. u = x*w; v = 1-y*h;
  1210. vert.position = Vector2( Xoffset+u, -1+2*y*h );
  1211. vr::DistortionCoordinates_t dc0 = m_pHMD->ComputeDistortion( vr::Eye_Right, u, v );
  1212. vert.texCoordRed = Vector2(dc0.rfRed[0], 1 - dc0.rfRed[1]);
  1213. vert.texCoordGreen = Vector2(dc0.rfGreen[0], 1 - dc0.rfGreen[1]);
  1214. vert.texCoordBlue = Vector2(dc0.rfBlue[0], 1 - dc0.rfBlue[1]);
  1215. vVerts.push_back( vert );
  1216. }
  1217. }
  1218. std::vector<GLushort> vIndices;
  1219. GLushort a,b,c,d;
  1220. GLushort offset = 0;
  1221. for( GLushort y=0; y<m_iLensGridSegmentCountV-1; y++ )
  1222. {
  1223. for( GLushort x=0; x<m_iLensGridSegmentCountH-1; x++ )
  1224. {
  1225. a = m_iLensGridSegmentCountH*y+x +offset;
  1226. b = m_iLensGridSegmentCountH*y+x+1 +offset;
  1227. c = (y+1)*m_iLensGridSegmentCountH+x+1 +offset;
  1228. d = (y+1)*m_iLensGridSegmentCountH+x +offset;
  1229. vIndices.push_back( a );
  1230. vIndices.push_back( b );
  1231. vIndices.push_back( c );
  1232. vIndices.push_back( a );
  1233. vIndices.push_back( c );
  1234. vIndices.push_back( d );
  1235. }
  1236. }
  1237. offset = (m_iLensGridSegmentCountH)*(m_iLensGridSegmentCountV);
  1238. for( GLushort y=0; y<m_iLensGridSegmentCountV-1; y++ )
  1239. {
  1240. for( GLushort x=0; x<m_iLensGridSegmentCountH-1; x++ )
  1241. {
  1242. a = m_iLensGridSegmentCountH*y+x +offset;
  1243. b = m_iLensGridSegmentCountH*y+x+1 +offset;
  1244. c = (y+1)*m_iLensGridSegmentCountH+x+1 +offset;
  1245. d = (y+1)*m_iLensGridSegmentCountH+x +offset;
  1246. vIndices.push_back( a );
  1247. vIndices.push_back( b );
  1248. vIndices.push_back( c );
  1249. vIndices.push_back( a );
  1250. vIndices.push_back( c );
  1251. vIndices.push_back( d );
  1252. }
  1253. }
  1254. m_uiIndexSize = vIndices.size();
  1255. glGenVertexArrays( 1, &m_unLensVAO );
  1256. glBindVertexArray( m_unLensVAO );
  1257. glGenBuffers( 1, &m_glIDVertBuffer );
  1258. glBindBuffer( GL_ARRAY_BUFFER, m_glIDVertBuffer );
  1259. glBufferData( GL_ARRAY_BUFFER, vVerts.size()*sizeof(VertexDataLens), &vVerts[0], GL_STATIC_DRAW );
  1260. glGenBuffers( 1, &m_glIDIndexBuffer );
  1261. glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_glIDIndexBuffer );
  1262. glBufferData( GL_ELEMENT_ARRAY_BUFFER, vIndices.size()*sizeof(GLushort), &vIndices[0], GL_STATIC_DRAW );
  1263. glEnableVertexAttribArray( 0 );
  1264. glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexDataLens), (void *)offsetof( VertexDataLens, position ) );
  1265. glEnableVertexAttribArray( 1 );
  1266. glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexDataLens), (void *)offsetof( VertexDataLens, texCoordRed ) );
  1267. glEnableVertexAttribArray(2);
  1268. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexDataLens), (void *)offsetof( VertexDataLens, texCoordGreen ) );
  1269. glEnableVertexAttribArray(3);
  1270. glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexDataLens), (void *)offsetof( VertexDataLens, texCoordBlue ) );
  1271. glBindVertexArray( 0 );
  1272. glDisableVertexAttribArray(0);
  1273. glDisableVertexAttribArray(1);
  1274. glDisableVertexAttribArray(2);
  1275. glDisableVertexAttribArray(3);
  1276. glBindBuffer(GL_ARRAY_BUFFER, 0);
  1277. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  1278. }
  1279. //-----------------------------------------------------------------------------
  1280. // Purpose:
  1281. //-----------------------------------------------------------------------------
  1282. void CMainApplication::RenderStereoTargets()
  1283. {
  1284. B3_PROFILE("CMainApplication::RenderStereoTargets");
  1285. sExample->stepSimulation(1./60.);
  1286. glClearColor( 0.15f, 0.15f, 0.18f, 1.0f ); // nice background color, but not black
  1287. glEnable( GL_MULTISAMPLE );
  1288. m_app->m_instancingRenderer->init();
  1289. Matrix4 rotYtoZ = rotYtoZ.identity();
  1290. //some Bullet apps (especially robotics related) require Z as up-axis)
  1291. if (m_app->getUpAxis()==2)
  1292. {
  1293. rotYtoZ.rotateX(-90);
  1294. }
  1295. // Left Eye
  1296. {
  1297. Matrix4 viewMatLeft = m_mat4eyePosLeft * m_mat4HMDPose * rotYtoZ;
  1298. Matrix4 viewMatCenter = m_mat4HMDPose * rotYtoZ;
  1299. //0,1,2,3
  1300. //4,5,6,7,
  1301. //8,9,10,11
  1302. //12,13,14,15
  1303. //m_mat4eyePosLeft.get()[10]
  1304. //m_app->m_instancingRenderer->getActiveCamera()->setCameraTargetPosition(
  1305. // m_mat4eyePosLeft.get()[3],
  1306. // m_mat4eyePosLeft.get()[7],
  1307. // m_mat4eyePosLeft.get()[11]);
  1308. Matrix4 m;
  1309. m = viewMatCenter;
  1310. const float* mat = m.invertAffine().get();
  1311. /*printf("camera:\n,%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f",
  1312. mat[0],mat[1],mat[2],mat[3],
  1313. mat[4],mat[5],mat[6],mat[7],
  1314. mat[8],mat[9],mat[10],mat[11],
  1315. mat[12],mat[13],mat[14],mat[15]);
  1316. */
  1317. float dist=1;
  1318. m_app->m_instancingRenderer->getActiveCamera()->setCameraTargetPosition(
  1319. mat[12]-dist*mat[8],
  1320. mat[13]-dist*mat[9],
  1321. mat[14]-dist*mat[10]
  1322. );
  1323. m_app->m_instancingRenderer->getActiveCamera()->setCameraUpVector(mat[0],mat[1],mat[2]);
  1324. m_app->m_instancingRenderer->getActiveCamera()->setVRCamera(viewMatLeft.get(),m_mat4ProjectionLeft.get());
  1325. m_app->m_instancingRenderer->updateCamera(m_app->getUpAxis());
  1326. }
  1327. glBindFramebuffer( GL_FRAMEBUFFER, leftEyeDesc.m_nRenderFramebufferId );
  1328. glViewport(0, 0, m_nRenderWidth, m_nRenderHeight );
  1329. m_app->m_window->startRendering();
  1330. RenderScene( vr::Eye_Left );
  1331. m_app->m_instancingRenderer->setRenderFrameBuffer((unsigned int)leftEyeDesc.m_nRenderFramebufferId);
  1332. if (gDebugDrawFlags)
  1333. {
  1334. sExample->physicsDebugDraw(gDebugDrawFlags);
  1335. }
  1336. //else
  1337. {
  1338. sExample->renderScene();
  1339. }
  1340. //m_app->m_instancingRenderer->renderScene();
  1341. DrawGridData gridUp;
  1342. gridUp.upAxis = m_app->getUpAxis();
  1343. // m_app->drawGrid(gridUp);
  1344. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  1345. glDisable( GL_MULTISAMPLE );
  1346. glBindFramebuffer(GL_READ_FRAMEBUFFER, leftEyeDesc.m_nRenderFramebufferId);
  1347. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, leftEyeDesc.m_nResolveFramebufferId );
  1348. glBlitFramebuffer( 0, 0, m_nRenderWidth, m_nRenderHeight, 0, 0, m_nRenderWidth, m_nRenderHeight,
  1349. GL_COLOR_BUFFER_BIT,
  1350. GL_LINEAR );
  1351. glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  1352. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 );
  1353. glEnable( GL_MULTISAMPLE );
  1354. // Right Eye
  1355. {
  1356. Matrix4 viewMatRight = m_mat4eyePosRight * m_mat4HMDPose * rotYtoZ;
  1357. m_app->m_instancingRenderer->getActiveCamera()->setVRCamera(viewMatRight.get(),m_mat4ProjectionRight.get());
  1358. m_app->m_instancingRenderer->updateCamera(m_app->getUpAxis());
  1359. }
  1360. glBindFramebuffer( GL_FRAMEBUFFER, rightEyeDesc.m_nRenderFramebufferId );
  1361. glViewport(0, 0, m_nRenderWidth, m_nRenderHeight );
  1362. m_app->m_window->startRendering();
  1363. RenderScene( vr::Eye_Right );
  1364. m_app->m_instancingRenderer->setRenderFrameBuffer((unsigned int)rightEyeDesc.m_nRenderFramebufferId);
  1365. //m_app->m_renderer->renderScene();
  1366. if (gDebugDrawFlags)
  1367. {
  1368. sExample->physicsDebugDraw(gDebugDrawFlags);
  1369. }
  1370. //else
  1371. {
  1372. sExample->renderScene();
  1373. }
  1374. //m_app->drawGrid(gridUp);
  1375. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  1376. glDisable( GL_MULTISAMPLE );
  1377. glBindFramebuffer(GL_READ_FRAMEBUFFER, rightEyeDesc.m_nRenderFramebufferId );
  1378. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rightEyeDesc.m_nResolveFramebufferId );
  1379. glBlitFramebuffer( 0, 0, m_nRenderWidth, m_nRenderHeight, 0, 0, m_nRenderWidth, m_nRenderHeight,
  1380. GL_COLOR_BUFFER_BIT,
  1381. GL_LINEAR );
  1382. glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  1383. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0 );
  1384. }
  1385. //-----------------------------------------------------------------------------
  1386. // Purpose:
  1387. //-----------------------------------------------------------------------------
  1388. void CMainApplication::RenderScene( vr::Hmd_Eye nEye )
  1389. {
  1390. B3_PROFILE("RenderScene");
  1391. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1392. glEnable(GL_DEPTH_TEST);
  1393. if( m_bShowCubes )
  1394. {
  1395. glUseProgram( m_unSceneProgramID );
  1396. glUniformMatrix4fv( m_nSceneMatrixLocation, 1, GL_FALSE, GetCurrentViewProjectionMatrix( nEye ).get() );
  1397. glBindVertexArray( m_unSceneVAO );
  1398. glBindTexture( GL_TEXTURE_2D, m_iTexture );
  1399. glDrawArrays( GL_TRIANGLES, 0, m_uiVertcount );
  1400. glBindVertexArray( 0 );
  1401. }
  1402. bool bIsInputCapturedByAnotherProcess = m_pHMD->IsInputFocusCapturedByAnotherProcess();
  1403. if( !bIsInputCapturedByAnotherProcess )
  1404. {
  1405. // draw the controller axis lines
  1406. glUseProgram( m_unControllerTransformProgramID );
  1407. glUniformMatrix4fv( m_nControllerMatrixLocation, 1, GL_FALSE, GetCurrentViewProjectionMatrix( nEye ).get() );
  1408. glBindVertexArray( m_unControllerVAO );
  1409. glDrawArrays( GL_LINES, 0, m_uiControllerVertcount );
  1410. glBindVertexArray( 0 );
  1411. }
  1412. // ----- Render Model rendering -----
  1413. glUseProgram( m_unRenderModelProgramID );
  1414. for( uint32_t unTrackedDevice = 0; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; unTrackedDevice++ )
  1415. {
  1416. if( !m_rTrackedDeviceToRenderModel[ unTrackedDevice ] || !m_rbShowTrackedDevice[ unTrackedDevice ] )
  1417. continue;
  1418. const vr::TrackedDevicePose_t & pose = m_rTrackedDevicePose[ unTrackedDevice ];
  1419. if( !pose.bPoseIsValid )
  1420. continue;
  1421. if( bIsInputCapturedByAnotherProcess && m_pHMD->GetTrackedDeviceClass( unTrackedDevice ) == vr::TrackedDeviceClass_Controller )
  1422. continue;
  1423. const Matrix4 & matDeviceToTracking = m_rmat4DevicePose[ unTrackedDevice ];
  1424. Matrix4 matMVP = GetCurrentViewProjectionMatrix( nEye ) * matDeviceToTracking;
  1425. glUniformMatrix4fv( m_nRenderModelMatrixLocation, 1, GL_FALSE, matMVP.get() );
  1426. m_rTrackedDeviceToRenderModel[ unTrackedDevice ]->Draw();
  1427. }
  1428. glUseProgram( 0 );
  1429. }
  1430. //-----------------------------------------------------------------------------
  1431. // Purpose:
  1432. //-----------------------------------------------------------------------------
  1433. void CMainApplication::RenderDistortion()
  1434. {
  1435. glDisable(GL_DEPTH_TEST);
  1436. glViewport( 0, 0, m_nWindowWidth, m_nWindowHeight );
  1437. glBindVertexArray( m_unLensVAO );
  1438. glUseProgram( m_unLensProgramID );
  1439. //render left lens (first half of index array )
  1440. glBindTexture(GL_TEXTURE_2D, leftEyeDesc.m_nResolveTextureId );
  1441. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  1442. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  1443. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  1444. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
  1445. glDrawElements( GL_TRIANGLES, m_uiIndexSize/2, GL_UNSIGNED_SHORT, 0 );
  1446. //render right lens (second half of index array )
  1447. glBindTexture(GL_TEXTURE_2D, rightEyeDesc.m_nResolveTextureId );
  1448. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  1449. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  1450. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  1451. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
  1452. glDrawElements( GL_TRIANGLES, m_uiIndexSize/2, GL_UNSIGNED_SHORT, (const void *)(m_uiIndexSize) );
  1453. glBindVertexArray( 0 );
  1454. glUseProgram( 0 );
  1455. }
  1456. //-----------------------------------------------------------------------------
  1457. // Purpose:
  1458. //-----------------------------------------------------------------------------
  1459. Matrix4 CMainApplication::GetHMDMatrixProjectionEye( vr::Hmd_Eye nEye )
  1460. {
  1461. if ( !m_pHMD )
  1462. return Matrix4();
  1463. vr::HmdMatrix44_t mat = m_pHMD->GetProjectionMatrix( nEye, m_fNearClip, m_fFarClip, vr::API_OpenGL);
  1464. return Matrix4(
  1465. mat.m[0][0], mat.m[1][0], mat.m[2][0], mat.m[3][0],
  1466. mat.m[0][1], mat.m[1][1], mat.m[2][1], mat.m[3][1],
  1467. mat.m[0][2], mat.m[1][2], mat.m[2][2], mat.m[3][2],
  1468. mat.m[0][3], mat.m[1][3], mat.m[2][3], mat.m[3][3]
  1469. );
  1470. }
  1471. //-----------------------------------------------------------------------------
  1472. // Purpose:
  1473. //-----------------------------------------------------------------------------
  1474. Matrix4 CMainApplication::GetHMDMatrixPoseEye( vr::Hmd_Eye nEye )
  1475. {
  1476. if ( !m_pHMD )
  1477. return Matrix4();
  1478. vr::HmdMatrix34_t matEyeRight = m_pHMD->GetEyeToHeadTransform( nEye );
  1479. Matrix4 matrixObj(
  1480. matEyeRight.m[0][0], matEyeRight.m[1][0], matEyeRight.m[2][0], 0.0,
  1481. matEyeRight.m[0][1], matEyeRight.m[1][1], matEyeRight.m[2][1], 0.0,
  1482. matEyeRight.m[0][2], matEyeRight.m[1][2], matEyeRight.m[2][2], 0.0,
  1483. matEyeRight.m[0][3], matEyeRight.m[1][3], matEyeRight.m[2][3], 1.0f
  1484. );
  1485. return matrixObj.invert();
  1486. }
  1487. //-----------------------------------------------------------------------------
  1488. // Purpose:
  1489. //-----------------------------------------------------------------------------
  1490. Matrix4 CMainApplication::GetCurrentViewProjectionMatrix( vr::Hmd_Eye nEye )
  1491. {
  1492. Matrix4 matMVP;
  1493. if( nEye == vr::Eye_Left )
  1494. {
  1495. matMVP = m_mat4ProjectionLeft * m_mat4eyePosLeft * m_mat4HMDPose;
  1496. }
  1497. else if( nEye == vr::Eye_Right )
  1498. {
  1499. matMVP = m_mat4ProjectionRight * m_mat4eyePosRight * m_mat4HMDPose;
  1500. }
  1501. return matMVP;
  1502. }
  1503. //-----------------------------------------------------------------------------
  1504. // Purpose:
  1505. //-----------------------------------------------------------------------------
  1506. void CMainApplication::UpdateHMDMatrixPose()
  1507. {
  1508. if (!m_pHMD)
  1509. return;
  1510. {
  1511. B3_PROFILE("WaitGetPoses");
  1512. vr::VRCompositor()->WaitGetPoses(m_rTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, NULL, 0);
  1513. }
  1514. m_iValidPoseCount = 0;
  1515. m_strPoseClasses = "";
  1516. {
  1517. B3_PROFILE("for loop");
  1518. for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice)
  1519. {
  1520. if (m_rTrackedDevicePose[nDevice].bPoseIsValid)
  1521. {
  1522. m_iValidPoseCount++;
  1523. m_rmat4DevicePose[nDevice] = ConvertSteamVRMatrixToMatrix4(m_rTrackedDevicePose[nDevice].mDeviceToAbsoluteTracking);
  1524. if (m_rDevClassChar[nDevice] == 0)
  1525. {
  1526. switch (m_pHMD->GetTrackedDeviceClass(nDevice))
  1527. {
  1528. case vr::TrackedDeviceClass_Controller: m_rDevClassChar[nDevice] = 'C'; break;
  1529. case vr::TrackedDeviceClass_HMD: m_rDevClassChar[nDevice] = 'H'; break;
  1530. case vr::TrackedDeviceClass_Invalid: m_rDevClassChar[nDevice] = 'I'; break;
  1531. case vr::TrackedDeviceClass_Other: m_rDevClassChar[nDevice] = 'O'; break;
  1532. case vr::TrackedDeviceClass_TrackingReference: m_rDevClassChar[nDevice] = 'T'; break;
  1533. default: m_rDevClassChar[nDevice] = '?'; break;
  1534. }
  1535. }
  1536. m_strPoseClasses += m_rDevClassChar[nDevice];
  1537. }
  1538. }
  1539. }
  1540. {
  1541. B3_PROFILE("m_mat4HMDPose invert");
  1542. if (m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid)
  1543. {
  1544. m_mat4HMDPose = m_rmat4DevicePose[vr::k_unTrackedDeviceIndex_Hmd].invert();
  1545. }
  1546. }
  1547. }
  1548. //-----------------------------------------------------------------------------
  1549. // Purpose: Finds a render model we've already loaded or loads a new one
  1550. //-----------------------------------------------------------------------------
  1551. CGLRenderModel *CMainApplication::FindOrLoadRenderModel( const char *pchRenderModelName )
  1552. {
  1553. CGLRenderModel *pRenderModel = NULL;
  1554. for( std::vector< CGLRenderModel * >::iterator i = m_vecRenderModels.begin(); i != m_vecRenderModels.end(); i++ )
  1555. {
  1556. if( !stricmp( (*i)->GetName().c_str(), pchRenderModelName ) )
  1557. {
  1558. pRenderModel = *i;
  1559. break;
  1560. }
  1561. }
  1562. // load the model if we didn't find one
  1563. if( !pRenderModel )
  1564. {
  1565. vr::RenderModel_t *pModel;
  1566. vr::EVRRenderModelError error;
  1567. while ( 1 )
  1568. {
  1569. error = vr::VRRenderModels()->LoadRenderModel_Async( pchRenderModelName, &pModel );
  1570. if ( error != vr::VRRenderModelError_Loading )
  1571. break;
  1572. ThreadSleep( 1 );
  1573. }
  1574. if ( error != vr::VRRenderModelError_None )
  1575. {
  1576. b3Printf( "Unable to load render model %s - %s\n", pchRenderModelName, vr::VRRenderModels()->GetRenderModelErrorNameFromEnum( error ) );
  1577. return NULL; // move on to the next tracked device
  1578. }
  1579. vr::RenderModel_TextureMap_t *pTexture;
  1580. while ( 1 )
  1581. {
  1582. error = vr::VRRenderModels()->LoadTexture_Async( pModel->diffuseTextureId, &pTexture );
  1583. if ( error != vr::VRRenderModelError_Loading )
  1584. break;
  1585. ThreadSleep( 1 );
  1586. }
  1587. if ( error != vr::VRRenderModelError_None )
  1588. {
  1589. b3Printf( "Unable to load render texture id:%d for render model %s\n", pModel->diffuseTextureId, pchRenderModelName );
  1590. vr::VRRenderModels()->FreeRenderModel( pModel );
  1591. return NULL; // move on to the next tracked device
  1592. }
  1593. pRenderModel = new CGLRenderModel( pchRenderModelName );
  1594. if ( !pRenderModel->BInit( *pModel, *pTexture ) )
  1595. {
  1596. b3Printf( "Unable to create GL model from render model %s\n", pchRenderModelName );
  1597. delete pRenderModel;
  1598. pRenderModel = NULL;
  1599. }
  1600. else
  1601. {
  1602. m_vecRenderModels.push_back( pRenderModel );
  1603. }
  1604. vr::VRRenderModels()->FreeRenderModel( pModel );
  1605. vr::VRRenderModels()->FreeTexture( pTexture );
  1606. }
  1607. return pRenderModel;
  1608. }
  1609. //-----------------------------------------------------------------------------
  1610. // Purpose: Create/destroy GL a Render Model for a single tracked device
  1611. //-----------------------------------------------------------------------------
  1612. void CMainApplication::SetupRenderModelForTrackedDevice( vr::TrackedDeviceIndex_t unTrackedDeviceIndex )
  1613. {
  1614. if( unTrackedDeviceIndex >= vr::k_unMaxTrackedDeviceCount )
  1615. return;
  1616. // try to find a model we've already set up
  1617. std::string sRenderModelName = GetTrackedDeviceString( m_pHMD, unTrackedDeviceIndex, vr::Prop_RenderModelName_String );
  1618. CGLRenderModel *pRenderModel = FindOrLoadRenderModel( sRenderModelName.c_str() );
  1619. if( !pRenderModel )
  1620. {
  1621. std::string sTrackingSystemName = GetTrackedDeviceString( m_pHMD, unTrackedDeviceIndex, vr::Prop_TrackingSystemName_String );
  1622. b3Printf( "Unable to load render model for tracked device %d (%s.%s)", unTrackedDeviceIndex, sTrackingSystemName.c_str(), sRenderModelName.c_str() );
  1623. }
  1624. else
  1625. {
  1626. m_rTrackedDeviceToRenderModel[ unTrackedDeviceIndex ] = pRenderModel;
  1627. m_rbShowTrackedDevice[ unTrackedDeviceIndex ] = true;
  1628. }
  1629. }
  1630. //-----------------------------------------------------------------------------
  1631. // Purpose: Create/destroy GL Render Models
  1632. //-----------------------------------------------------------------------------
  1633. void CMainApplication::SetupRenderModels()
  1634. {
  1635. memset( m_rTrackedDeviceToRenderModel, 0, sizeof( m_rTrackedDeviceToRenderModel ) );
  1636. if( !m_pHMD )
  1637. return;
  1638. for( uint32_t unTrackedDevice = vr::k_unTrackedDeviceIndex_Hmd + 1; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; unTrackedDevice++ )
  1639. {
  1640. if( !m_pHMD->IsTrackedDeviceConnected( unTrackedDevice ) )
  1641. continue;
  1642. SetupRenderModelForTrackedDevice( unTrackedDevice );
  1643. }
  1644. }
  1645. //-----------------------------------------------------------------------------
  1646. // Purpose: Converts a SteamVR matrix to our local matrix class
  1647. //-----------------------------------------------------------------------------
  1648. Matrix4 CMainApplication::ConvertSteamVRMatrixToMatrix4( const vr::HmdMatrix34_t &matPose )
  1649. {
  1650. Matrix4 matrixObj(
  1651. matPose.m[0][0], matPose.m[1][0], matPose.m[2][0], 0.0,
  1652. matPose.m[0][1], matPose.m[1][1], matPose.m[2][1], 0.0,
  1653. matPose.m[0][2], matPose.m[1][2], matPose.m[2][2], 0.0,
  1654. matPose.m[0][3], matPose.m[1][3], matPose.m[2][3], 1.0f
  1655. );
  1656. return matrixObj;
  1657. }
  1658. //-----------------------------------------------------------------------------
  1659. // Purpose: Create/destroy GL Render Models
  1660. //-----------------------------------------------------------------------------
  1661. CGLRenderModel::CGLRenderModel( const std::string & sRenderModelName )
  1662. : m_sModelName( sRenderModelName )
  1663. {
  1664. m_glIndexBuffer = 0;
  1665. m_glVertArray = 0;
  1666. m_glVertBuffer = 0;
  1667. m_glTexture = 0;
  1668. }
  1669. CGLRenderModel::~CGLRenderModel()
  1670. {
  1671. Cleanup();
  1672. }
  1673. //-----------------------------------------------------------------------------
  1674. // Purpose: Allocates and populates the GL resources for a render model
  1675. //-----------------------------------------------------------------------------
  1676. bool CGLRenderModel::BInit( const vr::RenderModel_t & vrModel, const vr::RenderModel_TextureMap_t & vrDiffuseTexture )
  1677. {
  1678. // create and bind a VAO to hold state for this model
  1679. glGenVertexArrays( 1, &m_glVertArray );
  1680. glBindVertexArray( m_glVertArray );
  1681. // Populate a vertex buffer
  1682. glGenBuffers( 1, &m_glVertBuffer );
  1683. glBindBuffer( GL_ARRAY_BUFFER, m_glVertBuffer );
  1684. glBufferData( GL_ARRAY_BUFFER, sizeof( vr::RenderModel_Vertex_t ) * vrModel.unVertexCount, vrModel.rVertexData, GL_STATIC_DRAW );
  1685. // Identify the components in the vertex buffer
  1686. glEnableVertexAttribArray( 0 );
  1687. glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof( vr::RenderModel_Vertex_t ), (void *)offsetof( vr::RenderModel_Vertex_t, vPosition ) );
  1688. glEnableVertexAttribArray( 1 );
  1689. glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, sizeof( vr::RenderModel_Vertex_t ), (void *)offsetof( vr::RenderModel_Vertex_t, vNormal ) );
  1690. glEnableVertexAttribArray( 2 );
  1691. glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, sizeof( vr::RenderModel_Vertex_t ), (void *)offsetof( vr::RenderModel_Vertex_t, rfTextureCoord ) );
  1692. // Create and populate the index buffer
  1693. glGenBuffers( 1, &m_glIndexBuffer );
  1694. glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_glIndexBuffer );
  1695. glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( uint16_t ) * vrModel.unTriangleCount * 3, vrModel.rIndexData, GL_STATIC_DRAW );
  1696. glBindVertexArray( 0 );
  1697. // create and populate the texture
  1698. glGenTextures(1, &m_glTexture );
  1699. glBindTexture( GL_TEXTURE_2D, m_glTexture );
  1700. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, vrDiffuseTexture.unWidth, vrDiffuseTexture.unHeight,
  1701. 0, GL_RGBA, GL_UNSIGNED_BYTE, vrDiffuseTexture.rubTextureMapData );
  1702. // If this renders black ask McJohn what's wrong.
  1703. glGenerateMipmap(GL_TEXTURE_2D);
  1704. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  1705. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  1706. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  1707. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
  1708. GLfloat fLargest;
  1709. glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest );
  1710. glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest );
  1711. glBindTexture( GL_TEXTURE_2D, 0 );
  1712. m_unVertexCount = vrModel.unTriangleCount * 3;
  1713. return true;
  1714. }
  1715. //-----------------------------------------------------------------------------
  1716. // Purpose: Frees the GL resources for a render model
  1717. //-----------------------------------------------------------------------------
  1718. void CGLRenderModel::Cleanup()
  1719. {
  1720. if( m_glVertBuffer )
  1721. {
  1722. glDeleteBuffers(1, &m_glIndexBuffer);
  1723. glDeleteVertexArrays( 1, &m_glVertArray );
  1724. glDeleteBuffers(1, &m_glVertBuffer);
  1725. m_glIndexBuffer = 0;
  1726. m_glVertArray = 0;
  1727. m_glVertBuffer = 0;
  1728. }
  1729. }
  1730. //-----------------------------------------------------------------------------
  1731. // Purpose: Draws the render model
  1732. //-----------------------------------------------------------------------------
  1733. void CGLRenderModel::Draw()
  1734. {
  1735. glBindVertexArray( m_glVertArray );
  1736. glActiveTexture( GL_TEXTURE0 );
  1737. glBindTexture( GL_TEXTURE_2D, m_glTexture );
  1738. glDrawElements( GL_TRIANGLES, m_unVertexCount, GL_UNSIGNED_SHORT, 0 );
  1739. glBindVertexArray( 0 );
  1740. }
  1741. //-----------------------------------------------------------------------------
  1742. // Purpose:
  1743. //-----------------------------------------------------------------------------
  1744. int main(int argc, char *argv[])
  1745. {
  1746. #ifdef BT_USE_CUSTOM_PROFILER
  1747. //b3SetCustomEnterProfileZoneFunc(...);
  1748. //b3SetCustomLeaveProfileZoneFunc(...);
  1749. #endif
  1750. CMainApplication *pMainApplication = new CMainApplication( argc, argv );
  1751. if (!pMainApplication->BInit())
  1752. {
  1753. pMainApplication->Shutdown();
  1754. return 1;
  1755. }
  1756. if (sExample)
  1757. {
  1758. sExample->processCommandLineArgs(argc,argv);
  1759. }
  1760. //request disable VSYNC
  1761. typedef bool (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int);
  1762. PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;
  1763. wglSwapIntervalEXT =
  1764. (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress("wglSwapIntervalEXT");
  1765. if (wglSwapIntervalEXT)
  1766. wglSwapIntervalEXT(0);
  1767. pMainApplication->RunMainLoop();
  1768. pMainApplication->Shutdown();
  1769. #ifdef BT_USE_CUSTOM_PROFILER
  1770. //...
  1771. #endif
  1772. return 0;
  1773. }
  1774. #endif //BT_ENABLE_VR