Преглед на файлове

Review VR simulator mechanism

- No default VR device parameteres inside raylib
- VR device parameter should be provided by user
- VR distortion shader should be provided by user
Ray преди 6 години
родител
ревизия
5bfa675350
променени са 5 файла, в които са добавени 201 реда и са изтрити 326 реда
  1. 34 4
      examples/core/core_vr_simulator.c
  2. 43 0
      examples/core/resources/distortion.fs
  3. 0 2
      src/config.h
  4. 5 25
      src/raylib.h
  5. 119 295
      src/rlgl.h

+ 34 - 4
examples/core/core_vr_simulator.c

@@ -23,7 +23,35 @@ int main()
     InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator");
 
     // Init VR simulator (Oculus Rift CV1 parameters)
-    InitVrSimulator(GetVrDeviceInfo(HMD_OCULUS_RIFT_CV1));
+    InitVrSimulator();
+
+    VrDeviceInfo hmd = { 0 };               // VR device parameters (head-mounted-device)
+    
+    // Oculus Rift CV1 parameters for simulator
+    hmd.hResolution = 2160;                 // HMD horizontal resolution in pixels
+    hmd.vResolution = 1200;                 // HMD vertical resolution in pixels
+    hmd.hScreenSize = 0.133793f;            // HMD horizontal size in meters
+    hmd.vScreenSize = 0.0669f;              // HMD vertical size in meters
+    hmd.vScreenCenter = 0.04678f;           // HMD screen center in meters
+    hmd.eyeToScreenDistance = 0.041f;       // HMD distance between eye and display in meters
+    hmd.lensSeparationDistance = 0.07f;     // HMD lens separation distance in meters
+    hmd.interpupillaryDistance = 0.07f;     // HMD IPD (distance between pupils) in meters
+    
+    // NOTE: CV1 uses a Fresnel-hybrid-asymmetric lenses with specific distortion compute shaders.
+    // Following parameters are an approximation to distortion stereo rendering but results differ from actual device.
+    hmd.lensDistortionValues[0] = 1.0f;     // HMD lens distortion constant parameter 0
+    hmd.lensDistortionValues[1] = 0.22f;    // HMD lens distortion constant parameter 1
+    hmd.lensDistortionValues[2] = 0.24f;    // HMD lens distortion constant parameter 2
+    hmd.lensDistortionValues[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
+    
+    // Distortion shader (uses device lens distortion and chroma)
+    Shader distortion = LoadShader(0, "resources/distortion.fs");
+    
+    SetVrConfiguration(hmd, distortion);    // Set Vr device parameters for stereo rendering
     
     // Define the camera to look into our 3d world
     Camera camera;
@@ -77,9 +105,11 @@ int main()
 
     // De-Initialization
     //--------------------------------------------------------------------------------------
-    CloseVrSimulator();     // Close VR simulator
-    
-    CloseWindow();          // Close window and OpenGL context
+    UnloadShader(distortion);   // Unload distortion shader
+
+    CloseVrSimulator();         // Close VR simulator
+
+    CloseWindow();              // Close window and OpenGL context
     //--------------------------------------------------------------------------------------
 
     return 0;

+ 43 - 0
examples/core/resources/distortion.fs

@@ -0,0 +1,43 @@
+#version 330
+
+in vec2 fragTexCoord;
+in vec4 fragColor;
+out vec4 finalColor;
+
+uniform sampler2D texture0;
+uniform vec2 leftLensCenter = vec2(0.288, 0.5);
+uniform vec2 rightLensCenter = vec2(0.712, 0.5);
+uniform vec2 leftScreenCenter = vec2(0.25, 0.5);
+uniform vec2 rightScreenCenter = vec2(0.75, 0.5);
+uniform vec2 scale = vec2(0.25, 0.45);
+uniform vec2 scaleIn = vec2(4, 2.2222);
+uniform vec4 hmdWarpParam = vec4(1, 0.22, 0.24, 0);
+uniform vec4 chromaAbParam = vec4(0.996, -0.004, 1.014, 0.0);
+
+void main()
+{
+    vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter;
+    vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter;
+    vec2 theta = (fragTexCoord - lensCenter)*scaleIn;
+    float rSq = theta.x*theta.x + theta.y*theta.y;
+    vec2 theta1 = theta*(hmdWarpParam.x + hmdWarpParam.y*rSq + hmdWarpParam.z*rSq*rSq + hmdWarpParam.w*rSq*rSq*rSq);
+    vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq);
+    vec2 tcBlue = lensCenter + scale*thetaBlue;
+
+    if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue)))
+    {
+        finalColor = vec4(0.0, 0.0, 0.0, 1.0);
+    }
+    else
+    {
+        float blue = texture(texture0, tcBlue).b;
+        vec2 tcGreen = lensCenter + scale*theta1;
+        float green = texture(texture0, tcGreen).g;
+
+        vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq);
+        vec2 tcRed = lensCenter + scale*thetaRed;
+
+        float red = texture(texture0, tcRed).r;
+        finalColor = vec4(red, green, blue, 1.0);
+    }
+};

