oculus_rift.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*******************************************************************************************
  2. *
  3. * raylib [core] example - Oculus Rift CV1
  4. *
  5. * Compile example using:
  6. * gcc -o $(NAME_PART).exe $(FILE_NAME) -I..\src\external -I..\src\external\OculusSDK\LibOVR\Include /
  7. * -L. -L..\src\external\OculusSDK\LibOVR -lLibOVRRT32_1 -lraylib -lglfw3 -lopengl32 -lgdi32 -std=c99 /
  8. * -Wl,-allow-multiple-definition
  9. *
  10. * #define SUPPORT_OCULUS_RIFT_CV1 / RLGL_OCULUS_SUPPORT
  11. * Enable Oculus Rift CV1 functionality
  12. *
  13. * This example has been created using raylib 1.5 (www.raylib.com)
  14. * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
  15. *
  16. * Copyright (c) 2016 Ramon Santamaria (@raysan5)
  17. *
  18. ********************************************************************************************/
  19. #include "raylib.h"
  20. #include "glad.h" // Required for: OpenGL types and functions declarations
  21. #include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality
  22. #include <string.h> // Required for: memset()
  23. #include <stdlib.h> // Required for: exit()
  24. #include <stdio.h> // required for: vfprintf()
  25. #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
  26. #define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code
  27. #if defined(RLGL_OCULUS_SUPPORT)
  28. #include "OVR_CAPI_GL.h" // Oculus SDK for OpenGL
  29. #endif
  30. //----------------------------------------------------------------------------------
  31. // Defines and Macros
  32. //----------------------------------------------------------------------------------
  33. // ...
  34. //----------------------------------------------------------------------------------
  35. // Types and Structures Definition
  36. //----------------------------------------------------------------------------------
  37. // TraceLog message types
  38. typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
  39. #if defined(RLGL_OCULUS_SUPPORT)
  40. // Oculus buffer type
  41. typedef struct OculusBuffer {
  42. ovrTextureSwapChain textureChain;
  43. GLuint depthId;
  44. GLuint fboId;
  45. int width;
  46. int height;
  47. } OculusBuffer;
  48. // Oculus mirror texture type
  49. typedef struct OculusMirror {
  50. ovrMirrorTexture texture;
  51. GLuint fboId;
  52. int width;
  53. int height;
  54. } OculusMirror;
  55. // Oculus layer type
  56. typedef struct OculusLayer {
  57. ovrViewScaleDesc viewScaleDesc;
  58. ovrLayerEyeFov eyeLayer; // layer 0
  59. //ovrLayerQuad quadLayer; // TODO: layer 1: '2D' quad for GUI
  60. Matrix eyeProjections[2];
  61. int width;
  62. int height;
  63. } OculusLayer;
  64. #endif
  65. //----------------------------------------------------------------------------------
  66. // Global Variables Definition
  67. //----------------------------------------------------------------------------------
  68. #if defined(RLGL_OCULUS_SUPPORT)
  69. // OVR device variables
  70. static ovrSession session; // Oculus session (pointer to ovrHmdStruct)
  71. static ovrHmdDesc hmdDesc; // Oculus device descriptor parameters
  72. static ovrGraphicsLuid luid; // Oculus locally unique identifier for the program (64 bit)
  73. static OculusLayer layer; // Oculus drawing layer (similar to photoshop)
  74. static OculusBuffer buffer; // Oculus internal buffers (texture chain and fbo)
  75. static OculusMirror mirror; // Oculus mirror texture and fbo
  76. static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain
  77. #endif
  78. //----------------------------------------------------------------------------------
  79. // Module specific Functions Declaration
  80. //----------------------------------------------------------------------------------
  81. #if defined(RLGL_OCULUS_SUPPORT)
  82. static bool InitOculusDevice(void); // Initialize Oculus device (returns true if success)
  83. static void CloseOculusDevice(void); // Close Oculus device
  84. static void UpdateOculusTracking(Camera *camera); // Update Oculus head position-orientation tracking
  85. static void BeginOculusDrawing(void); // Setup Oculus buffers for drawing
  86. static void EndOculusDrawing(void); // Finish Oculus drawing and blit framebuffer to mirror
  87. static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers
  88. static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers
  89. static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers
  90. static void UnloadOculusMirror(ovrSession session, OculusMirror mirror); // Unload Oculus mirror buffers
  91. static void BlitOculusMirror(ovrSession session, OculusMirror mirror); // Copy Oculus screen buffer to mirror texture
  92. static OculusLayer InitOculusLayer(ovrSession session); // Init Oculus layer (similar to photoshop)
  93. static Matrix FromOvrMatrix(ovrMatrix4f ovrM); // Convert from Oculus ovrMatrix4f struct to raymath Matrix struct
  94. #endif
  95. static void TraceLog(int msgType, const char *text, ...);
  96. int main()
  97. {
  98. // Initialization
  99. //--------------------------------------------------------------------------------------
  100. int screenWidth = 1080;
  101. int screenHeight = 600;
  102. // NOTE: screenWidth/screenHeight should match VR device aspect ratio
  103. InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift");
  104. bool vrDeviceReady = InitOculusDevice(); // Init VR device Oculus Rift CV1
  105. if (!vrDeviceReady) InitVrSimulator(HMD_OCULUS_RIFT_CV1); // Init VR simulator if device fails
  106. // Define the camera to look into our 3d world
  107. Camera camera;
  108. camera.position = (Vector3){ 5.0f, 2.0f, 5.0f }; // Camera position
  109. camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
  110. camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
  111. camera.fovy = 60.0f; // Camera field-of-view Y
  112. Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
  113. SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set first person camera mode
  114. SetTargetFPS(90); // Set our game to run at 90 frames-per-second
  115. //--------------------------------------------------------------------------------------
  116. // Main game loop
  117. while (!WindowShouldClose()) // Detect window close button or ESC key
  118. {
  119. // Update
  120. //----------------------------------------------------------------------------------
  121. if (!vrDeviceReady) UpdateCamera(&camera); // Update camera (simulator mode)
  122. else UpdateOculusTracking(&camera); // Update camera with device tracking data
  123. if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); // Toggle VR mode
  124. //----------------------------------------------------------------------------------
  125. // Draw
  126. //----------------------------------------------------------------------------------
  127. BeginDrawing();
  128. ClearBackground(RAYWHITE);
  129. if (vrDeviceReady) BeginOculusDrawing();
  130. else BeginVrDrawing();
  131. Begin3dMode(camera);
  132. DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
  133. DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
  134. DrawGrid(40, 1.0f);
  135. End3dMode();
  136. if (vrDeviceReady) EndOculusDrawing();
  137. else EndVrDrawing();
  138. DrawFPS(10, 10);
  139. EndDrawing();
  140. //----------------------------------------------------------------------------------
  141. }
  142. // De-Initialization
  143. //--------------------------------------------------------------------------------------
  144. if (vrDeviceReady) CloseOculusDevice();
  145. else CloseVrSimulator();
  146. CloseWindow(); // Close window and OpenGL context
  147. //--------------------------------------------------------------------------------------
  148. return 0;
  149. }
  150. //----------------------------------------------------------------------------------
  151. // Module specific Functions Definition
  152. //----------------------------------------------------------------------------------
  153. #if defined(RLGL_OCULUS_SUPPORT)
  154. // Set internal projection and modelview matrix depending on eyes tracking data
  155. static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView)
  156. {
  157. Matrix eyeProjection = matProjection;
  158. Matrix eyeModelView = matModelView;
  159. glViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y,
  160. layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h);
  161. Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x,
  162. layer.eyeLayer.RenderPose[eye].Orientation.y,
  163. layer.eyeLayer.RenderPose[eye].Orientation.z,
  164. layer.eyeLayer.RenderPose[eye].Orientation.w };
  165. QuaternionInvert(&eyeRenderPose);
  166. Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose);
  167. Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x,
  168. -layer.eyeLayer.RenderPose[eye].Position.y,
  169. -layer.eyeLayer.RenderPose[eye].Position.z);
  170. Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement
  171. eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement
  172. eyeProjection = layer.eyeProjections[eye];
  173. }
  174. // Initialize Oculus device (returns true if success)
  175. static bool InitOculusDevice(void)
  176. {
  177. bool oculusReady = false;
  178. ovrResult result = ovr_Initialize(NULL);
  179. if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device");
  180. else
  181. {
  182. result = ovr_Create(&session, &luid);
  183. if (OVR_FAILURE(result))
  184. {
  185. TraceLog(WARNING, "OVR: Could not create Oculus session");
  186. ovr_Shutdown();
  187. }
  188. else
  189. {
  190. hmdDesc = ovr_GetHmdDesc(session);
  191. TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName);
  192. TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer);
  193. TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId);
  194. TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type);
  195. //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber);
  196. TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
  197. // NOTE: Oculus mirror is set to defined screenWidth and screenHeight...
  198. // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2)
  199. // Initialize Oculus Buffers
  200. layer = InitOculusLayer(session);
  201. buffer = LoadOculusBuffer(session, layer.width, layer.height);
  202. mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded...
  203. layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
  204. // Recenter OVR tracking origin
  205. ovr_RecenterTrackingOrigin(session);
  206. oculusReady = true;
  207. }
  208. }
  209. return oculusReady;
  210. }
  211. // Close Oculus device (and unload buffers)
  212. static void CloseOculusDevice(void)
  213. {
  214. UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
  215. UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
  216. ovr_Destroy(session); // Free Oculus session data
  217. ovr_Shutdown(); // Close Oculus device connection
  218. }
  219. // Update Oculus head position-orientation tracking
  220. static void UpdateOculusTracking(Camera *camera)
  221. {
  222. frameIndex++;
  223. ovrPosef eyePoses[2];
  224. ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime);
  225. layer.eyeLayer.RenderPose[0] = eyePoses[0];
  226. layer.eyeLayer.RenderPose[1] = eyePoses[1];
  227. // TODO: Update external camera with eyePoses data (position, orientation)
  228. // NOTE: We can simplify to simple camera if we consider IPD and HMD device configuration again later
  229. // it will be useful for the user to draw, lets say, billboards oriented to camera
  230. // Get session status information
  231. ovrSessionStatus sessionStatus;
  232. ovr_GetSessionStatus(session, &sessionStatus);
  233. if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit...");
  234. if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
  235. //if (sessionStatus.HmdPresent) // HMD is present.
  236. //if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR.
  237. //if (sessionStatus.HmdMounted) // HMD is on the user's head.
  238. //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD.
  239. }
  240. // Setup Oculus buffers for drawing
  241. static void BeginOculusDrawing(void)
  242. {
  243. GLuint currentTexId;
  244. int currentIndex;
  245. ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, &currentIndex);
  246. ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, &currentTexId);
  247. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
  248. glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
  249. //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded
  250. }
  251. // Finish Oculus drawing and blit framebuffer to mirror
  252. static void EndOculusDrawing(void)
  253. {
  254. // Unbind current framebuffer (Oculus buffer)
  255. glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
  256. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
  257. ovr_CommitTextureSwapChain(session, buffer.textureChain);
  258. ovrLayerHeader *layers = &layer.eyeLayer.Header;
  259. ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1);
  260. // Blit mirror texture to back buffer
  261. BlitOculusMirror(session, mirror);
  262. }
  263. // Load Oculus required buffers: texture-swap-chain, fbo, texture-depth
  264. static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height)
  265. {
  266. OculusBuffer buffer;
  267. buffer.width = width;
  268. buffer.height = height;
  269. // Create OVR texture chain
  270. ovrTextureSwapChainDesc desc = {};
  271. desc.Type = ovrTexture_2D;
  272. desc.ArraySize = 1;
  273. desc.Width = width;
  274. desc.Height = height;
  275. desc.MipLevels = 1;
  276. desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; // Requires glEnable(GL_FRAMEBUFFER_SRGB);
  277. desc.SampleCount = 1;
  278. desc.StaticImage = ovrFalse;
  279. ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain);
  280. if (!OVR_SUCCESS(result)) TraceLog(WARNING, "OVR: Failed to create swap textures buffer");
  281. int textureCount = 0;
  282. ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount);
  283. if (!OVR_SUCCESS(result) || !textureCount) TraceLog(WARNING, "OVR: Unable to count swap chain textures");
  284. for (int i = 0; i < textureCount; ++i)
  285. {
  286. GLuint chainTexId;
  287. ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, i, &chainTexId);
  288. glBindTexture(GL_TEXTURE_2D, chainTexId);
  289. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  290. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  291. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  292. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  293. }
  294. glBindTexture(GL_TEXTURE_2D, 0);
  295. /*
  296. // Setup framebuffer object (using depth texture)
  297. glGenFramebuffers(1, &buffer.fboId);
  298. glGenTextures(1, &buffer.depthId);
  299. glBindTexture(GL_TEXTURE_2D, buffer.depthId);
  300. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  301. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  302. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  303. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  304. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
  305. */
  306. // Setup framebuffer object (using depth renderbuffer)
  307. glGenFramebuffers(1, &buffer.fboId);
  308. glGenRenderbuffers(1, &buffer.depthId);
  309. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
  310. glBindRenderbuffer(GL_RENDERBUFFER, buffer.depthId);
  311. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, buffer.width, buffer.height);
  312. glBindRenderbuffer(GL_RENDERBUFFER, 0);
  313. glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer.depthId);
  314. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
  315. return buffer;
  316. }
  317. // Unload texture required buffers
  318. static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer)
  319. {
  320. if (buffer.textureChain)
  321. {
  322. ovr_DestroyTextureSwapChain(session, buffer.textureChain);
  323. buffer.textureChain = NULL;
  324. }
  325. if (buffer.depthId != 0) glDeleteTextures(1, &buffer.depthId);
  326. if (buffer.fboId != 0) glDeleteFramebuffers(1, &buffer.fboId);
  327. }
  328. // Load Oculus mirror buffers
  329. static OculusMirror LoadOculusMirror(ovrSession session, int width, int height)
  330. {
  331. OculusMirror mirror;
  332. mirror.width = width;
  333. mirror.height = height;
  334. ovrMirrorTextureDesc mirrorDesc;
  335. memset(&mirrorDesc, 0, sizeof(mirrorDesc));
  336. mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
  337. mirrorDesc.Width = mirror.width;
  338. mirrorDesc.Height = mirror.height;
  339. if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(WARNING, "Could not create mirror texture");
  340. glGenFramebuffers(1, &mirror.fboId);
  341. return mirror;
  342. }
  343. // Unload Oculus mirror buffers
  344. static void UnloadOculusMirror(ovrSession session, OculusMirror mirror)
  345. {
  346. if (mirror.fboId != 0) glDeleteFramebuffers(1, &mirror.fboId);
  347. if (mirror.texture) ovr_DestroyMirrorTexture(session, mirror.texture);
  348. }
  349. // Copy Oculus screen buffer to mirror texture
  350. static void BlitOculusMirror(ovrSession session, OculusMirror mirror)
  351. {
  352. GLuint mirrorTextureId;
  353. ovr_GetMirrorTextureBufferGL(session, mirror.texture, &mirrorTextureId);
  354. glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId);
  355. glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0);
  356. #if defined(GRAPHICS_API_OPENGL_33)
  357. // NOTE: glBlitFramebuffer() requires extension: GL_EXT_framebuffer_blit (not available in OpenGL ES 2.0)
  358. glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
  359. #endif
  360. glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  361. }
  362. // Init Oculus layer (similar to photoshop)
  363. static OculusLayer InitOculusLayer(ovrSession session)
  364. {
  365. OculusLayer layer = { 0 };
  366. layer.viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
  367. memset(&layer.eyeLayer, 0, sizeof(ovrLayerEyeFov));
  368. layer.eyeLayer.Header.Type = ovrLayerType_EyeFov;
  369. layer.eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
  370. ovrEyeRenderDesc eyeRenderDescs[2];
  371. for (int eye = 0; eye < 2; eye++)
  372. {
  373. eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]);
  374. ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(eyeRenderDescs[eye].Fov, 0.01f, 10000.0f, ovrProjection_None); //ovrProjection_ClipRangeOpenGL);
  375. layer.eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection); // NOTE: struct ovrMatrix4f { float M[4][4] } --> struct Matrix
  376. layer.viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset;
  377. layer.eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov;
  378. ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, layer.eyeLayer.Fov[eye], 1.0f);
  379. layer.eyeLayer.Viewport[eye].Size = eyeSize;
  380. layer.eyeLayer.Viewport[eye].Pos.x = layer.width;
  381. layer.eyeLayer.Viewport[eye].Pos.y = 0;
  382. layer.height = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h);
  383. layer.width += eyeSize.w;
  384. }
  385. return layer;
  386. }
  387. // Convert from Oculus ovrMatrix4f struct to raymath Matrix struct
  388. static Matrix FromOvrMatrix(ovrMatrix4f ovrmat)
  389. {
  390. Matrix rmat;
  391. rmat.m0 = ovrmat.M[0][0];
  392. rmat.m1 = ovrmat.M[1][0];
  393. rmat.m2 = ovrmat.M[2][0];
  394. rmat.m3 = ovrmat.M[3][0];
  395. rmat.m4 = ovrmat.M[0][1];
  396. rmat.m5 = ovrmat.M[1][1];
  397. rmat.m6 = ovrmat.M[2][1];
  398. rmat.m7 = ovrmat.M[3][1];
  399. rmat.m8 = ovrmat.M[0][2];
  400. rmat.m9 = ovrmat.M[1][2];
  401. rmat.m10 = ovrmat.M[2][2];
  402. rmat.m11 = ovrmat.M[3][2];
  403. rmat.m12 = ovrmat.M[0][3];
  404. rmat.m13 = ovrmat.M[1][3];
  405. rmat.m14 = ovrmat.M[2][3];
  406. rmat.m15 = ovrmat.M[3][3];
  407. MatrixTranspose(&rmat);
  408. return rmat;
  409. }
  410. #endif
  411. // Output a trace log message
  412. // NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
  413. static void TraceLog(int msgType, const char *text, ...)
  414. {
  415. va_list args;
  416. va_start(args, text);
  417. switch (msgType)
  418. {
  419. case INFO: fprintf(stdout, "INFO: "); break;
  420. case ERROR: fprintf(stdout, "ERROR: "); break;
  421. case WARNING: fprintf(stdout, "WARNING: "); break;
  422. case DEBUG: fprintf(stdout, "DEBUG: "); break;
  423. default: break;
  424. }
  425. vfprintf(stdout, text, args);
  426. fprintf(stdout, "\n");
  427. va_end(args);
  428. if (msgType == ERROR) exit(1);
  429. }