Starting work on VR simulator support
If Oculus device is not available or not initialized correctly, simulated VR view is generated using stereo-rendering and distortion
This commit is contained in:
parent
24c9b1f717
commit
b01f5ff6a7
2 changed files with 113 additions and 39 deletions
145
src/rlgl.c
145
src/rlgl.c
|
@ -76,6 +76,7 @@
|
||||||
#include "standard_shader.h" // Standard shader to embed
|
#include "standard_shader.h" // Standard shader to embed
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code
|
||||||
#if defined(RLGL_OCULUS_SUPPORT)
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
#include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
|
#include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
|
||||||
#endif
|
#endif
|
||||||
|
@ -266,6 +267,8 @@ static OculusMirror mirror; // Oculus mirror texture and fbo
|
||||||
static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain
|
static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool vrSimulator = false; // VR simulator (stereo rendering on window, without vr device)
|
||||||
|
|
||||||
// Compressed textures support flags
|
// Compressed textures support flags
|
||||||
static bool texCompDXTSupported = false; // DDS texture compression support
|
static bool texCompDXTSupported = false; // DDS texture compression support
|
||||||
static bool npotSupported = false; // NPOT textures full support
|
static bool npotSupported = false; // NPOT textures full support
|
||||||
|
@ -306,7 +309,7 @@ static void SetShaderLights(Shader shader); // Sets shader uniform values for li
|
||||||
static char *ReadTextFile(const char *fileName);
|
static char *ReadTextFile(const char *fileName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RLGL_OCULUS_SUPPORT) // Oculus Rift functions
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers
|
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers
|
||||||
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers
|
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers
|
||||||
static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers
|
static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers
|
||||||
|
@ -1158,8 +1161,8 @@ void rlglDraw(void)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// NOTE: Default buffers always drawn at the end
|
// NOTE: Default buffers always drawn at the end
|
||||||
UpdateDefaultBuffers();
|
rlglUpdateDefaultBuffers();
|
||||||
DrawDefaultBuffers();
|
rlglDrawDefaultBuffers();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2471,57 +2474,86 @@ void DestroyLight(Light light)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(RLGL_OCULUS_SUPPORT)
|
// Init Oculus Rift device (or Oculus device simulator)
|
||||||
// Init Oculus Rift device
|
|
||||||
// NOTE: Device initialization should be done before window creation?
|
|
||||||
void InitOculusDevice(void)
|
void InitOculusDevice(void)
|
||||||
{
|
{
|
||||||
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
// Initialize Oculus device
|
// Initialize Oculus device
|
||||||
ovrResult result = ovr_Initialize(NULL);
|
ovrResult result = ovr_Initialize(NULL);
|
||||||
if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device");
|
|
||||||
|
|
||||||
result = ovr_Create(&session, &luid);
|
|
||||||
if (OVR_FAILURE(result))
|
if (OVR_FAILURE(result))
|
||||||
{
|
{
|
||||||
TraceLog(WARNING, "OVR: Could not create Oculus session");
|
TraceLog(WARNING, "OVR: Could not initialize Oculus device");
|
||||||
ovr_Shutdown();
|
TraceLog(INFO, "VR: Initializing Oculus simulator");
|
||||||
|
vrSimulator = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = ovr_Create(&session, &luid);
|
||||||
|
if (OVR_FAILURE(result))
|
||||||
|
{
|
||||||
|
TraceLog(WARNING, "OVR: Could not create Oculus session");
|
||||||
|
ovr_Shutdown();
|
||||||
|
|
||||||
|
TraceLog(INFO, "VR: Initializing Oculus simulator");
|
||||||
|
vrSimulator = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hmdDesc = ovr_GetHmdDesc(session);
|
||||||
|
|
||||||
|
TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName);
|
||||||
|
TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer);
|
||||||
|
TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId);
|
||||||
|
TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type);
|
||||||
|
//TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber);
|
||||||
|
TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
|
||||||
|
|
||||||
|
// NOTE: Oculus mirror is set to defined screenWidth and screenHeight...
|
||||||
|
// ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2)
|
||||||
|
|
||||||
|
// Initialize Oculus Buffers
|
||||||
|
layer = InitOculusLayer(session);
|
||||||
|
buffer = LoadOculusBuffer(session, layer.width, layer.height);
|
||||||
|
mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded...
|
||||||
|
layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
|
||||||
|
|
||||||
|
// Recenter OVR tracking origin
|
||||||
|
ovr_RecenterTrackingOrigin(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
vrSimulator = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
hmdDesc = ovr_GetHmdDesc(session);
|
if (vrSimulator)
|
||||||
|
{
|
||||||
TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName);
|
// TODO: Initialize framebuffer and textures for stereo rendering
|
||||||
TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer);
|
// TODO: Load oculus-distortion shader (oculus parameters setup internally)
|
||||||
TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId);
|
}
|
||||||
TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type);
|
|
||||||
//TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber);
|
|
||||||
TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
|
|
||||||
|
|
||||||
// NOTE: Oculus mirror is set to defined screenWidth and screenHeight...
|
|
||||||
// ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2)
|
|
||||||
|
|
||||||
// Initialize Oculus Buffers
|
|
||||||
layer = InitOculusLayer(session);
|
|
||||||
buffer = LoadOculusBuffer(session, layer.width, layer.height);
|
|
||||||
mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded...
|
|
||||||
layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
|
|
||||||
|
|
||||||
// Recenter OVR tracking origin
|
|
||||||
ovr_RecenterTrackingOrigin(session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close Oculus Rift device
|
// Close Oculus Rift device (or Oculus device simulator)
|
||||||
void CloseOculusDevice(void)
|
void CloseOculusDevice(void)
|
||||||
{
|
{
|
||||||
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
|
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
|
||||||
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
|
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
|
||||||
|
|
||||||
ovr_Destroy(session); // Free Oculus session data
|
ovr_Destroy(session); // Free Oculus session data
|
||||||
ovr_Shutdown(); // Close Oculus device connection
|
ovr_Shutdown(); // Close Oculus device connection
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (vrSimulator)
|
||||||
|
{
|
||||||
|
// TODO: Unload stereo framebuffer and texture
|
||||||
|
// TODO: Unload oculus-distortion shader
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Oculus Rift tracking (position and orientation)
|
// Update Oculus Rift tracking (position and orientation)
|
||||||
void UpdateOculusTracking(void)
|
void UpdateOculusTracking(void)
|
||||||
{
|
{
|
||||||
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
|
|
||||||
ovrPosef eyePoses[2];
|
ovrPosef eyePoses[2];
|
||||||
|
@ -2540,10 +2572,21 @@ void UpdateOculusTracking(void)
|
||||||
//if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR.
|
//if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR.
|
||||||
//if (sessionStatus.HmdMounted) // HMD is on the user's head.
|
//if (sessionStatus.HmdMounted) // HMD is on the user's head.
|
||||||
//if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD.
|
//if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (vrSimulator)
|
||||||
|
{
|
||||||
|
// TODO: Use alternative inputs (mouse, keyboard) to simulate tracking data (eyes position/orientation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set internal projection and modelview matrix depending on eyes tracking data
|
||||||
void SetOculusView(int eye)
|
void SetOculusView(int eye)
|
||||||
{
|
{
|
||||||
|
Matrix eyeProjection;
|
||||||
|
Matrix eyeModelView;
|
||||||
|
|
||||||
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h);
|
rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h);
|
||||||
|
|
||||||
Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x,
|
Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x,
|
||||||
|
@ -2557,16 +2600,26 @@ void SetOculusView(int eye)
|
||||||
-layer.eyeLayer.RenderPose[eye].Position.z);
|
-layer.eyeLayer.RenderPose[eye].Position.z);
|
||||||
|
|
||||||
Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement
|
Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement
|
||||||
Matrix eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement
|
eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement
|
||||||
|
|
||||||
// TODO: Find a better way to get camera view matrix (instead of using internal modelview)
|
// TODO: Find a better way to get camera view matrix (instead of using internal modelview)
|
||||||
|
|
||||||
|
eyeProjection = layer.eyeProjections[eye];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (vrSimulator)
|
||||||
|
{
|
||||||
|
// TODO: Setup viewport and projection/modelview matrices using tracking data
|
||||||
|
}
|
||||||
|
|
||||||
SetMatrixModelview(eyeModelView);
|
SetMatrixModelview(eyeModelView);
|
||||||
SetMatrixProjection(layer.eyeProjections[eye]);
|
SetMatrixProjection(eyeProjection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Begin Oculus drawing configuration
|
||||||
void BeginOculusDrawing(void)
|
void BeginOculusDrawing(void)
|
||||||
{
|
{
|
||||||
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
GLuint currentTexId;
|
GLuint currentTexId;
|
||||||
int currentIndex;
|
int currentIndex;
|
||||||
|
|
||||||
|
@ -2576,6 +2629,13 @@ void BeginOculusDrawing(void)
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
|
||||||
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded
|
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (vrSimulator)
|
||||||
|
{
|
||||||
|
// TODO: Setup framebuffer for stereo rendering
|
||||||
|
//rlEnableRenderTexture(buffer.fboId);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
|
// NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
|
||||||
// and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
|
// and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
|
||||||
|
@ -2587,8 +2647,10 @@ void BeginOculusDrawing(void)
|
||||||
rlClearScreenBuffers(); // Clear current framebuffer(s)
|
rlClearScreenBuffers(); // Clear current framebuffer(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// End Oculus drawing process (and desktop mirror)
|
||||||
void EndOculusDrawing(void)
|
void EndOculusDrawing(void)
|
||||||
{
|
{
|
||||||
|
#if defined(RLGL_OCULUS_SUPPORT)
|
||||||
// Unbind current framebuffer (Oculus buffer)
|
// Unbind current framebuffer (Oculus buffer)
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
@ -2600,10 +2662,21 @@ void EndOculusDrawing(void)
|
||||||
|
|
||||||
// Blit mirror texture to back buffer
|
// Blit mirror texture to back buffer
|
||||||
BlitOculusMirror(session, mirror);
|
BlitOculusMirror(session, mirror);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (vrSimulator)
|
||||||
|
{
|
||||||
|
// Unbind current framebuffer
|
||||||
|
//rlDisableRenderTexture();
|
||||||
|
|
||||||
|
// TODO: Draw RenderTexture (fbo) using distortion shader
|
||||||
|
//BeginShaderMode(distortion);
|
||||||
|
// TODO: DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
||||||
|
//EndShaderMode();
|
||||||
|
}
|
||||||
|
|
||||||
rlDisableDepthTest();
|
rlDisableDepthTest();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Definition
|
// Module specific Functions Definition
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
// Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33
|
// Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33
|
||||||
//#define GRAPHICS_API_OPENGL_11 // Only available on PLATFORM_DESKTOP
|
//#define GRAPHICS_API_OPENGL_11 // Only available on PLATFORM_DESKTOP
|
||||||
//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP or PLATFORM_OCULUS
|
//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP and RLGL_OCULUS_SUPPORT
|
||||||
//#define GRAPHICS_API_OPENGL_ES2 // Only available on PLATFORM_ANDROID or PLATFORM_RPI or PLATFORM_WEB
|
//#define GRAPHICS_API_OPENGL_ES2 // Only available on PLATFORM_ANDROID or PLATFORM_RPI or PLATFORM_WEB
|
||||||
|
|
||||||
// Security check in case no GRAPHICS_API_OPENGL_* defined
|
// Security check in case no GRAPHICS_API_OPENGL_* defined
|
||||||
|
@ -304,6 +304,9 @@ void rlglDraw(void); // Draw VAO/VBO
|
||||||
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
|
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
|
||||||
void rlglLoadExtensions(void *loader); // Load OpenGL extensions
|
void rlglLoadExtensions(void *loader); // Load OpenGL extensions
|
||||||
|
|
||||||
|
void rlglUpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data
|
||||||
|
void rlglDrawDefaultBuffers(void); // Draw default internal buffers vertex data
|
||||||
|
|
||||||
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU
|
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU
|
||||||
RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments)
|
RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments)
|
||||||
void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data
|
void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data
|
||||||
|
@ -353,14 +356,12 @@ void DestroyLight(Light light); // Destroy a
|
||||||
void TraceLog(int msgType, const char *text, ...);
|
void TraceLog(int msgType, const char *text, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RLGL_OCULUS_SUPPORT)
|
|
||||||
void InitOculusDevice(void); // Init Oculus Rift device
|
void InitOculusDevice(void); // Init Oculus Rift device
|
||||||
void CloseOculusDevice(void); // Close Oculus Rift device
|
void CloseOculusDevice(void); // Close Oculus Rift device
|
||||||
void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation)
|
void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation)
|
||||||
void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data
|
void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data
|
||||||
void BeginOculusDrawing(void); // Begin Oculus drawing configuration
|
void BeginOculusDrawing(void); // Begin Oculus drawing configuration
|
||||||
void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror)
|
void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror)
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue