Browse Source

Compute stereo config from device parameters

Simulator configuration is directly obtained from VR device parameters!
Ray 9 years ago
parent
commit
24c267d324
1 changed files with 108 additions and 141 deletions
  1. 108 141
      src/rlgl.c

+ 108 - 141
src/rlgl.c

@@ -31,7 +31,7 @@
 #include <stdio.h>                  // Required for: fopen(), fclose(), fread()... [Used only on ReadTextFile()]
 #include <stdio.h>                  // Required for: fopen(), fclose(), fread()... [Used only on ReadTextFile()]
 #include <stdlib.h>                 // Required for: malloc(), free(), rand()
 #include <stdlib.h>                 // Required for: malloc(), free(), rand()
 #include <string.h>                 // Required for: strcmp(), strlen(), strtok()
 #include <string.h>                 // Required for: strcmp(), strlen(), strtok()
-#include <math.h>                   // Required for: atan()
+#include <math.h>                   // Required for: atan2()
 
 
 #ifndef RLGL_STANDALONE
 #ifndef RLGL_STANDALONE
     #include "raymath.h"            // Required for Vector3 and Matrix functions
     #include "raymath.h"            // Required for Vector3 and Matrix functions
@@ -206,6 +206,15 @@ typedef struct {
     float chromaAbCorrection[4];    // HMD chromatic aberration correction parameters
     float chromaAbCorrection[4];    // HMD chromatic aberration correction parameters
 } VrDeviceInfo;
 } VrDeviceInfo;
 
 
+// VR Stereo rendering configuration for simulator
+typedef struct {
+    RenderTexture2D stereoFbo;      // VR stereo rendering framebuffer
+    Shader distortionShader;        // VR stereo rendering distortion shader
+    //Rectangle eyesViewport[2];      // VR stereo rendering eyes viewports
+    Matrix eyesProjection[2];       // VR stereo rendering eyes projection matrices
+    Matrix eyesViewOffset[2];       // VR stereo rendering eyes view offset matrices
+} VrStereoConfig;
+
 #if defined(RLGL_OCULUS_SUPPORT)
 #if defined(RLGL_OCULUS_SUPPORT)
 typedef struct OculusBuffer {
 typedef struct OculusBuffer {
     ovrTextureSwapChain textureChain;
     ovrTextureSwapChain textureChain;
@@ -292,19 +301,15 @@ static OculusMirror mirror;             // Oculus mirror texture and fbo
 static unsigned int frameIndex = 0;     // Oculus frames counter, used to discard frames from chain
 static unsigned int frameIndex = 0;     // Oculus frames counter, used to discard frames from chain
 #endif
 #endif
 
 
+// VR global variables
+static VrDeviceInfo hmd;                // Current VR device info
+static VrStereoConfig vrConfig;         // VR stereo configuration for simulator
 static bool vrDeviceReady = false;      // VR device ready flag
 static bool vrDeviceReady = false;      // VR device ready flag
 static bool vrSimulator = false;        // VR simulator enabled flag
 static bool vrSimulator = false;        // VR simulator enabled flag
 static bool vrEnabled = false;          // VR experience enabled (device or simulator)
 static bool vrEnabled = false;          // VR experience enabled (device or simulator)
 static bool vrRendering = true;         // VR stereo rendering enabled/disabled flag
 static bool vrRendering = true;         // VR stereo rendering enabled/disabled flag
                                         // NOTE: This flag is useful to render data over stereo image (i.e. FPS)
                                         // NOTE: This flag is useful to render data over stereo image (i.e. FPS)
 
 
-static RenderTexture2D stereoFbo;       // Stereo rendering framebuffer
-static Shader distortionShader;         // Stereo rendering distortion shader (simulator)
-
-// Compressed textures support flags
-static bool texCompDXTSupported = false;    // DDS texture compression support
-static bool npotSupported = false;          // NPOT textures full support
-
 #if defined(GRAPHICS_API_OPENGL_ES2)
 #if defined(GRAPHICS_API_OPENGL_ES2)
 // NOTE: VAO functionality is exposed through extensions (OES)
 // NOTE: VAO functionality is exposed through extensions (OES)
 static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
 static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
@@ -313,6 +318,10 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
 //static PFNGLISVERTEXARRAYOESPROC glIsVertexArray;        // NOTE: Fails in WebGL, omitted
 //static PFNGLISVERTEXARRAYOESPROC glIsVertexArray;        // NOTE: Fails in WebGL, omitted
 #endif
 #endif
 
 
+// Compressed textures support flags
+static bool texCompDXTSupported = false;    // DDS texture compression support
+static bool npotSupported = false;          // NPOT textures full support
+
 static int blendMode = 0;   // Track current blending mode
 static int blendMode = 0;   // Track current blending mode
 
 
 // White texture useful for plain color polys (required by shader)
 // White texture useful for plain color polys (required by shader)
@@ -341,7 +350,7 @@ static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers
 static void UnloadDefaultBuffers(void);     // Unload default internal buffers vertex data from CPU and GPU
 static void UnloadDefaultBuffers(void);     // Unload default internal buffers vertex data from CPU and GPU
 
 
 // Configure stereo rendering (including distortion shader) with HMD device parameters
 // Configure stereo rendering (including distortion shader) with HMD device parameters
-static void SetupVrDevice(VrDeviceInfo info);
+static void SetStereoConfig(VrDeviceInfo info);
 
 
 // Set internal projection and modelview matrix depending on eyes tracking data
 // Set internal projection and modelview matrix depending on eyes tracking data
 static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView);
 static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView);