+ 0 - 2
src/config.h

@@ -57,8 +57,6 @@
 //------------------------------------------------------------------------------------
 // Support VR simulation functionality (stereo rendering)
 #define SUPPORT_VR_SIMULATOR        1
-// Include stereo rendering distortion shader (shader_distortion.h)
-#define SUPPORT_DISTORTION_SHADER   1
 
 
 //------------------------------------------------------------------------------------

+ 5 - 25
src/raylib.h

@@ -443,16 +443,6 @@ typedef struct VrDeviceInfo {
     float chromaAbCorrection[4];    // HMD chromatic aberration correction parameters
 } VrDeviceInfo;
 
-// VR Stereo rendering configuration for simulator
-typedef struct VrStereoConfig {
-    RenderTexture2D stereoFbo;      // VR stereo rendering framebuffer
-    Shader distortionShader;        // VR stereo rendering distortion shader
-    Matrix eyesProjection[2];       // VR stereo rendering eyes projection matrices
-    Matrix eyesViewOffset[2];       // VR stereo rendering eyes view offset matrices
-    int eyeViewportRight[4];        // VR stereo rendering right eye viewport [x, y, w, h]
-    int eyeViewportLeft[4];         // VR stereo rendering left eye viewport [x, y, w, h]
-} VrStereoConfig;
-
 //----------------------------------------------------------------------------------
 // Enumerators Definition
 //----------------------------------------------------------------------------------
@@ -860,16 +850,6 @@ typedef enum {
     CAMERA_ORTHOGRAPHIC
 } CameraType;
 
-// Head Mounted Display devices
-typedef enum {
-    HMD_DEFAULT_DEVICE = 0,
-    HMD_OCULUS_RIFT_DK2,
-    HMD_OCULUS_RIFT_CV1,
-    HMD_OCULUS_GO,
-    HMD_VALVE_HTC_VIVE,
-    HMD_SONY_PSVR
-} VrDeviceType;
-
 // Type of n-patch
 typedef enum {
     NPT_9PATCH = 0,         // Npatch defined by 3x3 tiles
@@ -1330,7 +1310,7 @@ RLAPI Shader GetShaderDefault(void);                                      // Get
 RLAPI Texture2D GetTextureDefault(void);                                  // Get default texture
 
 // Shader configuration functions
-RLAPI int GetShaderLocation(Shader shader, const char *uniformName);              // Get shader uniform location
+RLAPI int GetShaderLocation(Shader shader, const char *uniformName);      // Get shader uniform location
 RLAPI void SetShaderValue(Shader shader, int uniformLoc, const void *value, int uniformType);               // Set shader uniform value
 RLAPI void SetShaderValueV(Shader shader, int uniformLoc, const void *value, int uniformType, int count);   // Set shader uniform value vector
 RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat);         // Set shader uniform value (matrix 4x4)
@@ -1344,7 +1324,7 @@ RLAPI Matrix GetMatrixModelview();                                        // Get
 RLAPI Texture2D GenTextureCubemap(Shader shader, Texture2D skyHDR, int size);       // Generate cubemap texture from HDR texture
 RLAPI Texture2D GenTextureIrradiance(Shader shader, Texture2D cubemap, int size);   // Generate irradiance texture using cubemap data
 RLAPI Texture2D GenTexturePrefilter(Shader shader, Texture2D cubemap, int size);    // Generate prefilter texture using cubemap data
-RLAPI Texture2D GenTextureBRDF(Shader shader, int size);                  // Generate BRDF texture using cubemap data
+RLAPI Texture2D GenTextureBRDF(Shader shader, int size);                  // Generate BRDF texture
 
 // Shading begin/end functions
 RLAPI void BeginShaderMode(Shader shader);                                // Begin custom shader drawing
