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