diff options
| author | victorfisac <victorfisac@gmail.com> | 2016-07-05 11:57:05 +0200 |
|---|---|---|
| committer | victorfisac <victorfisac@gmail.com> | 2016-07-05 11:57:05 +0200 |
| commit | 1aecd5be072083e27e4289499865b5681f1ea656 (patch) | |
| tree | 808159aa95df9b2be5509d83791aa6cad4ddf6b8 /src | |
| parent | 1b0996fb0bcf68e2a14bc6260c6f2c5366ab033f (diff) | |
| parent | 2ff2096b36d80078cbda5e61ff77d7fedeeeaeb5 (diff) | |
| download | raylib-1aecd5be072083e27e4289499865b5681f1ea656.tar.gz raylib-1aecd5be072083e27e4289499865b5681f1ea656.zip | |
Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 1 | ||||
| -rw-r--r-- | src/core.c | 154 | ||||
| -rw-r--r-- | src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h | 21 | ||||
| -rw-r--r-- | src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h | 102 | ||||
| -rw-r--r-- | src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h | 4 | ||||
| -rw-r--r-- | src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h | 4 | ||||
| -rw-r--r-- | src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h | 4 | ||||
| -rw-r--r-- | src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h | 80 | ||||
| -rw-r--r-- | src/external/OculusSDK/LibOVR/Include/OVR_Version.h | 2 | ||||
| -rw-r--r-- | src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll | bin | 964048 -> 1018320 bytes | |||
| -rw-r--r-- | src/models.c | 78 | ||||
| -rw-r--r-- | src/raylib.h | 4 | ||||
| -rw-r--r-- | src/rlgl.c | 981 | ||||
| -rw-r--r-- | src/rlgl.h | 22 | ||||
| -rw-r--r-- | src/shapes.c | 6 | ||||
| -rw-r--r-- | src/standard_shader.h | 6 | ||||
| -rw-r--r-- | src/textures.c | 7 |
17 files changed, 883 insertions, 593 deletions
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) @@ -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) @@ -444,7 +440,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"); @@ -476,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) @@ -518,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) @@ -531,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 @@ -610,8 +616,8 @@ void Begin3dMode(Camera camera) // Ends 3D mode and returns to default 2D orthographic mode void End3dMode(void) -{ - rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) +{ + rlglDraw(); // Process internal buffers (update + draw) rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack @@ -1433,7 +1439,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 @@ -1480,16 +1486,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! @@ -1504,25 +1515,40 @@ static void InitDisplay(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 { @@ -1738,29 +1764,33 @@ 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) -{ - rlglInit(); // Init rlgl - rlglInitGraphics(renderOffsetX, renderOffsetY, renderWidth, renderHeight); // Init graphics (OpenGL stuff) + // Initialize OpenGL context (states and resources) + 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 + 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 #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. - // 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)) { @@ -2109,8 +2139,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; @@ -2119,9 +2155,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 @@ -2188,11 +2221,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) @@ -2645,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)) { @@ -2735,7 +2765,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++) { @@ -2770,7 +2800,7 @@ static void *GamepadThread(void *arg) return NULL; } -#endif +#endif // PLATFORM_RPI // Plays raylib logo appearing animation static void LogoAnimation(void) diff --git a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h index c182ed5b..718c21cb 100644 --- a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h +++ b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h @@ -1487,6 +1487,25 @@ public: } } + // Decompose a quat into quat = swing * twist, where twist is a rotation about axis, + // and swing is a rotation perpendicular to axis. + Quat GetSwingTwist(const Vector3<T>& axis, Quat* twist) const + { + OVR_MATH_ASSERT(twist); + OVR_MATH_ASSERT(axis.IsNormalized()); + + // Create a normalized quaternion from projection of (x,y,z) onto axis + T d = axis.Dot(Vector3<T>(x, y, z)); + *twist = Quat(axis.x*d, axis.y*d, axis.z*d, w); + T len = twist->Length(); + if (len == 0) + twist->w = T(1); // identity + else + twist /= len; // normalize + + return *this * twist.Inverted(); + } + // Normalized linear interpolation of quaternions // NOTE: This function is a bad approximation of Slerp() // when the angle between the *this and b is large. @@ -1500,7 +1519,7 @@ public: Quat Slerp(const Quat& b, T s) const { Vector3<T> delta = (b * this->Inverted()).ToRotationVector(); - return FromRotationVector(delta * s) * *this; + return (FromRotationVector(delta * s) * *this).Normalized(); // normalize so errors don't accumulate } // Spherical linear interpolation: much faster for small rotations, accurate for large rotations. See FastTo/FromRotationVector diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h index b1ec3cc0..cf7aab62 100644 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h +++ b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h @@ -493,7 +493,7 @@ typedef enum ovrStatusBits_ /// Specifies the description of a single sensor. /// -/// \see ovrGetTrackerDesc +/// \see ovr_GetTrackerDesc /// typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTrackerDesc_ { @@ -665,6 +665,18 @@ typedef enum ovrTextureFormat_ OVR_FORMAT_D32_FLOAT, OVR_FORMAT_D32_FLOAT_S8X24_UINT, + // Added in 1.5 compressed formats can be used for static layers + OVR_FORMAT_BC1_UNORM, + OVR_FORMAT_BC1_UNORM_SRGB, + OVR_FORMAT_BC2_UNORM, + OVR_FORMAT_BC2_UNORM_SRGB, + OVR_FORMAT_BC3_UNORM, + OVR_FORMAT_BC3_UNORM_SRGB, + OVR_FORMAT_BC6H_UF16, + OVR_FORMAT_BC6H_SF16, + OVR_FORMAT_BC7_UNORM, + OVR_FORMAT_BC7_UNORM_SRGB, + OVR_FORMAT_ENUMSIZE = 0x7fffffff ///< \internal Force type int32_t. } ovrTextureFormat; @@ -779,18 +791,20 @@ typedef enum ovrTouch_ ovrTouch_A = ovrButton_A, ovrTouch_B = ovrButton_B, ovrTouch_RThumb = ovrButton_RThumb, + ovrTouch_RThumbRest = 0x00000008, ovrTouch_RIndexTrigger = 0x00000010, // Bit mask of all the button touches on the right controller - ovrTouch_RButtonMask = ovrTouch_A | ovrTouch_B | ovrTouch_RThumb | ovrTouch_RIndexTrigger, + ovrTouch_RButtonMask = ovrTouch_A | ovrTouch_B | ovrTouch_RThumb | ovrTouch_RThumbRest | ovrTouch_RIndexTrigger, ovrTouch_X = ovrButton_X, ovrTouch_Y = ovrButton_Y, ovrTouch_LThumb = ovrButton_LThumb, + ovrTouch_LThumbRest = 0x00000800, ovrTouch_LIndexTrigger = 0x00001000, // Bit mask of all the button touches on the left controller - ovrTouch_LButtonMask = ovrTouch_X | ovrTouch_Y | ovrTouch_LThumb | ovrTouch_LIndexTrigger, + ovrTouch_LButtonMask = ovrTouch_X | ovrTouch_Y | ovrTouch_LThumb | ovrTouch_LThumbRest | ovrTouch_LIndexTrigger, // Finger pose state // Derived internally based on distance, proximity to sensors and filtering. @@ -959,36 +973,6 @@ extern "C" { // ----------------------------------------------------------------------------------- // ***** API Interfaces -// Overview of the API -// -// Setup: -// - ovr_Initialize(). -// - ovr_Create(&hmd, &graphicsId). -// - Use hmd members and ovr_GetFovTextureSize() to determine graphics configuration -// and ovr_GetRenderDesc() to get per-eye rendering parameters. -// - Allocate texture swap chains with ovr_CreateTextureSwapChainDX() or -// ovr_CreateTextureSwapChainGL(). Create any associated render target views or -// frame buffer objects. -// -// Application Loop: -// - Call ovr_GetPredictedDisplayTime() to get the current frame timing information. -// - Call ovr_GetTrackingState() and ovr_CalcEyePoses() to obtain the predicted -// rendering pose for each eye based on timing. -// - Render the scene content into the current buffer of the texture swapchains -// for each eye and layer you plan to update this frame. If you render into a -// texture swap chain, you must call ovr_CommitTextureSwapChain() on it to commit -// the changes before you reference the chain this frame (otherwise, your latest -// changes won't be picked up). -// - Call ovr_SubmitFrame() to render the distorted layers to and present them on the HMD. -// If ovr_SubmitFrame returns ovrSuccess_NotVisible, there is no need to render the scene -// for the next loop iteration. Instead, just call ovr_SubmitFrame again until it returns -// ovrSuccess. -// -// Shutdown: -// - ovr_Destroy(). -// - ovr_Shutdown(). - - /// Initializes LibOVR /// /// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT @@ -1097,6 +1081,35 @@ OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString(); OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message); +/// Identify client application info. +/// +/// The string is one or more newline-delimited lines of optional info +/// indicating engine name, engine version, engine plugin name, engine plugin +/// version, engine editor. The order of the lines is not relevant. Individual +/// lines are optional. A newline is not necessary at the end of the last line. +/// Call after ovr_Initialize and before the first call to ovr_Create. +/// Each value is limited to 20 characters. Key names such as 'EngineName:' +/// 'EngineVersion:' do not count towards this limit. +/// +/// \param[in] identity Specifies one or more newline-delimited lines of optional info: +/// EngineName: %s\n +/// EngineVersion: %s\n +/// EnginePluginName: %s\n +/// EnginePluginVersion: %s\n +/// EngineEditor: <boolean> ('true' or 'false')\n +/// +/// <b>Example code</b> +/// \code{.cpp} +/// ovr_IdentifyClient("EngineName: Unity\n" +/// "EngineVersion: 5.3.3\n" +/// "EnginePluginName: OVRPlugin\n" +/// "EnginePluginVersion: 1.2.0\n" +/// "EngineEditor: true"); +/// \endcode +/// +OVR_PUBLIC_FUNCTION(ovrResult) ovr_IdentifyClient(const char* identity); + + //------------------------------------------------------------------------------------- /// @name HMD Management /// @@ -1153,7 +1166,7 @@ OVR_PUBLIC_FUNCTION(ovrTrackerDesc) ovr_GetTrackerDesc(ovrSession session, unsig /// Creates a handle to a VR session. /// /// Upon success the returned ovrSession must be eventually freed with ovr_Destroy when it is no longer needed. -/// A second call to ovr_Create will result in an error return value if the previous Hmd has not been destroyed. +/// A second call to ovr_Create will result in an error return value if the previous session has not been destroyed. /// /// \param[out] pSession Provides a pointer to an ovrSession which will be written to upon success. /// \param[out] luid Provides a system specific graphics adapter identifier that locates which @@ -1161,7 +1174,7 @@ OVR_PUBLIC_FUNCTION(ovrTrackerDesc) ovr_GetTrackerDesc(ovrSession session, unsig /// or no rendering output will be possible. This is important for stability on multi-adapter systems. An /// application that simply chooses the default adapter will not run reliably on multi-adapter systems. /// \return Returns an ovrResult indicating success or failure. Upon failure -/// the returned pHmd will be NULL. +/// the returned ovrSession will be NULL. /// /// <b>Example code</b> /// \code{.cpp} @@ -1177,7 +1190,7 @@ OVR_PUBLIC_FUNCTION(ovrTrackerDesc) ovr_GetTrackerDesc(ovrSession session, unsig OVR_PUBLIC_FUNCTION(ovrResult) ovr_Create(ovrSession* pSession, ovrGraphicsLuid* pLuid); -/// Destroys the HMD. +/// Destroys the session. /// /// \param[in] session Specifies an ovrSession previously returned by ovr_Create. /// \see ovr_Create @@ -1304,7 +1317,7 @@ OVR_PUBLIC_FUNCTION(void) ovr_ClearShouldRecenterFlag(ovrSession session); /// ovrTrackingState value. Use 0 to request the most recent tracking state. /// \param[in] latencyMarker Specifies that this call is the point in time where /// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer -/// provides "SensorSampleTimestamp", that will override the value stored here. +/// provides "SensorSampleTime", that will override the value stored here. /// \return Returns the ovrTrackingState that is predicted for the given absTime. /// /// \see ovrTrackingState, ovr_GetEyePoses, ovr_GetTimeInSeconds @@ -1363,11 +1376,10 @@ OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetConnectedControllerTypes(ovrSession ses /// /// \see ovrControllerType /// -OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetControllerVibration(ovrSession session, ovrControllerType controllerType, - float frequency, float amplitude); +OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetControllerVibration(ovrSession session, ovrControllerType controllerType, float frequency, float amplitude); -///@} +///@} //------------------------------------------------------------------------------------- // @name Layers @@ -1768,7 +1780,7 @@ OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovr_GetRenderDesc(ovrSession session, /// ovrLayerQuad layer1; /// ... /// ovrLayerHeader* layers[2] = { &layer0.Header, &layer1.Header }; -/// ovrResult result = ovr_SubmitFrame(hmd, frameIndex, nullptr, layers, 2); +/// ovrResult result = ovr_SubmitFrame(session, frameIndex, nullptr, layers, 2); /// \endcode /// /// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true @@ -1844,7 +1856,7 @@ OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds(); /// App can toggle performance HUD modes as such: /// \code{.cpp} /// ovrPerfHudMode PerfHudMode = ovrPerfHud_LatencyTiming; -/// ovr_SetInt(Hmd, OVR_PERF_HUD_MODE, (int)PerfHudMode); +/// ovr_SetInt(session, OVR_PERF_HUD_MODE, (int)PerfHudMode); /// \endcode /// typedef enum ovrPerfHudMode_ @@ -1864,7 +1876,7 @@ typedef enum ovrPerfHudMode_ /// App can toggle layer HUD modes as such: /// \code{.cpp} /// ovrLayerHudMode LayerHudMode = ovrLayerHud_Info; -/// ovr_SetInt(Hmd, OVR_LAYER_HUD_MODE, (int)LayerHudMode); +/// ovr_SetInt(session, OVR_LAYER_HUD_MODE, (int)LayerHudMode); /// \endcode /// typedef enum ovrLayerHudMode_ @@ -1885,7 +1897,7 @@ typedef enum ovrLayerHudMode_ /// App can toggle the debug HUD modes as such: /// \code{.cpp} /// ovrDebugHudStereoMode DebugHudMode = ovrDebugHudStereo_QuadWithCrosshair; -/// ovr_SetInt(Hmd, OVR_DEBUG_HUD_STEREO_MODE, (int)DebugHudMode); +/// ovr_SetInt(session, OVR_DEBUG_HUD_STEREO_MODE, (int)DebugHudMode); /// \endcode /// /// The app can modify the visual properties of the stereo guide (i.e. quad, crosshair) @@ -2004,7 +2016,7 @@ OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetFloatArray(ovrSession session, const char* p /// \param[in] defaultVal Specifes the value to return if the property couldn't be read. /// \return Returns the string property if it exists. Otherwise returns defaultVal, which can be specified as NULL. /// The return memory is guaranteed to be valid until next call to ovr_GetString or -/// until the HMD is destroyed, whichever occurs first. +/// until the session is destroyed, whichever occurs first. OVR_PUBLIC_FUNCTION(const char*) ovr_GetString(ovrSession session, const char* propertyName, const char* defaultVal); diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h index c5344813..930dfcbe 100644 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h +++ b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h @@ -9,6 +9,10 @@ #define OVR_CAPI_Audio_h #ifdef _WIN32 +// Prevents <Windows.h> from defining min() and max() macro symbols. +#ifndef NOMINMAX +#define NOMINMAX +#endif #include <windows.h> #include "OVR_CAPI.h" #define OVR_AUDIO_MAX_DEVICE_STR_SIZE 128 diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h index 50806bca..982af8f0 100644 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h +++ b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h @@ -25,7 +25,7 @@ /// \param[in] desc Specifies requested texture properties. See notes for more info about texture format. /// \param[in] bindFlags Specifies what ovrTextureBindFlags the application requires for this texture chain. /// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid upon a successful return value, else it will be NULL. -/// This texture chain must be eventually destroyed via ovr_DestroyTextureSwapChain before destroying the HMD with ovr_Destroy. +/// This texture chain must be eventually destroyed via ovr_DestroyTextureSwapChain before destroying the session with ovr_Destroy. /// /// \return Returns an ovrResult indicating success or failure. In the case of failure, use /// ovr_GetLastErrorInfo to get more information. @@ -88,7 +88,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession sessio /// which must be the same one the application renders to the textures with. /// \param[in] desc Specifies requested texture properties. See notes for more info about texture format. /// \param[out] out_MirrorTexture Returns the created ovrMirrorTexture, which will be valid upon a successful return value, else it will be NULL. -/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the HMD with ovr_Destroy. +/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the session with ovr_Destroy. /// /// \return Returns an ovrResult indicating success or failure. In the case of failure, use /// ovr_GetLastErrorInfo to get more information. diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h index 1658ca57..81487947 100644 --- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h +++ b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h @@ -15,7 +15,7 @@ /// \param[in] desc Specifies the requested texture properties. See notes for more info about texture format. /// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid upon /// a successful return value, else it will be NULL. This texture swap chain must be eventually -/// destroyed via ovr_DestroyTextureSwapChain before destroying the HMD with ovr_Destroy. +/// destroyed via ovr_DestroyTextureSwapChain before destroying the session with ovr_Destroy. /// /// \return Returns an ovrResult indicating success or failure. In the case of failure, use /// ovr_GetLastErrorInfo to get more information. @@ -64,7 +64,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferGL(ovrSession sessio /// \param[in] session Specifies an ovrSession previously returned by ovr_Create. /// \param[in] desc Specifies the requested mirror texture description. /// \param[out] out_MirrorTexture Specifies the created ovrMirrorTexture, which will be valid upon a successful return value, else it will be NULL. -/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the HMD with ovr_Destroy. +/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the session with ovr_Destroy. /// /// \return Returns an ovrResult indicating success or failure. In the case of failure, use /// ovr_GetLastErrorInfo to get more information. diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h b/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h index ed0be0e7..9fc527c7 100644 --- a/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h +++ b/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h @@ -14,9 +14,6 @@ - - - #ifndef OVR_RESULT_DEFINED #define OVR_RESULT_DEFINED ///< Allows ovrResult to be independently defined. /// API call results are represented at the highest level by a single ovrResult. @@ -59,27 +56,26 @@ typedef enum ovrSuccessType_ { /// This is a general success result. Use OVR_SUCCESS to test for success. ovrSuccess = 0, +} ovrSuccessType; +#endif +// Public success types +// Success is a value greater or equal to 0, while all error types are negative values. +typedef enum ovrSuccessTypes_ +{ /// Returned from a call to SubmitFrame. The call succeeded, but what the app /// rendered will not be visible on the HMD. Ideally the app should continue /// calling SubmitFrame, but not do any rendering. When the result becomes /// ovrSuccess, rendering should continue as usual. ovrSuccess_NotVisible = 1000, - ovrSuccess_HMDFirmwareMismatch = 4100, ///< The HMD Firmware is out of date but is acceptable. - ovrSuccess_TrackerFirmwareMismatch = 4101, ///< The Tracker Firmware is out of date but is acceptable. - ovrSuccess_ControllerFirmwareMismatch = 4104, ///< The controller firmware is out of date but is acceptable. - ovrSuccess_TrackerDriverNotFound = 4105, ///< The tracker driver interface was not found. Can be a temporary error - -} ovrSuccessType; -#endif - +} ovrSuccessTypes; +// Public error types typedef enum ovrErrorType_ { /* General errors */ ovrError_MemoryAllocationFailure = -1000, ///< Failure to allocate memory. - ovrError_SocketCreationFailure = -1001, ///< Failure to create a socket. ovrError_InvalidSession = -1002, ///< Invalid ovrSession parameter provided. ovrError_Timeout = -1003, ///< The operation timed out. ovrError_NotInitialized = -1004, ///< The system or component has not been initialized. @@ -94,10 +90,8 @@ typedef enum ovrErrorType_ ovrError_ServiceDeadlockDetected = -1014, ///< The service watchdog discovered a deadlock. /* Audio error range, reserved for Audio errors. */ - ovrError_AudioReservedBegin = -2000, ///< First Audio error. ovrError_AudioDeviceNotFound = -2001, ///< Failure to find the specified audio device. ovrError_AudioComError = -2002, ///< Generic COM error. - ovrError_AudioReservedEnd = -2999, ///< Last Audio error. /* Initialization errors. */ ovrError_Initialize = -3000, ///< Generic initialization error. @@ -122,51 +116,6 @@ typedef enum ovrErrorType_ ovrError_DisplayManagerInit = -3019, ///< Initialization of the DisplayManager failed. ovrError_TrackerDriverInit = -3020, ///< Failed to get the interface for an attached tracker - /* Hardware errors */ - ovrError_InvalidBundleAdjustment = -4000, ///< Headset has no bundle adjustment data. - ovrError_USBBandwidth = -4001, ///< The USB hub cannot handle the camera frame bandwidth. - ovrError_USBEnumeratedSpeed = -4002, ///< The USB camera is not enumerating at the correct device speed. - ovrError_ImageSensorCommError = -4003, ///< Unable to communicate with the image sensor. - ovrError_GeneralTrackerFailure = -4004, ///< We use this to report various sensor issues that don't fit in an easily classifiable bucket. - ovrError_ExcessiveFrameTruncation = -4005, ///< A more than acceptable number of frames are coming back truncated. - ovrError_ExcessiveFrameSkipping = -4006, ///< A more than acceptable number of frames have been skipped. - ovrError_SyncDisconnected = -4007, ///< The sensor is not receiving the sync signal (cable disconnected?). - ovrError_TrackerMemoryReadFailure = -4008, ///< Failed to read memory from the sensor. - ovrError_TrackerMemoryWriteFailure = -4009, ///< Failed to write memory from the sensor. - ovrError_TrackerFrameTimeout = -4010, ///< Timed out waiting for a camera frame. - ovrError_TrackerTruncatedFrame = -4011, ///< Truncated frame returned from sensor. - ovrError_TrackerDriverFailure = -4012, ///< The sensor driver has encountered a problem. - ovrError_TrackerNRFFailure = -4013, ///< The sensor wireless subsystem has encountered a problem. - ovrError_HardwareGone = -4014, ///< The hardware has been unplugged - ovrError_NordicEnabledNoSync = -4015, ///< The nordic indicates that sync is enabled but it is not sending sync pulses - ovrError_NordicSyncNoFrames = -4016, ///< It looks like we're getting a sync signal, but no camera frames have been received - ovrError_CatastrophicFailure = -4017, ///< A catastrophic failure has occurred. We will attempt to recover by resetting the device - ovrError_CatastrophicTimeout = -4018, ///< The catastrophic recovery has timed out. - ovrError_RepeatCatastrophicFail = -4019, ///< Catastrophic failure has repeated too many times. - ovrError_USBOpenDeviceFailure = -4020, ///< Could not open handle for Rift device (likely already in use by another process). - ovrError_HMDGeneralFailure = -4021, ///< Unexpected HMD issues that don't fit a specific bucket. - - ovrError_HMDFirmwareMismatch = -4100, ///< The HMD Firmware is out of date and is unacceptable. - ovrError_TrackerFirmwareMismatch = -4101, ///< The sensor Firmware is out of date and is unacceptable. - ovrError_BootloaderDeviceDetected = -4102, ///< A bootloader HMD is detected by the service. - ovrError_TrackerCalibrationError = -4103, ///< The sensor calibration is missing or incorrect. - ovrError_ControllerFirmwareMismatch = -4104, ///< The controller firmware is out of date and is unacceptable. - ovrError_DevManDeviceDetected = -4105, ///< A DeviceManagement mode HMD is detected by the service. - ovrError_RebootedBootloaderDevice = -4106, ///< Had to reboot bootloader device, which succeeded. - ovrError_FailedRebootBootloaderDev = -4107, ///< Had to reboot bootloader device, which failed. Device is stuck in bootloader mode. - - ovrError_IMUTooManyLostSamples = -4200, ///< Too many lost IMU samples. - ovrError_IMURateError = -4201, ///< IMU rate is outside of the expected range. - ovrError_FeatureReportFailure = -4202, ///< A feature report has failed. - ovrError_HMDWirelessTimeout = -4203, ///< HMD wireless interface never returned from busy state. - - ovrError_BootloaderAssertLog = -4300, ///< HMD Bootloader Assert Log was not empty. - ovrError_AppAssertLog = -4301, ///< HMD App Assert Log was not empty. - - /* Synchronization errors */ - ovrError_Incomplete = -5000, ///< Requested async work not yet complete. - ovrError_Abandoned = -5001, ///< Requested async work was abandoned and result is incomplete. - /* Rendering errors */ ovrError_DisplayLost = -6000, ///< In the event of a system-wide graphics reset or cable unplug this is returned to the app. ovrError_TextureSwapChainFull = -6001, ///< ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain. @@ -182,18 +131,6 @@ typedef enum ovrErrorType_ ovrError_RuntimeException = -7000, ///< A runtime exception occurred. The application is required to shutdown LibOVR and re-initialize it before this error state will be cleared. - ovrError_MetricsUnknownApp = -90000, - ovrError_MetricsDuplicateApp = -90001, - ovrError_MetricsNoEvents = -90002, - ovrError_MetricsRuntime = -90003, - ovrError_MetricsFile = -90004, - ovrError_MetricsNoClientInfo = -90005, - ovrError_MetricsNoAppMetaData = -90006, - ovrError_MetricsNoApp = -90007, - ovrError_MetricsOafFailure = -90008, - ovrError_MetricsSessionAlreadyActive = -90009, - ovrError_MetricsSessionNotActive = -90010, - } ovrErrorType; @@ -206,4 +143,5 @@ typedef struct ovrErrorInfo_ char ErrorString[512]; ///< A UTF8-encoded null-terminated English string describing the problem. The format of this string is subject to change in future versions. } ovrErrorInfo; + #endif /* OVR_ErrorCode_h */ diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_Version.h b/src/external/OculusSDK/LibOVR/Include/OVR_Version.h index dbfe4deb..376fa7d5 100644 --- a/src/external/OculusSDK/LibOVR/Include/OVR_Version.h +++ b/src/external/OculusSDK/LibOVR/Include/OVR_Version.h @@ -19,7 +19,7 @@ // Master version numbers #define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning. #define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change LibOVR/Projects/Windows/LibOVR.props in parallel. -#define OVR_MINOR_VERSION 4 // +#define OVR_MINOR_VERSION 5 // #define OVR_PATCH_VERSION 0 #define OVR_BUILD_NUMBER 0 diff --git a/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll b/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll Binary files differindex 70f63f70..8553ce11 100644 --- a/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll +++ b/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll diff --git a/src/models.c b/src/models.c index 8deabcb0..b194a0db 100644 --- a/src/models.c +++ b/src/models.c @@ -40,7 +40,7 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define CUBIC_MAP_HALF_BLOCK_SIZE 0.5 +// ... //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -808,13 +808,6 @@ void UnloadMaterial(Material material) rlDeleteTextures(material.texSpecular.id); } -// Link a texture to a model -void SetModelTexture(Model *model, Texture2D texture) -{ - if (texture.id <= 0) model->material.texDiffuse = GetDefaultTexture(); // Use default white texture - else model->material.texDiffuse = texture; -} - // Generate a mesh from heightmap static Mesh GenMeshHeightmap(Image heightmap, Vector3 size) { @@ -1549,8 +1542,11 @@ BoundingBox CalculateBoundingBox(Mesh mesh) // Detect and resolve cubicmap collisions // NOTE: player position (or camera) is modified inside this function +// TODO: This functions needs to be completely reviewed! Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius) { + #define CUBIC_MAP_HALF_BLOCK_SIZE 0.5 + Color *cubicmapPixels = GetImageData(cubicmap); // Detect the cell where the player is located @@ -1562,15 +1558,15 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p locationCellX = floor(playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE); locationCellY = floor(playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE); - if (locationCellX >= 0 && locationCellY >= 0 && locationCellX < cubicmap.width && locationCellY < cubicmap.height) + if ((locationCellX >= 0) && (locationCellY >= 0) && (locationCellX < cubicmap.width) && (locationCellY < cubicmap.height)) { // Multiple Axis -------------------------------------------------------------------------------------------- // Axis x-, y- - if (locationCellX > 0 && locationCellY > 0) + if ((locationCellX > 0) && (locationCellY > 0)) { - if ((cubicmapPixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0) && - (cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0)) + if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0) && + (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0)) { if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)) @@ -1583,10 +1579,10 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p } // Axis x-, y+ - if (locationCellX > 0 && locationCellY < cubicmap.height - 1) + if ((locationCellX > 0) && (locationCellY < cubicmap.height - 1)) { - if ((cubicmapPixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0) && - (cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0)) + if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0) && + (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0)) { if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)) @@ -1599,10 +1595,10 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p } // Axis x+, y- - if (locationCellX < cubicmap.width - 1 && locationCellY > 0) + if ((locationCellX < cubicmap.width - 1) && (locationCellY > 0)) { - if ((cubicmapPixels[locationCellY * cubicmap.width + (locationCellX + 1)].r != 0) && - (cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0)) + if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) && + (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0)) { if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)) @@ -1615,10 +1611,10 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p } // Axis x+, y+ - if (locationCellX < cubicmap.width - 1 && locationCellY < cubicmap.height - 1) + if ((locationCellX < cubicmap.width - 1) && (locationCellY < cubicmap.height - 1)) { - if ((cubicmapPixels[locationCellY * cubicmap.width + (locationCellX + 1)].r != 0) && - (cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0)) + if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) && + (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0)) { if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)) @@ -1635,7 +1631,7 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p // Axis x- if (locationCellX > 0) { - if (cubicmapPixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0) + if (cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0) { if ((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) { @@ -1647,7 +1643,7 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p // Axis x+ if (locationCellX < cubicmap.width - 1) { - if (cubicmapPixels[locationCellY * cubicmap.width + (locationCellX + 1)].r != 0) + if (cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) { if ((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) { @@ -1659,7 +1655,7 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p // Axis y- if (locationCellY > 0) { - if (cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0) + if (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0) { if ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius) { @@ -1671,7 +1667,7 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p // Axis y+ if (locationCellY < cubicmap.height - 1) { - if (cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0) + if (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0) { if ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius) { @@ -1684,11 +1680,11 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p // Diagonals ------------------------------------------------------------------------------------------------------- // Axis x-, y- - if (locationCellX > 0 && locationCellY > 0) + if ((locationCellX > 0) && (locationCellY > 0)) { - if ((cubicmapPixels[locationCellY * cubicmap.width + (locationCellX - 1)].r == 0) && - (cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r == 0) && - (cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX - 1)].r != 0)) + if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r == 0) && + (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r == 0) && + (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX - 1)].r != 0)) { if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)) @@ -1707,11 +1703,11 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p } // Axis x-, y+ - if (locationCellX > 0 && locationCellY < cubicmap.height - 1) + if ((locationCellX > 0) && (locationCellY < cubicmap.height - 1)) { - if ((cubicmapPixels[locationCellY * cubicmap.width + (locationCellX - 1)].r == 0) && - (cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r == 0) && - (cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX - 1)].r != 0)) + if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r == 0) && + (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r == 0) && + (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX - 1)].r != 0)) { if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)) @@ -1730,11 +1726,11 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p } // Axis x+, y- - if (locationCellX < cubicmap.width - 1 && locationCellY > 0) + if ((locationCellX < cubicmap.width - 1) && (locationCellY > 0)) { - if ((cubicmapPixels[locationCellY * cubicmap.width + (locationCellX + 1)].r == 0) && - (cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r == 0) && - (cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX + 1)].r != 0)) + if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r == 0) && + (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r == 0) && + (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX + 1)].r != 0)) { if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)) @@ -1753,11 +1749,11 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p } // Axis x+, y+ - if (locationCellX < cubicmap.width - 1 && locationCellY < cubicmap.height - 1) + if ((locationCellX < cubicmap.width - 1) && (locationCellY < cubicmap.height - 1)) { - if ((cubicmapPixels[locationCellY * cubicmap.width + (locationCellX + 1)].r == 0) && - (cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r == 0) && - (cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX + 1)].r != 0)) + if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r == 0) && + (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r == 0) && + (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX + 1)].r != 0)) { if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)) diff --git a/src/raylib.h b/src/raylib.h index 0c9f0280..89fc457f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -794,7 +794,6 @@ Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d mod Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) void UnloadModel(Model model); // Unload 3d model from memory -void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model Material LoadMaterial(const char *fileName); // Load material data (from file) Material LoadDefaultMaterial(void); // Load default material (uses default models shader) @@ -853,9 +852,10 @@ 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 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) //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) @@ -31,6 +31,7 @@ #include <stdio.h> // Required for: fopen(), fclose(), fread()... [Used only on ReadTextFile()] #include <stdlib.h> // Required for: malloc(), free(), rand() #include <string.h> // Required for: strcmp(), strlen(), strtok() +#include <math.h> // Required for: atan() #ifndef RLGL_STANDALONE #include "raymath.h" // Required for Vector3 and Matrix functions @@ -44,6 +45,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/gl3.h> // OpenGL 3 library for OSX @@ -68,10 +73,11 @@ #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #endif -#if !defined(GRAPHICS_API_OPENGL_11) +#if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_STANDARD_SHADER) #include "standard_shader.h" // Standard shader to embed #endif +//#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code #if defined(RLGL_OCULUS_SUPPORT) #include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL #endif @@ -130,6 +136,12 @@ #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #endif +#if defined(GRAPHICS_API_OPENGL_ES2) + #define glClearDepth glClearDepthf + #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER + #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER +#endif + // Default vertex attribute names on shader to set location points #define DEFAULT_ATTRIB_POSITION_NAME "vertexPosition" // shader-location = 0 #define DEFAULT_ATTRIB_TEXCOORD_NAME "vertexTexCoord" // shader-location = 1 @@ -235,7 +247,7 @@ static bool useTempBuffer = false; static Shader defaultShader; static Shader standardShader; // Lazy initialization when GetStandardShader() static Shader currentShader; // By default, defaultShader -static bool standardShaderLoaded = false; +static bool standardShaderLoaded = false; // Flag to track if standard shader has been loaded // Flags for supported extensions static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension) @@ -262,6 +274,14 @@ 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 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 distortionShader; + // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support static bool npotSupported = false; // NPOT textures full support @@ -274,11 +294,15 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays; //static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted #endif -static int blendMode = 0; +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 (required by Oculus device) +static int screenWidth; // Default framebuffer width +static int screenHeight; // Default framebuffer height + //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- @@ -294,15 +318,18 @@ 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 +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); #endif -#if defined(RLGL_OCULUS_SUPPORT) // Oculus Rift functions +#if defined(RLGL_OCULUS_SUPPORT) static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers @@ -465,7 +492,8 @@ 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); @@ -857,6 +885,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 } @@ -916,6 +946,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) @@ -927,8 +959,8 @@ int rlGetVersion(void) // Module Functions Definition - rlgl Functions //---------------------------------------------------------------------------------- -// Init OpenGL 3.3+ required data -void rlglInit(void) +// Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states +void rlglInit(int width, int height) { // Check OpenGL information and capabilities //------------------------------------------------------------------------------ @@ -1074,18 +1106,7 @@ void rlglInit(void) // Initialize buffers, default shaders and default textures //---------------------------------------------------------- - // Set default draw mode - currentDrawMode = RL_TRIANGLES; - - // Reset projection and modelview matrices - projection = MatrixIdentity(); - modelview = MatrixIdentity(); - currentMatrix = &modelview; - - // Initialize matrix stack - for (int i = 0; i < MATRIX_STACK_SIZE; i++) stack[i] = MatrixIdentity(); - - // Create default white texture for plain colors (required by shader) + // Init default white texture unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) whiteTexture = rlglLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1); @@ -1097,7 +1118,8 @@ void rlglInit(void) defaultShader = LoadDefaultShader(); currentShader = defaultShader; - LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads) + // Init default vertex arrays buffers (lines, triangles, quads) + LoadDefaultBuffers(); // Init temp vertex buffer, used when transformation required (translate, rotate, scale) tempBuffer = (Vector3 *)malloc(sizeof(Vector3)*TEMP_VERTEX_BUFFER_SIZE); @@ -1115,7 +1137,50 @@ void rlglInit(void) drawsCounter = 1; draws[drawsCounter - 1].textureId = whiteTexture; + currentDrawMode = RL_TRIANGLES; // Set default draw mode + + // Init internal matrix stack (emulating OpenGL 1.1) + for (int i = 0; i < MATRIX_STACK_SIZE; i++) stack[i] = MatrixIdentity(); + + // Init internal projection and modelview matrices + 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) + + // Store screen size into global variables + screenWidth = width; + screenHeight = height; + + TraceLog(INFO, "OpenGL default states initialized successfully"); } // Vertex Buffer Object deinitialization (memory free) @@ -1145,76 +1210,32 @@ 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 - UpdateDefaultBuffers(); - DrawDefaultBuffers(); -#endif -} - -// Initialize Graphics Device (OpenGL stuff) -// NOTE: Stores global variables screenWidth and screenHeight -void rlglInitGraphics(int offsetX, int offsetY, int width, int height) -{ - // NOTE: Required! viewport must be recalculated if screen resized! - glViewport(offsetX/2, offsetY/2, width - offsetX, height - offsetY); // Set viewport width and height - - // NOTE: Don't confuse glViewport with the transformation matrix - // NOTE: glViewport just defines the area of the context that you will actually draw to. - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) - //glClearDepth(1.0f); // Clear depth buffer (default) - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D - - glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D) - glDepthFunc(GL_LEQUAL); // Type of depth testing to apply - - glEnable(GL_BLEND); // Enable color blending (required to work with transparencies) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed) - -#if defined(GRAPHICS_API_OPENGL_11) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation (Deprecated in OGL 3.0) - // Other options: GL_FASTEST, GL_DONT_CARE (default) -#endif - - rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix - rlLoadIdentity(); // Reset current matrix (PROJECTION) - - rlOrtho(0, width - offsetX, height - offsetY, 0, 0.0f, 1.0f); // Config orthographic mode: top-left corner --> (0,0) - - rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix - rlLoadIdentity(); // Reset current matrix (MODELVIEW) - - // NOTE: All shapes/models triangles are drawn CCW - - glEnable(GL_CULL_FACE); // Enable backface culling (Disabled by default) - //glCullFace(GL_BACK); // Cull the Back face (default) - //glFrontFace(GL_CCW); // Front face are defined counter clockwise (default) + // 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); -#if defined(GRAPHICS_API_OPENGL_11) - glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) (Deprecated on OpenGL 3.3+) - // Possible options: GL_SMOOTH (Color interpolation) or GL_FLAT (no interpolation) + // NOTE: Default buffers upload and draw + UpdateDefaultBuffers(); + + if (vrEnabled && vrControl) DrawDefaultBuffers(2); + else DrawDefaultBuffers(1); #endif - - 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 defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33) + // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions) 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 defined(GRAPHICS_API_OPENGL_21) + if (GLAD_GL_VERSION_2_1) TraceLog(INFO, "OpenGL 2.1 profile supported"); +#elif defined(GRAPHICS_API_OPENGL_33) + if(GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported"); +#endif // 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 @@ -1628,8 +1649,8 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) int drawHint = GL_STATIC_DRAW; if (dynamic) drawHint = GL_DYNAMIC_DRAW; - GLuint vaoId = 0; // Vertex Array Objects (VAO) - GLuint vboId[7]; // Vertex Buffer Objects (VBOs) + GLuint vaoId = 0; // Vertex Array Objects (VAO) + GLuint vboId[7] = { 0 }; // Vertex Buffer Objects (VBOs) if (vaoSupported) { @@ -1725,7 +1746,6 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*mesh->triangleCount*3, mesh->indices, GL_STATIC_DRAW); } - mesh->vboId[0] = vboId[0]; // Vertex position VBO mesh->vboId[1] = vboId[1]; // Texcoords VBO mesh->vboId[2] = vboId[2]; // Normals VBO @@ -1848,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) @@ -1895,12 +1912,12 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // Upload to shader glossiness glUniform1f(glGetUniformLocation(material.shader.id, "glossiness"), material.glossiness); } - + // Set shader textures (diffuse, normal, specular) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id); glUniform1i(material.shader.mapTexture0Loc, 0); // Diffuse texture fits in active texture unit 0 - + if ((material.texNormal.id != 0) && (material.shader.mapTexture1Loc != -1)) { // Upload to shader specular map flag @@ -1920,7 +1937,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) glBindTexture(GL_TEXTURE_2D, material.texSpecular.id); glUniform1i(material.shader.mapTexture2Loc, 2); // Specular texture fits in active texture unit 2 } - + if (vaoSupported) { glBindVertexArray(mesh.vaoId); @@ -1945,12 +1962,22 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) glEnableVertexAttribArray(material.shader.normalLoc); } - // Bind mesh VBO data: vertex colors (shader-location = 3, if available) , tangents, texcoords2 (if available) + // Bind mesh VBO data: vertex colors (shader-location = 3, if available) if (material.shader.colorLoc != -1) { - glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]); - glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(material.shader.colorLoc); + if (mesh.vboId[3] != 0) + { + glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]); + glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(material.shader.colorLoc); + } + else + { + // Set default value for unused attribute + // NOTE: Required when using default shader and no VAO support + glVertexAttrib4f(material.shader.colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); + glDisableVertexAttribArray(material.shader.colorLoc); + } } // Bind mesh VBO data: vertex tangents (shader-location = 4, if available) @@ -1972,9 +1999,21 @@ 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); + else modelview = 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) { @@ -1999,6 +2038,10 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) } glUseProgram(0); // Unbind shader program + + // Restore projection/modelview matrices + projection = matProjection; + modelview = matView; #endif } @@ -2293,7 +2336,7 @@ Shader GetDefaultShader(void) Shader GetStandardShader(void) { Shader shader = { 0 }; - + #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) if (standardShaderLoaded) shader = standardShader; else @@ -2314,7 +2357,7 @@ int GetShaderLocation(Shader shader, const char *uniformName) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) location = glGetUniformLocation(shader.id, uniformName); - if (location == -1) TraceLog(WARNING, "[SHDR ID %i] Shader location for %s could not be found", shader.id, uniformName); + if (location == -1) TraceLog(DEBUG, "[SHDR ID %i] Shader location for %s could not be found", shader.id, uniformName); #endif return location; } @@ -2461,131 +2504,348 @@ void DestroyLight(Light light) #endif } -#if defined(RLGL_OCULUS_SUPPORT) -// Init Oculus Rift device -// NOTE: Device initialization should be done before window creation? +// Init Oculus Rift device (or Oculus device simulator) void InitOculusDevice(void) { +#if defined(RLGL_OCULUS_SUPPORT) // Initialize Oculus device ovrResult result = ovr_Initialize(NULL); - if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device"); - - result = ovr_Create(&session, &luid); if (OVR_FAILURE(result)) { - TraceLog(WARNING, "OVR: Could not create Oculus session"); - ovr_Shutdown(); + TraceLog(WARNING, "OVR: Could not initialize Oculus device"); + oculusReady = false; } + else + { + result = ovr_Create(&session, &luid); + if (OVR_FAILURE(result)) + { + TraceLog(WARNING, "OVR: Could not create Oculus session"); + ovr_Shutdown(); + oculusReady = false; + } + else + { + hmdDesc = ovr_GetHmdDesc(session); + + TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); + TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); + TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); + TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); + //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); + TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); + + // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... + // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) + + // Initialize Oculus Buffers + layer = InitOculusLayer(session); + buffer = LoadOculusBuffer(session, layer.width, layer.height); + mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... + layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); + + // Recenter OVR tracking origin + ovr_RecenterTrackingOrigin(session); + + oculusReady = true; + vrEnabled = true; + } + } +#else + oculusReady = false; +#endif - hmdDesc = ovr_GetHmdDesc(session); - - TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); - TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); - TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); - TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); - //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); - TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); - - // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... - // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) - - // Initialize Oculus Buffers - layer = InitOculusLayer(session); - buffer = LoadOculusBuffer(session, layer.width, layer.height); - mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... - layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); - - // Recenter OVR tracking origin - ovr_RecenterTrackingOrigin(session); + if (!oculusReady) + { + TraceLog(WARNING, "VR: Initializing Oculus simulator"); + + // 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?) + distortionShader = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); + + oculusSimulator = true; + vrEnabled = true; + } } -// Close Oculus Rift device +// Close Oculus Rift device (or Oculus device simulator) void CloseOculusDevice(void) { - UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer - UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers +#if defined(RLGL_OCULUS_SUPPORT) + if (oculusReady) + { + 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 + } + else +#endif + { + // Unload stereo framebuffer and texture + rlDeleteRenderTextures(stereoFbo); + + // Unload oculus-distortion shader + UnloadShader(distortionShader); + } + + oculusReady = false; +} + +// Detect if oculus device is available +bool IsOculusReady(void) +{ + return (oculusReady || oculusSimulator) && vrEnabled; +} - ovr_Destroy(session); // Free Oculus session data - ovr_Shutdown(); // Close Oculus device connection +// Enable/Disable VR experience (Oculus device or simulator) +void ToggleVR(void) +{ + vrEnabled = !vrEnabled; } // Update Oculus Rift tracking (position and orientation) void UpdateOculusTracking(void) { - frameIndex++; +#if defined(RLGL_OCULUS_SUPPORT) + if (oculusReady) + { + 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]; + 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 + { + // TODO: Use alternative inputs (mouse, keyboard) to simulate tracking data (eyes position/orientation) + } } -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); +// Set internal projection and modelview matrix depending on eyes tracking data +static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) +{ + if (vrEnabled) + { + Matrix eyeProjection = matProjection; + Matrix eyeModelView = matModelView; + +#if defined(RLGL_OCULUS_SUPPORT) + if (oculusReady) + { + 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); + + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement + eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + + eyeProjection = layer.eyeProjections[eye]; + } + else +#endif + { + // Setup viewport and projection/modelview matrices using tracking data + rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); + + 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 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 = eyeProjectionShift/(float)HScreenSize; //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 }; + + // 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 == 0) + { + projectionOffset.x *= -1.0f; + viewOffset.x *= -1.0f; + } - 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); + // Adjust the view and projection matrixes + // View matrix is translated based on the eye offset + Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); - Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); - Matrix modelEyeView = MatrixMultiply(modelview, eyeView); // Using internal camera modelview matrix + Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z); + Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z); - SetMatrixModelview(modelEyeView); - SetMatrixProjection(layer.eyeProjections[eye]); + eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection + eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview + + MatrixTranspose(&eyeProjection); + } + + SetMatrixModelview(eyeModelView); // ERROR! We are modifying modelview for next eye!!! + SetMatrixProjection(eyeProjection); + } } +// Begin Oculus drawing configuration void BeginOculusDrawing(void) { - GLuint currentTexId; - int currentIndex; - - ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); - ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); +#if defined(RLGL_OCULUS_SUPPORT) + if (oculusReady) + { + 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 + { + // Setup framebuffer for stereo rendering + rlEnableRenderTexture(stereoFbo.id); + } - //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); + //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) 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); +#if defined(RLGL_OCULUS_SUPPORT) + if (oculusReady) + { + // 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 + { + // Unbind current framebuffer + rlDisableRenderTexture(); + + rlClearScreenBuffers(); // Clear current framebuffer + + // 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 + currentShader = distortionShader; + + rlEnableTexture(stereoFbo.texture.id); + + rlPushMatrix(); + rlBegin(RL_QUADS); + rlColor4ub(255, 255, 255, 255); + rlNormal3f(0.0f, 0.0f, 1.0f); + + // Bottom-left corner for texture and quad + rlTexCoord2f(0.0f, 1.0f); + rlVertex2f(0.0f, 0.0f); + + // Bottom-right corner for texture and quad + rlTexCoord2f(0.0f, 0.0f); + rlVertex2f(0.0f, stereoFbo.texture.height); - // 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); + // 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(); + + UpdateDefaultBuffers(); + DrawDefaultBuffers(1); + + currentShader = defaultShader; + } + + rlDisableDepthTest(); + + vrControl = false; } -#endif //---------------------------------------------------------------------------------- // Module specific Functions Definition @@ -2746,55 +3006,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); @@ -2813,6 +3083,7 @@ static Shader LoadStandardShader(void) { Shader shader; +#if !defined(RLGL_NO_STANDARD_SHADER) // Load standard shader (embeded in standard_shader.h) shader.id = LoadShaderProgram(vStandardShaderStr, fStandardShaderStr); @@ -2828,6 +3099,10 @@ static Shader LoadStandardShader(void) TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded, using default shader", shader.id); shader = GetDefaultShader(); } +#else + shader = defaultShader; + TraceLog(WARNING, "[SHDR ID %i] Standard shader not available, using default shader", shader.id); +#endif return shader; } @@ -2878,12 +3153,13 @@ static void UnloadDefaultShader(void) static void UnloadStandardShader(void) { glUseProgram(0); - +#if !defined(RLGL_NO_STANDARD_SHADER) //glDetachShader(defaultShader, vertexShader); //glDetachShader(defaultShader, fragmentShader); //glDeleteShader(vertexShader); // Already deleted on shader compilation //glDeleteShader(fragmentShader); // Already deleted on shader compilation glDeleteProgram(standardShader.id); +#endif } @@ -3009,7 +3285,7 @@ static void LoadDefaultBuffers(void) glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers VAO initialized successfully (triangles)", triangles.vaoId); - else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers VBOs initialized successfully(triangles)", triangles.vboId[0], triangles.vboId[1]); + else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers VBOs initialized successfully (triangles)", triangles.vboId[0], triangles.vboId[1]); // Upload and link quads vertex buffers if (vaoSupported) @@ -3131,146 +3407,154 @@ static void UpdateDefaultBuffers(void) // Draw default internal buffers vertex data // NOTE: We draw in this order: lines, triangles, quads -static void DrawDefaultBuffers(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; @@ -3287,6 +3571,10 @@ static void DrawDefaultBuffers(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 @@ -3682,7 +3970,10 @@ static void BlitOculusMirror(ovrSession session, OculusMirror mirror) glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0); +#if defined(GRAPHICS_API_OPENGL_33) + // NOTE: glBlitFramebuffer() requires extension: GL_EXT_framebuffer_blit (not available in OpenGL ES 2.0) glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); +#endif glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); } @@ -48,25 +48,31 @@ // Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33 //#define GRAPHICS_API_OPENGL_11 // Only available on PLATFORM_DESKTOP -//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP or PLATFORM_OCULUS +//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP and RLGL_OCULUS_SUPPORT //#define GRAPHICS_API_OPENGL_ES2 // Only available on PLATFORM_ANDROID or PLATFORM_RPI or PLATFORM_WEB // Security check in case no GRAPHICS_API_OPENGL_* defined -#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 @@ -292,10 +298,9 @@ 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 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 @@ -347,14 +352,13 @@ 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 +bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready +void ToggleVR(void); // Enable/Disable VR experience (Oculus device or simulator) #ifdef __cplusplus } diff --git a/src/shapes.c b/src/shapes.c index 3ccfd660..2a4e19c2 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -135,7 +135,7 @@ void DrawCircleV(Vector2 center, float radius, Color color) } rlEnd(); } - else if ((rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) + else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) { rlEnableTexture(GetDefaultTexture().id); // Default white texture @@ -218,7 +218,7 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color) rlVertex2i(position.x + size.x, position.y); rlEnd(); } - else if ((rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) + else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) { rlEnableTexture(GetDefaultTexture().id); // Default white texture @@ -264,7 +264,7 @@ void DrawRectangleLines(int posX, int posY, int width, int height, Color color) rlVertex2i(posX + 1, posY + 1); rlEnd(); } - else if ((rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) + else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) { DrawRectangle(posX, posY, width, 1, color); DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color); diff --git a/src/standard_shader.h b/src/standard_shader.h index a4bc9694..e1668ae7 100644 --- a/src/standard_shader.h +++ b/src/standard_shader.h @@ -166,9 +166,9 @@ static const char fStandardShaderStr[] = " else if(lights[i].type == 2) lighting += CalcSpotLight(lights[i], n, v, spec);\n" " }\n" " }\n" -#if defined(GRAPHICS_API_OPENGL_33) -" finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n" -#elif defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) " gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n" +#elif defined(GRAPHICS_API_OPENGL_33) +" finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n" #endif "}\n"; diff --git a/src/textures.c b/src/textures.c index 518348f4..f5523a3e 100644 --- a/src/textures.c +++ b/src/textures.c @@ -422,12 +422,7 @@ void UnloadTexture(Texture2D texture) // Unload render texture from GPU memory void UnloadRenderTexture(RenderTexture2D target) { - if (target.id != 0) - { - rlDeleteRenderTextures(target); - - TraceLog(INFO, "[FBO ID %i] Unloaded render texture data from VRAM (GPU)", target.id); - } + if (target.id != 0) rlDeleteRenderTextures(target); } // Get pixel data from image in the form of Color struct array |
