From 70a96fff80d0fb42722788df268b0c8e77e97120 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 8 Jun 2016 13:16:01 +0200 Subject: Simplified Oculus integration --- src/core.c | 48 ++++++------------------------------------------ 1 file changed, 6 insertions(+), 42 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index 4ba7505b..4223afd9 100644 --- a/src/core.c +++ b/src/core.c @@ -513,11 +513,6 @@ void CloseWindow(void) } #endif -#if defined(PLATFORM_OCULUS) - ovr_Destroy(session); // Must be called after glfwTerminate() - ovr_Shutdown(); -#endif - TraceLog(INFO, "Window closed successfully"); } @@ -526,6 +521,7 @@ void CloseWindow(void) // NOTE: Device initialization should be done before window creation? void InitOculusDevice(void) { + // Initialize Oculus device ovrResult result = ovr_Initialize(NULL); if (OVR_FAILURE(result)) TraceLog(ERROR, "OVR: Could not initialize Oculus device"); @@ -545,13 +541,13 @@ void InitOculusDevice(void) TraceLog(INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber); TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); - screenWidth = hmdDesc.Resolution.w/2; - screenHeight = hmdDesc.Resolution.h/2; + // 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); + mirror = LoadOculusMirror(session, screenWidth, screenHeight); layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); } @@ -561,8 +557,8 @@ void CloseOculusDevice(void) UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers - ovr_Destroy(session); // Must be called after glfwTerminate() --> REALLY??? - ovr_Shutdown(); + ovr_Destroy(session); // Free Oculus session data + ovr_Shutdown(); // Close Oculus device connection } // Update Oculus Rift tracking (position and orientation) @@ -1625,31 +1621,7 @@ static void InitDisplay(int width, int height) // Downscale matrix is required in case desired screen area is bigger than display area downscaleView = MatrixIdentity(); - -#if defined(PLATFORM_OCULUS) - ovrResult result = ovr_Initialize(NULL); - if (OVR_FAILURE(result)) TraceLog(ERROR, "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(); - } - 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: Serian Number: %s", hmdDesc.SerialNumber); - TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); - - screenWidth = hmdDesc.Resolution.w/2; - screenHeight = hmdDesc.Resolution.h/2; -#endif - #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) glfwSetErrorCallback(ErrorCallback); @@ -1964,14 +1936,6 @@ static void InitGraphics(void) rlglInit(); // Init rlgl rlglInitGraphics(renderOffsetX, renderOffsetY, renderWidth, renderHeight); // Init graphics (OpenGL stuff) -#if defined(PLATFORM_OCULUS) - // Initialize Oculus Buffers - layer = InitOculusLayer(session); - buffer = LoadOculusBuffer(session, layer.width, layer.height); - mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); - layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); -#endif - ClearBackground(RAYWHITE); // Default background color for raylib games :P #if defined(PLATFORM_ANDROID) -- cgit v1.2.3 From 27ba7de1e4a9d262b2f3039433977d6cffa1da8d Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 11 Jun 2016 14:08:39 +0200 Subject: Added some comments --- src/core.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index 4223afd9..0c1e0454 100644 --- a/src/core.c +++ b/src/core.c @@ -209,23 +209,23 @@ float gamepadAxisValues[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis st #endif #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) -static EGLDisplay display; // Native display device (physical screen connection) -static EGLSurface surface; // Surface to draw on, framebuffers (connected to context) -static EGLContext context; // Graphic context, mode in which drawing can be done -static EGLConfig config; // Graphic config -static uint64_t baseTime; // Base time measure for hi-res timer -static bool windowShouldClose = false; // Flag to set window for closing +static EGLDisplay display; // Native display device (physical screen connection) +static EGLSurface surface; // Surface to draw on, framebuffers (connected to context) +static EGLContext context; // Graphic context, mode in which drawing can be done +static EGLConfig config; // Graphic config +static uint64_t baseTime; // Base time measure for hi-res timer +static bool windowShouldClose = false; // Flag to set window for closing #endif #if defined(PLATFORM_OCULUS) // OVR device variables -static ovrSession session; -static ovrHmdDesc hmdDesc; -static ovrGraphicsLuid luid; -static OculusLayer layer; -static OculusBuffer buffer; -static OculusMirror mirror; -static unsigned int frameIndex = 0; +static ovrSession session; // Oculus session (pointer to ovrHmdStruct) +static ovrHmdDesc hmdDesc; // Oculus device descriptor parameters +static ovrGraphicsLuid luid; // Oculus locally unique identifier for the program (64 bit) +static OculusLayer layer; // Oculus drawing layer (similar to photoshop) +static OculusBuffer buffer; // Oculus internal buffers (texture chain and fbo) +static OculusMirror mirror; // Oculus mirror texture and fbo +static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain #endif static unsigned int displayWidth, displayHeight; // Display width and height (monitor, device-screen, LCD, ...) @@ -280,8 +280,8 @@ static bool showLogo = false; // Track if showing logo at init is //---------------------------------------------------------------------------------- // Other Modules Functions Declaration (required by core) //---------------------------------------------------------------------------------- -extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow() -extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory +extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow() +extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory //---------------------------------------------------------------------------------- // Module specific Functions Declaration @@ -523,7 +523,7 @@ void InitOculusDevice(void) { // Initialize Oculus device ovrResult result = ovr_Initialize(NULL); - if (OVR_FAILURE(result)) TraceLog(ERROR, "OVR: Could not initialize Oculus device"); + if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device"); result = ovr_Create(&session, &luid); if (OVR_FAILURE(result)) @@ -538,7 +538,7 @@ void InitOculusDevice(void) 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: Serian Number: %s", hmdDesc.SerialNumber); + //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... -- cgit v1.2.3 From 66ec0b5d829de6db72d8a7508373ab52a8c3c1f2 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 12 Jun 2016 10:47:50 +0200 Subject: Oculus tracking correction --- src/core.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index 0c1e0454..122453e3 100644 --- a/src/core.c +++ b/src/core.c @@ -565,7 +565,7 @@ void CloseOculusDevice(void) void UpdateOculusTracking(void) { frameIndex++; - + ovrPosef eyePoses[2]; ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); @@ -644,14 +644,6 @@ void BeginDrawing(void) previousTime = currentTime; #if defined(PLATFORM_OCULUS) - frameIndex++; - - ovrPosef eyePoses[2]; - ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); - - layer.eyeLayer.RenderPose[0] = eyePoses[0]; - layer.eyeLayer.RenderPose[1] = eyePoses[1]; - SetOculusBuffer(session, buffer); #endif -- cgit v1.2.3 From c25b4cdc69999c851594f7644ce89556be039c70 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 14 Jun 2016 15:42:04 +0200 Subject: Move OpenGL extensions loading to rlgl --- src/core.c | 20 +++----------------- src/rlgl.c | 21 ++++++++++++++++++++- src/rlgl.h | 3 ++- 3 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index 122453e3..bd49b549 100644 --- a/src/core.c +++ b/src/core.c @@ -58,10 +58,6 @@ #define PLATFORM_DESKTOP // Enable PLATFORM_DESKTOP code-base #endif -#if defined(PLATFORM_DESKTOP) - #include "external/glad.h" // GLAD library: Manage OpenGL headers and extensions -#endif - #if defined(PLATFORM_OCULUS) #include "../examples/oculus_glfw_sample/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL #endif @@ -1747,19 +1743,9 @@ static void InitDisplay(int width, int height) #endif #if defined(PLATFORM_DESKTOP) - // Load OpenGL 3.3 extensions using GLAD - if (rlGetVersion() == OPENGL_33) - { - // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); - else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); - - if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); - else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported"); - - // With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans - //if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object - } + // Load OpenGL 3.3 extensions + // NOTE: GLFW loader function is passed as parameter + rlglLoadExtensions(glfwGetProcAddress); #endif // Enables GPU v-sync, so frames are not limited to screen refresh rate (60Hz -> 60 FPS) diff --git a/src/rlgl.c b/src/rlgl.c index e69ff983..26961ca9 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -872,6 +872,23 @@ int rlGetVersion(void) #endif } +// Load OpenGL extensions +// NOTE: External loader function could be passed as a pointer +void rlglLoadExtensions(void *loader) +{ +#if defined(GRAPHICS_API_OPENGL_33) + // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions + if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); + else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); + + if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); + else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported"); + + // With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans + //if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object +#endif +} + //---------------------------------------------------------------------------------- // Module Functions Definition - rlgl Functions //---------------------------------------------------------------------------------- @@ -1184,11 +1201,13 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma GLuint id = 0; // Check texture format support by OpenGL 1.1 (compressed textures not supported) - if ((rlGetVersion() == OPENGL_11) && (textureFormat >= 8)) +#if defined(GRAPHICS_API_OPENGL_11) + if (textureFormat >= 8) { TraceLog(WARNING, "OpenGL 1.1 does not support GPU compressed texture formats"); return id; } +#endif if ((!texCompDXTSupported) && ((textureFormat == COMPRESSED_DXT1_RGB) || (textureFormat == COMPRESSED_DXT1_RGBA) || (textureFormat == COMPRESSED_DXT3_RGBA) || (textureFormat == COMPRESSED_DXT5_RGBA))) diff --git a/src/rlgl.h b/src/rlgl.h index 9c25f710..28c50b8f 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 +//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP or PLATFORM_OCULUS //#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 @@ -296,6 +296,7 @@ void rlglInit(void); // Initialize rlgl (shaders, VAO void rlglClose(void); // De-init rlgl 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 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) -- cgit v1.2.3 From 3ce02282063b47bd3e0beb0453d33ef316a371fa Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 14 Jun 2016 17:16:20 +0200 Subject: Move Oculus Rift support to rlgl module --- src/core.c | 386 +--------------------------------------------------------- src/raylib.h | 19 +-- src/rlgl.c | 390 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/rlgl.h | 9 ++ 4 files changed, 399 insertions(+), 405 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index bd49b549..fb71af21 100644 --- a/src/core.c +++ b/src/core.c @@ -9,7 +9,7 @@ * PLATFORM_ANDROID - Only OpenGL ES 2.0 devices * PLATFORM_RPI - Rapsberry Pi (tested on Raspbian) * PLATFORM_WEB - Emscripten, HTML5 -* PLATFORM_OCULUS - Oculus Rift CV1 (with desktop mirror) +* Oculus Rift CV1 (with desktop mirror) - View [rlgl] module to enable it * * On PLATFORM_DESKTOP, the external lib GLFW3 (www.glfw.com) is used to manage graphic * device, OpenGL context and input on multiple operating systems (Windows, Linux, OSX). @@ -54,14 +54,6 @@ #include // String function definitions, memset() #include // Macros for reporting and retrieving error conditions through error codes -#if defined(PLATFORM_OCULUS) - #define PLATFORM_DESKTOP // Enable PLATFORM_DESKTOP code-base -#endif - -#if defined(PLATFORM_OCULUS) - #include "../examples/oculus_glfw_sample/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL -#endif - #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) //#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3 #include // GLFW3 library: Windows, OpenGL context and Input management @@ -134,31 +126,7 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -#if defined(PLATFORM_OCULUS) -typedef struct OculusBuffer { - ovrTextureSwapChain textureChain; - GLuint depthId; - GLuint fboId; - int width; - int height; -} OculusBuffer; - -typedef struct OculusMirror { - ovrMirrorTexture texture; - GLuint fboId; - int width; - int height; -} OculusMirror; - -typedef struct OculusLayer { - ovrViewScaleDesc viewScaleDesc; - ovrLayerEyeFov eyeLayer; // layer 0 - //ovrLayerQuad quadLayer; // TODO: layer 1: '2D' quad for GUI - Matrix eyeProjections[2]; - int width; - int height; -} OculusLayer; -#endif +// ... //---------------------------------------------------------------------------------- // Global Variables Definition @@ -213,17 +181,6 @@ static uint64_t baseTime; // Base time measure for hi-res timer static bool windowShouldClose = false; // Flag to set window for closing #endif -#if defined(PLATFORM_OCULUS) -// OVR device variables -static ovrSession session; // Oculus session (pointer to ovrHmdStruct) -static ovrHmdDesc hmdDesc; // Oculus device descriptor parameters -static ovrGraphicsLuid luid; // Oculus locally unique identifier for the program (64 bit) -static OculusLayer layer; // Oculus drawing layer (similar to photoshop) -static OculusBuffer buffer; // Oculus internal buffers (texture chain and fbo) -static OculusMirror mirror; // Oculus mirror texture and fbo -static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain -#endif - static unsigned int displayWidth, displayHeight; // Display width and height (monitor, device-screen, LCD, ...) static int screenWidth, screenHeight; // Screen width and height (used render area) static int renderWidth, renderHeight; // Framebuffer width and height (render area) @@ -233,7 +190,6 @@ static int renderOffsetX = 0; // Offset X from render area (must b static int renderOffsetY = 0; // Offset Y from render area (must be divided by 2) static bool fullscreen = false; // Fullscreen mode (useful only for PLATFORM_DESKTOP) static Matrix downscaleView; // Matrix to downscale view (in case screen size bigger than display size) -static Matrix cameraView; // Store camera view matrix (required for Oculus Rift) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) static const char *windowTitle; // Window text title... @@ -332,19 +288,6 @@ static void InitGamepad(void); // Init raw gamepad inpu static void *GamepadThread(void *arg); // Mouse reading thread #endif -#if defined(PLATFORM_OCULUS) -// Oculus Rift functions -static Matrix FromOvrMatrix(ovrMatrix4f ovrM); -static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); -static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); -static void SetOculusBuffer(ovrSession session, OculusBuffer buffer); -static void UnsetOculusBuffer(OculusBuffer buffer); -static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers -static void UnloadOculusMirror(ovrSession session, OculusMirror mirror); // Unload Oculus mirror buffers -static void BlitOculusMirror(ovrSession session, OculusMirror mirror); -static OculusLayer InitOculusLayer(ovrSession session); -#endif - //---------------------------------------------------------------------------------- // Module Functions Definition - Window and OpenGL Context Functions //---------------------------------------------------------------------------------- @@ -393,11 +336,6 @@ void InitWindow(int width, int height, const char *title) //emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenInputCallback); #endif -#if defined(PLATFORM_OCULUS) - // Recenter OVR tracking origin - ovr_RecenterTrackingOrigin(session); -#endif - mousePosition.x = (float)screenWidth/2.0f; mousePosition.y = (float)screenHeight/2.0f; @@ -512,64 +450,6 @@ void CloseWindow(void) TraceLog(INFO, "Window closed successfully"); } -#if defined(PLATFORM_OCULUS) -// Init Oculus Rift device -// NOTE: Device initialization should be done before window creation? -void InitOculusDevice(void) -{ - // 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(); - } - - 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, screenWidth, screenHeight); - layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); -} - -// Close Oculus Rift device -void CloseOculusDevice(void) -{ - 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 -} - -// Update Oculus Rift tracking (position and orientation) -void UpdateOculusTracking(void) -{ - frameIndex++; - - ovrPosef eyePoses[2]; - ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); - - layer.eyeLayer.RenderPose[0] = eyePoses[0]; - layer.eyeLayer.RenderPose[1] = eyePoses[1]; -} -#endif - // Detect if KEY_ESCAPE pressed or Close icon pressed bool WindowShouldClose(void) { @@ -638,10 +518,6 @@ void BeginDrawing(void) currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called updateTime = currentTime - previousTime; previousTime = currentTime; - -#if defined(PLATFORM_OCULUS) - SetOculusBuffer(session, buffer); -#endif rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -654,49 +530,7 @@ void BeginDrawing(void) // End canvas drawing and Swap Buffers (Double Buffering) void EndDrawing(void) { -#if defined(PLATFORM_OCULUS) - for (int eye = 0; eye < 2; eye++) - { - 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 eyeRPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, - layer.eyeLayer.RenderPose[eye].Orientation.y, - layer.eyeLayer.RenderPose[eye].Orientation.z, - layer.eyeLayer.RenderPose[eye].Orientation.w }; - QuaternionInvert(&eyeRPose); - Matrix eyeOrientation = QuaternionToMatrix(eyeRPose); - Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, - -layer.eyeLayer.RenderPose[eye].Position.y, - -layer.eyeLayer.RenderPose[eye].Position.z); - - Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); - Matrix modelEyeView = MatrixMultiply(cameraView, eyeView); // Using internal camera modelview matrix - - SetMatrixModelview(modelEyeView); - SetMatrixProjection(layer.eyeProjections[eye]); -#endif - - rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) - -#if defined(PLATFORM_OCULUS) - } - - UnsetOculusBuffer(buffer); - - ovr_CommitTextureSwapChain(session, buffer.textureChain); - - ovrLayerHeader *layers = &layer.eyeLayer.Header; - ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); - - // Blit mirror texture to back buffer - BlitOculusMirror(session, mirror); - - // Get session status information - ovrSessionStatus sessionStatus; - ovr_GetSessionStatus(session, &sessionStatus); - if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); - if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); -#endif + rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events @@ -768,7 +602,7 @@ void Begin3dMode(Camera camera) rlLoadIdentity(); // Reset current matrix (MODELVIEW) // Setup Camera view - cameraView = MatrixLookAt(camera.position, camera.target, camera.up); + Matrix cameraView = MatrixLookAt(camera.position, camera.target, camera.up); rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D @@ -1738,9 +1572,7 @@ static void InitDisplay(int width, int height) #endif glfwMakeContextCurrent(window); -#if defined(PLATFORM_OCULUS) - glfwSwapInterval(0); -#endif + glfwSwapInterval(0); // Disable VSync by default #if defined(PLATFORM_DESKTOP) // Load OpenGL 3.3 extensions @@ -2940,214 +2772,6 @@ static void *GamepadThread(void *arg) } #endif - -#if defined(PLATFORM_OCULUS) -// Convert from Oculus ovrMatrix4f struct to raymath Matrix struct -static Matrix FromOvrMatrix(ovrMatrix4f ovrmat) -{ - Matrix rmat; - - rmat.m0 = ovrmat.M[0][0]; - rmat.m1 = ovrmat.M[1][0]; - rmat.m2 = ovrmat.M[2][0]; - rmat.m3 = ovrmat.M[3][0]; - rmat.m4 = ovrmat.M[0][1]; - rmat.m5 = ovrmat.M[1][1]; - rmat.m6 = ovrmat.M[2][1]; - rmat.m7 = ovrmat.M[3][1]; - rmat.m8 = ovrmat.M[0][2]; - rmat.m9 = ovrmat.M[1][2]; - rmat.m10 = ovrmat.M[2][2]; - rmat.m11 = ovrmat.M[3][2]; - rmat.m12 = ovrmat.M[0][3]; - rmat.m13 = ovrmat.M[1][3]; - rmat.m14 = ovrmat.M[2][3]; - rmat.m15 = ovrmat.M[3][3]; - - MatrixTranspose(&rmat); - - return rmat; -} - -// Load Oculus required buffers: texture-swap-chain, fbo, texture-depth -static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) -{ - OculusBuffer buffer; - buffer.width = width; - buffer.height = height; - - // Create OVR texture chain - ovrTextureSwapChainDesc desc = {}; - desc.Type = ovrTexture_2D; - desc.ArraySize = 1; - desc.Width = width; - desc.Height = height; - desc.MipLevels = 1; - desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; // Requires glEnable(GL_FRAMEBUFFER_SRGB); - desc.SampleCount = 1; - desc.StaticImage = ovrFalse; - - ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain); - - if (!OVR_SUCCESS(result)) TraceLog(WARNING, "OVR: Failed to create swap textures buffer"); - - int textureCount = 0; - ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount); - - if (!OVR_SUCCESS(result) || !textureCount) TraceLog(WARNING, "OVR: Unable to count swap chain textures"); - - for (int i = 0; i < textureCount; ++i) - { - GLuint chainTexId; - ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, i, &chainTexId); - glBindTexture(GL_TEXTURE_2D, chainTexId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - glBindTexture(GL_TEXTURE_2D, 0); - - /* - // Setup framebuffer object (using depth texture) - glGenFramebuffers(1, &buffer.fboId); - glGenTextures(1, &buffer.depthId); - glBindTexture(GL_TEXTURE_2D, buffer.depthId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); - */ - - // Setup framebuffer object (using depth renderbuffer) - glGenFramebuffers(1, &buffer.fboId); - glGenRenderbuffers(1, &buffer.depthId); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); - glBindRenderbuffer(GL_RENDERBUFFER, buffer.depthId); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, buffer.width, buffer.height); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer.depthId); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - - return buffer; -} - -// Unload texture required buffers -static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer) -{ - if (buffer.textureChain) - { - ovr_DestroyTextureSwapChain(session, buffer.textureChain); - buffer.textureChain = NULL; - } - - if (buffer.depthId != 0) glDeleteTextures(1, &buffer.depthId); - if (buffer.fboId != 0) glDeleteFramebuffers(1, &buffer.fboId); -} - -// Set current Oculus buffer -static void SetOculusBuffer(ovrSession session, OculusBuffer buffer) -{ - GLuint currentTexId; - int currentIndex; - - ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); - ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); - - 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 - - //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // Required if OculusBuffer format is OVR_FORMAT_R8G8B8A8_UNORM_SRGB - glEnable(GL_FRAMEBUFFER_SRGB); -} - -// Unset Oculus buffer -static void UnsetOculusBuffer(OculusBuffer buffer) -{ - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -// Load Oculus mirror buffers -static OculusMirror LoadOculusMirror(ovrSession session, int width, int height) -{ - OculusMirror mirror; - mirror.width = width; - mirror.height = height; - - ovrMirrorTextureDesc mirrorDesc; - memset(&mirrorDesc, 0, sizeof(mirrorDesc)); - mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; - mirrorDesc.Width = mirror.width; - mirrorDesc.Height = mirror.height; - - if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(WARNING, "Could not create mirror texture"); - - glGenFramebuffers(1, &mirror.fboId); - - return mirror; -} - -// Unload Oculus mirror buffers -static void UnloadOculusMirror(ovrSession session, OculusMirror mirror) -{ - if (mirror.fboId != 0) glDeleteFramebuffers(1, &mirror.fboId); - if (mirror.texture) ovr_DestroyMirrorTexture(session, mirror.texture); -} - -static void BlitOculusMirror(ovrSession session, OculusMirror mirror) -{ - GLuint mirrorTextureId; - - ovr_GetMirrorTextureBufferGL(session, mirror.texture, &mirrorTextureId); - - glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0); - glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); -} - -// Requires: session, hmdDesc -static OculusLayer InitOculusLayer(ovrSession session) -{ - OculusLayer layer = { 0 }; - - layer.viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f; - - memset(&layer.eyeLayer, 0, sizeof(ovrLayerEyeFov)); - layer.eyeLayer.Header.Type = ovrLayerType_EyeFov; - layer.eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; - - ovrEyeRenderDesc eyeRenderDescs[2]; - - for (int eye = 0; eye < 2; eye++) - { - eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]); - ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(eyeRenderDescs[eye].Fov, 0.01f, 10000.0f, ovrProjection_None); //ovrProjection_ClipRangeOpenGL); - layer.eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection); // NOTE: struct ovrMatrix4f { float M[4][4] } --> struct Matrix - - layer.viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset; - layer.eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov; - - ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, layer.eyeLayer.Fov[eye], 1.0f); - layer.eyeLayer.Viewport[eye].Size = eyeSize; - layer.eyeLayer.Viewport[eye].Pos.x = layer.width; - layer.eyeLayer.Viewport[eye].Pos.y = 0; - - layer.height = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h); - layer.width += eyeSize.w; - } - - return layer; -} -#endif - // Plays raylib logo appearing animation static void LogoAnimation(void) { diff --git a/src/raylib.h b/src/raylib.h index 9120ddc4..0c9f0280 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -64,7 +64,7 @@ //#define PLATFORM_ANDROID // Android device //#define PLATFORM_RPI // Raspberry Pi //#define PLATFORM_WEB // HTML5 (emscripten, asm.js) -//#define PLATFORM_OCULUS // Oculus Rift CV1 +//#define RLGL_OCULUS_SUPPORT // Oculus Rift CV1 (complementary to PLATFORM_DESKTOP) // Security check in case no PLATFORM_* defined #if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI) && !defined(PLATFORM_WEB) @@ -545,12 +545,6 @@ void InitWindow(int width, int height, struct android_app *state); // Init Andr void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics #endif -#if defined(PLATFORM_OCULUS) -void InitOculusDevice(void); // Init Oculus Rift device -void CloseOculusDevice(void); // Close Oculus Rift device -void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -#endif - void CloseWindow(void); // Close Window and Terminate Context bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus) @@ -852,6 +846,17 @@ void EndBlendMode(void); // End blend Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool void DestroyLight(Light light); // Destroy a light and take it out of the list +//------------------------------------------------------------------------------------ +// Oculus Rift CV1 Functions (Module: rlgl) +// NOTE: This functions are useless when using OpenGL 1.1 +//------------------------------------------------------------------------------------ +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 SetOculusMatrix(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) + //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) //------------------------------------------------------------------------------------ diff --git a/src/rlgl.c b/src/rlgl.c index 26961ca9..1e392889 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -72,6 +72,10 @@ #include "standard_shader.h" // Standard shader to embed #endif +#if defined(RLGL_OCULUS_SUPPORT) + #include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL +#endif + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -172,6 +176,32 @@ typedef struct { //Guint fboId; } DrawCall; +#if defined(RLGL_OCULUS_SUPPORT) +typedef struct OculusBuffer { + ovrTextureSwapChain textureChain; + GLuint depthId; + GLuint fboId; + int width; + int height; +} OculusBuffer; + +typedef struct OculusMirror { + ovrMirrorTexture texture; + GLuint fboId; + int width; + int height; +} OculusMirror; + +typedef struct OculusLayer { + ovrViewScaleDesc viewScaleDesc; + ovrLayerEyeFov eyeLayer; // layer 0 + //ovrLayerQuad quadLayer; // TODO: layer 1: '2D' quad for GUI + Matrix eyeProjections[2]; + int width; + int height; +} OculusLayer; +#endif + //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- @@ -221,6 +251,17 @@ static Light lights[MAX_LIGHTS]; // Lights pool static int lightsCount; // Counts current enabled physic objects #endif +#if defined(RLGL_OCULUS_SUPPORT) +// OVR device variables +static ovrSession session; // Oculus session (pointer to ovrHmdStruct) +static ovrHmdDesc hmdDesc; // Oculus device descriptor parameters +static ovrGraphicsLuid luid; // Oculus locally unique identifier for the program (64 bit) +static OculusLayer layer; // Oculus drawing layer (similar to photoshop) +static OculusBuffer buffer; // Oculus internal buffers (texture chain and fbo) +static OculusMirror mirror; // Oculus mirror texture and fbo +static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain +#endif + // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support static bool npotSupported = false; // NPOT textures full support @@ -261,6 +302,16 @@ 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 +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 +static void UnloadOculusMirror(ovrSession session, OculusMirror mirror); // Unload Oculus mirror buffers +static void BlitOculusMirror(ovrSession session, OculusMirror mirror); // Copy Oculus screen buffer to mirror texture +static OculusLayer InitOculusLayer(ovrSession session); // Init Oculus layer (similar to photoshop) +static Matrix FromOvrMatrix(ovrMatrix4f ovrM); // Convert from Oculus ovrMatrix4f struct to raymath Matrix struct +#endif + #if defined(GRAPHICS_API_OPENGL_11) static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight); static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight); @@ -872,23 +923,6 @@ int rlGetVersion(void) #endif } -// Load OpenGL extensions -// NOTE: External loader function could be passed as a pointer -void rlglLoadExtensions(void *loader) -{ -#if defined(GRAPHICS_API_OPENGL_33) - // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions - if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); - else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); - - if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); - else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported"); - - // With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans - //if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object -#endif -} - //---------------------------------------------------------------------------------- // Module Functions Definition - rlgl Functions //---------------------------------------------------------------------------------- @@ -1170,6 +1204,23 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height) TraceLog(INFO, "OpenGL graphic device initialized successfully"); } +// Load OpenGL extensions +// NOTE: External loader function could be passed as a pointer +void rlglLoadExtensions(void *loader) +{ +#if defined(GRAPHICS_API_OPENGL_33) + // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions + if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); + else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); + + if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); + else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported"); + + // With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans + //if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object +#endif +} + // Get world coordinates from screen coordinates Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view) { @@ -2410,6 +2461,130 @@ void DestroyLight(Light light) #endif } +#if defined(RLGL_OCULUS_SUPPORT) +// Init Oculus Rift device +// NOTE: Device initialization should be done before window creation? +void InitOculusDevice(void) +{ + // 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(); + } + + 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); +} + +// Close Oculus Rift device +void CloseOculusDevice(void) +{ + 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 +} + +// Update Oculus Rift tracking (position and orientation) +void UpdateOculusTracking(void) +{ + frameIndex++; + + ovrPosef eyePoses[2]; + ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); + + layer.eyeLayer.RenderPose[0] = eyePoses[0]; + layer.eyeLayer.RenderPose[1] = eyePoses[1]; +} + +void SetOculusMatrix(int eye) +{ + 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 eyeRPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, + layer.eyeLayer.RenderPose[eye].Orientation.w }; + QuaternionInvert(&eyeRPose); + Matrix eyeOrientation = QuaternionToMatrix(eyeRPose); + Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, + -layer.eyeLayer.RenderPose[eye].Position.y, + -layer.eyeLayer.RenderPose[eye].Position.z); + + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); + Matrix modelEyeView = MatrixMultiply(modelview, eyeView); // Using internal camera modelview matrix + + SetMatrixModelview(modelEyeView); + SetMatrixProjection(layer.eyeProjections[eye]); +} + +void BeginOculusDrawing(void) +{ + GLuint currentTexId; + int currentIndex; + + ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); + + 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 + + //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Same as rlClearScreenBuffers() + + // 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: + // - Require OculusBuffer format to be OVR_FORMAT_R8G8B8A8_UNORM_SRGB + // - Do NOT enable GL_FRAMEBUFFER_SRGB + //glEnable(GL_FRAMEBUFFER_SRGB); +} + +void EndOculusDrawing(void) +{ + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + ovr_CommitTextureSwapChain(session, buffer.textureChain); + + ovrLayerHeader *layers = &layer.eyeLayer.Header; + ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); + + // Blit mirror texture to back buffer + BlitOculusMirror(session, mirror); + + // Get session status information + ovrSessionStatus sessionStatus; + ovr_GetSessionStatus(session, &sessionStatus); + if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); + if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); +} +#endif + //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- @@ -3390,6 +3565,187 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) } #endif +#if defined(RLGL_OCULUS_SUPPORT) +// Load Oculus required buffers: texture-swap-chain, fbo, texture-depth +static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) +{ + OculusBuffer buffer; + buffer.width = width; + buffer.height = height; + + // Create OVR texture chain + ovrTextureSwapChainDesc desc = {}; + desc.Type = ovrTexture_2D; + desc.ArraySize = 1; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; // Requires glEnable(GL_FRAMEBUFFER_SRGB); + desc.SampleCount = 1; + desc.StaticImage = ovrFalse; + + ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain); + + if (!OVR_SUCCESS(result)) TraceLog(WARNING, "OVR: Failed to create swap textures buffer"); + + int textureCount = 0; + ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount); + + if (!OVR_SUCCESS(result) || !textureCount) TraceLog(WARNING, "OVR: Unable to count swap chain textures"); + + for (int i = 0; i < textureCount; ++i) + { + GLuint chainTexId; + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, i, &chainTexId); + glBindTexture(GL_TEXTURE_2D, chainTexId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + glBindTexture(GL_TEXTURE_2D, 0); + + /* + // Setup framebuffer object (using depth texture) + glGenFramebuffers(1, &buffer.fboId); + glGenTextures(1, &buffer.depthId); + glBindTexture(GL_TEXTURE_2D, buffer.depthId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + */ + + // Setup framebuffer object (using depth renderbuffer) + glGenFramebuffers(1, &buffer.fboId); + glGenRenderbuffers(1, &buffer.depthId); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); + glBindRenderbuffer(GL_RENDERBUFFER, buffer.depthId); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, buffer.width, buffer.height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer.depthId); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + return buffer; +} + +// Unload texture required buffers +static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer) +{ + if (buffer.textureChain) + { + ovr_DestroyTextureSwapChain(session, buffer.textureChain); + buffer.textureChain = NULL; + } + + if (buffer.depthId != 0) glDeleteTextures(1, &buffer.depthId); + if (buffer.fboId != 0) glDeleteFramebuffers(1, &buffer.fboId); +} + +// Load Oculus mirror buffers +static OculusMirror LoadOculusMirror(ovrSession session, int width, int height) +{ + OculusMirror mirror; + mirror.width = width; + mirror.height = height; + + ovrMirrorTextureDesc mirrorDesc; + memset(&mirrorDesc, 0, sizeof(mirrorDesc)); + mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + mirrorDesc.Width = mirror.width; + mirrorDesc.Height = mirror.height; + + if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(WARNING, "Could not create mirror texture"); + + glGenFramebuffers(1, &mirror.fboId); + + return mirror; +} + +// Unload Oculus mirror buffers +static void UnloadOculusMirror(ovrSession session, OculusMirror mirror) +{ + if (mirror.fboId != 0) glDeleteFramebuffers(1, &mirror.fboId); + if (mirror.texture) ovr_DestroyMirrorTexture(session, mirror.texture); +} + +// Copy Oculus screen buffer to mirror texture +static void BlitOculusMirror(ovrSession session, OculusMirror mirror) +{ + GLuint mirrorTextureId; + + ovr_GetMirrorTextureBufferGL(session, mirror.texture, &mirrorTextureId); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0); + glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); +} + +// Init Oculus layer (similar to photoshop) +static OculusLayer InitOculusLayer(ovrSession session) +{ + OculusLayer layer = { 0 }; + + layer.viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f; + + memset(&layer.eyeLayer, 0, sizeof(ovrLayerEyeFov)); + layer.eyeLayer.Header.Type = ovrLayerType_EyeFov; + layer.eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; + + ovrEyeRenderDesc eyeRenderDescs[2]; + + for (int eye = 0; eye < 2; eye++) + { + eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]); + ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(eyeRenderDescs[eye].Fov, 0.01f, 10000.0f, ovrProjection_None); //ovrProjection_ClipRangeOpenGL); + layer.eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection); // NOTE: struct ovrMatrix4f { float M[4][4] } --> struct Matrix + + layer.viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset; + layer.eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov; + + ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, layer.eyeLayer.Fov[eye], 1.0f); + layer.eyeLayer.Viewport[eye].Size = eyeSize; + layer.eyeLayer.Viewport[eye].Pos.x = layer.width; + layer.eyeLayer.Viewport[eye].Pos.y = 0; + + layer.height = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h); + layer.width += eyeSize.w; + } + + return layer; +} + +// Convert from Oculus ovrMatrix4f struct to raymath Matrix struct +static Matrix FromOvrMatrix(ovrMatrix4f ovrmat) +{ + Matrix rmat; + + rmat.m0 = ovrmat.M[0][0]; + rmat.m1 = ovrmat.M[1][0]; + rmat.m2 = ovrmat.M[2][0]; + rmat.m3 = ovrmat.M[3][0]; + rmat.m4 = ovrmat.M[0][1]; + rmat.m5 = ovrmat.M[1][1]; + rmat.m6 = ovrmat.M[2][1]; + rmat.m7 = ovrmat.M[3][1]; + rmat.m8 = ovrmat.M[0][2]; + rmat.m9 = ovrmat.M[1][2]; + rmat.m10 = ovrmat.M[2][2]; + rmat.m11 = ovrmat.M[3][2]; + rmat.m12 = ovrmat.M[0][3]; + rmat.m13 = ovrmat.M[1][3]; + rmat.m14 = ovrmat.M[2][3]; + rmat.m15 = ovrmat.M[3][3]; + + MatrixTranspose(&rmat); + + return rmat; +} +#endif + #if defined(RLGL_STANDALONE) // Output a trace log message // NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning diff --git a/src/rlgl.h b/src/rlgl.h index 28c50b8f..1e77b771 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -347,6 +347,15 @@ 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 SetOculusMatrix(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 } #endif -- cgit v1.2.3 From 4df7a0f2f8cf5c4dde236bd99d05d83c7b472db5 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 16 Jun 2016 20:25:50 +0200 Subject: Added support for OpenGL 2.1 --- src/Makefile | 1 + src/core.c | 21 +++++++----- src/rlgl.c | 105 ++++++++++++++++++++++++++++++++++------------------------- src/rlgl.h | 12 +++++-- 4 files changed, 84 insertions(+), 55 deletions(-) (limited to 'src/core.c') diff --git a/src/Makefile b/src/Makefile index ce703c3a..33b666b4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -51,6 +51,7 @@ ifeq ($(PLATFORM),PLATFORM_RPI) else # define raylib graphics api to use (OpenGL 1.1 by default) GRAPHICS ?= GRAPHICS_API_OPENGL_11 + #GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1 #GRAPHICS = GRAPHICS_API_OPENGL_33 # Uncomment to use OpenGL 3.3 endif ifeq ($(PLATFORM),PLATFORM_WEB) diff --git a/src/core.c b/src/core.c index fb71af21..7c2dbcb9 100644 --- a/src/core.c +++ b/src/core.c @@ -1480,16 +1480,21 @@ static void InitDisplay(int width, int height) // NOTE: When asking for an OpenGL context version, most drivers provide highest supported version // with forward compatibility to older OpenGL versions. // For example, if using OpenGL 1.1, driver can provide a 3.3 context fordward compatible. - - // Check selection OpenGL version (not initialized yet!) - if (rlGetVersion() == OPENGL_33) + + if (configFlags & FLAG_MSAA_4X_HINT) { - if (configFlags & FLAG_MSAA_4X_HINT) - { - glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0 - TraceLog(INFO, "Trying to enable MSAA x4"); - } + glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0 + TraceLog(INFO, "Trying to enable MSAA x4"); + } + // Check selection OpenGL version + if (rlGetVersion() == OPENGL_21) + { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // Choose OpenGL major version (just hint) + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); // Choose OpenGL minor version (just hint) + } + else if (rlGetVersion() == OPENGL_33) + { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint) glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above! diff --git a/src/rlgl.c b/src/rlgl.c index fec03926..99ef4a4f 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -44,6 +44,10 @@ #endif #endif +#if defined(GRAPHICS_API_OPENGL_21) + #define GRAPHICS_API_OPENGL_33 +#endif + #if defined(GRAPHICS_API_OPENGL_33) #ifdef __APPLE__ #include // OpenGL 3 library for OSX @@ -916,6 +920,8 @@ int rlGetVersion(void) { #if defined(GRAPHICS_API_OPENGL_11) return OPENGL_11; +#elif defined(GRAPHICS_API_OPENGL_21) + return OPENGL_21; #elif defined(GRAPHICS_API_OPENGL_33) return OPENGL_33; #elif defined(GRAPHICS_API_OPENGL_ES2) @@ -1213,7 +1219,8 @@ void rlglLoadExtensions(void *loader) if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); - if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); + if (GLAD_GL_VERSION_2_1) TraceLog(INFO, "OpenGL 2.1 profile supported"); + else if(GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported"); // With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans @@ -2752,55 +2759,65 @@ static Shader LoadDefaultShader(void) Shader shader; // Vertex shader directly defined, no external file required -#if defined(GRAPHICS_API_OPENGL_33) - char vShaderStr[] = "#version 330 \n" - "in vec3 vertexPosition; \n" - "in vec2 vertexTexCoord; \n" - "in vec4 vertexColor; \n" - "out vec2 fragTexCoord; \n" - "out vec4 fragColor; \n" + char vDefaultShaderStr[] = +#if defined(GRAPHICS_API_OPENGL_21) + "#version 120 \n" #elif defined(GRAPHICS_API_OPENGL_ES2) - char vShaderStr[] = "#version 100 \n" - "attribute vec3 vertexPosition; \n" - "attribute vec2 vertexTexCoord; \n" - "attribute vec4 vertexColor; \n" - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" -#endif - "uniform mat4 mvpMatrix; \n" - "void main() \n" - "{ \n" - " fragTexCoord = vertexTexCoord; \n" - " fragColor = vertexColor; \n" - " gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n" - "} \n"; + "#version 100 \n" +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) + "attribute vec3 vertexPosition; \n" + "attribute vec2 vertexTexCoord; \n" + "attribute vec4 vertexColor; \n" + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" +#elif defined(GRAPHICS_API_OPENGL_33) + "#version 330 \n" + "in vec3 vertexPosition; \n" + "in vec2 vertexTexCoord; \n" + "in vec4 vertexColor; \n" + "out vec2 fragTexCoord; \n" + "out vec4 fragColor; \n" +#endif + "uniform mat4 mvpMatrix; \n" + "void main() \n" + "{ \n" + " fragTexCoord = vertexTexCoord; \n" + " fragColor = vertexColor; \n" + " gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n" + "} \n"; // Fragment shader directly defined, no external file required -#if defined(GRAPHICS_API_OPENGL_33) - char fShaderStr[] = "#version 330 \n" - "in vec2 fragTexCoord; \n" - "in vec4 fragColor; \n" - "out vec4 finalColor; \n" + char fDefaultShaderStr[] = +#if defined(GRAPHICS_API_OPENGL_21) + "#version 120 \n" #elif defined(GRAPHICS_API_OPENGL_ES2) - char fShaderStr[] = "#version 100 \n" - "precision mediump float; \n" // precision required for OpenGL ES2 (WebGL) - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" -#endif - "uniform sampler2D texture0; \n" - "uniform vec4 colDiffuse; \n" - "void main() \n" - "{ \n" -#if defined(GRAPHICS_API_OPENGL_33) - " vec4 texelColor = texture(texture0, fragTexCoord); \n" - " finalColor = texelColor*colDiffuse*fragColor; \n" -#elif defined(GRAPHICS_API_OPENGL_ES2) - " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0 - " gl_FragColor = texelColor*colDiffuse*fragColor; \n" + "#version 100 \n" + "precision mediump float; \n" // precision required for OpenGL ES2 (WebGL) +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) + "varying vec2 fragTexCoord; \n" + "varying vec4 fragColor; \n" +#elif defined(GRAPHICS_API_OPENGL_33) + "#version 330 \n" + "in vec2 fragTexCoord; \n" + "in vec4 fragColor; \n" + "out vec4 finalColor; \n" +#endif + "uniform sampler2D texture0; \n" + "uniform vec4 colDiffuse; \n" + "void main() \n" + "{ \n" +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) + " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0 + " gl_FragColor = texelColor*colDiffuse*fragColor; \n" +#elif defined(GRAPHICS_API_OPENGL_33) + " vec4 texelColor = texture(texture0, fragTexCoord); \n" + " finalColor = texelColor*colDiffuse*fragColor; \n" #endif - "} \n"; + "} \n"; - shader.id = LoadShaderProgram(vShaderStr, fShaderStr); + shader.id = LoadShaderProgram(vDefaultShaderStr, fDefaultShaderStr); if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Default shader loaded successfully", shader.id); else TraceLog(WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id); diff --git a/src/rlgl.h b/src/rlgl.h index 1e77b771..3322d80c 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -52,21 +52,27 @@ //#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 -#if !defined(GRAPHICS_API_OPENGL_11) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2) +#if !defined(GRAPHICS_API_OPENGL_11) && !defined(GRAPHICS_API_OPENGL_21) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2) #define GRAPHICS_API_OPENGL_11 #endif // Security check in case multiple GRAPHICS_API_OPENGL_* defined #if defined(GRAPHICS_API_OPENGL_11) + #if defined(GRAPHICS_API_OPENGL_21) + #undef GRAPHICS_API_OPENGL_21 + #endif #if defined(GRAPHICS_API_OPENGL_33) #undef GRAPHICS_API_OPENGL_33 #endif - #if defined(GRAPHICS_API_OPENGL_ES2) #undef GRAPHICS_API_OPENGL_ES2 #endif #endif +#if defined(GRAPHICS_API_OPENGL_21) + #define GRAPHICS_API_OPENGL_33 +#endif + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -90,7 +96,7 @@ typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode; typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode; -typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; +typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion; #if defined(RLGL_STANDALONE) #ifndef __cplusplus -- cgit v1.2.3 From 24c9b1f717bd9a6510667907614928188a6b6a6f Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 17 Jun 2016 13:54:45 +0200 Subject: Improving Oculus Rift example... Under design... looking for the easiest and most comprehensive way for the user to use VR... --- examples/core_oculus_rift.c | 40 ++++++++++++++++++++++------------------ src/core.c | 10 ++++++++++ src/raylib.h | 3 ++- src/rlgl.c | 10 +++++----- src/rlgl.h | 2 +- 5 files changed, 40 insertions(+), 25 deletions(-) (limited to 'src/core.c') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 3c9d7840..32e6b1c6 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -51,27 +51,31 @@ int main() ClearBackground(RAYWHITE); - BeginOculusDrawing(); + Begin3dMode(camera); + //BeginOculusDrawing(camera); // Add it to Begin3dMode() ? - for (int eye = 0; eye < 2; eye++) - { - // TODO: Probably projection and view matrices could be created here... - // ...without the need to create it internally through Begin3dMode() - Begin3dMode(camera); + for (int eye = 0; eye < 2; eye++) + { + // TODO: Probably projection and view matrices could be created here... + // ...without the need to create it internally through Begin3dMode() + //Begin3dMode(camera); + + SetOculusView(eye); + + DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); + DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); + + DrawGrid(10, 1.0f); + + // TODO: Call internal buffers drawing directly (rlglDraw()) and... + // ...reset internal matrices, instead of letting End3dMode() do that + //End3dMode(); - SetOculusMatrix(eye); - - DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); - DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); - - DrawGrid(10, 1.0f); - - // TODO: Call internal buffers drawing directly (rlglDraw()) and... - // ...reset internal matrices, instead of letting End3dMode() do that - End3dMode(); - } + DrawDefaultBuffers(); // Process internal dynamic buffers + } - EndOculusDrawing(); + End3dMode(); + //EndOculusDrawing(); // Add it to End3dMode() ? EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/src/core.c b/src/core.c index 7c2dbcb9..eef81bad 100644 --- a/src/core.c +++ b/src/core.c @@ -606,6 +606,8 @@ void Begin3dMode(Camera camera) rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D + + //if (vrEnabled) BeginVrMode(); } // Ends 3D mode and returns to default 2D orthographic mode @@ -1015,6 +1017,14 @@ Matrix GetCameraMatrix(Camera camera) return MatrixLookAt(camera.position, camera.target, camera.up); } +// Update and draw default buffers vertex data +// NOTE: This data has been stored dynamically during frame on each Draw*() call +void DrawDefaultBuffers(void) +{ + rlglUpdateDefaultBuffers(); // Upload frame vertex data to GPU + rlglDrawDefaultBuffers(); // Draw vertex data into framebuffer +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions //---------------------------------------------------------------------------------- diff --git a/src/raylib.h b/src/raylib.h index 0c9f0280..ed787892 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -572,6 +572,7 @@ void EndTextureMode(void); // Ends drawing to r Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) +void DrawDefaultBuffers(void); // Update and draw default buffers vertex data (stored dynamically in frame) void SetTargetFPS(int fps); // Set target FPS (maximum) float GetFPS(void); // Returns current FPS @@ -853,7 +854,7 @@ void DestroyLight(Light light); // Destroy a 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 SetOculusMatrix(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 EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) diff --git a/src/rlgl.c b/src/rlgl.c index 6d003869..d68b9109 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -297,8 +297,8 @@ static void UnloadDefaultShader(void); // Unload default shader static void UnloadStandardShader(void); // Unload standard shader static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads) -static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data -static void DrawDefaultBuffers(void); // Draw default internal buffers vertex data +void rlglUpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data +void rlglDrawDefaultBuffers(void); // Draw default internal buffers vertex data static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array @@ -2542,7 +2542,7 @@ void UpdateOculusTracking(void) //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD. } -void SetOculusMatrix(int eye) +void SetOculusView(int eye) { 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); @@ -3089,7 +3089,7 @@ static void LoadDefaultBuffers(void) // Update default internal buffers (VAOs/VBOs) with vertex array data // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required) -static void UpdateDefaultBuffers(void) +void rlglUpdateDefaultBuffers(void) { // Update lines vertex buffers if (lines.vCounter > 0) @@ -3159,7 +3159,7 @@ static void UpdateDefaultBuffers(void) // Draw default internal buffers vertex data // NOTE: We draw in this order: lines, triangles, quads -static void DrawDefaultBuffers(void) +void rlglDrawDefaultBuffers(void) { // Set current shader and upload current MVP matrix if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) diff --git a/src/rlgl.h b/src/rlgl.h index 3322d80c..8904b9ac 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -357,7 +357,7 @@ void TraceLog(int msgType, const char *text, ...); 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 SetOculusMatrix(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 EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) #endif -- cgit v1.2.3 From 6062201e8f543c227a0adbb77f3a0941772be889 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 21 Jun 2016 08:59:29 +0200 Subject: Simplify Oculus example... ...to align it with standard raylib code. Final goal would be having the same code work for every platform with no changes... --- examples/core_oculus_rift.c | 12 +----------- src/core.c | 5 +++-- src/rlgl.c | 12 +++++++++++- src/rlgl.h | 1 + 4 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src/core.c') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 32e6b1c6..e0ab61fd 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -52,14 +52,9 @@ int main() ClearBackground(RAYWHITE); Begin3dMode(camera); - //BeginOculusDrawing(camera); // Add it to Begin3dMode() ? - + for (int eye = 0; eye < 2; eye++) { - // TODO: Probably projection and view matrices could be created here... - // ...without the need to create it internally through Begin3dMode() - //Begin3dMode(camera); - SetOculusView(eye); DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); @@ -67,15 +62,10 @@ int main() DrawGrid(10, 1.0f); - // TODO: Call internal buffers drawing directly (rlglDraw()) and... - // ...reset internal matrices, instead of letting End3dMode() do that - //End3dMode(); - DrawDefaultBuffers(); // Process internal dynamic buffers } End3dMode(); - //EndOculusDrawing(); // Add it to End3dMode() ? EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/src/core.c b/src/core.c index eef81bad..af82e092 100644 --- a/src/core.c +++ b/src/core.c @@ -607,13 +607,14 @@ void Begin3dMode(Camera camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D - //if (vrEnabled) BeginVrMode(); + if (VrEnabled()) BeginOculusDrawing(); } // Ends 3D mode and returns to default 2D orthographic mode void End3dMode(void) { - rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) + if (VrEnabled()) EndOculusDrawing(); + else rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack diff --git a/src/rlgl.c b/src/rlgl.c index 2d4d951c..eee19ef4 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -76,7 +76,7 @@ #include "standard_shader.h" // Standard shader to embed #endif -#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code +//#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 @@ -268,6 +268,7 @@ static unsigned int frameIndex = 0; // Oculus frames counter, used to discar #endif static bool vrSimulator = false; // VR simulator (stereo rendering on window, without vr device) +static bool vrEnabled = false; // VR enabled flag (required by core module) // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support @@ -2523,6 +2524,7 @@ void InitOculusDevice(void) } #else vrSimulator = true; + vrEnabled = true; #endif if (vrSimulator) @@ -2548,6 +2550,14 @@ void CloseOculusDevice(void) // TODO: Unload stereo framebuffer and texture // TODO: Unload oculus-distortion shader } + + vrEnabled = false; +} + +// Track stereoscopic rendering +bool VrEnabled(void) +{ + return vrEnabled; } // Update Oculus Rift tracking (position and orientation) diff --git a/src/rlgl.h b/src/rlgl.h index e2e1dde6..c0e93a65 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -362,6 +362,7 @@ void UpdateOculusTracking(void); // Update Oculus Rift tracking (posi 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) +bool VrEnabled(void); // Track stereoscopic rendering #ifdef __cplusplus } -- cgit v1.2.3 From 03d9583b945dcf17d6a93ed97deeb9f9721284b5 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 21 Jun 2016 13:49:13 +0200 Subject: Add oculus simulator (in case device is not detected) --- src/core.c | 7 +- src/rlgl.c | 263 ++++++++++++++++++++++++++++++++++++++++--------------------- src/rlgl.h | 2 +- 3 files changed, 178 insertions(+), 94 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index af82e092..1073ae6a 100644 --- a/src/core.c +++ b/src/core.c @@ -607,14 +607,15 @@ void Begin3dMode(Camera camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D - if (VrEnabled()) BeginOculusDrawing(); + if (IsOculusReady()) BeginOculusDrawing(); } // Ends 3D mode and returns to default 2D orthographic mode void End3dMode(void) { - if (VrEnabled()) EndOculusDrawing(); - else rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) + if (IsOculusReady()) EndOculusDrawing(); + + rlglDraw(); // Process internal buffers (update + draw) rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack diff --git a/src/rlgl.c b/src/rlgl.c index eee19ef4..f1d49df9 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -267,8 +267,11 @@ 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) -static bool vrEnabled = false; // VR enabled flag (required by core module) +static bool oculusEnabled = false; // Oculus device enabled flag (required by core module) +static bool oculusSimulator = false; // Oculus device simulator + +static RenderTexture2D stereoFbo; +static Shader distortion; // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support @@ -865,6 +868,8 @@ void rlDeleteRenderTextures(RenderTexture2D target) if (target.id != 0) glDeleteFramebuffers(1, &target.id); if (target.texture.id != 0) glDeleteTextures(1, &target.texture.id); if (target.depth.id != 0) glDeleteTextures(1, &target.depth.id); + + TraceLog(INFO, "[FBO ID %i] Unloaded render texture data from VRAM (GPU)", target.id); #endif } @@ -2484,8 +2489,7 @@ void InitOculusDevice(void) if (OVR_FAILURE(result)) { TraceLog(WARNING, "OVR: Could not initialize Oculus device"); - TraceLog(INFO, "VR: Initializing Oculus simulator"); - vrSimulator = true; + oculusEnabled = false; } else { @@ -2494,9 +2498,7 @@ void InitOculusDevice(void) { TraceLog(WARNING, "OVR: Could not create Oculus session"); ovr_Shutdown(); - - TraceLog(INFO, "VR: Initializing Oculus simulator"); - vrSimulator = true; + oculusEnabled = false; } else { @@ -2520,17 +2522,29 @@ void InitOculusDevice(void) // Recenter OVR tracking origin ovr_RecenterTrackingOrigin(session); + + oculusEnabled = true; } } #else - vrSimulator = true; - vrEnabled = true; + oculusEnabled = false; #endif - if (vrSimulator) + if (!oculusEnabled) { - // TODO: Initialize framebuffer and textures for stereo rendering - // TODO: Load oculus-distortion shader (oculus parameters setup internally) + TraceLog(INFO, "VR: Initializing Oculus simulator"); + + int screenWidth = 1080; + int screenHeight = 600; + + // Initialize framebuffer and textures for stereo rendering + stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); + + // Load oculus-distortion shader (oculus parameters setup internally) + // TODO: Embed coulus distortion shader (in this function like default shader?) + distortion = LoadShader("resources/shaders/base.vs", "resources/shaders/distortion.fs"); + + oculusSimulator = true; } } @@ -2538,53 +2552,60 @@ void InitOculusDevice(void) void CloseOculusDevice(void) { #if defined(RLGL_OCULUS_SUPPORT) - UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer - UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers + if (oculusEnabled) + { + 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 + ovr_Destroy(session); // Free Oculus session data + ovr_Shutdown(); // Close Oculus device connection + } + else #endif - - if (vrSimulator) { - // TODO: Unload stereo framebuffer and texture - // TODO: Unload oculus-distortion shader + // Unload stereo framebuffer and texture + rlDeleteRenderTextures(stereoFbo); + + // Unload oculus-distortion shader + UnloadShader(distortion); } - vrEnabled = false; + oculusEnabled = false; } -// Track stereoscopic rendering -bool VrEnabled(void) +// Detect if oculus device is available +bool IsOculusReady(void) { - return vrEnabled; + return (oculusEnabled || oculusSimulator); } // Update Oculus Rift tracking (position and orientation) void UpdateOculusTracking(void) { #if defined(RLGL_OCULUS_SUPPORT) - frameIndex++; + if (oculusEnabled) + { + frameIndex++; - ovrPosef eyePoses[2]; - ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); - - layer.eyeLayer.RenderPose[0] = eyePoses[0]; - layer.eyeLayer.RenderPose[1] = eyePoses[1]; - - // Get session status information - ovrSessionStatus sessionStatus; - ovr_GetSessionStatus(session, &sessionStatus); - - if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); - if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); - //if (sessionStatus.HmdPresent) // HMD is present. - //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. + ovrPosef eyePoses[2]; + ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); + + layer.eyeLayer.RenderPose[0] = eyePoses[0]; + layer.eyeLayer.RenderPose[1] = eyePoses[1]; + + // Get session status information + ovrSessionStatus sessionStatus; + ovr_GetSessionStatus(session, &sessionStatus); + + if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); + if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); + //if (sessionStatus.HmdPresent) // HMD is present. + //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. + } + else #endif - - if (vrSimulator) { // TODO: Use alternative inputs (mouse, keyboard) to simulate tracking data (eyes position/orientation) } @@ -2597,29 +2618,44 @@ void SetOculusView(int eye) 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); + if (oculusEnabled) + { + 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, - layer.eyeLayer.RenderPose[eye].Orientation.y, - layer.eyeLayer.RenderPose[eye].Orientation.z, - layer.eyeLayer.RenderPose[eye].Orientation.w }; - QuaternionInvert(&eyeRenderPose); - Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); - Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, - -layer.eyeLayer.RenderPose[eye].Position.y, - -layer.eyeLayer.RenderPose[eye].Position.z); + Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, + layer.eyeLayer.RenderPose[eye].Orientation.w }; + QuaternionInvert(&eyeRenderPose); + Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); + Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, + -layer.eyeLayer.RenderPose[eye].Position.y, + -layer.eyeLayer.RenderPose[eye].Position.z); - Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement - eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing 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]; + // TODO: Find a better way to get camera view matrix (instead of using internal modelview) + + eyeProjection = layer.eyeProjections[eye]; + } + else #endif - - if (vrSimulator) { - // TODO: Setup viewport and projection/modelview matrices using tracking data + int screenWidth = 1080; + int screenHeight = 600; + float fovy = 45.0f; + + // Setup viewport and projection/modelview matrices using tracking data + rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); + + eyeProjection = MatrixPerspective(fovy, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0); + MatrixTranspose(&eyeProjection); + + // TODO: Compute eyes IPD and apply to current modelview matrix (camera) + Matrix eyeView = MatrixIdentity(); + + eyeModelView = MatrixMultiply(modelview, eyeView); } SetMatrixModelview(eyeModelView); @@ -2630,21 +2666,23 @@ void SetOculusView(int eye) void BeginOculusDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) - GLuint currentTexId; - int currentIndex; - - ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); - ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); + if (oculusEnabled) + { + GLuint currentTexId; + int currentIndex; + + ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); - 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 + 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 + } + else #endif - - if (vrSimulator) { - // TODO: Setup framebuffer for stereo rendering - //rlEnableRenderTexture(buffer.fboId); + // Setup framebuffer for stereo rendering + rlEnableRenderTexture(stereoFbo.id); } // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) @@ -2661,28 +2699,73 @@ void BeginOculusDrawing(void) 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); - - ovr_CommitTextureSwapChain(session, buffer.textureChain); - - ovrLayerHeader *layers = &layer.eyeLayer.Header; - ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); + if (oculusEnabled) + { + // Unbind current framebuffer (Oculus buffer) + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + ovr_CommitTextureSwapChain(session, buffer.textureChain); + + ovrLayerHeader *layers = &layer.eyeLayer.Header; + ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); - // Blit mirror texture to back buffer - BlitOculusMirror(session, mirror); + // Blit mirror texture to back buffer + BlitOculusMirror(session, mirror); + } + else #endif - - if (vrSimulator) { // Unbind current framebuffer - //rlDisableRenderTexture(); + rlDisableRenderTexture(); + + rlClearScreenBuffers(); // Clear current framebuffer - // 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(); + int screenWidth = 1080; + int screenHeight = 600; + + // Set viewport to default framebuffer size (screen size) + rlViewport(0, 0, screenWidth, screenHeight); + + // Let rlgl reconfigure internal matrices + rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix + rlLoadIdentity(); // Reset internal projection matrix + rlOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix + rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix + rlLoadIdentity(); // Reset internal modelview matrix + + // Draw RenderTexture (stereoFbo) using distortion shader + BeginShaderMode(distortion); + + rlEnableTexture(stereoFbo.texture.id); + + rlPushMatrix(); + rlBegin(RL_QUADS); + rlColor4ub(255, 255, 255, 255); + rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer + + // 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, stereoFbo.texture.height); + + // Top-right corner for texture and quad + rlTexCoord2f(1.0f, 0.0f); + rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height); + + // Top-left corner for texture and quad + rlTexCoord2f(1.0f, 1.0f); + rlVertex2f(stereoFbo.texture.width, 0.0f); + rlEnd(); + rlPopMatrix(); + + rlDisableTexture(); + + //rlglDraw(); + EndShaderMode(); } rlDisableDepthTest(); diff --git a/src/rlgl.h b/src/rlgl.h index c0e93a65..2bd7a6b4 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -362,7 +362,7 @@ void UpdateOculusTracking(void); // Update Oculus Rift tracking (posi 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) -bool VrEnabled(void); // Track stereoscopic rendering +bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready #ifdef __cplusplus } -- cgit v1.2.3 From a522b6e23b8ef5cb5ffc006320c300f7c7bf191c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 24 Jun 2016 19:34:47 +0200 Subject: Corrected issue with unclosed threads --- src/core.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index 1073ae6a..bc195219 100644 --- a/src/core.c +++ b/src/core.c @@ -444,7 +444,15 @@ void CloseWindow(void) eglTerminate(display); display = EGL_NO_DISPLAY; - } + } +#endif + +#if defined(PLATFORM_RPI) + // Wait for mouse and gamepad threads to finish before closing + // NOTE: Those threads should already have finished at this point + // because they are controlled by windowShouldClose variable + pthread_join(mouseThreadId, NULL); + pthread_join(gamepadThreadId, NULL); #endif TraceLog(INFO, "Window closed successfully"); @@ -1766,12 +1774,12 @@ static void InitGraphics(void) ClearBackground(RAYWHITE); // Default background color for raylib games :P #if defined(PLATFORM_ANDROID) - windowReady = true; // IMPORTANT! + windowReady = true; // IMPORTANT! #endif } // Compute framebuffer size relative to screen size and display size -// NOTE: Global variables renderWidth/renderHeight can be modified +// NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified static void SetupFramebufferSize(int displayWidth, int displayHeight) { // TODO: SetupFramebufferSize() does not consider properly display video modes. @@ -2662,7 +2670,7 @@ static void *MouseThread(void *arg) int mouseRelX = 0; int mouseRelY = 0; - while(1) + while (1) { if (read(mouseStream, &mouse, sizeof(MouseEvent)) == (int)sizeof(MouseEvent)) { @@ -2752,7 +2760,7 @@ static void *GamepadThread(void *arg) // Read gamepad event struct js_event gamepadEvent; - while (1) + while (!windowShouldClose) { for (int i = 0; i < MAX_GAMEPADS; i++) { @@ -2787,7 +2795,7 @@ static void *GamepadThread(void *arg) return NULL; } -#endif +#endif // PLATFORM_RPI // Plays raylib logo appearing animation static void LogoAnimation(void) -- cgit v1.2.3 From 9ee96bea95e2b9b2180edee8ed01171fb64bfcd6 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 25 Jun 2016 21:28:50 +0200 Subject: Unified functions: InitGraphicsDevice() Following XNA style, now we have InitGraphicsDevice(), replacing InitDisplay() + InitGraphics() --- src/core.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index bc195219..62b916fb 100644 --- a/src/core.c +++ b/src/core.c @@ -238,8 +238,7 @@ extern void UnloadDefaultFont(void); // [Module: text] Unloads default fo //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static void InitDisplay(int width, int height); // Initialize display device and framebuffer -static void InitGraphics(void); // Initialize OpenGL graphics +static void InitGraphicsDevice(int width, int height); // Initialize graphics device static void SetupFramebufferSize(int displayWidth, int displayHeight); static void InitTimer(void); // Initialize timer static double GetTime(void); // Returns time since InitTimer() was run @@ -300,11 +299,8 @@ void InitWindow(int width, int height, const char *title) // Store window title (could be useful...) windowTitle = title; - // Init device display (monitor, LCD, ...) - InitDisplay(width, height); - - // Init OpenGL graphics - InitGraphics(); + // Init graphics device (display device and OpenGL context) + InitGraphicsDevice(width, height); // Load default font for convenience // NOTE: External function (defined in module: text) @@ -1453,7 +1449,7 @@ bool IsButtonReleased(int button) // Initialize display device and framebuffer // NOTE: width and height represent the screen (framebuffer) desired size, not actual display size // If width or height are 0, default display size will be used for framebuffer size -static void InitDisplay(int width, int height) +static void InitGraphicsDevice(int width, int height) { screenWidth = width; // User desired width screenHeight = height; // User desired height @@ -1763,11 +1759,8 @@ static void InitDisplay(int width, int height) TraceLog(INFO, "Viewport offsets: %i, %i", renderOffsetX, renderOffsetY); } #endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) -} -// Initialize OpenGL graphics -static void InitGraphics(void) -{ + // Initialize OpenGL context (states and resources) rlglInit(); // Init rlgl rlglInitGraphics(renderOffsetX, renderOffsetY, renderWidth, renderHeight); // Init graphics (OpenGL stuff) @@ -2213,11 +2206,8 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) } else { - // Init device display (monitor, LCD, ...) - InitDisplay(screenWidth, screenHeight); - - // Init OpenGL graphics - InitGraphics(); + // Init graphics device (display device and OpenGL context) + InitGraphicsDevice(screenWidth, screenHeight); // Load default font for convenience // NOTE: External function (defined in module: text) -- cgit v1.2.3 From 71ab20229564a4c519ab46ee34ec785846bdbe83 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 25 Jun 2016 23:28:50 +0200 Subject: Removed rlglInitGraphics(), integrated into rlglInit() Redesigned rlgl usage: - rlViewport() must be called by user - Internal projection/modelview matrices must be setup by user --- CHANGELOG | 1 + src/core.c | 28 +++++++++++++----- src/rlgl.c | 97 ++++++++++++++++++++++++-------------------------------------- src/rlgl.h | 1 - 4 files changed, 60 insertions(+), 67 deletions(-) (limited to 'src/core.c') diff --git a/CHANGELOG b/CHANGELOG index debc7ff5..d8370b61 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -37,6 +37,7 @@ other changes: [rlgl] Improved 2D vs 3D drawing system (lines, triangles, quads) [rlgl] Improved DXT-ETC1 support on HTML5 [rlgl] Review function: rlglUnproject() +[rlgl] Removed function: rlglInitGraphics(), integrated into rlglInit() [rlgl] Updated Mesh and Shader structs [rlgl] Simplified internal (default) dynamic buffers [rlgl] Added support for indexed and dynamic mesh data diff --git a/src/core.c b/src/core.c index 62b916fb..de632c09 100644 --- a/src/core.c +++ b/src/core.c @@ -1761,8 +1761,19 @@ static void InitGraphicsDevice(int width, int height) #endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) // Initialize OpenGL context (states and resources) - rlglInit(); // Init rlgl - rlglInitGraphics(renderOffsetX, renderOffsetY, renderWidth, renderHeight); // Init graphics (OpenGL stuff) + rlglInit(); + + // Initialize screen viewport (area of the screen that you will actually draw to) + // NOTE: Viewport must be recalculated if screen is resized + rlViewport(renderOffsetX/2, renderOffsetY/2, renderWidth - renderOffsetX, renderHeight - renderOffsetY); + + // Initialize internal projection and modelview matrices + // NOTE: Default to orthographic projection mode with top-left corner at (0,0) + rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix + rlLoadIdentity(); // Reset current matrix (PROJECTION) + rlOrtho(0, renderWidth - renderOffsetX, renderHeight - renderOffsetY, 0, 0.0f, 1.0f); + rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix + rlLoadIdentity(); // Reset current matrix (MODELVIEW) ClearBackground(RAYWHITE); // Default background color for raylib games :P @@ -2127,8 +2138,14 @@ static void CursorEnterCallback(GLFWwindow *window, int enter) // NOTE: Window resizing not allowed by default static void WindowSizeCallback(GLFWwindow *window, int width, int height) { - // If window is resized, graphics device is re-initialized (but only ortho mode) - rlglInitGraphics(0, 0, width, height); + // If window is resized, viewport and projection matrix needs to be re-calculated + rlViewport(0, 0, width, height); // Set viewport width and height + rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix + rlLoadIdentity(); // Reset current matrix (PROJECTION) + rlOrtho(0, width, height, 0, 0.0f, 1.0f); // Orthographic projection mode with top-left corner at (0,0) + rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix + rlLoadIdentity(); // Reset current matrix (MODELVIEW) + rlClearScreenBuffers(); // Clear screen buffers (color and depth) // Window size must be updated to be used on 3D mode to get new aspect ratio (Begin3dMode()) screenWidth = width; @@ -2137,9 +2154,6 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height) renderHeight = height; // NOTE: Postprocessing texture is not scaled to new size - - // Background must be also re-cleared - ClearBackground(RAYWHITE); } // GLFW3 WindowIconify Callback, runs when window is minimized/restored diff --git a/src/rlgl.c b/src/rlgl.c index 185ea4fc..99afd681 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -290,8 +290,7 @@ static int blendMode = 0; // Track current blending mode // White texture useful for plain color polys (required by shader) static unsigned int whiteTexture; -// Default framebuffer size -// NOTE: Updated when calling rlglInitGraphics() +// Default framebuffer size (required by Oculus device) static int screenWidth; // Default framebuffer width static int screenHeight; // Default framebuffer height @@ -481,10 +480,15 @@ void rlOrtho(double left, double right, double bottom, double top, double near, #endif -// Set the viewport area (trasnformation from normalized device coordinates to window coordinates) +// Set the viewport area (transformation from normalized device coordinates to window coordinates) +// NOTE: Updates global variables: screenWidth, screenHeight void rlViewport(int x, int y, int width, int height) { glViewport(x, y, width, height); + + // Store default framebuffer size + screenWidth = width; + screenHeight = height; } //---------------------------------------------------------------------------------- @@ -947,7 +951,7 @@ int rlGetVersion(void) // Module Functions Definition - rlgl Functions //---------------------------------------------------------------------------------- -// Init OpenGL 3.3+ required data +// Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states void rlglInit(void) { // Check OpenGL information and capabilities @@ -1134,7 +1138,37 @@ void rlglInit(void) projection = MatrixIdentity(); modelview = MatrixIdentity(); currentMatrix = &modelview; +#endif // defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + + // Initialize OpenGL default states + //---------------------------------------------------------- + + // Init state: Depth test + glDepthFunc(GL_LEQUAL); // Type of depth testing to apply + glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D) + + // Init state: Blending mode + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed) + glEnable(GL_BLEND); // Enable color blending (required to work with transparencies) + + // Init state: Culling + // NOTE: All shapes/models triangles are drawn CCW + glCullFace(GL_BACK); // Cull the back face (default) + glFrontFace(GL_CCW); // Front face are defined counter clockwise (default) + glEnable(GL_CULL_FACE); // Enable backface culling + +#if defined(GRAPHICS_API_OPENGL_11) + // Init state: Color hints (deprecated in OpenGL 3.0+) + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation + glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) #endif + + // Init state: Color/Depth buffers clear + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) + glClearDepth(1.0f); // Set clear depth value (default) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D) + + TraceLog(INFO, "OpenGL default states initialized successfully"); } // Vertex Buffer Object deinitialization (memory free) @@ -1176,61 +1210,6 @@ void rlglDraw(void) #endif } -// Initialize OpenGL states -// NOTE: Stores global variables screenWidth and screenHeight -void rlglInitGraphics(int offsetX, int offsetY, int width, int height) -{ - // Store default framebuffer size - screenWidth = width; - screenHeight = height; - - // Init state: Viewport - // NOTE: Viewport must be recalculated if screen is resized, don't confuse glViewport with the - // transformation matrix, glViewport just defines the area of the context that you will actually draw to. - glViewport(offsetX/2, offsetY/2, width - offsetX, height - offsetY); // Set viewport width and height - - // Init state: Depth Test - glDepthFunc(GL_LEQUAL); // Type of depth testing to apply - glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D) - - // Init state: Blending mode - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed) - glEnable(GL_BLEND); // Enable color blending (required to work with transparencies) - - // Init state: Culling - // NOTE: All shapes/models triangles are drawn CCW - glCullFace(GL_BACK); // Cull the back face (default) - glFrontFace(GL_CCW); // Front face are defined counter clockwise (default) - glEnable(GL_CULL_FACE); // Enable backface culling - -#if defined(GRAPHICS_API_OPENGL_11) - // Init state: Color hints (deprecated in OpenGL 3.0+) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation - glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) -#endif - - // Init state: Color/Depth buffers clear - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) - glClearDepth(1.0f); // Set clear depth value (default) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D) - - // Init state: projection and modelview matrices - // NOTE: Setup global variables: projection and modelview - rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix - rlLoadIdentity(); // Reset current matrix (PROJECTION) - rlOrtho(0, width - offsetX, height - offsetY, 0, 0.0f, 1.0f); // Orthographic projection mode with top-left corner at (0,0) - rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix - rlLoadIdentity(); // Reset current matrix (MODELVIEW) - - // NOTE: projection and modelview could be set alternatively using: - //Matrix matOrtho = MatrixOrtho(0, width - offsetX, height - offsetY, 0, 0.0f, 1.0f); - //MatrixTranspose(&matOrtho); - //projection = matOrtho; // Global variable - //modelview = MatrixIdentity(); // Global variable - - TraceLog(INFO, "OpenGL graphic device initialized successfully"); -} - // Load OpenGL extensions // NOTE: External loader function could be passed as a pointer void rlglLoadExtensions(void *loader) diff --git a/src/rlgl.h b/src/rlgl.h index 2bd7a6b4..61d11d66 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -301,7 +301,6 @@ int rlGetVersion(void); // Returns current OpenGL versio void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...) void rlglClose(void); // De-init rlgl 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 -- cgit v1.2.3 From 6981e2bffaf6626b4ffc3f667dd9cc1de2c196da Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 26 Jun 2016 01:36:06 +0200 Subject: Get supported videomodes for fullscreen --- src/core.c | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index de632c09..f02178c5 100644 --- a/src/core.c +++ b/src/core.c @@ -480,16 +480,14 @@ bool IsWindowMinimized(void) } // Fullscreen toggle -// TODO: When destroying window context is lost and resources too, take care! void ToggleFullscreen(void) { #if defined(PLATFORM_DESKTOP) fullscreen = !fullscreen; // Toggle fullscreen flag - rlglClose(); // De-init rlgl - glfwDestroyWindow(window); // Destroy the current window (we will recreate it!) - - InitWindow(screenWidth, screenHeight, windowTitle); + // NOTE: glfwSetWindowMonitor() doesn't work properly (bugs) + if (fullscreen) glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE); + else glfwSetWindowMonitor(window, NULL, 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE); #endif #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) @@ -1525,25 +1523,40 @@ static void InitGraphicsDevice(int width, int height) if (fullscreen) { - // At this point we need to manage render size vs screen size - // NOTE: This function uses and modifies global module variables: - // screenWidth/screenHeight - renderWidth/renderHeight - downscaleView - SetupFramebufferSize(displayWidth, displayHeight); - - // TODO: SetupFramebufferSize() does not consider properly display video modes. - // It setups a renderWidth/renderHeight with black bars that could not match a valid video mode, - // and so, framebuffer is not scaled properly to some monitors. - + // Obtain recommended displayWidth/displayHeight from a valid videomode for the monitor int count; const GLFWvidmode *modes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); + // Get closest videomode to desired screenWidth/screenHeight for (int i = 0; i < count; i++) { - // TODO: Check modes[i]->width; - // TODO: Check modes[i]->height; + if (modes[i].width >= screenWidth) + { + if (modes[i].height >= screenHeight) + { + displayWidth = modes[i].width; + displayHeight = modes[i].height; + break; + } + } } - window = glfwCreateWindow(screenWidth, screenHeight, windowTitle, glfwGetPrimaryMonitor(), NULL); + TraceLog(WARNING, "Closest fullscreen videomode: %i x %i", displayWidth, displayHeight); + + // NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example, + // for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3), + // framebuffer is rendered correctly but once displayed on a 16:9 monitor, it gets stretched + // by the sides to fit all monitor space... + + // At this point we need to manage render size vs screen size + // NOTE: This function uses and modifies global module variables: + // screenWidth/screenHeight - renderWidth/renderHeight - downscaleView + SetupFramebufferSize(displayWidth, displayHeight); + + window = glfwCreateWindow(displayWidth, displayHeight, windowTitle, glfwGetPrimaryMonitor(), NULL); + + // NOTE: Full-screen change, not working properly... + //glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE); } else { @@ -1785,11 +1798,7 @@ static void InitGraphicsDevice(int width, int height) // Compute framebuffer size relative to screen size and display size // NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified static void SetupFramebufferSize(int displayWidth, int displayHeight) -{ - // TODO: SetupFramebufferSize() does not consider properly display video modes. - // It setups a renderWidth/renderHeight with black bars that could not match a valid video mode, - // and so, framebuffer is not scaled properly to some monitors. - +{ // Calculate renderWidth and renderHeight, we have the display size (input params) and the desired screen size (global var) if ((screenWidth > displayWidth) || (screenHeight > displayHeight)) { -- cgit v1.2.3 From 8652e644dd9f013464ac1cf1bf9f643637209ff8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 26 Jun 2016 14:13:11 +0200 Subject: Corrected bug on stereo rendering --- src/core.c | 2 +- src/rlgl.c | 12 ++++++------ src/rlgl.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index f02178c5..47ce5cea 100644 --- a/src/core.c +++ b/src/core.c @@ -1774,7 +1774,7 @@ static void InitGraphicsDevice(int width, int height) #endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) // Initialize OpenGL context (states and resources) - rlglInit(); + rlglInit(screenWidth, screenHeight); // Initialize screen viewport (area of the screen that you will actually draw to) // NOTE: Viewport must be recalculated if screen is resized diff --git a/src/rlgl.c b/src/rlgl.c index 99afd681..ea65b6a4 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -485,10 +485,6 @@ void rlOrtho(double left, double right, double bottom, double top, double near, void rlViewport(int x, int y, int width, int height) { glViewport(x, y, width, height); - - // Store default framebuffer size - screenWidth = width; - screenHeight = height; } //---------------------------------------------------------------------------------- @@ -952,7 +948,7 @@ int rlGetVersion(void) //---------------------------------------------------------------------------------- // Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states -void rlglInit(void) +void rlglInit(int width, int height) { // Check OpenGL information and capabilities //------------------------------------------------------------------------------ @@ -1167,6 +1163,10 @@ void rlglInit(void) glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) glClearDepth(1.0f); // Set clear depth value (default) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D) + + // Store screen size into global variables + screenWidth = width; + screenHeight = height; TraceLog(INFO, "OpenGL default states initialized successfully"); } @@ -2524,7 +2524,7 @@ void InitOculusDevice(void) if (!oculusEnabled) { TraceLog(WARNING, "VR: Initializing Oculus simulator"); - + // Initialize framebuffer and textures for stereo rendering stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); diff --git a/src/rlgl.h b/src/rlgl.h index 61d11d66..0f9c7a80 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -298,7 +298,7 @@ int rlGetVersion(void); // Returns current OpenGL versio //------------------------------------------------------------------------------------ // Functions Declaration - rlgl functionality //------------------------------------------------------------------------------------ -void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...) +void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states) void rlglClose(void); // De-init rlgl void rlglDraw(void); // Draw VAO/VBO void rlglLoadExtensions(void *loader); // Load OpenGL extensions -- cgit v1.2.3 From ee72654b557202a673f042484c83d3020ae618b8 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 4 Jul 2016 01:29:23 +0200 Subject: Redesigned stereo rendering mechanism Now it's easier for the user! Just init Oculus device and get stereo rendering! --- examples/core_oculus_rift.c | 11 +- examples/resources/shaders/glsl330/distortion.fs | 9 +- src/core.c | 18 +- src/raylib.h | 2 - src/rlgl.c | 443 ++++++++++++----------- src/rlgl.h | 4 - 6 files changed, 251 insertions(+), 236 deletions(-) (limited to 'src/core.c') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index c073d3d6..131a21c2 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -50,22 +50,15 @@ int main() // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - + ClearBackground(RAYWHITE); - + Begin3dMode(camera); - for (int eye = 0; eye < 2; eye++) - { - SetOculusView(eye); - DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); DrawGrid(10, 1.0f); - - DrawDefaultBuffers(); // Process internal dynamic buffers - } End3dMode(); diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index 4cd9937f..62856341 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -10,12 +10,13 @@ uniform sampler2D texture0; out vec4 finalColor; // NOTE: Add here your custom variables -const vec2 LeftLensCenter = vec2(0.2863248, 0.5); -const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftLensCenter = vec2(0.288, 0.5); +const vec2 RightLensCenter = vec2(0.712, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); -const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -const vec2 ScaleIn = vec2(4, 2.2222); +uniform vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +uniform vec2 ScaleIn = vec2(4, 2.2222); + const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); diff --git a/src/core.c b/src/core.c index 47ce5cea..a8557831 100644 --- a/src/core.c +++ b/src/core.c @@ -520,6 +520,8 @@ void BeginDrawing(void) currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called updateTime = currentTime - previousTime; previousTime = currentTime; + + if (IsOculusReady()) BeginOculusDrawing(); rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -533,6 +535,8 @@ void BeginDrawing(void) void EndDrawing(void) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) + + if (IsOculusReady()) EndOculusDrawing(); SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events @@ -608,15 +612,11 @@ void Begin3dMode(Camera camera) rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D - - if (IsOculusReady()) BeginOculusDrawing(); } // Ends 3D mode and returns to default 2D orthographic mode void End3dMode(void) -{ - if (IsOculusReady()) EndOculusDrawing(); - +{ rlglDraw(); // Process internal buffers (update + draw) rlMatrixMode(RL_PROJECTION); // Switch to projection matrix @@ -1021,14 +1021,6 @@ Matrix GetCameraMatrix(Camera camera) return MatrixLookAt(camera.position, camera.target, camera.up); } -// Update and draw default buffers vertex data -// NOTE: This data has been stored dynamically during frame on each Draw*() call -void DrawDefaultBuffers(void) -{ - rlglUpdateDefaultBuffers(); // Upload frame vertex data to GPU - rlglDrawDefaultBuffers(); // Draw vertex data into framebuffer -} - //---------------------------------------------------------------------------------- // Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions //---------------------------------------------------------------------------------- diff --git a/src/raylib.h b/src/raylib.h index 6bacfc67..89fc457f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -572,7 +572,6 @@ void EndTextureMode(void); // Ends drawing to r Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) -void DrawDefaultBuffers(void); // Update and draw default buffers vertex data (stored dynamically in frame) void SetTargetFPS(int fps); // Set target FPS (maximum) float GetFPS(void); // Returns current FPS @@ -853,7 +852,6 @@ void DestroyLight(Light light); // Destroy a 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) bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready diff --git a/src/rlgl.c b/src/rlgl.c index d3ffdd8b..57e6b894 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -276,9 +276,10 @@ static unsigned int frameIndex = 0; // Oculus frames counter, used to discar static bool oculusReady = false; // Oculus device ready flag static bool oculusSimulator = false; // Oculus device simulator static bool vrEnabled = false; // VR experience enabled (Oculus device or simulator) +static bool vrControl = true; // VR controlled by user code, instead of internally static RenderTexture2D stereoFbo; -static Shader distortion; +static Shader distortionShader; // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support @@ -315,10 +316,13 @@ static void UnloadDefaultShader(void); // Unload default shader static void UnloadStandardShader(void); // Unload standard shader static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads) -void rlglUpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data -void rlglDrawDefaultBuffers(void); // Draw default internal buffers vertex data +static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data +static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers vertex data static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU +// Set internal projection and modelview matrix depending on eyes tracking data +static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView); + static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array static char *ReadTextFile(const char *fileName); @@ -1205,15 +1209,14 @@ void rlglClose(void) void rlglDraw(void) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) -/* - for (int i = 0; i < modelsCount; i++) - { - rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform); - } -*/ - // NOTE: Default buffers always drawn at the end - rlglUpdateDefaultBuffers(); - rlglDrawDefaultBuffers(); + // NOTE: In a future version, models could be stored in a stack... + //for (int i = 0; i < modelsCount; i++) rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform); + + // NOTE: Default buffers upload and draw + UpdateDefaultBuffers(); + + if (vrEnabled && vrControl) DrawDefaultBuffers(2); + else DrawDefaultBuffers(1); #endif } @@ -1865,26 +1868,23 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) #endif #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + int eyesCount = 1; + if (vrEnabled) eyesCount = 2; + glUseProgram(material.shader.id); + // Upload to shader material.colDiffuse + float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 }; + glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse); + // At this point the modelview matrix just contains the view matrix (camera) // That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() Matrix matView = modelview; // View matrix (camera) Matrix matProjection = projection; // Projection matrix (perspective) - + // Calculate model-view matrix combining matModel and matView Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates - // Calculate model-view-projection matrix (MVP) - Matrix matMVP = MatrixMultiply(matModelView, matProjection); // Transform to screen-space coordinates - - // Send combined model-view-projection matrix to shader - glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); - - // Upload to shader material.colDiffuse - float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 }; - glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse); - // Check if using standard shader to get location points // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations) if (material.shader.id == standardShader.id) @@ -1989,9 +1989,20 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); } - // Draw call! - if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw - else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); + for (int eye = 0; eye < eyesCount; eye++) + { + if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); + + // Calculate model-view-projection matrix (MVP) + Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates + + // Send combined model-view-projection matrix to shader + glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); + + // Draw call! + if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw + else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); + } if (material.texNormal.id != 0) { @@ -2016,6 +2027,10 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) } glUseProgram(0); // Unbind shader program + + // Restore projection/modelview matrices + projection = matProjection; + modelview = matView; #endif } @@ -2538,7 +2553,7 @@ void InitOculusDevice(void) // Load oculus-distortion shader (oculus parameters setup internally) // TODO: Embed coulus distortion shader (in this function like default shader?) - distortion = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); + distortionShader = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); oculusSimulator = true; vrEnabled = true; @@ -2564,7 +2579,7 @@ void CloseOculusDevice(void) rlDeleteRenderTextures(stereoFbo); // Unload oculus-distortion shader - UnloadShader(distortion); + UnloadShader(distortionShader); } oculusReady = false; @@ -2615,13 +2630,13 @@ void UpdateOculusTracking(void) } // Set internal projection and modelview matrix depending on eyes tracking data -void SetOculusView(int eye) -{ - Matrix eyeProjection; - Matrix eyeModelView; - +static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) +{ if (vrEnabled) { + Matrix eyeProjection = matProjection; + Matrix eyeModelView = matModelView; + #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) { @@ -2639,10 +2654,8 @@ void SetOculusView(int eye) -layer.eyeLayer.RenderPose[eye].Position.z); Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement - eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + eyeModelView = MatrixMultiply(matModelView, 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]; } else @@ -2651,28 +2664,43 @@ void SetOculusView(int eye) // Setup viewport and projection/modelview matrices using tracking data rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); - float hmdIPD = 0.064f; - float hmdHScreenSize = 0.14976f; - float hmdVScreenSize = 0.0936f; - //float hmdVScreenCenter = 0.04675f; - float hmdEyeToScreenDistance = 0.041f; - float hmdLensSeparationDistance = 0.064f; + static float IPD = 0.064f; // InterpupillaryDistance + float HScreenSize = 0.14976f; + float VScreenSize = 0.0936f; // HScreenSize/(1280.0f/800.0f) + float VScreenCenter = 0.04675f; + float EyeToScreenDistance = 0.041f; + float LensSeparationDistance = 0.064f; //0.0635f (DK1) - //NOTE: fovy value hardcoded to 60 degrees (Oculus Rift CV1 vertical FOV is 100 degrees) - //float halfScreenDistance = hmdVScreenSize/2.0f; - //float yfov = 2.0f*atan(halfScreenDistance/hmdEyeToScreenDistance); - - float viewCenter = (float)hmdHScreenSize*0.25f; - float eyeProjectionShift = viewCenter - hmdLensSeparationDistance*0.5f; - float projectionCenterOffset = 4.0f*eyeProjectionShift/(float)hmdHScreenSize; - + // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) + float halfScreenDistance = VScreenSize/2.0f; + float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG; + + float viewCenter = (float)HScreenSize*0.25f; + float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f; + float projectionCenterOffset = 4.0f*eyeProjectionShift/(float)HScreenSize; +/* + static float scale[2] = { 0.25, 0.45 }; + + if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01; + else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01; + else if (IsKeyDown(KEY_UP)) scale[1] += 0.01; + else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01; + SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2); + + if (IsKeyDown(KEY_N)) IPD += 0.02; + else if (IsKeyDown(KEY_M)) IPD -= 0.02; +*/ // The matrixes for offsetting the projection and view for each eye, to achieve stereo effect Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f }; - Vector3 viewOffset = { -hmdIPD/2.0f, 0.0f, 0.0f }; + + // 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. + Vector3 viewOffset = { -IPD/2.0f, 0.075f, 0.045f }; // Negate the left eye versions - if (eye == 1) + if (eye == 0) { projectionOffset.x *= -1.0f; viewOffset.x *= -1.0f; @@ -2680,29 +2708,18 @@ void SetOculusView(int eye) // Adjust the view and projection matrixes // View matrix is translated based on the eye offset - Matrix projCenter = MatrixPerspective(60.0, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); + Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z); Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z); eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection - eyeModelView = MatrixMultiply(modelview, viewTranslation); // modelview + eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview MatrixTranspose(&eyeProjection); - - /* - // NOTE: fovy value hardcoded to 60 degrees (Oculus Rift CV1 vertical FOV is 100 degrees) - eyeProjection = MatrixPerspective(60.0, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0); - MatrixTranspose(&eyeProjection); - - // TODO: Compute eyes IPD and apply to current modelview matrix (camera) - Matrix eyeView = MatrixIdentity(); - - eyeModelView = MatrixMultiply(modelview, eyeView); - */ } - SetMatrixModelview(eyeModelView); + SetMatrixModelview(eyeModelView); // ERROR! We are modifying modelview for next eye!!! SetMatrixProjection(eyeProjection); } } @@ -2738,6 +2755,8 @@ void BeginOculusDrawing(void) //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) rlClearScreenBuffers(); // Clear current framebuffer(s) + + vrControl = true; } // End Oculus drawing process (and desktop mirror) @@ -2777,40 +2796,44 @@ void EndOculusDrawing(void) rlLoadIdentity(); // Reset internal modelview matrix // Draw RenderTexture (stereoFbo) using distortion shader - BeginShaderMode(distortion); + currentShader = distortionShader; - rlEnableTexture(stereoFbo.texture.id); + rlEnableTexture(stereoFbo.texture.id); - rlPushMatrix(); - rlBegin(RL_QUADS); - rlColor4ub(255, 255, 255, 255); - rlNormal3f(0.0f, 0.0f, 1.0f); + 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-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, stereoFbo.texture.height); + // Bottom-right corner for texture and quad + rlTexCoord2f(0.0f, 0.0f); + rlVertex2f(0.0f, stereoFbo.texture.height); - // Top-right corner for texture and quad - rlTexCoord2f(1.0f, 0.0f); - rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height); + // Top-right corner for texture and quad + rlTexCoord2f(1.0f, 0.0f); + rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height); - // Top-left corner for texture and quad - rlTexCoord2f(1.0f, 1.0f); - rlVertex2f(stereoFbo.texture.width, 0.0f); - rlEnd(); - rlPopMatrix(); + // Top-left corner for texture and quad + rlTexCoord2f(1.0f, 1.0f); + rlVertex2f(stereoFbo.texture.width, 0.0f); + rlEnd(); + rlPopMatrix(); - rlDisableTexture(); - - //rlglDraw(); - EndShaderMode(); + rlDisableTexture(); + + UpdateDefaultBuffers(); + DrawDefaultBuffers(1); + + currentShader = defaultShader; } rlDisableDepthTest(); + + vrControl = false; } //---------------------------------------------------------------------------------- @@ -3303,7 +3326,7 @@ static void LoadDefaultBuffers(void) // Update default internal buffers (VAOs/VBOs) with vertex array data // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required) -void rlglUpdateDefaultBuffers(void) +static void UpdateDefaultBuffers(void) { // Update lines vertex buffers if (lines.vCounter > 0) @@ -3373,146 +3396,154 @@ void rlglUpdateDefaultBuffers(void) // Draw default internal buffers vertex data // NOTE: We draw in this order: lines, triangles, quads -void rlglDrawDefaultBuffers(void) +static void DrawDefaultBuffers(int eyesCount) { - // Set current shader and upload current MVP matrix - if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) - { - glUseProgram(currentShader.id); - - // Create modelview-projection matrix - Matrix matMVP = MatrixMultiply(modelview, projection); - - glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); - glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f); - glUniform1i(currentShader.mapTexture0Loc, 0); - - // NOTE: Additional map textures not considered for default buffers drawing - } - - // Draw lines buffers - if (lines.vCounter > 0) + Matrix matProjection = projection; + Matrix matModelView = modelview; + + for (int eye = 0; eye < eyesCount; eye++) { - glBindTexture(GL_TEXTURE_2D, whiteTexture); + if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); - if (vaoSupported) + // Set current shader and upload current MVP matrix + if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) { - glBindVertexArray(lines.vaoId); + glUseProgram(currentShader.id); + + // Create modelview-projection matrix + Matrix matMVP = MatrixMultiply(modelview, projection); + + glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); + glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f); + glUniform1i(currentShader.mapTexture0Loc, 0); + + // NOTE: Additional map textures not considered for default buffers drawing } - else + + // Draw lines buffers + if (lines.vCounter > 0) { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); - } + glBindTexture(GL_TEXTURE_2D, whiteTexture); - glDrawArrays(GL_LINES, 0, lines.vCounter); - - if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - } + if (vaoSupported) + { + glBindVertexArray(lines.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + } - // Draw triangles buffers - if (triangles.vCounter > 0) - { - glBindTexture(GL_TEXTURE_2D, whiteTexture); + glDrawArrays(GL_LINES, 0, lines.vCounter); - if (vaoSupported) - { - glBindVertexArray(triangles.vaoId); - } - else - { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); + if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); } - glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter); + // Draw triangles buffers + if (triangles.vCounter > 0) + { + glBindTexture(GL_TEXTURE_2D, whiteTexture); - if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - } + if (vaoSupported) + { + glBindVertexArray(triangles.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + } - // Draw quads buffers - if (quads.vCounter > 0) - { - int quadsCount = 0; - int numIndicesToProcess = 0; - int indicesOffset = 0; + glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter); - if (vaoSupported) - { - glBindVertexArray(quads.vaoId); + if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); } - else + + // Draw quads buffers + if (quads.vCounter > 0) { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: texcoord (shader-location = 1) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]); - glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.texcoordLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); - } + int quadsCount = 0; + int numIndicesToProcess = 0; + int indicesOffset = 0; - //TraceLog(DEBUG, "Draws required per frame: %i", drawsCounter); + if (vaoSupported) + { + glBindVertexArray(quads.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: texcoord (shader-location = 1) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]); + glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.texcoordLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); + } - for (int i = 0; i < drawsCounter; i++) - { - quadsCount = draws[i].vertexCount/4; - numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad + //TraceLog(DEBUG, "Draws required per frame: %i", drawsCounter); - //TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount); + for (int i = 0; i < drawsCounter; i++) + { + quadsCount = draws[i].vertexCount/4; + numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad - glBindTexture(GL_TEXTURE_2D, draws[i].textureId); + //TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount); - // NOTE: The final parameter tells the GPU the offset in bytes from the start of the index buffer to the location of the first index to process -#if defined(GRAPHICS_API_OPENGL_33) - glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*indicesOffset)); -#elif defined(GRAPHICS_API_OPENGL_ES2) - glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*indicesOffset)); -#endif - //GLenum err; - //if ((err = glGetError()) != GL_NO_ERROR) TraceLog(INFO, "OpenGL error: %i", (int)err); //GL_INVALID_ENUM! + glBindTexture(GL_TEXTURE_2D, draws[i].textureId); - indicesOffset += draws[i].vertexCount/4*6; - } + // NOTE: The final parameter tells the GPU the offset in bytes from the start of the index buffer to the location of the first index to process + #if defined(GRAPHICS_API_OPENGL_33) + glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*indicesOffset)); + #elif defined(GRAPHICS_API_OPENGL_ES2) + glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*indicesOffset)); + #endif + //GLenum err; + //if ((err = glGetError()) != GL_NO_ERROR) TraceLog(INFO, "OpenGL error: %i", (int)err); //GL_INVALID_ENUM! - if (!vaoSupported) - { - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } + indicesOffset += draws[i].vertexCount/4*6; + } - glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures - } + if (!vaoSupported) + { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } - if (vaoSupported) glBindVertexArray(0); // Unbind VAO + glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures + } - glUseProgram(0); // Unbind shader program + if (vaoSupported) glBindVertexArray(0); // Unbind VAO + glUseProgram(0); // Unbind shader program + } + // Reset draws counter drawsCounter = 1; draws[0].textureId = whiteTexture; @@ -3529,6 +3560,10 @@ void rlglDrawDefaultBuffers(void) // Reset depth for next draw currentDepth = -1.0f; + + // Restore projection/modelview matrices + projection = matProjection; + modelview = matModelView; } // Unload default internal buffers vertex data from CPU and GPU diff --git a/src/rlgl.h b/src/rlgl.h index 675bb74f..f52af6f9 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -303,9 +303,6 @@ void rlglClose(void); // De-init rlgl void rlglDraw(void); // Draw VAO/VBO 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 @@ -358,7 +355,6 @@ void TraceLog(int msgType, const char *text, ...); 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) bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready -- cgit v1.2.3 From 2ff2096b36d80078cbda5e61ff77d7fedeeeaeb5 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 4 Jul 2016 18:35:50 +0200 Subject: Moved Oculus enable drawing to user side... Still thinking about the best way to manage this... --- examples/core_oculus_rift.c | 4 ++++ src/core.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/core.c') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 131a21c2..734ba8fd 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -52,6 +52,8 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); + + if (IsOculusReady()) BeginOculusDrawing(); Begin3dMode(camera); @@ -62,6 +64,8 @@ int main() End3dMode(); + if (IsOculusReady()) EndOculusDrawing(); + DrawFPS(10, 10); EndDrawing(); diff --git a/src/core.c b/src/core.c index a8557831..f8a83e25 100644 --- a/src/core.c +++ b/src/core.c @@ -521,7 +521,7 @@ void BeginDrawing(void) updateTime = currentTime - previousTime; previousTime = currentTime; - if (IsOculusReady()) BeginOculusDrawing(); + //if (IsOculusReady()) BeginOculusDrawing(); rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -536,7 +536,7 @@ void EndDrawing(void) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) - if (IsOculusReady()) EndOculusDrawing(); + //if (IsOculusReady()) EndOculusDrawing(); SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events @@ -2675,7 +2675,7 @@ static void *MouseThread(void *arg) int mouseRelX = 0; int mouseRelY = 0; - while (1) + while (!windowShouldClose) { if (read(mouseStream, &mouse, sizeof(MouseEvent)) == (int)sizeof(MouseEvent)) { -- cgit v1.2.3 From bc80174357392c0a16b74cd4a9e497a1de367760 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 6 Jul 2016 00:54:38 +0200 Subject: VR Functions renaming (for generic HMD device) Stereo rendering has been moved again to Begin3dMode() and End3dMode(), it has some limitations but makes more sense... --- examples/core_oculus_rift.c | 19 ++++++++----------- src/core.c | 8 ++++---- src/raylib.h | 29 +++++++++++++++++++++-------- src/rlgl.c | 45 +++++++++++++++++++++++---------------------- src/rlgl.h | 16 ++++++++-------- 5 files changed, 64 insertions(+), 53 deletions(-) (limited to 'src/core.c') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 734ba8fd..fa70c487 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -23,7 +23,8 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift"); - InitOculusDevice(); + // NOTE: If device is not available, it fallbacks to default device (simulator) + InitVrDevice(HMD_OCULUS_RIFT_CV1); // Init VR device (Oculus Rift CV1) // Define the camera to look into our 3d world Camera camera; @@ -42,9 +43,9 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdateOculusTracking(); + UpdateVrTracking(); - if (IsKeyPressed(KEY_SPACE)) ToggleVR(); + if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); //---------------------------------------------------------------------------------- // Draw @@ -52,20 +53,16 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); - - if (IsOculusReady()) BeginOculusDrawing(); Begin3dMode(camera); DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); - + DrawGrid(10, 1.0f); - + End3dMode(); - - if (IsOculusReady()) EndOculusDrawing(); - + DrawFPS(10, 10); EndDrawing(); @@ -74,7 +71,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - CloseOculusDevice(); // Close Oculus Rift device + CloseVrDevice(); // Close VR device CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/src/core.c b/src/core.c index f8a83e25..107fc0a0 100644 --- a/src/core.c +++ b/src/core.c @@ -521,8 +521,6 @@ void BeginDrawing(void) updateTime = currentTime - previousTime; previousTime = currentTime; - //if (IsOculusReady()) BeginOculusDrawing(); - rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here @@ -535,8 +533,6 @@ void BeginDrawing(void) void EndDrawing(void) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) - - //if (IsOculusReady()) EndOculusDrawing(); SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events @@ -590,6 +586,8 @@ void End2dMode(void) void Begin3dMode(Camera camera) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) + + if (IsVrDeviceReady()) BeginVrDrawing(); rlMatrixMode(RL_PROJECTION); // Switch to projection matrix @@ -618,6 +616,8 @@ void Begin3dMode(Camera camera) void End3dMode(void) { rlglDraw(); // Process internal buffers (update + draw) + + if (IsVrDeviceReady()) EndVrDrawing(); rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack diff --git a/src/raylib.h b/src/raylib.h index 89fc457f..227f83f2 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -527,6 +527,19 @@ typedef struct GestureEvent { // Camera system modes typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; +// Head Mounted Display devices +typedef enum { + HMD_DEFAULT_DEVICE = 0, + HMD_OCULUS_RIFT_DK2, + HMD_OCULUS_RIFT_CV1, + HMD_VALVE_HTC_VIVE, + HMD_SAMSUNG_GEAR_VR, + HMD_GOOGLE_CARDBOARD, + HMD_SONY_PLAYSTATION_VR, + HMD_RAZER_OSVR, + HMD_FOVE_VR, +} HmdDevice; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -846,16 +859,16 @@ Light CreateLight(int type, Vector3 position, Color diffuse); // Create a void DestroyLight(Light light); // Destroy a light and take it out of the list //------------------------------------------------------------------------------------ -// Oculus Rift CV1 Functions (Module: rlgl) +// VR experience Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -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 BeginOculusDrawing(void); // Begin Oculus drawing configuration -void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) -bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready -void ToggleVR(void); // Enable/Disable VR experience (Oculus device or simulator) +void InitVrDevice(int hmdDevice); // Init VR device +void CloseVrDevice(void); // Close VR device +void UpdateVrTracking(void); // Update VR tracking (position and orientation) +void BeginVrDrawing(void); // Begin VR drawing configuration +void EndVrDrawing(void); // End VR drawing process (and desktop mirror) +bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready +void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator) //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) diff --git a/src/rlgl.c b/src/rlgl.c index af2d57cb..a71142b0 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -322,7 +322,7 @@ static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU // Set internal projection and modelview matrix depending on eyes tracking data -static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView); +static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array @@ -2001,7 +2001,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) for (int eye = 0; eye < eyesCount; eye++) { - if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); + if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView); else modelview = matModelView; // Calculate model-view-projection matrix (MVP) @@ -2504,8 +2504,9 @@ void DestroyLight(Light light) #endif } -// Init Oculus Rift device (or Oculus device simulator) -void InitOculusDevice(void) +// Init VR device (or simulator) +// NOTE: If device is not available, it fallbacks to default device (simulator) +void InitVrDevice(int hmdDevice) { #if defined(RLGL_OCULUS_SUPPORT) // Initialize Oculus device @@ -2557,7 +2558,7 @@ void InitOculusDevice(void) if (!oculusReady) { - TraceLog(WARNING, "VR: Initializing Oculus simulator"); + TraceLog(WARNING, "HMD Device not found: Initializing VR simulator"); // Initialize framebuffer and textures for stereo rendering stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); @@ -2571,8 +2572,8 @@ void InitOculusDevice(void) } } -// Close Oculus Rift device (or Oculus device simulator) -void CloseOculusDevice(void) +// Close VR device (or simulator) +void CloseVrDevice(void) { #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) @@ -2596,20 +2597,20 @@ void CloseOculusDevice(void) oculusReady = false; } -// Detect if oculus device is available -bool IsOculusReady(void) +// Detect if VR device is available +bool IsVrDeviceReady(void) { return (oculusReady || oculusSimulator) && vrEnabled; } -// Enable/Disable VR experience (Oculus device or simulator) -void ToggleVR(void) +// Enable/Disable VR experience (device or simulator) +void ToggleVrMode(void) { vrEnabled = !vrEnabled; } -// Update Oculus Rift tracking (position and orientation) -void UpdateOculusTracking(void) +// Update VR tracking (position and orientation) +void UpdateVrTracking(void) { #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) @@ -2641,7 +2642,7 @@ void UpdateOculusTracking(void) } // Set internal projection and modelview matrix depending on eyes tracking data -static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) +static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) { if (vrEnabled) { @@ -2675,12 +2676,12 @@ static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) // Setup viewport and projection/modelview matrices using tracking data rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); - static float IPD = 0.064f; // InterpupillaryDistance + static float IPD = 0.064f; // InterpupillaryDistance float HScreenSize = 0.14976f; - float VScreenSize = 0.0936f; // HScreenSize/(1280.0f/800.0f) - float VScreenCenter = 0.04675f; + float VScreenSize = 0.0936f; // HScreenSize/(1280.0f/800.0f) (DK2) + float VScreenCenter = 0.04675f; // VScreenSize/2 float EyeToScreenDistance = 0.041f; - float LensSeparationDistance = 0.064f; //0.0635f (DK1) + float LensSeparationDistance = 0.064f; //0.0635f (DK1) // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) float halfScreenDistance = VScreenSize/2.0f; @@ -2730,13 +2731,13 @@ static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) MatrixTranspose(&eyeProjection); } - SetMatrixModelview(eyeModelView); // ERROR! We are modifying modelview for next eye!!! + SetMatrixModelview(eyeModelView); SetMatrixProjection(eyeProjection); } } // Begin Oculus drawing configuration -void BeginOculusDrawing(void) +void BeginVrDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) @@ -2771,7 +2772,7 @@ void BeginOculusDrawing(void) } // End Oculus drawing process (and desktop mirror) -void EndOculusDrawing(void) +void EndVrDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) @@ -3414,7 +3415,7 @@ static void DrawDefaultBuffers(int eyesCount) for (int eye = 0; eye < eyesCount; eye++) { - if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); + if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView); // Set current shader and upload current MVP matrix if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) diff --git a/src/rlgl.h b/src/rlgl.h index f52af6f9..f984c0c6 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -350,15 +350,15 @@ Light CreateLight(int type, Vector3 position, Color diffuse); // Create a void DestroyLight(Light light); // Destroy a light and take it out of the list void TraceLog(int msgType, const char *text, ...); -#endif -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 BeginOculusDrawing(void); // Begin Oculus drawing configuration -void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) -bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready -void ToggleVR(void); // Enable/Disable VR experience (Oculus device or simulator) +void InitVrDevice(int hmdDevice); // Init VR device +void CloseVrDevice(void); // Close VR device +void UpdateVrTracking(void); // Update VR tracking (position and orientation) +void BeginVrDrawing(void); // Begin VR drawing configuration +void EndVrDrawing(void); // End VR drawing process (and desktop mirror) +bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready +void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator) +#endif #ifdef __cplusplus } -- cgit v1.2.3 From 11172118d10e193afade9816e145f0d57bcd4bb8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 13 Jul 2016 20:05:00 +0200 Subject: Review comments --- src/core.c | 11 +++++------ src/rlgl.c | 15 ++++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index 107fc0a0..a3253d79 100644 --- a/src/core.c +++ b/src/core.c @@ -181,11 +181,10 @@ static uint64_t baseTime; // Base time measure for hi-res timer static bool windowShouldClose = false; // Flag to set window for closing #endif -static unsigned int displayWidth, displayHeight; // Display width and height (monitor, device-screen, LCD, ...) +// Display size-related data +static unsigned int displayWidth, displayHeight; // Display width and height (monitor, device-screen, LCD, ...) static int screenWidth, screenHeight; // Screen width and height (used render area) -static int renderWidth, renderHeight; // Framebuffer width and height (render area) - // NOTE: Framebuffer could include black bars - +static int renderWidth, renderHeight; // Framebuffer width and height (render area, including black bars if required) static int renderOffsetX = 0; // Offset X from render area (must be divided by 2) static int renderOffsetY = 0; // Offset Y from render area (must be divided by 2) static bool fullscreen = false; // Fullscreen mode (useful only for PLATFORM_DESKTOP) @@ -214,7 +213,7 @@ static bool cursorHidden; // Track if cursor is hidden #endif static Vector2 mousePosition; // Mouse position on screen -static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen +static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen #if defined(PLATFORM_DESKTOP) static char **dropFilesPath; // Store dropped files paths as strings @@ -226,7 +225,7 @@ static double updateTime, drawTime; // Time measures for update and draw static double frameTime; // Time measure for one frame static double targetTime = 0.0; // Desired time for one frame, if 0 not applied -static char configFlags = 0; // Configuration flags (bit based) +static char configFlags = 0; // Configuration flags (bit based) static bool showLogo = false; // Track if showing logo at init is enabled //---------------------------------------------------------------------------------- diff --git a/src/rlgl.c b/src/rlgl.c index 1d5d6157..586c15e3 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -257,9 +257,9 @@ static DrawMode currentDrawMode; static float currentDepth = -1.0f; -static DynamicBuffer lines; -static DynamicBuffer triangles; -static DynamicBuffer quads; +static DynamicBuffer lines; // Default dynamic buffer for lines data +static DynamicBuffer triangles; // Default dynamic buffer for triangles data +static DynamicBuffer quads; // Default dynamic buffer for quads data (used to draw textures) // Default buffers draw calls static DrawCall *draws; @@ -271,9 +271,10 @@ static int tempBufferCount = 0; static bool useTempBuffer = false; // Shader Programs -static Shader defaultShader; -static Shader standardShader; // Lazy initialization when GetStandardShader() -static Shader currentShader; // By default, defaultShader +static Shader defaultShader; // Basic shader, support vertex color and diffuse texture +static Shader standardShader; // Shader with support for lighting and materials + // NOTE: Lazy initialization when GetStandardShader() +static Shader currentShader; // Shader to be used on rendering (by default, defaultShader) static bool standardShaderLoaded = false; // Flag to track if standard shader has been loaded // Flags for supported extensions @@ -357,7 +358,7 @@ static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array -static char *ReadTextFile(const char *fileName); +static char *ReadTextFile(const char *fileName); // Read chars array from text file #endif #if defined(RLGL_OCULUS_SUPPORT) -- cgit v1.2.3