@@ -1355,10 +1335,10 @@ RLAPI void BeginScissorMode(int x, int y, int width, int height);         // Beg
 RLAPI void EndScissorMode(void);                                          // End scissor mode
 
 // VR control functions
-RLAPI VrDeviceInfo GetVrDeviceInfo(int vrDeviceType);   // Get VR device information for some standard devices
-RLAPI void InitVrSimulator(VrDeviceInfo info);          // Init VR simulator for selected device parameters
-RLAPI void UpdateVrTracking(Camera *camera);            // Update VR tracking (position and orientation) and camera
+RLAPI void InitVrSimulator(void);                       // Init VR simulator for selected device parameters
 RLAPI void CloseVrSimulator(void);                      // Close VR simulator for current device
+RLAPI void UpdateVrTracking(Camera *camera);            // Update VR tracking (position and orientation) and camera
+RLAPI void SetVrConfiguration(VrDeviceInfo info, Shader distortion);      // Set stereo rendering configuration parameters 
 RLAPI bool IsVrSimulatorReady(void);                    // Detect if VR simulator is ready
 RLAPI void ToggleVrMode(void);                          // Enable/Disable VR experience
 RLAPI void BeginVrDrawing(void);                        // Begin VR simulator stereo rendering

+ 119 - 295
src/rlgl.h

@@ -32,9 +32,6 @@
 *   #define SUPPORT_VR_SIMULATOR
 *       Support VR simulation functionality (stereo rendering)
 *
-*   #define SUPPORT_DISTORTION_SHADER
-*       Include stereo rendering distortion shader (embedded)
-*
 *   DEPENDENCIES:
 *       raymath     - 3D math functionality (Vector3, Matrix, Quaternion)
 *       GLAD        - OpenGL extensions loading (OpenGL 3.3 Core only)
@@ -263,7 +260,6 @@ typedef unsigned char byte;
 
     // VR Stereo rendering configuration for simulator
     typedef struct VrStereoConfig {
-        RenderTexture2D stereoFbo;      // VR stereo rendering framebuffer
         Shader distortionShader;        // VR stereo rendering distortion shader
         Matrix eyesProjection[2];       // VR stereo rendering eyes projection matrices
         Matrix eyesViewOffset[2];       // VR stereo rendering eyes view offset matrices
@@ -390,16 +386,6 @@ typedef unsigned char byte;
 
     #define MAP_DIFFUSE      MAP_ALBEDO
     #define MAP_SPECULAR     MAP_METALNESS
-
-    // VR Head Mounted Display devices
-    typedef enum {
-        HMD_DEFAULT_DEVICE = 0,
-        HMD_OCULUS_RIFT_DK2,
-        HMD_OCULUS_RIFT_CV1,
-        HMD_OCULUS_GO,
-        HMD_VALVE_HTC_VIVE,
-        HMD_SONY_PSVR
-    } VrDevice;
 #endif
 
 #if defined(__cplusplus)
@@ -534,14 +520,14 @@ void BeginBlendMode(int mode);                    // Begin blending mode (alpha,
 void EndBlendMode(void);                          // End blending mode (reset to default: alpha blending)
 
 // VR control functions
-VrDeviceInfo GetVrDeviceInfo(int vrDeviceType);   // Get VR device information for some standard devices
-void InitVrSimulator(VrDeviceInfo info);          // Init VR simulator for selected device parameters
-void UpdateVrTracking(Camera *camera);            // Update VR tracking (position and orientation) and camera
-void CloseVrSimulator(void);                      // Close VR simulator for current device
-bool IsVrSimulatorReady(void);                    // Detect if VR simulator is ready
-void ToggleVrMode(void);                          // Enable/Disable VR experience
-void BeginVrDrawing(void);                        // Begin VR simulator stereo rendering
-void EndVrDrawing(void);                          // End VR simulator stereo rendering
+RLAPI void InitVrSimulator(void);                       // Init VR simulator for selected device parameters
+RLAPI void CloseVrSimulator(void);                      // Close VR simulator for current device
+RLAPI void UpdateVrTracking(Camera *camera);            // Update VR tracking (position and orientation) and camera
+RLAPI void SetVrConfiguration(VrDeviceInfo info, Shader distortion);      // Set stereo rendering configuration parameters 
+RLAPI bool IsVrSimulatorReady(void);                    // Detect if VR simulator is ready
+RLAPI void ToggleVrMode(void);                          // Enable/Disable VR experience
+RLAPI void BeginVrDrawing(void);                        // Begin VR simulator stereo rendering
+RLAPI void EndVrDrawing(void);                          // End VR simulator stereo rendering
 
 void TraceLog(int msgType, const char *text, ...);      // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
 int GetPixelDataSize(int width, int height, int format);// Get pixel data size in bytes (image or texture)
@@ -561,10 +547,7 @@ int GetPixelDataSize(int width, int height, int format);// Get pixel data size i
 
 #if defined(RLGL_IMPLEMENTATION)
 
-#if defined(RLGL_STANDALONE)
-    #define SUPPORT_VR_SIMULATOR
-    #define SUPPORT_DISTORTION_SHADER
-#else
+#if !defined(RLGL_STANDALONE)
     // Check if config flags have been externally provided on compilation line
     #if !defined(EXTERNAL_CONFIG_FLAGS)
         #include "config.h"         // Defines module configuration flags
@@ -740,88 +723,20 @@ typedef struct DrawCall {
     //Matrix modelview;         // Modelview matrix for this draw
 } DrawCall;
 
+#if defined(SUPPORT_VR_SIMULATOR)
+// VR Stereo rendering configuration for simulator
+typedef struct VrStereoConfig {
+    Shader distortionShader;        // VR stereo rendering distortion shader
+    Matrix eyesProjection[2];       // VR stereo rendering eyes projection matrices
+    Matrix eyesViewOffset[2];       // VR stereo rendering eyes view offset matrices
+    int eyeViewportRight[4];        // VR stereo rendering right eye viewport [x, y, w, h]
+    int eyeViewportLeft[4];         // VR stereo rendering left eye viewport [x, y, w, h]
+} VrStereoConfig;
+#endif
+
 //----------------------------------------------------------------------------------
 // Global Variables Definition
 //----------------------------------------------------------------------------------
-#if !defined(GRAPHICS_API_OPENGL_11) && defined(SUPPORT_DISTORTION_SHADER)
-    // Distortion shader embedded
-    static char distortionFShaderStr[] =
-    #if defined(GRAPHICS_API_OPENGL_21)
-    "#version 120                       \n"
-    #elif defined(GRAPHICS_API_OPENGL_ES2)
-    "#version 100                       \n"
-    "precision mediump float;           \n"     // precision required for OpenGL ES2 (WebGL)
-    #endif
-    #if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
-    "varying vec2 fragTexCoord;         \n"
-    "varying vec4 fragColor;            \n"
-    #elif defined(GRAPHICS_API_OPENGL_33)
-    "#version 330                       \n"
-    "in vec2 fragTexCoord;              \n"
-    "in vec4 fragColor;                 \n"
-    "out vec4 finalColor;               \n"
-    #endif
-    "uniform sampler2D texture0;                                     \n"
-    #if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
-    "uniform vec2 leftLensCenter;       \n"
-    "uniform vec2 rightLensCenter;      \n"
-    "uniform vec2 leftScreenCenter;     \n"
-    "uniform vec2 rightScreenCenter;    \n"
-    "uniform vec2 scale;                \n"
-    "uniform vec2 scaleIn;              \n"
-    "uniform vec4 hmdWarpParam;         \n"
-    "uniform vec4 chromaAbParam;        \n"
-    #elif defined(GRAPHICS_API_OPENGL_33)
-    "uniform vec2 leftLensCenter = vec2(0.288, 0.5);                 \n"
-    "uniform vec2 rightLensCenter = vec2(0.712, 0.5);                \n"
-    "uniform vec2 leftScreenCenter = vec2(0.25, 0.5);                \n"
-    "uniform vec2 rightScreenCenter = vec2(0.75, 0.5);               \n"
-    "uniform vec2 scale = vec2(0.25, 0.45);                          \n"
-    "uniform vec2 scaleIn = vec2(4, 2.2222);                         \n"
-    "uniform vec4 hmdWarpParam = vec4(1, 0.22, 0.24, 0);             \n"
-    "uniform vec4 chromaAbParam = vec4(0.996, -0.004, 1.014, 0.0);   \n"
-    #endif
-    "void main() \n"
-    "{ \n"
-    "   vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter; \n"
-    "   vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter; \n"
-    "   vec2 theta = (fragTexCoord - lensCenter)*scaleIn; \n"
-    "   float rSq = theta.x*theta.x + theta.y*theta.y; \n"
-    "   vec2 theta1 = theta*(hmdWarpParam.x + hmdWarpParam.y*rSq + hmdWarpParam.z*rSq*rSq + hmdWarpParam.w*rSq*rSq*rSq); \n"
-    "   vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq); \n"
-    "   vec2 tcBlue = lensCenter + scale*thetaBlue; \n"
-    "   if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue))) \n"
-    "   { \n"
-    #if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
-    "       gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); \n"
-    #elif defined(GRAPHICS_API_OPENGL_33)
-    "       finalColor = vec4(0.0, 0.0, 0.0, 1.0); \n"
-    #endif
-    "   } \n"
-    "   else \n"
-    "   { \n"
-    #if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
-    "       float blue = texture2D(texture0, tcBlue).b; \n"
-    "       vec2 tcGreen = lensCenter + scale*theta1; \n"
-    "       float green = texture2D(texture0, tcGreen).g; \n"
-    #elif defined(GRAPHICS_API_OPENGL_33)
-    "       float blue = texture(texture0, tcBlue).b; \n"
-    "       vec2 tcGreen = lensCenter + scale*theta1; \n"
-    "       float green = texture(texture0, tcGreen).g; \n"
-    #endif
-    "       vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq); \n"
-    "       vec2 tcRed = lensCenter + scale*thetaRed; \n"
-    #if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
-    "       float red = texture2D(texture0, tcRed).r; \n"
-    "       gl_FragColor = vec4(red, green, blue, 1.0); \n"
-    #elif defined(GRAPHICS_API_OPENGL_33)
-    "       float red = texture(texture0, tcRed).r; \n"
-    "       finalColor = vec4(red, green, blue, 1.0); \n"
-    #endif
-    "    } \n"
-    "} \n";
-#endif
-
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
 static Matrix stack[MAX_MATRIX_STACK_SIZE] = { 0 };
 static int stackCounter = 0;
@@ -891,6 +806,7 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
 #if defined(SUPPORT_VR_SIMULATOR)
 // VR global variables
 static VrStereoConfig vrConfig = { 0 };     // VR stereo configuration for simulator
+static RenderTexture2D stereoFbo;           // VR stereo rendering framebuffer
 static bool vrSimulatorReady = false;       // VR simulator ready flag
 static bool vrStereoRender = false;         // VR stereo rendering enabled/disabled flag
                                             // NOTE: This flag is useful to render data over stereo image (i.e. FPS)
@@ -924,7 +840,6 @@ static void GenDrawCube(void);              // Generate and draw cube
 static void GenDrawQuad(void);              // Generate and draw quad
 
 #if defined(SUPPORT_VR_SIMULATOR)
-static VrStereoConfig SetStereoConfig(VrDeviceInfo info, Shader distortion);    // Configure stereo rendering (including distortion shader) with HMD device parameters
 static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView);  // Set internal projection and modelview matrix depending on eye
 #endif
 
