Browse Source

Fix for vr rendering not taking render target size into account (#2424)

Maiko Steeman 3 years ago
parent
commit
ccfac59c60
3 changed files with 26 additions and 6 deletions
  1. 6 3
      examples/core/core_vr_simulator.c
  2. 2 2
      src/rcore.c
  3. 18 1
      src/rlgl.h

+ 6 - 3
examples/core/core_vr_simulator.c

@@ -78,7 +78,11 @@ int main(void)
 
     // Initialize framebuffer for stereo rendering
     // NOTE: Screen size should match HMD aspect ratio
-    RenderTexture2D target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
+    RenderTexture2D target = LoadRenderTexture(device.hResolution, device.vResolution);
+
+    // The target's height is flipped (in the source Rectangle), due to OpenGL reasons
+    Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };
+    Rectangle destRec = { 0.0f, 0.0f, (float)GetScreenWidth(), (float)GetScreenHeight() };
 
     // Define the camera to look into our 3d world
     Camera camera = { 0 };
@@ -121,8 +125,7 @@ int main(void)
         BeginDrawing();
             ClearBackground(RAYWHITE);
             BeginShaderMode(distortion);
-                DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
-                              (float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
+                DrawTexturePro(target.texture, sourceRec, destRec, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
             EndShaderMode();
             DrawFPS(10, 10);
         EndDrawing();

+ 2 - 2
src/rcore.c

@@ -2348,8 +2348,8 @@ VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device)
 
         // Fovy is normally computed with: 2*atan2f(device.vScreenSize, 2*device.eyeToScreenDistance)
         // ...but with lens distortion it is increased (see Oculus SDK Documentation)
-        //float fovy = 2.0f*atan2f(device.vScreenSize*0.5f*distortionScale, device.eyeToScreenDistance);     // Really need distortionScale?
-        float fovy = 2.0f*(float)atan2f(device.vScreenSize*0.5f, device.eyeToScreenDistance);
+        float fovy = 2.0f*atan2f(device.vScreenSize*0.5f*distortionScale, device.eyeToScreenDistance);     // Really need distortionScale?
+       // float fovy = 2.0f*(float)atan2f(device.vScreenSize*0.5f, device.eyeToScreenDistance);
 
         // Compute camera projection matrices
         float projOffset = 4.0f*lensShift;      // Scaled to projection space coordinates [-1..1]

+ 18 - 1
src/rlgl.h

@@ -929,6 +929,11 @@ typedef struct rlglData {
 
         int framebufferWidth;               // Default framebuffer width
         int framebufferHeight;              // Default framebuffer height
+        
+        int viewportX;                      // Current opengl viewport offset x
+        int viewportY;                      // Current opengl viewport offset y
+        int viewportWidth;                  // Current opengl viewport width
+        int viewportHeight;                 // Current opengl viewport height
 
     } State;            // Renderer state
     struct {
@@ -1232,6 +1237,11 @@ void rlOrtho(double left, double right, double bottom, double top, double znear,
 // Set the viewport area (transformation from normalized device coordinates to window coordinates)
 void rlViewport(int x, int y, int width, int height)
 {
+    RLGL.State.viewportX = x;
+    RLGL.State.viewportY = y;
+    RLGL.State.viewportWidth = width;
+    RLGL.State.viewportHeight = height;
+
     glViewport(x, y, width, height);
 }
 
@@ -2494,6 +2504,11 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
     Matrix matProjection = RLGL.State.projection;
     Matrix matModelView = RLGL.State.modelview;
 
+    int originalViewportX = RLGL.State.viewportX;
+    int originalViewportY = RLGL.State.viewportY;
+    int originalViewportWidth = RLGL.State.viewportWidth;
+    int originalViewportHeight = RLGL.State.viewportHeight;
+
     int eyeCount = 1;
     if (RLGL.State.stereoRender) eyeCount = 2;
 
@@ -2502,7 +2517,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
         if (eyeCount == 2)
         {
             // Setup current eye viewport (half screen width)
-            rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
+            rlViewport(originalViewportX + eye * originalViewportWidth / 2, originalViewportY, originalViewportWidth / 2, originalViewportHeight);
 
             // Set current eye view offset to modelview matrix
             rlSetMatrixModelview(rlMatrixMultiply(matModelView, RLGL.State.viewOffsetStereo[eye]));
@@ -2601,6 +2616,8 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
 
         glUseProgram(0);    // Unbind shader program
     }
+
+    if (eyeCount == 2) rlViewport(originalViewportX, originalViewportY, originalViewportWidth, originalViewportHeight);
     //------------------------------------------------------------------------------------------------------------
 
     // Reset batch buffers