@@ -2535,6 +2544,7 @@ void DestroyLight(Light light)
 
 
 // Init VR device (or simulator)
 // Init VR device (or simulator)
 // NOTE: If device is not available, it fallbacks to default device (simulator)
 // NOTE: If device is not available, it fallbacks to default device (simulator)
+// NOTE: It modifies the global variable: VrDeviceInfo hmd
 void InitVrDevice(int hmdDevice)
 void InitVrDevice(int hmdDevice)
 {
 {
     switch (hmdDevice)
     switch (hmdDevice)
@@ -2560,40 +2570,39 @@ void InitVrDevice(int hmdDevice)
 
 
     if (!vrDeviceReady)
     if (!vrDeviceReady)
     {
     {
-        TraceLog(WARNING, "VR Device not found: Initializing VR Simulator");
+        TraceLog(WARNING, "VR Device not found: Initializing VR Simulator (Oculus Rift DK2)");
 
 
         // Initialize framebuffer and textures for stereo rendering
         // Initialize framebuffer and textures for stereo rendering
-        stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight);
+        vrConfig.stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight);
         
         
         // Load distortion shader (initialized by default with Oculus Rift CV1 parameters)
         // Load distortion shader (initialized by default with Oculus Rift CV1 parameters)
-        distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr);
-        if (distortionShader.id != 0) LoadDefaultShaderLocations(&distortionShader);
-        
-        VrDeviceInfo info = { 0 };
-        
+        vrConfig.distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr);
+        if (vrConfig.distortionShader.id != 0) LoadDefaultShaderLocations(&vrConfig.distortionShader);
+
         if ((hmdDevice == HMD_DEFAULT_DEVICE) || 
         if ((hmdDevice == HMD_DEFAULT_DEVICE) || 
             (hmdDevice == HMD_OCULUS_RIFT_DK2) || 
             (hmdDevice == HMD_OCULUS_RIFT_DK2) || 
             (hmdDevice == HMD_OCULUS_RIFT_CV1))
             (hmdDevice == HMD_OCULUS_RIFT_CV1))
         {
         {
-            info.hResolution = 1280;                // HMD horizontal resolution in pixels
-            info.vResolution = 800;                 // HMD vertical resolution in pixels
-            info.hScreenSize = 0.14976f;;           // HMD horizontal size in meters
-            info.vScreenSize = 0.09356f;            // HMD vertical size in meters
-            info.vScreenCenter = 0.04675f;          // HMD screen center in meters
-            info.eyeToScreenDistance = 0.041f;      // HMD distance between eye and display in meters
-            info.lensSeparationDistance = 0.0635f;  // HMD lens separation distance in meters
-            info.interpupillaryDistance = 0.064f;   // HMD IPD (distance between pupils) in meters
-            info.distortionK[0] = 1.0f;             // HMD lens distortion constant parameter 0
-            info.distortionK[1] = 0.22f;            // HMD lens distortion constant parameter 1
-            info.distortionK[2] = 0.24f;            // HMD lens distortion constant parameter 2
-            info.distortionK[3] = 0.0f;             // HMD lens distortion constant parameter 3
-            info.chromaAbCorrection[0] = 0.996f;    // HMD chromatic aberration correction parameter 0
-            info.chromaAbCorrection[1] = -0.004f;   // HMD chromatic aberration correction parameter 1
-            info.chromaAbCorrection[2] = 1.014f;    // HMD chromatic aberration correction parameter 2
-            info.chromaAbCorrection[3] = 0.0f;      // HMD chromatic aberration correction parameter 3
+            // NOTE: Oculus Rift DK2 parameters
+            hmd.hResolution = 1280;                // HMD horizontal resolution in pixels
+            hmd.vResolution = 800;                 // HMD vertical resolution in pixels
+            hmd.hScreenSize = 0.14976f;;           // HMD horizontal size in meters
+            hmd.vScreenSize = 0.09356f;            // HMD vertical size in meters
+            hmd.vScreenCenter = 0.04675f;          // HMD screen center in meters
+            hmd.eyeToScreenDistance = 0.041f;      // HMD distance between eye and display in meters
+            hmd.lensSeparationDistance = 0.0635f;  // HMD lens separation distance in meters
+            hmd.interpupillaryDistance = 0.064f;   // HMD IPD (distance between pupils) in meters
+            hmd.distortionK[0] = 1.0f;             // HMD lens distortion constant parameter 0
+            hmd.distortionK[1] = 0.22f;            // HMD lens distortion constant parameter 1
+            hmd.distortionK[2] = 0.24f;            // HMD lens distortion constant parameter 2
+            hmd.distortionK[3] = 0.0f;             // HMD lens distortion constant parameter 3
+            hmd.chromaAbCorrection[0] = 0.996f;    // HMD chromatic aberration correction parameter 0
+            hmd.chromaAbCorrection[1] = -0.004f;   // HMD chromatic aberration correction parameter 1
+            hmd.chromaAbCorrection[2] = 1.014f;    // HMD chromatic aberration correction parameter 2
+            hmd.chromaAbCorrection[3] = 0.0f;      // HMD chromatic aberration correction parameter 3
         }
         }
 
 
