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.
This commit is contained in:
parent
4fba09794f
commit
a76fcaba3e
5 changed files with 300 additions and 403 deletions
|
@ -2,10 +2,10 @@
|
||||||
*
|
*
|
||||||
* raylib [core] example - VR Simulator (Oculus Rift CV1 parameters)
|
* raylib [core] example - VR Simulator (Oculus Rift CV1 parameters)
|
||||||
*
|
*
|
||||||
* This example has been created using raylib 1.7 (www.raylib.com)
|
* This example has been created using raylib 3.6-dev (www.raylib.com)
|
||||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
|
* Copyright (c) 2017-2021 Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
|
@ -25,40 +25,55 @@ int main(void)
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
// NOTE: screenWidth/screenHeight should match VR device aspect ratio
|
// NOTE: screenWidth/screenHeight should match VR device aspect ratio
|
||||||
|
|
||||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator");
|
||||||
|
|
||||||
// Init VR simulator (Oculus Rift CV1 parameters)
|
// VR device parameters definition
|
||||||
InitVrSimulator();
|
VrDeviceInfo device = {
|
||||||
|
|
||||||
VrDeviceInfo hmd = { 0 }; // VR device parameters (head-mounted-device)
|
|
||||||
|
|
||||||
// Oculus Rift CV1 parameters for simulator
|
// Oculus Rift CV1 parameters for simulator
|
||||||
hmd.hResolution = 2160; // HMD horizontal resolution in pixels
|
.hResolution = 2160, // Horizontal resolution in pixels
|
||||||
hmd.vResolution = 1200; // HMD vertical resolution in pixels
|
.vResolution = 1200, // Vertical resolution in pixels
|
||||||
hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters
|
.hScreenSize = 0.133793f, // Horizontal size in meters
|
||||||
hmd.vScreenSize = 0.0669f; // HMD vertical size in meters
|
.vScreenSize = 0.0669f, // Vertical size in meters
|
||||||
hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
|
.vScreenCenter = 0.04678f, // Screen center in meters
|
||||||
hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
|
.eyeToScreenDistance = 0.041f, // Distance between eye and display in meters
|
||||||
hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters
|
.lensSeparationDistance = 0.07f, // Lens separation distance in meters
|
||||||
hmd.interpupillaryDistance = 0.07f; // HMD IPD (distance between pupils) in meters
|
.interpupillaryDistance = 0.07f, // IPD (distance between pupils) in meters
|
||||||
|
|
||||||
// NOTE: CV1 uses a Fresnel-hybrid-asymmetric lenses with specific distortion compute shaders.
|
// 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.
|
// 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
|
.lensDistortionValues[0] = 1.0f, // Lens distortion constant parameter 0
|
||||||
hmd.lensDistortionValues[1] = 0.22f; // HMD lens distortion constant parameter 1
|
.lensDistortionValues[1] = 0.22f, // Lens distortion constant parameter 1
|
||||||
hmd.lensDistortionValues[2] = 0.24f; // HMD lens distortion constant parameter 2
|
.lensDistortionValues[2] = 0.24f, // Lens distortion constant parameter 2
|
||||||
hmd.lensDistortionValues[3] = 0.0f; // HMD lens distortion constant parameter 3
|
.lensDistortionValues[3] = 0.0f, // Lens distortion constant parameter 3
|
||||||
hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0
|
.chromaAbCorrection[0] = 0.996f, // Chromatic aberration correction parameter 0
|
||||||
hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1
|
.chromaAbCorrection[1] = -0.004f, // Chromatic aberration correction parameter 1
|
||||||
hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2
|
.chromaAbCorrection[2] = 1.014f, // Chromatic aberration correction parameter 2
|
||||||
hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3
|
.chromaAbCorrection[3] = 0.0f, // Chromatic aberration correction parameter 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// Init VR simulator (Oculus Rift CV1 parameters)
|
||||||
|
InitVrSimulator(device);
|
||||||
|
|
||||||
|
// Get Vr stereo config parameters for device parameters
|
||||||
|
VrStereoConfig config = GetVrConfig(device);
|
||||||
|
|
||||||
// Distortion shader (uses device lens distortion and chroma)
|
// Distortion shader (uses device lens distortion and chroma)
|
||||||
Shader distortion = LoadShader(0, TextFormat("resources/distortion%i.fs", GLSL_VERSION));
|
Shader distortion = LoadShader(0, TextFormat("resources/distortion%i.fs", GLSL_VERSION));
|
||||||
|
|
||||||
SetVrConfiguration(hmd, distortion); // Set Vr device parameters for stereo rendering
|
// Update distortion shader with lens and distortion-scale parameters
|
||||||
|
SetShaderValue(distortion, GetShaderLocation(distortion, "leftLensCenter"), config.leftLensCenter, SHADER_UNIFORM_VEC2);
|
||||||
|
SetShaderValue(distortion, GetShaderLocation(distortion, "rightLensCenter"), config.rightLensCenter, SHADER_UNIFORM_VEC2);
|
||||||
|
SetShaderValue(distortion, GetShaderLocation(distortion, "leftScreenCenter"), config.leftScreenCenter, SHADER_UNIFORM_VEC2);
|
||||||
|
SetShaderValue(distortion, GetShaderLocation(distortion, "rightScreenCenter"), config.rightScreenCenter, SHADER_UNIFORM_VEC2);
|
||||||
|
|
||||||
|
SetShaderValue(distortion, GetShaderLocation(distortion, "scale"), config.scale, SHADER_UNIFORM_VEC2);
|
||||||
|
SetShaderValue(distortion, GetShaderLocation(distortion, "scaleIn"), config.scaleIn, SHADER_UNIFORM_VEC2);
|
||||||
|
SetShaderValue(distortion, GetShaderLocation(distortion, "deviceWarpParam"), device.lensDistortionValues, SHADER_UNIFORM_VEC4);
|
||||||
|
SetShaderValue(distortion, GetShaderLocation(distortion, "chromaAbParam"), device.chromaAbCorrection, SHADER_UNIFORM_VEC4);
|
||||||
|
|
||||||
|
// Initialize framebuffer for stereo rendering
|
||||||
|
// NOTE: Screen size should match HMD aspect ratio
|
||||||
|
RenderTexture2D target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
|
@ -81,8 +96,6 @@ int main(void)
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera); // Update camera (simulator mode)
|
UpdateCamera(&camera); // Update camera (simulator mode)
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); // Toggle VR mode
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -91,8 +104,7 @@ int main(void)
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
BeginVrDrawing();
|
BeginVrDrawing(target);
|
||||||
|
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
|
|
||||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||||
|
@ -101,9 +113,12 @@ int main(void)
|
||||||
DrawGrid(40, 1.0f);
|
DrawGrid(40, 1.0f);
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
EndVrDrawing();
|
EndVrDrawing();
|
||||||
|
|
||||||
|
BeginShaderMode(distortion);
|
||||||
|
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
|
||||||
|
EndShaderMode();
|
||||||
|
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
@ -112,6 +127,7 @@ int main(void)
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadRenderTexture(target); // Unload stereo render fbo
|
||||||
UnloadShader(distortion); // Unload distortion shader
|
UnloadShader(distortion); // Unload distortion shader
|
||||||
|
|
||||||
CloseVrSimulator(); // Close VR simulator
|
CloseVrSimulator(); // Close VR simulator
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
#define SUPPORT_COMPRESSION_API 1
|
#define SUPPORT_COMPRESSION_API 1
|
||||||
// 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_DATA_STORAGE 1
|
#define SUPPORT_DATA_STORAGE 1
|
||||||
|
// Support VR simulation functionality (stereo rendering)
|
||||||
|
#define SUPPORT_VR_SIMULATOR 1
|
||||||
|
|
||||||
// core: Configuration values
|
// core: Configuration values
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
@ -78,12 +80,7 @@
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module: rlgl - Configuration Flags
|
// Module: rlgl - Configuration values
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
// Support VR simulation functionality (stereo rendering)
|
|
||||||
#define SUPPORT_VR_SIMULATOR 1
|
|
||||||
|
|
||||||
// rlgl: Configuration values
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||||
#define DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch limits
|
#define DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch limits
|
||||||
|
|
155
src/core.c
155
src/core.c
|
@ -80,7 +80,10 @@
|
||||||
* for linkage
|
* for linkage
|
||||||
*
|
*
|
||||||
* #define SUPPORT_DATA_STORAGE
|
* #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:
|
* DEPENDENCIES:
|
||||||
* rglfw - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX. FreeBSD, OpenBSD, NetBSD, DragonFly)
|
* 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
|
unsigned long long base; // Base time measure for hi-res timer
|
||||||
#endif
|
#endif
|
||||||
} Time;
|
} 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;
|
} CoreData;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -2000,6 +2012,147 @@ void EndTextureMode(void)
|
||||||
CORE.Window.currentFbo.height = CORE.Window.screen.height;
|
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)
|
// Begin scissor mode (define screen area for following drawing)
|
||||||
// NOTE: Scissor rec refers to bottom-left corner, we change it to upper-left
|
// NOTE: Scissor rec refers to bottom-left corner, we change it to upper-left
|
||||||
void BeginScissorMode(int x, int y, int width, int height)
|
void BeginScissorMode(int x, int y, int width, int height)
|
||||||
|
|
40
src/raylib.h
40
src/raylib.h
|
@ -449,18 +449,28 @@ typedef struct Music {
|
||||||
|
|
||||||
// Head-Mounted-Display device parameters
|
// Head-Mounted-Display device parameters
|
||||||
typedef struct VrDeviceInfo {
|
typedef struct VrDeviceInfo {
|
||||||
int hResolution; // HMD horizontal resolution in pixels
|
int hResolution; // Horizontal resolution in pixels
|
||||||
int vResolution; // HMD vertical resolution in pixels
|
int vResolution; // Vertical resolution in pixels
|
||||||
float hScreenSize; // HMD horizontal size in meters
|
float hScreenSize; // Horizontal size in meters
|
||||||
float vScreenSize; // HMD vertical size in meters
|
float vScreenSize; // Vertical size in meters
|
||||||
float vScreenCenter; // HMD screen center in meters
|
float vScreenCenter; // Screen center in meters
|
||||||
float eyeToScreenDistance; // HMD distance between eye and display in meters
|
float eyeToScreenDistance; // Distance between eye and display in meters
|
||||||
float lensSeparationDistance; // HMD lens separation distance in meters
|
float lensSeparationDistance; // Lens separation distance in meters
|
||||||
float interpupillaryDistance; // HMD IPD (distance between pupils) in meters
|
float interpupillaryDistance; // IPD (distance between pupils) in meters
|
||||||
float lensDistortionValues[4]; // HMD lens distortion constant parameters
|
float lensDistortionValues[4]; // Lens distortion constant parameters
|
||||||
float chromaAbCorrection[4]; // HMD chromatic aberration correction parameters
|
float chromaAbCorrection[4]; // Chromatic aberration correction parameters
|
||||||
} VrDeviceInfo;
|
} 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
|
// Enumerators Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -1441,14 +1451,14 @@ RLAPI void BeginBlendMode(int mode); // Beg
|
||||||
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
|
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
|
||||||
|
|
||||||
// VR control functions
|
// 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 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 bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
|
||||||
RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
|
RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
|
||||||
RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering
|
RLAPI void BeginVrDrawing(RenderTexture2D target); // Begin VR simulator stereo rendering (using provided fbo)
|
||||||
RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
|
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)
|
// Audio Loading and Playing Functions (Module: audio)
|
||||||
|
|
403
src/rlgl.h
403
src/rlgl.h
|
@ -29,8 +29,6 @@
|
||||||
* #define RLGL_STANDALONE
|
* #define RLGL_STANDALONE
|
||||||
* Use rlgl as standalone library (no raylib dependency)
|
* Use rlgl as standalone library (no raylib dependency)
|
||||||
*
|
*
|
||||||
* #define SUPPORT_VR_SIMULATOR
|
|
||||||
* Support VR simulation functionality (stereo rendering)
|
|
||||||
*
|
*
|
||||||
* DEPENDENCIES:
|
* DEPENDENCIES:
|
||||||
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
|
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
|
||||||
|
@ -327,29 +325,6 @@ typedef enum {
|
||||||
float fovy; // Camera field-of-view apperture in Y (degrees)
|
float fovy; // Camera field-of-view apperture in Y (degrees)
|
||||||
} Camera;
|
} 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
|
// TraceLog message types
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LOG_ALL,
|
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 float rlGetLineWidth(void); // Get the line drawing width
|
||||||
RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
|
RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
|
||||||
RLAPI void rlDisableSmoothLines(void); // Disable 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 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)
|
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 void *rlReadTexturePixels(Texture2D texture); // Read texture pixel data
|
||||||
RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
|
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)
|
// Framebuffer management (fbo)
|
||||||
RLAPI unsigned int rlLoadFramebuffer(int width, int height); // Load an empty framebuffer
|
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
|
RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType); // Attach texture/renderbuffer to a framebuffer
|
||||||
|
@ -605,6 +585,7 @@ RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat);
|
||||||
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
|
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 void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
|
||||||
RLAPI Matrix GetMatrixModelview(void); // Get internal modelview matrix
|
RLAPI Matrix GetMatrixModelview(void); // Get internal modelview matrix
|
||||||
|
RLAPI Matrix GetMatrixProjection(void); // Get internal projection matrix
|
||||||
|
|
||||||
// Texture maps generation (PBR)
|
// Texture maps generation (PBR)
|
||||||
// NOTE: Required shaders should be provided
|
// 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 BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
|
||||||
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
|
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 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)
|
RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data size in bytes (image or texture)
|
||||||
#endif
|
#endif
|
||||||
|
@ -847,17 +818,6 @@ typedef struct RenderBatch {
|
||||||
float currentDepth; // Current depth value for next draw
|
float currentDepth; // Current depth value for next draw
|
||||||
} RenderBatch;
|
} 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)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
typedef struct rlglData {
|
typedef struct rlglData {
|
||||||
RenderBatch *currentBatch; // Current render batch
|
RenderBatch *currentBatch; // Current render batch
|
||||||
|
@ -882,6 +842,10 @@ typedef struct rlglData {
|
||||||
Shader defaultShader; // Basic shader, support vertex color and diffuse texture
|
Shader defaultShader; // Basic shader, support vertex color and diffuse texture
|
||||||
Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
|
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 currentBlendMode; // Blending mode active
|
||||||
int glBlendSrcFactor; // Blending source factor
|
int glBlendSrcFactor; // Blending source factor
|
||||||
int glBlendDstFactor; // Blending destination factor
|
int glBlendDstFactor; // Blending destination factor
|
||||||
|
@ -910,15 +874,6 @@ typedef struct rlglData {
|
||||||
int maxDepthBits; // Maximum bits for depth component
|
int maxDepthBits; // Maximum bits for depth component
|
||||||
|
|
||||||
} ExtSupported; // Extensions supported flags
|
} 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;
|
} rlglData;
|
||||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
#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 GenDrawCube(void); // Generate and draw cube
|
||||||
static void GenDrawQuad(void); // Generate and draw quad
|
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
|
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_11)
|
#if defined(GRAPHICS_API_OPENGL_11)
|
||||||
|
@ -1469,13 +1419,13 @@ void rlEnableBackfaceCulling(void) { glEnable(GL_CULL_FACE); }
|
||||||
void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); }
|
void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); }
|
||||||
|
|
||||||
// Enable scissor test
|
// Enable scissor test
|
||||||
RLAPI void rlEnableScissorTest(void) { glEnable(GL_SCISSOR_TEST); }
|
void rlEnableScissorTest(void) { glEnable(GL_SCISSOR_TEST); }
|
||||||
|
|
||||||
// Disable scissor test
|
// Disable scissor test
|
||||||
RLAPI void rlDisableScissorTest(void) { glDisable(GL_SCISSOR_TEST); }
|
void rlDisableScissorTest(void) { glDisable(GL_SCISSOR_TEST); }
|
||||||
|
|
||||||
// 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
|
// Enable wire mode
|
||||||
void rlEnableWireMode(void)
|
void rlEnableWireMode(void)
|
||||||
|
@ -1524,6 +1474,18 @@ void rlDisableSmoothLines(void)
|
||||||
#endif
|
#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
|
// Unload framebuffer from GPU memory
|
||||||
// NOTE: All attached textures/cubemaps/renderbuffers are also deleted
|
// NOTE: All attached textures/cubemaps/renderbuffers are also deleted
|
||||||
void rlUnloadFramebuffer(unsigned int id)
|
void rlUnloadFramebuffer(unsigned int id)
|
||||||
|
@ -2889,16 +2851,21 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
}
|
}
|
||||||
|
|
||||||
int eyesCount = 1;
|
int eyesCount = 1;
|
||||||
#if defined(SUPPORT_VR_SIMULATOR)
|
if (RLGL.State.stereoRender) eyesCount = 2;
|
||||||
if (RLGL.Vr.stereoRender) eyesCount = 2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int eye = 0; eye < eyesCount; eye++)
|
for (int eye = 0; eye < eyesCount; eye++)
|
||||||
{
|
{
|
||||||
if (eyesCount == 1) RLGL.State.modelview = matModelView;
|
if (eyesCount == 1) RLGL.State.modelview = matModelView;
|
||||||
#if defined(SUPPORT_VR_SIMULATOR)
|
else
|
||||||
else SetStereoView(eye, matProjection, matModelView);
|
{
|
||||||
#endif
|
// 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)
|
// Calculate model-view-projection matrix (MVP)
|
||||||
Matrix matMVP = MatrixMultiply(RLGL.State.modelview, RLGL.State.projection); // Transform to screen-space coordinates
|
Matrix matMVP = MatrixMultiply(RLGL.State.modelview, RLGL.State.projection); // Transform to screen-space coordinates
|
||||||
|
@ -3145,6 +3112,20 @@ void *rlReadTexturePixels(Texture2D texture)
|
||||||
return pixels;
|
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
|
// Module Functions Definition - Shaders Functions
|
||||||
// NOTE: Those functions are exposed directly to the user in raylib.h
|
// NOTE: Those functions are exposed directly to the user in raylib.h
|
||||||
|
@ -3813,250 +3794,6 @@ void EndBlendMode(void)
|
||||||
BeginBlendMode(BLEND_ALPHA);
|
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
|
// Module specific Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -4475,15 +4212,21 @@ static void DrawRenderBatch(RenderBatch *batch)
|
||||||
Matrix matModelView = RLGL.State.modelview;
|
Matrix matModelView = RLGL.State.modelview;
|
||||||
|
|
||||||
int eyesCount = 1;
|
int eyesCount = 1;
|
||||||
#if defined(SUPPORT_VR_SIMULATOR)
|
if (RLGL.State.stereoRender) eyesCount = 2;
|
||||||
if (RLGL.Vr.stereoRender) eyesCount = 2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int eye = 0; eye < eyesCount; eye++)
|
for (int eye = 0; eye < eyesCount; eye++)
|
||||||
{
|
{
|
||||||
#if defined(SUPPORT_VR_SIMULATOR)
|
if (eyesCount == 2)
|
||||||
if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView);
|
{
|
||||||
#endif
|
// 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
|
// Draw buffers
|
||||||
if (batch->vertexBuffer[batch->currentBuffer].vCounter > 0)
|
if (batch->vertexBuffer[batch->currentBuffer].vCounter > 0)
|
||||||
{
|
{
|
||||||
|
@ -4769,28 +4512,6 @@ static void GenDrawCube(void)
|
||||||
glDeleteBuffers(1, &cubeVBO);
|
glDeleteBuffers(1, &cubeVBO);
|
||||||
glDeleteVertexArrays(1, &cubeVAO);
|
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
|
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_11)
|
#if defined(GRAPHICS_API_OPENGL_11)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue