From 000e867d28a0399a1ae216e9d3a40353b12d6a8c Mon Sep 17 00:00:00 2001 From: FireFlyForLife Date: Sat, 2 Apr 2022 19:51:37 +0100 Subject: [PATCH] Fix for vr rendering not taking render target size into account --- examples/core/core_vr_simulator.c | 9 ++++++--- src/rcore.c | 4 ++-- src/rlgl.h | 19 ++++++++++++++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/examples/core/core_vr_simulator.c b/examples/core/core_vr_simulator.c index 65f0dec65c14..c0f1b8d2009d 100644 --- a/examples/core/core_vr_simulator.c +++ b/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(); diff --git a/src/rcore.c b/src/rcore.c index d4b10504e079..afc300e73d45 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2347,8 +2347,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] diff --git a/src/rlgl.h b/src/rlgl.h index 8513998cb5e9..aef8a4b903e4 100644 --- a/src/rlgl.h +++ b/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