summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRay <[email protected]>2021-03-20 18:36:25 +0100
committerRay <[email protected]>2021-03-20 18:36:25 +0100
commita76fcaba3ea8092be4b5ee26f6e97948b20129aa (patch)
tree6c1b28e0b24e1ea71af41f813a97424f112218d1 /src
parent4fba09794fffd1bf0b2b678353ba746388ace619 (diff)
downloadraylib-a76fcaba3ea8092be4b5ee26f6e97948b20129aa.tar.gz
raylib-a76fcaba3ea8092be4b5ee26f6e97948b20129aa.zip
BIG CHANGE: REDESIGNED: Vr device simulator #1582
Vr simulator has been moved to core module and completely redesigned. Now user is in charge of stereo-render fbo and also in full control of distortion shader. Code is a bit more complex but better aligned with other raylib examples.
Diffstat (limited to 'src')
-rw-r--r--src/config.h9
-rw-r--r--src/core.c155
-rw-r--r--src/raylib.h40
-rw-r--r--src/rlgl.h409
4 files changed, 247 insertions, 366 deletions
diff --git a/src/config.h b/src/config.h
index 9513b849..c2997854 100644
--- a/src/config.h
+++ b/src/config.h
@@ -57,6 +57,8 @@
#define SUPPORT_COMPRESSION_API 1
// Support saving binary data automatically to a generated storage.data file. This file is managed internally.
#define SUPPORT_DATA_STORAGE 1
+// Support VR simulation functionality (stereo rendering)
+#define SUPPORT_VR_SIMULATOR 1
// core: Configuration values
//------------------------------------------------------------------------------------
@@ -78,12 +80,7 @@
//------------------------------------------------------------------------------------
-// Module: rlgl - Configuration Flags
-//------------------------------------------------------------------------------------
-// Support VR simulation functionality (stereo rendering)
-#define SUPPORT_VR_SIMULATOR 1
-
-// rlgl: Configuration values
+// Module: rlgl - Configuration values
//------------------------------------------------------------------------------------
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
#define DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch limits
diff --git a/src/core.c b/src/core.c
index 664bac02..9be1dc06 100644
--- a/src/core.c
+++ b/src/core.c
@@ -80,7 +80,10 @@
* for linkage
*
* #define SUPPORT_DATA_STORAGE
-* Support saving binary data automatically to a generated storage.data file. This file is managed internally.
+* Support saving binary data automatically to a generated storage.data file. This file is managed internally
+*
+* #define SUPPORT_VR_SIMULATOR
+* Support VR simulation functionality (stereo rendering)
*
* DEPENDENCIES:
* rglfw - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX. FreeBSD, OpenBSD, NetBSD, DragonFly)
@@ -473,6 +476,15 @@ typedef struct CoreData {
unsigned long long base; // Base time measure for hi-res timer
#endif
} Time;
+#if defined(SUPPORT_VR_SIMULATOR)
+ struct {
+ VrStereoConfig config; // VR stereo configuration for simulator
+ unsigned int stereoFboId; // VR stereo rendering framebuffer id
+ unsigned int stereoTexId; // VR stereo color texture (attached to framebuffer)
+ bool simulatorReady; // VR simulator ready flag
+ bool stereoRender; // VR stereo rendering enabled/disabled flag
+ } Vr; // VR simulator data
+#endif // SUPPORT_VR_SIMULATOR
} CoreData;
//----------------------------------------------------------------------------------
@@ -2000,6 +2012,147 @@ void EndTextureMode(void)
CORE.Window.currentFbo.height = CORE.Window.screen.height;
}
+
+#if defined(SUPPORT_VR_SIMULATOR)
+// Init VR simulator for selected device parameters
+void InitVrSimulator(VrDeviceInfo device)
+{
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ // Reset CORE.Vr.config for a new values assignment
+ memset(&CORE.Vr.config, 0, sizeof(VrStereoConfig));
+
+ // Compute aspect ratio
+ float aspect = ((float)device.hResolution*0.5f)/(float)device.vResolution;
+
+ // Compute lens parameters
+ float lensShift = (device.hScreenSize*0.25f - device.lensSeparationDistance*0.5f)/device.hScreenSize;
+ CORE.Vr.config.leftLensCenter[0] = 0.25f + lensShift;
+ CORE.Vr.config.leftLensCenter[1] = 0.5f;
+ CORE.Vr.config.rightLensCenter[0] = 0.75f - lensShift;
+ CORE.Vr.config.rightLensCenter[1] = 0.5f;
+ CORE.Vr.config.leftScreenCenter[0] = 0.25f;
+ CORE.Vr.config.leftScreenCenter[1] = 0.5f;
+ CORE.Vr.config.rightScreenCenter[0] = 0.75f;
+ CORE.Vr.config.rightScreenCenter[1] = 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 = device.lensDistortionValues[0] +
+ device.lensDistortionValues[1]*lensRadiusSq +
+ device.lensDistortionValues[2]*lensRadiusSq*lensRadiusSq +
+ device.lensDistortionValues[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq;
+
+ float normScreenWidth = 0.5f;
+ float normScreenHeight = 1.0f;
+ CORE.Vr.config.scaleIn[0] = 2.0f/normScreenWidth;
+ CORE.Vr.config.scaleIn[1] = 2.0f/normScreenHeight/aspect;
+ CORE.Vr.config.scale[0] = normScreenWidth*0.5f/distortionScale;
+ CORE.Vr.config.scale[1] = normScreenHeight*0.5f*aspect/distortionScale;
+
+ // 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);
+
+ // Compute camera projection matrices
+ float projOffset = 4.0f*lensShift; // Scaled to projection space coordinates [-1..1]
+ Matrix proj = MatrixPerspective(fovy, aspect, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
+ rlSetMatrixProjectionStereo(MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f)), 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.
+ rlSetMatrixViewOffsetStereo(MatrixTranslate(-device.interpupillaryDistance*0.5f, 0.075f, 0.045f), MatrixTranslate(device.interpupillaryDistance*0.5f, 0.075f, 0.045f));
+
+ // Compute eyes Viewports
+ /*
+ CORE.Vr.config.eyeViewportRight[0] = 0;
+ CORE.Vr.config.eyeViewportRight[1] = 0;
+ CORE.Vr.config.eyeViewportRight[2] = device.hResolution/2;
+ CORE.Vr.config.eyeViewportRight[3] = device.vResolution;
+
+ CORE.Vr.config.eyeViewportLeft[0] = device.hResolution/2;
+ CORE.Vr.config.eyeViewportLeft[1] = 0;
+ CORE.Vr.config.eyeViewportLeft[2] = device.hResolution/2;
+ CORE.Vr.config.eyeViewportLeft[3] = device.vResolution;
+ */
+
+ CORE.Vr.simulatorReady = true;
+#else
+ TRACELOG(LOG_WARNING, "RLGL: VR Simulator not supported on OpenGL 1.1");
+#endif
+}
+
+// Update VR tracking (position and orientation) and camera
+// NOTE: Camera (position, target, up) gets update with head tracking information
+void UpdateVrTracking(Camera *camera)
+{
+ // TODO: Simulate 1st person camera system
+}
+
+// Close VR simulator for current device
+void CloseVrSimulator(void)
+{
+ CORE.Vr.simulatorReady = false;
+}
+
+// Get stereo rendering configuration parameters
+VrStereoConfig GetVrConfig(VrDeviceInfo device)
+{
+ VrStereoConfig config = { 0 };
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ config = CORE.Vr.config;
+#endif
+ return config;
+}
+
+// Detect if VR simulator is running
+bool IsVrSimulatorReady(void)
+{
+ return CORE.Vr.simulatorReady;
+}
+
+// Begin VR drawing configuration
+void BeginVrDrawing(RenderTexture2D target)
+{
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ if (CORE.Vr.simulatorReady)
+ {
+ rlEnableFramebuffer(target.id); // Setup framebuffer for stereo rendering
+ //glEnable(GL_FRAMEBUFFER_SRGB); // Enable SRGB framebuffer (only if required)
+
+ //rlViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
+ rlClearScreenBuffers(); // Clear current framebuffer
+
+ rlEnableStereoRender();
+ }
+#endif
+}
+
+// End VR drawing process (and desktop mirror)
+void EndVrDrawing(void)
+{
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ if (CORE.Vr.simulatorReady)
+ {
+ rlDisableStereoRender();
+
+ rlDisableFramebuffer(); // Unbind current framebuffer
+
+ // Reset viewport and default projection-modelview matrices
+ rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight);
+ SetMatrixProjection(MatrixOrtho(0.0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, 0.0, 0.0, 1.0));
+ SetMatrixModelview(MatrixIdentity());
+
+ rlDisableDepthTest();
+ }
+#endif
+}
+#endif // SUPPORT_VR_SIMULATOR
+
// Begin scissor mode (define screen area for following drawing)
// NOTE: Scissor rec refers to bottom-left corner, we change it to upper-left
void BeginScissorMode(int x, int y, int width, int height)
diff --git a/src/raylib.h b/src/raylib.h
index 0db3f06f..f3f9d7ec 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -449,18 +449,28 @@ typedef struct Music {
// Head-Mounted-Display device parameters
typedef struct VrDeviceInfo {
- int hResolution; // HMD horizontal resolution in pixels
- int vResolution; // HMD vertical resolution in pixels
- float hScreenSize; // HMD horizontal size in meters
- float vScreenSize; // HMD vertical size in meters
- float vScreenCenter; // HMD screen center in meters
- float eyeToScreenDistance; // HMD distance between eye and display in meters
- float lensSeparationDistance; // HMD lens separation distance in meters
- float interpupillaryDistance; // HMD IPD (distance between pupils) in meters
- float lensDistortionValues[4]; // HMD lens distortion constant parameters
- float chromaAbCorrection[4]; // HMD chromatic aberration correction parameters
+ int hResolution; // Horizontal resolution in pixels
+ int vResolution; // Vertical resolution in pixels
+ float hScreenSize; // Horizontal size in meters
+ float vScreenSize; // Vertical size in meters
+ float vScreenCenter; // Screen center in meters
+ float eyeToScreenDistance; // Distance between eye and display in meters
+ float lensSeparationDistance; // Lens separation distance in meters
+ float interpupillaryDistance; // IPD (distance between pupils) in meters
+ float lensDistortionValues[4]; // Lens distortion constant parameters
+ float chromaAbCorrection[4]; // Chromatic aberration correction parameters
} VrDeviceInfo;
+// VR Stereo rendering configuration for simulator
+typedef struct VrStereoConfig {
+ float leftLensCenter[2]; // VR left lens center
+ float rightLensCenter[2]; // VR right lens center
+ float leftScreenCenter[2]; // VR left screen center
+ float rightScreenCenter[2]; // VR right screen center
+ float scale[2]; // VR distortion scale
+ float scaleIn[2]; // VR distortion scale in
+} VrStereoConfig;
+
//----------------------------------------------------------------------------------
// Enumerators Definition
//----------------------------------------------------------------------------------
@@ -1441,14 +1451,14 @@ RLAPI void BeginBlendMode(int mode); // Beg
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
// VR control functions
-RLAPI void InitVrSimulator(void); // Init VR simulator for selected device parameters
+RLAPI void InitVrSimulator(VrDeviceInfo device); // 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 UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
+RLAPI void BeginVrDrawing(RenderTexture2D target); // Begin VR simulator stereo rendering (using provided fbo)
RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
+RLAPI VrStereoConfig GetVrConfig(VrDeviceInfo device); // Get stereo rendering configuration parameters
+RLAPI Texture2D GetVrTexture(void); // Get VR framebuffer texture
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
diff --git a/src/rlgl.h b/src/rlgl.h
index 9f1b9af7..83c2aec8 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -29,8 +29,6 @@
* #define RLGL_STANDALONE
* Use rlgl as standalone library (no raylib dependency)
*
-* #define SUPPORT_VR_SIMULATOR
-* Support VR simulation functionality (stereo rendering)
*
* DEPENDENCIES:
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
@@ -327,29 +325,6 @@ typedef enum {
float fovy; // Camera field-of-view apperture in Y (degrees)
} Camera;
- // Head-Mounted-Display device parameters
- typedef struct VrDeviceInfo {
- int hResolution; // HMD horizontal resolution in pixels
- int vResolution; // HMD vertical resolution in pixels
- float hScreenSize; // HMD horizontal size in meters
- float vScreenSize; // HMD vertical size in meters
- float vScreenCenter; // HMD screen center in meters
- float eyeToScreenDistance; // HMD distance between eye and display in meters
- float lensSeparationDistance; // HMD lens separation distance in meters
- float interpupillaryDistance; // HMD IPD (distance between pupils) in meters
- float lensDistortionValues[4]; // HMD lens distortion constant parameters
- float chromaAbCorrection[4]; // HMD chromatic aberration correction parameters
- } VrDeviceInfo;
-
- // 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;
-
// TraceLog message types
typedef enum {
LOG_ALL,
@@ -532,6 +507,8 @@ RLAPI void rlSetLineWidth(float width); // Set the line dr
RLAPI float rlGetLineWidth(void); // Get the line drawing width
RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
RLAPI void rlDisableSmoothLines(void); // Disable line aliasing
+RLAPI void rlEnableStereoRender(void); // Enable stereo rendering
+RLAPI void rlDisableStereoRender(void); // Disable stereo rendering
RLAPI void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Clear color buffer with color
RLAPI void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
@@ -564,6 +541,9 @@ RLAPI void rlGenerateMipmaps(Texture2D *texture); // Gen
RLAPI void *rlReadTexturePixels(Texture2D texture); // Read texture pixel data
RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
+RLAPI void rlSetMatrixProjectionStereo(Matrix right, Matrix left); // Set eyes projection matrices for stereo rendering
+RLAPI void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left); // Set eyes view offsets matrices for stereo rendering
+
// Framebuffer management (fbo)
RLAPI unsigned int rlLoadFramebuffer(int width, int height); // Load an empty framebuffer
RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType); // Attach texture/renderbuffer to a framebuffer
@@ -597,14 +577,15 @@ RLAPI Texture2D GetShapesTexture(void); // Get
RLAPI Rectangle GetShapesTextureRec(void); // Get texture rectangle to draw shapes
// Shader configuration functions
-RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
-RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
+RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
+RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector
-RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4)
+RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4)
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
RLAPI Matrix GetMatrixModelview(void); // Get internal modelview matrix
+RLAPI Matrix GetMatrixProjection(void); // Get internal projection matrix
// Texture maps generation (PBR)
// NOTE: Required shaders should be provided
@@ -619,16 +600,6 @@ RLAPI void EndShaderMode(void); // End custom shader dra
RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
-// VR control functions
-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
-
RLAPI char *LoadFileText(const char *fileName); // Load chars array from text file
RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data size in bytes (image or texture)
#endif
@@ -847,17 +818,6 @@ typedef struct RenderBatch {
float currentDepth; // Current depth value for next draw
} RenderBatch;
-#if defined(SUPPORT_VR_SIMULATOR) && !defined(RLGL_STANDALONE)
-// 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
-
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
typedef struct rlglData {
RenderBatch *currentBatch; // Current render batch
@@ -881,6 +841,10 @@ typedef struct rlglData {
unsigned int defaultFShaderId; // Default fragment shader Id (used by default shader program)
Shader defaultShader; // Basic shader, support vertex color and diffuse texture
Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
+
+ bool stereoRender; // Stereo rendering flag
+ Matrix eyesProjection[2]; // VR stereo rendering eyes projection matrices
+ Matrix eyesViewOffset[2]; // VR stereo rendering eyes view offset matrices
int currentBlendMode; // Blending mode active
int glBlendSrcFactor; // Blending source factor
@@ -910,15 +874,6 @@ typedef struct rlglData {
int maxDepthBits; // Maximum bits for depth component
} ExtSupported; // Extensions supported flags
-#if defined(SUPPORT_VR_SIMULATOR)
- struct {
- VrStereoConfig config; // VR stereo configuration for simulator
- unsigned int stereoFboId; // VR stereo rendering framebuffer id
- unsigned int stereoTexId; // VR stereo color texture (attached to framebuffer)
- bool simulatorReady; // VR simulator ready flag
- bool stereoRender; // VR stereo rendering enabled/disabled flag
- } Vr; // VR simulator data
-#endif // SUPPORT_VR_SIMULATOR
} rlglData;
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
@@ -961,11 +916,6 @@ static void SetRenderBatchDefault(void); // Set default render ba
static void GenDrawCube(void); // Generate and draw cube
static void GenDrawQuad(void); // Generate and draw quad
-
-#if defined(SUPPORT_VR_SIMULATOR)
-static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); // Set internal projection and modelview matrix depending on eye
-#endif
-
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
#if defined(GRAPHICS_API_OPENGL_11)
@@ -1469,13 +1419,13 @@ void rlEnableBackfaceCulling(void) { glEnable(GL_CULL_FACE); }
void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); }
// Enable scissor test
-RLAPI void rlEnableScissorTest(void) { glEnable(GL_SCISSOR_TEST); }
+void rlEnableScissorTest(void) { glEnable(GL_SCISSOR_TEST); }
// Disable scissor test
-RLAPI void rlDisableScissorTest(void) { glDisable(GL_SCISSOR_TEST); }
+void rlDisableScissorTest(void) { glDisable(GL_SCISSOR_TEST); }
// Scissor test
-RLAPI void rlScissor(int x, int y, int width, int height) { glScissor(x, y, width, height); }
+void rlScissor(int x, int y, int width, int height) { glScissor(x, y, width, height); }
// Enable wire mode
void rlEnableWireMode(void)
@@ -1524,6 +1474,18 @@ void rlDisableSmoothLines(void)
#endif
}
+// Enable stereo rendering
+void rlEnableStereoRender(void)
+{
+ RLGL.State.stereoRender = true;
+}
+
+// Disable stereo rendering
+void rlDisableStereoRender(void)
+{
+ RLGL.State.stereoRender = false;
+}
+
// Unload framebuffer from GPU memory
// NOTE: All attached textures/cubemaps/renderbuffers are also deleted
void rlUnloadFramebuffer(unsigned int id)
@@ -2889,16 +2851,21 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
}
int eyesCount = 1;
-#if defined(SUPPORT_VR_SIMULATOR)
- if (RLGL.Vr.stereoRender) eyesCount = 2;
-#endif
+ if (RLGL.State.stereoRender) eyesCount = 2;
for (int eye = 0; eye < eyesCount; eye++)
{
if (eyesCount == 1) RLGL.State.modelview = matModelView;
- #if defined(SUPPORT_VR_SIMULATOR)
- else SetStereoView(eye, matProjection, matModelView);
- #endif
+ else
+ {
+ // Setup current eye viewport (half screen width)
+ rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
+
+ // Set current eye view offset to modelview matrix
+ SetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.eyesViewOffset[eye]));
+ // Set current eye projection matrix
+ SetMatrixProjection(RLGL.State.eyesProjection[eye]);
+ }
// Calculate model-view-projection matrix (MVP)
Matrix matMVP = MatrixMultiply(RLGL.State.modelview, RLGL.State.projection); // Transform to screen-space coordinates
@@ -3145,6 +3112,20 @@ void *rlReadTexturePixels(Texture2D texture)
return pixels;
}
+// Set eyes projection matrices for stereo rendering
+void rlSetMatrixProjectionStereo(Matrix right, Matrix left)
+{
+ RLGL.State.eyesProjection[0] = right;
+ RLGL.State.eyesProjection[1] = left;
+}
+
+// Set eyes view offsets matrices for stereo rendering
+void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left)
+{
+ RLGL.State.eyesViewOffset[0] = right;
+ RLGL.State.eyesViewOffset[1] = left;
+}
+
//----------------------------------------------------------------------------------
// Module Functions Definition - Shaders Functions
// NOTE: Those functions are exposed directly to the user in raylib.h
@@ -3813,250 +3794,6 @@ void EndBlendMode(void)
BeginBlendMode(BLEND_ALPHA);
}
-#if defined(SUPPORT_VR_SIMULATOR)
-// Init VR simulator for selected device parameters
-// NOTE: It modifies the global variable: RLGL.Vr.stereoFboId
-void InitVrSimulator(void)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- // Initialize framebuffer and textures for stereo rendering
- // NOTE: Screen size should match HMD aspect ratio
- RLGL.Vr.stereoFboId = rlLoadFramebuffer(RLGL.State.framebufferWidth, RLGL.State.framebufferHeight);
-
- // Load color/depth textures to attach to framebuffer
- RLGL.Vr.stereoTexId = rlLoadTexture(NULL, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
- unsigned int depthId = rlLoadTextureDepth(RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, true);
-
- // Attach color texture and depth renderbuffer/texture to FBO
- rlFramebufferAttach(RLGL.Vr.stereoFboId, RLGL.Vr.stereoTexId, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D);
- rlFramebufferAttach(RLGL.Vr.stereoFboId, depthId, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER);
-
- RLGL.Vr.simulatorReady = true;
-#else
- TRACELOG(LOG_WARNING, "RLGL: VR Simulator not supported on OpenGL 1.1");
-#endif
-}
-
-// Update VR tracking (position and orientation) and camera
-// NOTE: Camera (position, target, up) gets update with head tracking information
-void UpdateVrTracking(Camera *camera)
-{
- // TODO: Simulate 1st person camera system
-}
-
-// Close VR simulator for current device
-void CloseVrSimulator(void)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if (RLGL.Vr.simulatorReady)
- {
- rlUnloadTexture(RLGL.Vr.stereoTexId); // Unload color texture
- rlUnloadFramebuffer(RLGL.Vr.stereoFboId); // Unload stereo framebuffer and depth texture/renderbuffer
- }
-#endif
-}
-
-// Set stereo rendering configuration parameters
-void SetVrConfiguration(VrDeviceInfo hmd, Shader distortion)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- // Reset RLGL.Vr.config for a new values assignment
- memset(&RLGL.Vr.config, 0, sizeof(RLGL.Vr.config));
-
- // Assign distortion shader
- RLGL.Vr.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 = fabsf(-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;
-
- TRACELOGD("RLGL: VR device configuration:");
- TRACELOGD(" > 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 };
-
- TRACELOGD(" > Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
- TRACELOGD(" > Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
- TRACELOGD(" > Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]);
- TRACELOGD(" > Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]);
-
- // Fovy is normally computed with: 2*atan2f(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)
- // ...but with lens distortion it is increased (see Oculus SDK Documentation)
- //float fovy = 2.0f*atan2f(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance); // Really need distortionScale?
- float fovy = 2.0f*(float)atan2f(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, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
- RLGL.Vr.config.eyesProjection[0] = MatrixMultiply(proj, MatrixTranslate(projOffset, 0.0f, 0.0f));
- RLGL.Vr.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.
- RLGL.Vr.config.eyesViewOffset[0] = MatrixTranslate(-hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
- RLGL.Vr.config.eyesViewOffset[1] = MatrixTranslate(hmd.interpupillaryDistance*0.5f, 0.075f, 0.045f);
-
- // Compute eyes Viewports
- RLGL.Vr.config.eyeViewportRight[2] = hmd.hResolution/2;
- RLGL.Vr.config.eyeViewportRight[3] = hmd.vResolution;
-
- RLGL.Vr.config.eyeViewportLeft[0] = hmd.hResolution/2;
- RLGL.Vr.config.eyeViewportLeft[1] = 0;
- RLGL.Vr.config.eyeViewportLeft[2] = hmd.hResolution/2;
- RLGL.Vr.config.eyeViewportLeft[3] = hmd.vResolution;
-
- if (RLGL.Vr.config.distortionShader.id > 0)
- {
- // Update distortion shader with lens and distortion-scale parameters
- SetShaderValue(RLGL.Vr.config.distortionShader, GetShaderLocation(RLGL.Vr.config.distortionShader, "leftLensCenter"), leftLensCenter, SHADER_UNIFORM_VEC2);
- SetShaderValue(RLGL.Vr.config.distortionShader, GetShaderLocation(RLGL.Vr.config.distortionShader, "rightLensCenter"), rightLensCenter, SHADER_UNIFORM_VEC2);
- SetShaderValue(RLGL.Vr.config.distortionShader, GetShaderLocation(RLGL.Vr.config.distortionShader, "leftScreenCenter"), leftScreenCenter, SHADER_UNIFORM_VEC2);
- SetShaderValue(RLGL.Vr.config.distortionShader, GetShaderLocation(RLGL.Vr.config.distortionShader, "rightScreenCenter"), rightScreenCenter, SHADER_UNIFORM_VEC2);
-
- SetShaderValue(RLGL.Vr.config.distortionShader, GetShaderLocation(RLGL.Vr.config.distortionShader, "scale"), scale, SHADER_UNIFORM_VEC2);
- SetShaderValue(RLGL.Vr.config.distortionShader, GetShaderLocation(RLGL.Vr.config.distortionShader, "scaleIn"), scaleIn, SHADER_UNIFORM_VEC2);
- SetShaderValue(RLGL.Vr.config.distortionShader, GetShaderLocation(RLGL.Vr.config.distortionShader, "hmdWarpParam"), hmd.lensDistortionValues, SHADER_UNIFORM_VEC4);
- SetShaderValue(RLGL.Vr.config.distortionShader, GetShaderLocation(RLGL.Vr.config.distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, SHADER_UNIFORM_VEC4);
- }
-#endif
-}
-
-// Detect if VR simulator is running
-bool IsVrSimulatorReady(void)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- return RLGL.Vr.simulatorReady;
-#else
- return false;
-#endif
-}
-
-// Enable/Disable VR experience (device or simulator)
-void ToggleVrMode(void)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- RLGL.Vr.simulatorReady = !RLGL.Vr.simulatorReady;
-
- if (!RLGL.Vr.simulatorReady)
- {
- RLGL.Vr.stereoRender = false;
-
- // Reset viewport and default projection-modelview matrices
- rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight);
- RLGL.State.projection = MatrixOrtho(0.0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, 0.0, 0.0, 1.0);
- RLGL.State.modelview = MatrixIdentity();
- }
- else RLGL.Vr.stereoRender = true;
-#endif
-}
-
-// Begin VR drawing configuration
-void BeginVrDrawing(void)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if (RLGL.Vr.simulatorReady)
- {
- rlEnableFramebuffer(RLGL.Vr.stereoFboId); // Setup framebuffer for stereo rendering
- //glEnable(GL_FRAMEBUFFER_SRGB); // Enable SRGB framebuffer (only if required)
-
- //rlViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
- rlClearScreenBuffers(); // Clear current framebuffer
-
- RLGL.Vr.stereoRender = true;
- }
-#endif
-}
-
-// End VR drawing process (and desktop mirror)
-void EndVrDrawing(void)
-{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if (RLGL.Vr.simulatorReady)
- {
- RLGL.Vr.stereoRender = false; // Disable stereo render
-
- rlDisableFramebuffer(); // Unbind current framebuffer
-
- rlClearScreenBuffers(); // Clear current framebuffer
-
- // Set viewport to default framebuffer size (screen size)
- rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight);
-
- // Let rlgl reconfigure internal matrices
- rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix
- rlLoadIdentity(); // Reset internal projection matrix
- rlOrtho(0.0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, 0.0, 0.0, 1.0); // Recalculate internal RLGL.State.projection matrix
- rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
- rlLoadIdentity(); // Reset internal modelview matrix
-
- // Draw stereo framebuffer texture using distortion shader if available
- if (RLGL.Vr.config.distortionShader.id > 0) RLGL.State.currentShader = RLGL.Vr.config.distortionShader;
- else RLGL.State.currentShader = GetShaderDefault();
-
- rlEnableTexture(RLGL.Vr.stereoTexId);
-
- rlPushMatrix();
- rlBegin(RL_QUADS);
- rlColor4ub(255, 255, 255, 255);
- rlNormal3f(0.0f, 0.0f, 1.0f);
-
- // Bottom-left corner for texture and quad
- rlTexCoord2f(0.0f, 1.0f);
- rlVertex2f(0.0f, 0.0f);
-
- // Bottom-right corner for texture and quad
- rlTexCoord2f(0.0f, 0.0f);
- rlVertex2f(0.0f, (float)RLGL.State.framebufferHeight);
-
- // Top-right corner for texture and quad
- rlTexCoord2f(1.0f, 0.0f);
- rlVertex2f((float)RLGL.State.framebufferWidth, (float)RLGL.State.framebufferHeight);
-
- // Top-left corner for texture and quad
- rlTexCoord2f(1.0f, 1.0f);
- rlVertex2f((float)RLGL.State.framebufferWidth, 0.0f);
- rlEnd();
- rlPopMatrix();
-
- rlDisableTexture();
-
- // Update and draw render texture fbo with distortion to backbuffer
- DrawRenderBatch(RLGL.currentBatch);
-
- // Restore RLGL.State.defaultShader
- RLGL.State.currentShader = RLGL.State.defaultShader;
-
- // Reset viewport and default projection-modelview matrices
- rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight);
- RLGL.State.projection = MatrixOrtho(0.0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, 0.0, 0.0, 1.0);
- RLGL.State.modelview = MatrixIdentity();
-
- rlDisableDepthTest();
- }
-#endif
-}
-#endif // SUPPORT_VR_SIMULATOR
-
//----------------------------------------------------------------------------------
// Module specific Functions Definition
//----------------------------------------------------------------------------------
@@ -4475,15 +4212,21 @@ static void DrawRenderBatch(RenderBatch *batch)
Matrix matModelView = RLGL.State.modelview;
int eyesCount = 1;
-#if defined(SUPPORT_VR_SIMULATOR)
- if (RLGL.Vr.stereoRender) eyesCount = 2;
-#endif
+ if (RLGL.State.stereoRender) eyesCount = 2;
for (int eye = 0; eye < eyesCount; eye++)
{
-#if defined(SUPPORT_VR_SIMULATOR)
- if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView);
-#endif
+ if (eyesCount == 2)
+ {
+ // Setup current eye viewport (half screen width)
+ rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
+
+ // Set current eye view offset to modelview matrix
+ SetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.eyesViewOffset[eye]));
+ // Set current eye projection matrix
+ SetMatrixProjection(RLGL.State.eyesProjection[eye]);
+ }
+
// Draw buffers
if (batch->vertexBuffer[batch->currentBuffer].vCounter > 0)
{
@@ -4769,28 +4512,6 @@ static void GenDrawCube(void)
glDeleteBuffers(1, &cubeVBO);
glDeleteVertexArrays(1, &cubeVAO);
}
-
-#if defined(SUPPORT_VR_SIMULATOR)
-// Set internal projection and modelview matrix depending on eyes tracking data
-static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView)
-{
- Matrix eyeProjection = matProjection;
- Matrix eyeModelView = matModelView;
-
- // Setup viewport and projection/modelview matrices using tracking data
- rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
-
- // Apply view offset to modelview matrix
- eyeModelView = MatrixMultiply(matModelView, RLGL.Vr.config.eyesViewOffset[eye]);
-
- // Set current eye projection matrix
- eyeProjection = RLGL.Vr.config.eyesProjection[eye];
-
- SetMatrixModelview(eyeModelView);
- SetMatrixProjection(eyeProjection);
-}
-#endif // SUPPORT_VR_SIMULATOR
-
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
#if defined(GRAPHICS_API_OPENGL_11)