-        SetupVrDevice(info);
+        SetStereoConfig(hmd);
         
         
         vrSimulator = true;
         vrSimulator = true;
         vrEnabled = true;
         vrEnabled = true;
@@ -2608,11 +2617,8 @@ void CloseVrDevice(void)
     else
     else
 #endif
 #endif
     {
     {
-        // Unload stereo framebuffer and texture
-        rlDeleteRenderTextures(stereoFbo);
-        
-        // Unload oculus-distortion shader
-        UnloadShader(distortionShader);
+        rlDeleteRenderTextures(vrConfig.stereoFbo); // Unload stereo framebuffer and texture
+        UnloadShader(vrConfig.distortionShader);    // Unload distortion shader
     }
     }
     
     
     vrDeviceReady = false;
     vrDeviceReady = false;
@@ -2654,7 +2660,7 @@ void BeginVrDrawing(void)
 #endif
 #endif
     {
     {
         // Setup framebuffer for stereo rendering
         // Setup framebuffer for stereo rendering
-        rlEnableRenderTexture(stereoFbo.id);
+        rlEnableRenderTexture(vrConfig.stereoFbo.id);
     }
     }
 
 
     // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) 
     // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) 
@@ -2696,9 +2702,9 @@ void EndVrDrawing(void)
         rlLoadIdentity();                                       // Reset internal modelview matrix
         rlLoadIdentity();                                       // Reset internal modelview matrix
 
 
         // Draw RenderTexture (stereoFbo) using distortion shader 
         // Draw RenderTexture (stereoFbo) using distortion shader 
-        currentShader = distortionShader;
+        currentShader = vrConfig.distortionShader;
 
 
-        rlEnableTexture(stereoFbo.texture.id);
+        rlEnableTexture(vrConfig.stereoFbo.texture.id);
 
 
         rlPushMatrix();
         rlPushMatrix();
             rlBegin(RL_QUADS);
             rlBegin(RL_QUADS);
@@ -2711,15 +2717,15 @@ void EndVrDrawing(void)
 
 
                 // Bottom-right corner for texture and quad
                 // Bottom-right corner for texture and quad
                 rlTexCoord2f(0.0f, 0.0f);
                 rlTexCoord2f(0.0f, 0.0f);
-                rlVertex2f(0.0f, stereoFbo.texture.height);
+                rlVertex2f(0.0f, vrConfig.stereoFbo.texture.height);
 
 
                 // Top-right corner for texture and quad
                 // Top-right corner for texture and quad
                 rlTexCoord2f(1.0f, 0.0f);
                 rlTexCoord2f(1.0f, 0.0f);
-                rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height);
+                rlVertex2f(vrConfig.stereoFbo.texture.width, vrConfig.stereoFbo.texture.height);
 
 
                 // Top-left corner for texture and quad
                 // Top-left corner for texture and quad
                 rlTexCoord2f(1.0f, 1.0f);
                 rlTexCoord2f(1.0f, 1.0f);
-                rlVertex2f(stereoFbo.texture.width, 0.0f);
+                rlVertex2f(vrConfig.stereoFbo.texture.width, 0.0f);
             rlEnd();
             rlEnd();
         rlPopMatrix();
         rlPopMatrix();
 
 
@@ -3752,61 +3758,71 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight)
 #endif
 #endif
 
 
 // Configure stereo rendering (including distortion shader) with HMD device parameters
 // Configure stereo rendering (including distortion shader) with HMD device parameters
-static void SetupVrDevice(VrDeviceInfo hmd)
+static void SetStereoConfig(VrDeviceInfo hmd)
 {
 {
-            // NOTE: fovy value obtained from device parameters (Oculus Rift CV1)
-            //float fovy = 2.0f*atan((VScreenSize*0.5f)/EyeToScreenDistance)*RAD2DEG;
-
-            //float eyeProjectionShift = ;
-            //float projectionOffset = (HScreenSize*0.25f - LensSeparationDistance*0.5f)/(float)HScreenSize;
-
-    // Compute aspect ratio and FOV
-    //float aspect = ((float)hmd.hResolution/2.0f)/(float)hmd.vResolution;
+    // Compute aspect ratio
+    //float aspect = ((float)hmd.hResolution*0.5f)/(float)hmd.vResolution;
     float aspect = (float)screenWidth*0.5f/(float)screenHeight;
     float aspect = (float)screenWidth*0.5f/(float)screenHeight;
-
-    // Fov-y is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)*RAD2DEG
+    
+    // Compute lens parameters
+    float lensShift = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize;
+    float leftLensCenter[2] = { 0.25 + lensShift, 0.5f };
+    float rightLensCenter[2] = { 0.75 - lensShift, 0.5f };
+    float leftScreenCenter[2] = { 0.25f, 0.5f };
+    float rightScreenCenter[2] = { 0.75f, 0.5f };
+    
+    // Compute distortion scale parameters
+    // NOTE: To get lens max radius, lensShift must be normalized to [-1..1]
+    float lensRadius = fabsf(-1.0f - 4.0f*lensShift);
+    float lensRadiusSq = lensRadius*lensRadius;
+    float distortionScale = hmd.distortionK[0] + 
+                            hmd.distortionK[1]*lensRadiusSq + 
+                            hmd.distortionK[2]*lensRadiusSq*lensRadiusSq + 
+                            hmd.distortionK[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq;
+
+    float normScreenWidth = 0.5f;
+    float normScreenHeight = 1.0f;
+    float scaleIn[2] = { 2/normScreenWidth, 2/normScreenHeight/aspect };
+    float scale[2] = { normScreenWidth*0.5/distortionScale, normScreenHeight*0.5*aspect/distortionScale };
+    
+    // Update distortion shader with lens and distortion-scale parameters
+    SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftLensCenter"), leftLensCenter, 2);
+    SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightLensCenter"), rightLensCenter, 2);
+    SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftScreenCenter"), leftScreenCenter, 2);
+    SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightScreenCenter"), rightScreenCenter, 2);
+    
+    SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scale"), scale, 2);
+    SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scaleIn"), scaleIn, 2);
+    SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "hmdWarpParam"), hmd.distortionK, 4);
+    SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, 4);
+
+    // Fovy is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)*RAD2DEG
     // ...but with lens distortion it is increased (see Oculus SDK Documentation)
     // ...but with lens distortion it is increased (see Oculus SDK Documentation)
-    float radius = -1.0 - (4*(hmd.hScreenSize/4 - hmd.lensSeparationDistance/2)/hmd.hScreenSize);
-    float distScale = (hmd.distortionK[0] + hmd.distortionK[1]*pow(radius, 2) + hmd.distortionK[2]*pow(radius, 4) + hmd.distortionK[3]*pow(radius, 6));
-    //float fovy = 2.0f*atan2(hmd.vScreenSize*distScale, 2*hmd.eyeToScreenDistance)*RAD2DEG;
-    float fovy = 2.0f*atan((hmd.vScreenSize*0.5f)/hmd.eyeToScreenDistance)*RAD2DEG;
+    float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance)*RAD2DEG;     // Really need distortionScale?
 
 
     // Compute camera projection matrices
     // Compute camera projection matrices
+    float projOffset = 4.0f*lensShift;      // Scaled to projection space coordinates [-1..1]
     Matrix proj = MatrixPerspective(fovy, aspect, 0.01, 1000.0);
     Matrix proj = MatrixPerspective(fovy, aspect, 0.01, 1000.0);
-    //float projOffset = 4.0f*(hmd.hScreenSize/4 - hmd.interpupillaryDistance/2)/hmd.hScreenSize;
-    float projOffset = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize;
+    vrConfig.eyesProjection[0] = MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f));
+    vrConfig.eyesProjection[1] = MatrixMultiply(proj, MatrixTranslate(-projOffset, 0.0f, 0.0f));
+    
+    // NOTE: Projection matrices must be transposed due to raymath convention
+    MatrixTranspose(&vrConfig.eyesProjection[0]);
+    MatrixTranspose(&vrConfig.eyesProjection[1]);
     
     
-    //Matrix projLeft = MatrixMultiply(MatrixTranslate(projOffset, 0.0, 0.0), proj);
-    //matrix projRight = MatrixMultiply(MatrixTranslate(-projOffset, 0.0, 0.0)), proj);
-
     // Compute camera transformation matrices
     // Compute camera transformation matrices