@@ -3577,101 +3492,17 @@ void EndScissorMode(void)
 }
 
 #if defined(SUPPORT_VR_SIMULATOR)
-// Get VR device information for some standard devices
-VrDeviceInfo GetVrDeviceInfo(int vrDeviceType)
-{
-    VrDeviceInfo hmd = { 0 };                // Current VR device info
-
-    switch (vrDeviceType)
-    {
-        case HMD_DEFAULT_DEVICE:
-        case HMD_OCULUS_RIFT_CV1:
-        {
-            // Oculus Rift CV1 parameters
-            // NOTE: CV1 represents a complete HMD redesign compared to previous versions,
-            // new Fresnel-hybrid-asymmetric lenses have been added and, consequently,
-            // previous parameters (DK2) and distortion shader (DK2) doesn't work any more.
-            // I just defined a set of parameters for simulator that approximate to CV1 stereo rendering
-            // but result is not the same obtained with Oculus PC SDK.
-            hmd.hResolution = 2160;                 // HMD horizontal resolution in pixels
-            hmd.vResolution = 1200;                 // HMD vertical resolution in pixels
-            hmd.hScreenSize = 0.133793f;            // HMD horizontal size in meters
-            hmd.vScreenSize = 0.0669f;              // HMD vertical size in meters
-            hmd.vScreenCenter = 0.04678f;           // HMD screen center in meters
-            hmd.eyeToScreenDistance = 0.041f;       // HMD distance between eye and display in meters
-            hmd.lensSeparationDistance = 0.07f;     // HMD lens separation distance in meters
-            hmd.interpupillaryDistance = 0.07f;     // HMD IPD (distance between pupils) in meters
-            hmd.lensDistortionValues[0] = 1.0f;     // HMD lens distortion constant parameter 0
-            hmd.lensDistortionValues[1] = 0.22f;    // HMD lens distortion constant parameter 1
-            hmd.lensDistortionValues[2] = 0.24f;    // HMD lens distortion constant parameter 2
-            hmd.lensDistortionValues[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
-
-            TraceLog(LOG_INFO, "Initializing VR Simulator (Oculus Rift CV1)");
-        } break;
-        case HMD_OCULUS_RIFT_DK2:
-        {
-            // 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.04678f;           // 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.lensDistortionValues[0] = 1.0f;     // HMD lens distortion constant parameter 0
-            hmd.lensDistortionValues[1] = 0.22f;    // HMD lens distortion constant parameter 1
-            hmd.lensDistortionValues[2] = 0.24f;    // HMD lens distortion constant parameter 2
-            hmd.lensDistortionValues[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
-
-            TraceLog(LOG_INFO, "Initializing VR Simulator (Oculus Rift DK2)");
-        } break;
-        case HMD_OCULUS_GO:
-        {
-            // TODO: Provide device display and lens parameters
-        }
-        case HMD_VALVE_HTC_VIVE:
-        {
-            // TODO: Provide device display and lens parameters
-        }
-        case HMD_SONY_PSVR:
-        {
-            // TODO: Provide device display and lens parameters
-        }
-        default: break;
-    }
-
-    return hmd;
-}
-
 // Init VR simulator for selected device parameters
-// NOTE: It modifies the global variable: VrStereoConfig vrConfig
-void InitVrSimulator(VrDeviceInfo info)
+// NOTE: It modifies the global variable: stereoFbo
+void InitVrSimulator(void)
 {
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-    Shader distortion = { 0 };
-
-#if defined(SUPPORT_DISTORTION_SHADER)
-    // Load distortion shader
-    distortion = LoadShaderCode(NULL, distortionFShaderStr);
-    if (distortion.id > 0) SetShaderDefaultLocations(&distortion);
-#endif
-
-    // Set VR configutarion parameters, including distortion shader
-    vrConfig = SetStereoConfig(info, distortion);
-
+    // Initialize framebuffer and textures for stereo rendering
+    // NOTE: Screen size should match HMD aspect ratio
+    stereoFbo = rlLoadRenderTexture(screenWidth, screenHeight, UNCOMPRESSED_R8G8B8A8, 24, false);
+    
     vrSimulatorReady = true;
-#endif
-
-#if defined(GRAPHICS_API_OPENGL_11)
+#else
     TraceLog(LOG_WARNING, "VR Simulator not supported on OpenGL 1.1");
 #endif
 }
@@ -3687,14 +3518,90 @@ void UpdateVrTracking(Camera *camera)
 void CloseVrSimulator(void)
 {
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-    if (vrSimulatorReady)
+    if (vrSimulatorReady) rlDeleteRenderTextures(stereoFbo);        // Unload stereo framebuffer and texture
+#endif
+}
+
+// Set stereo rendering configuration parameters 
+void SetVrConfiguration(VrDeviceInfo hmd, Shader distortion)
+{
+    // Reset vrConfig for a new values assignment
+    memset(&vrConfig, 0, sizeof(vrConfig));
+    
+    // Assign distortion shader
+    vrConfig.distortionShader = distortion;
+
+    // Compute aspect ratio
+    float aspect = ((float)hmd.hResolution*0.5f)/(float)hmd.vResolution;
+
+    // Compute lens parameters
+    float lensShift = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize;
+    float leftLensCenter[2] = { 0.25f + lensShift, 0.5f };
+    float rightLensCenter[2] = { 0.75f - 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 = (float)fabs(-1.0f - 4.0f*lensShift);
+    float lensRadiusSq = lensRadius*lensRadius;
+    float distortionScale = hmd.lensDistortionValues[0] +
+                            hmd.lensDistortionValues[1]*lensRadiusSq +
+                            hmd.lensDistortionValues[2]*lensRadiusSq*lensRadiusSq +
+                            hmd.lensDistortionValues[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq;
+
+    TraceLog(LOG_DEBUG, "VR: Distortion Scale: %f", distortionScale);
+
+    float normScreenWidth = 0.5f;
+    float normScreenHeight = 1.0f;
+    float scaleIn[2] = { 2.0f/normScreenWidth, 2.0f/normScreenHeight/aspect };
+    float scale[2] = { normScreenWidth*0.5f/distortionScale, normScreenHeight*0.5f*aspect/distortionScale };
+
+    TraceLog(LOG_DEBUG, "VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
+    TraceLog(LOG_DEBUG, "VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
+    TraceLog(LOG_DEBUG, "VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]);
+    TraceLog(LOG_DEBUG, "VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]);
+
+    // Fovy is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)
+    // ...but with lens distortion it is increased (see Oculus SDK Documentation)
+    //float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance);     // Really need distortionScale?
+    float fovy = 2.0f*(float)atan2(hmd.vScreenSize*0.5f, hmd.eyeToScreenDistance);
+
+    // 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);
+    vrConfig.eyesProjection[0] = MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f));
+    vrConfig.eyesProjection[1] = MatrixMultiply(proj, MatrixTranslate(-projOffset, 0.0f, 0.0f));
+
+    // Compute camera transformation matrices
+    // 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);
+
+    // Compute eyes Viewports
+    vrConfig.eyeViewportRight[2] = hmd.hResolution/2;
+    vrConfig.eyeViewportRight[3] = hmd.vResolution;
+    
+    vrConfig.eyeViewportLeft[0] = hmd.hResolution/2;
+    vrConfig.eyeViewportLeft[1] = 0;
+    vrConfig.eyeViewportLeft[2] = hmd.hResolution/2;
+    vrConfig.eyeViewportLeft[3] = hmd.vResolution;
+
+    if (vrConfig.distortionShader.id > 0)
     {
-        rlDeleteRenderTextures(vrConfig.stereoFbo); // Unload stereo framebuffer and texture
-        #if defined(SUPPORT_DISTORTION_SHADER)
-        UnloadShader(vrConfig.distortionShader);    // Unload distortion shader
-        #endif
+        // Update distortion shader with lens and distortion-scale parameters
+        SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftLensCenter"), leftLensCenter, UNIFORM_VEC2);
+        SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightLensCenter"), rightLensCenter, UNIFORM_VEC2);
+        SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftScreenCenter"), leftScreenCenter, UNIFORM_VEC2);
+        SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightScreenCenter"), rightScreenCenter, UNIFORM_VEC2);
+
+        SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scale"), scale, UNIFORM_VEC2);
+        SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scaleIn"), scaleIn, UNIFORM_VEC2);
+        SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "hmdWarpParam"), hmd.lensDistortionValues, UNIFORM_VEC4);
+        SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, UNIFORM_VEC4);
     }
-#endif
 }
 
 // Detect if VR simulator is running
@@ -3733,7 +3640,7 @@ void BeginVrDrawing(void)
     if (vrSimulatorReady)
     {
         // Setup framebuffer for stereo rendering
-        rlEnableRenderTexture(vrConfig.stereoFbo.id);
+        rlEnableRenderTexture(stereoFbo.id);
 
         // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
         // and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
@@ -3771,13 +3678,11 @@ void EndVrDrawing(void)
         rlMatrixMode(RL_MODELVIEW);                             // Enable internal modelview matrix
         rlLoadIdentity();                                       // Reset internal modelview matrix
 
-#if defined(SUPPORT_DISTORTION_SHADER)
-        // Draw RenderTexture (stereoFbo) using distortion shader
-        currentShader = vrConfig.distortionShader;
-#else
-        currentShader = GetShaderDefault();
-#endif
-        rlEnableTexture(vrConfig.stereoFbo.texture.id);
+        // Draw RenderTexture (stereoFbo) using distortion shader if available
+        if (vrConfig.distortionShader.id > 0) currentShader = vrConfig.distortionShader;
+        else currentShader = GetShaderDefault();
+
+        rlEnableTexture(stereoFbo.texture.id);
 
         rlPushMatrix();
             rlBegin(RL_QUADS);
@@ -3790,15 +3695,15 @@ void EndVrDrawing(void)
 
                 // Bottom-right corner for texture and quad
                 rlTexCoord2f(0.0f, 0.0f);
-                rlVertex2f(0.0f, (float)vrConfig.stereoFbo.texture.height);
+                rlVertex2f(0.0f, (float)stereoFbo.texture.height);
 
                 // Top-right corner for texture and quad
                 rlTexCoord2f(1.0f, 0.0f);
-                rlVertex2f( (float)vrConfig.stereoFbo.texture.width, (float)vrConfig.stereoFbo.texture.height);
+                rlVertex2f( (float)stereoFbo.texture.width, (float)stereoFbo.texture.height);
 
                 // Top-left corner for texture and quad
                 rlTexCoord2f(1.0f, 1.0f);
-                rlVertex2f( (float)vrConfig.stereoFbo.texture.width, 0.0f);
+                rlVertex2f( (float)stereoFbo.texture.width, 0.0f);
             rlEnd();
         rlPopMatrix();
 
@@ -4472,87 +4377,6 @@ static void GenDrawCube(void)
 }
 
 #if defined(SUPPORT_VR_SIMULATOR)
-// Configure stereo rendering (including distortion shader) with HMD device parameters
-static VrStereoConfig SetStereoConfig(VrDeviceInfo hmd, Shader distortion)
-{
-    VrStereoConfig config = { 0 };
-
-    // Initialize framebuffer and textures for stereo rendering
-    // NOTE: Screen size should match HMD aspect ratio
-    config.stereoFbo = rlLoadRenderTexture(screenWidth, screenHeight, UNCOMPRESSED_R8G8B8A8, 24, false);
-
-    // Assign distortion shader
-    config.distortionShader = distortion;
-
-    // Compute aspect ratio
-    float aspect = ((float)hmd.hResolution*0.5f)/(float)hmd.vResolution;
-
-    // Compute lens parameters
-    float lensShift = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize;
-    float leftLensCenter[2] = { 0.25f + lensShift, 0.5f };
-    float rightLensCenter[2] = { 0.75f - 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 = (float)fabs(-1.0f - 4.0f*lensShift);
-    float lensRadiusSq = lensRadius*lensRadius;
-    float distortionScale = hmd.lensDistortionValues[0] +
-                            hmd.lensDistortionValues[1]*lensRadiusSq +
-                            hmd.lensDistortionValues[2]*lensRadiusSq*lensRadiusSq +
-                            hmd.lensDistortionValues[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq;
-
-    TraceLog(LOG_DEBUG, "VR: Distortion Scale: %f", distortionScale);
-
-    float normScreenWidth = 0.5f;
-    float normScreenHeight = 1.0f;
-    float scaleIn[2] = { 2.0f/normScreenWidth, 2.0f/normScreenHeight/aspect };
-    float scale[2] = { normScreenWidth*0.5f/distortionScale, normScreenHeight*0.5f*aspect/distortionScale };
-
-    TraceLog(LOG_DEBUG, "VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
-    TraceLog(LOG_DEBUG, "VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
-    TraceLog(LOG_DEBUG, "VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]);
-    TraceLog(LOG_DEBUG, "VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]);
-
-    // Fovy is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)
-    // ...but with lens distortion it is increased (see Oculus SDK Documentation)
-    //float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance);     // Really need distortionScale?
-    float fovy = 2.0f*(float)atan2(hmd.vScreenSize*0.5f, hmd.eyeToScreenDistance);
-
-    // 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);
-    config.eyesProjection[0] = MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f));
-    config.eyesProjection[1] = MatrixMultiply(proj, MatrixTranslate(-projOffset, 0.0f, 0.0f));
-
-    // Compute camera transformation matrices
-    // 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.
-    config.eyesViewOffset[0] = MatrixTranslate(-hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
-    config.eyesViewOffset[1] = MatrixTranslate(hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
-
-    // Compute eyes Viewports
-    //config.eyeViewportRight[0] = (int[4]){ 0, 0, hmd.hResolution/2, hmd.vResolution };
-    //config.eyeViewportLeft[0] = (int[4]){ hmd.hResolution/2, 0, hmd.hResolution/2, hmd.vResolution };
-
-#if defined(SUPPORT_DISTORTION_SHADER)
-    // Update distortion shader with lens and distortion-scale parameters
-    SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "leftLensCenter"), leftLensCenter, UNIFORM_VEC2);
-    SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "rightLensCenter"), rightLensCenter, UNIFORM_VEC2);
-    SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "leftScreenCenter"), leftScreenCenter, UNIFORM_VEC2);
-    SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "rightScreenCenter"), rightScreenCenter, UNIFORM_VEC2);
-
-    SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "scale"), scale, UNIFORM_VEC2);
-    SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "scaleIn"), scaleIn, UNIFORM_VEC2);
-    SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "hmdWarpParam"), hmd.lensDistortionValues, UNIFORM_VEC4);
-    SetShaderValue(config.distortionShader, GetShaderLocation(config.distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, UNIFORM_VEC4);
-#endif
-
-    return config;
-}
-
 // Set internal projection and modelview matrix depending on eyes tracking data
 static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView)
 {