aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2016-06-19 19:12:47 +0200
committerraysan5 <raysan5@gmail.com>2016-06-19 19:12:47 +0200
commitb01f5ff6a7e0d7a91057da618a688000eec6365d (patch)
treeab7b0a482a919f7f6b14bf86148b5567d857a541 /src
parent24c9b1f717bd9a6510667907614928188a6b6a6f (diff)
downloadraylib-b01f5ff6a7e0d7a91057da618a688000eec6365d.tar.gz
raylib-b01f5ff6a7e0d7a91057da618a688000eec6365d.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/rlgl.c145
-rw-r--r--src/rlgl.h7
2 files changed, 113 insertions, 39 deletions
diff --git a/src/rlgl.c b/src/rlgl.c
index d68b9109..2d4d951c 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -76,6 +76,7 @@
#include "standard_shader.h" // Standard shader to embed
#endif
+#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code
#if defined(RLGL_OCULUS_SUPPORT)
#include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
#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
#endif
+static bool vrSimulator = false; // VR simulator (stereo rendering on window, without vr device)
+
// Compressed textures support flags
static bool texCompDXTSupported = false; // DDS texture compression 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);
#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 void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required 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
- UpdateDefaultBuffers();
- DrawDefaultBuffers();
+ rlglUpdateDefaultBuffers();
+ rlglDrawDefaultBuffers();
#endif
}
@@ -2471,57 +2474,86 @@ void DestroyLight(Light light)
#endif
}
-#if defined(RLGL_OCULUS_SUPPORT)
-// Init Oculus Rift device
-// NOTE: Device initialization should be done before window creation?
+// Init Oculus Rift device (or Oculus device simulator)
void InitOculusDevice(void)
{
+#if defined(RLGL_OCULUS_SUPPORT)
// Initialize Oculus device
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))
{
- TraceLog(WARNING, "OVR: Could not create Oculus session");
- ovr_Shutdown();
+ TraceLog(WARNING, "OVR: Could not initialize Oculus device");
+ 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);
-
- 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);
+ if (vrSimulator)
+ {
+ // TODO: Initialize framebuffer and textures for stereo rendering
+ // TODO: Load oculus-distortion shader (oculus parameters setup internally)
+ }
}
-// Close Oculus Rift device
+// Close Oculus Rift device (or Oculus device simulator)
void CloseOculusDevice(void)
{
+#if defined(RLGL_OCULUS_SUPPORT)
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
ovr_Destroy(session); // Free Oculus session data
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)
void UpdateOculusTracking(void)
{
+#if defined(RLGL_OCULUS_SUPPORT)
frameIndex++;
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.HmdMounted) // HMD is on the user's head.
//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)
{
+ 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);
Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x,
@@ -2557,16 +2600,26 @@ void SetOculusView(int eye)
-layer.eyeLayer.RenderPose[eye].Position.z);
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)
+ eyeProjection = layer.eyeProjections[eye];
+#endif
+
+ if (vrSimulator)
+ {
+ // TODO: Setup viewport and projection/modelview matrices using tracking data
+ }
+
SetMatrixModelview(eyeModelView);
- SetMatrixProjection(layer.eyeProjections[eye]);
+ SetMatrixProjection(eyeProjection);
}
+// Begin Oculus drawing configuration
void BeginOculusDrawing(void)
{
+#if defined(RLGL_OCULUS_SUPPORT)
GLuint currentTexId;
int currentIndex;
@@ -2576,6 +2629,13 @@ void BeginOculusDrawing(void)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
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
+#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)
// 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)
}
+// End Oculus drawing process (and desktop mirror)
void EndOculusDrawing(void)
{
+#if defined(RLGL_OCULUS_SUPPORT)
// Unbind current framebuffer (Oculus buffer)
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
@@ -2600,10 +2662,21 @@ void EndOculusDrawing(void)
// Blit mirror texture to back buffer
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();
}
-#endif
//----------------------------------------------------------------------------------
// Module specific Functions Definition
diff --git a/src/rlgl.h b/src/rlgl.h
index 8904b9ac..e2e1dde6 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -48,7 +48,7 @@
// 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_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
// 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 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
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
@@ -353,14 +356,12 @@ void DestroyLight(Light light); // Destroy a
void TraceLog(int msgType, const char *text, ...);
#endif
-#if defined(RLGL_OCULUS_SUPPORT)
void InitOculusDevice(void); // Init Oculus Rift device
void CloseOculusDevice(void); // Close Oculus Rift device
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 BeginOculusDrawing(void); // Begin Oculus drawing configuration
void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror)
-#endif
#ifdef __cplusplus
}