-    //Matrix viewTransformLeft = MatrixTranslate(-hmd.interpupillaryDistance/2, 0.0, 0.0 );
-    //Matrix viewTransformRight = MatrixTranslate(hmd.interpupillaryDistance/2, 0.0, 0.0 );
-
-    // Compute eyes Viewports
-    // Rectangle viewportLeft = { 0, 0, hmd.hResolution/2, hmd.vResolution };
-    // Rectangle viewportRight = { hmd.hResolution/2, 0, hmd.hResolution/2, hmd.vResolution };
-
-    // Distortion shader parameters
-    float lensShift = 4*(hmd.hScreenSize/4 - hmd.lensSeparationDistance/2)/hmd.hScreenSize;
-    float leftLensCenter[2] = { lensShift, 0.0f };                  // REVIEW!!!
-    float rightLensCenter[2] = { -lensShift, 0.0f };                // REVIEW!!!
-    float leftScreenCenter[2] = { 0.25f, 0.5f };
-    float rightScreenCenter[2] = { 0.75f, 0.5f };
+    // NOTE: Camera movement might seem more natural if we model the head. 
+    // Our axis of rotation is the base of our head, so we might want to add 
+    // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions.
+    vrConfig.eyesViewOffset[0] = MatrixTranslate(-hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
+    vrConfig.eyesViewOffset[1] = MatrixTranslate(hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
     
     
-    float scaleIn[2] = { 1.0f, 1.0f/aspect };                       // REVIEW!!!
-    float scale[2] = { 1.0f/distScale, 1.0f*aspect/distScale };     // REVIEW!!!
-
-    // Distortion shader parameters update
-    //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "leftLensCenter"), leftLensCenter, 2);
-    //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "rightLensCenter"), rightLensCenter, 2);
-    SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "leftScreenCenter"), leftScreenCenter, 2);
-    SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "rightScreenCenter"), rightScreenCenter, 2);
+    // Compute eyes Viewports
+    //vrConfig.eyesViewport[0] = (Rectangle){ 0, 0, hmd.hResolution/2, hmd.vResolution };
+    //vrConfig.eyesViewport[1] = (Rectangle){ hmd.hResolution/2, 0, hmd.hResolution/2, hmd.vResolution };
     
     
-    //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scale"), scale, 2);
-    //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scaleIn"), scaleIn, 2);
-    SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "hmdWarpParam"), hmd.distortionK, 4);
-    SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, 4);
+    //https://forums.oculus.com/vip/discussion/3413/calculating-the-distortion-shader-parameters
+    //https://vrwiki.wikispaces.com/Theory+%26+practice
 }
 }
 
 
 // Set internal projection and modelview matrix depending on eyes tracking data
 // Set internal projection and modelview matrix depending on eyes tracking data
@@ -3844,59 +3860,10 @@ static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView)
             // Setup viewport and projection/modelview matrices using tracking data
             // Setup viewport and projection/modelview matrices using tracking data
             rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight);
             rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight);
 
 
-            float HScreenSize = 0.14976f;
-            float VScreenSize = 0.09356f;           // HScreenSize/(1280.0f/800.0f) (DK2)
-            float VScreenCenter = 0.04675f;         // VScreenSize/2
-            float EyeToScreenDistance = 0.041f;
-            float LensSeparationDistance = 0.0635f; // DK2
-            float InterpupillaryDistance = 0.064f;  // IPD
-            
-            // NOTE: fovy value obtained from device parameters (Oculus Rift CV1)
-            float halfScreenDistance = VScreenSize/2.0f;
-            float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG;
-
-            float viewCenter = (float)HScreenSize*0.25f;
-            float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f;
-            float projectionCenterOffset = eyeProjectionShift/(float)HScreenSize;   //4.0f*eyeProjectionShift/(float)HScreenSize;
-/*            
-            static float scale[2] = { 0.25, 0.45 };
-
-            if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01;
-            else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01;
-            else if (IsKeyDown(KEY_UP)) scale[1] += 0.01;
-            else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01;
-            
-            SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2);
-
-            if (IsKeyDown(KEY_N)) IPD += 0.02;
-            else if (IsKeyDown(KEY_M)) IPD -= 0.02;
-*/            
-            // The matrixes for offsetting the projection and view for each eye, to achieve stereo effect
-            Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f };
-            
-            // Camera movement might seem more natural if we model the head. 
-            // Our axis of rotation is the base of our head, so we might want to add 
-            // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions.
-            Vector3 viewOffset = { -InterpupillaryDistance/2.0f, 0.075f, 0.045f };
-
-            // Negate the left eye versions
-            if (eye == 0)
-            {
-                projectionOffset.x *= -1.0f;
-                viewOffset.x *= -1.0f;
-            }
-
-            // Adjust the view and projection matrixes
-            // View matrix is translated based on the eye offset
-            Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0);
-
-            Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z);
-            Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z);
-
-            eyeProjection = MatrixMultiply(projCenter, projTranslation);    // projection
-            eyeModelView = MatrixMultiply(matModelView, viewTranslation);   // modelview
+            // Apply view offset to modelview matrix
+            eyeModelView = MatrixMultiply(matModelView, vrConfig.eyesViewOffset[eye]);
             
             
-            MatrixTranspose(&eyeProjection);
+            eyeProjection = vrConfig.eyesProjection[eye];
         }
         }
 
 
         SetMatrixModelview(eyeModelView);
         SetMatrixModelview(eyeModelView);