瀏覽代碼

Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop

victorfisac 9 年之前
父節點
當前提交
1aecd5be07
共有 39 個文件被更改,包括 1149 次插入544 次删除
  1. 6 3
      CHANGELOG
  2. 1 1
      README.md
  3. 35 21
      examples/Makefile
  4. 6 6
      examples/audio_music_stream.c
  5. 2 2
      examples/core_2d_camera.c
  6. 2 2
      examples/core_color_select.c
  7. 17 18
      examples/core_oculus_rift.c
  8. 0 1
      examples/core_world_screen.c
  9. 1 1
      examples/models_cubicmap.c
  10. 1 1
      examples/models_heightmap.c
  11. 1 1
      examples/models_obj_loading.c
  12. 12 4
      examples/oculus_glfw_sample/rlgl_standalone.c
  13. 1 1
      examples/oculus_glfw_sample/rlgl_standalone_stereo.c
  14. 66 0
      examples/resources/shaders/glsl100/distortion.fs
  15. 69 0
      examples/resources/shaders/glsl330/distortion.fs
  16. 1 1
      examples/shaders_custom_uniform.c
  17. 1 1
      examples/shaders_postprocessing.c
  18. 2 2
      games/raylib_demo/raylib_demo.c
  19. 155 0
      shaders/glsl100/standard.fs
  20. 23 0
      shaders/glsl100/standard.vs
  21. 0 0
      shaders/glsl330/standard.fs
  22. 0 0
      shaders/glsl330/standard.vs
  23. 1 0
      src/Makefile
  24. 92 62
      src/core.c
  25. 20 1
      src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h
  26. 57 45
      src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h
  27. 4 0
      src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h
  28. 2 2
      src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h
  29. 2 2
      src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h
  30. 9 71
      src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h
  31. 1 1
      src/external/OculusSDK/LibOVR/Include/OVR_Version.h
  32. 二進制
      src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll
  33. 37 41
      src/models.c
  34. 2 2
      src/raylib.h
  35. 500 230
      src/rlgl.c
  36. 13 9
      src/rlgl.h
  37. 3 3
      src/shapes.c
  38. 3 3
      src/standard_shader.h
  39. 1 6
      src/textures.c

+ 6 - 3
CHANGELOG

@@ -1,20 +1,20 @@
 changelog
 ---------
 
-Current Release:    raylib 1.5.0 (23 June 2016)
+Current Release:    raylib 1.5.0 (xx June 2016)
 
 NOTE: Only versions marked as 'Release' are available in installer, updates are only available as source.
 NOTE: Current Release includes all previous updates.
 
 -----------------------------------------------
-Release:     raylib 1.5.0 (23 June 2016)
+Release:     raylib 1.5.0 (xx June 2016)
 -----------------------------------------------
 NOTE: 
   Probably this new version is the biggest boost of the library ever, lots of parts of the library have been redesigned, 
   lots of bugs have been solved and some **AMAZING** new features have been added.
 
 HUGE changes:
-[core] OCULUS RIFT CV1: Added support for VR witha bunch of Oculus-specific functions to init/close device and Oculus rendering.
+[rlgl] OCULUS RIFT CV1: Added support for VR witha bunch of Oculus-specific functions to init/close device and Oculus rendering.
 [rlgl] MATERIALS SYSTEM: Added support for Materials (.mtl) and multiple material properties: diffuse, specular, normal.
 [rlgl] LIGHTING SYSTEM: Added support for up to 8 lights of 3 different types: Omni, Directional and Spot
 [physac] REDESIGNED: Improved performance and simplified usage, physic objects are managed internally
@@ -27,6 +27,7 @@ other changes:
 [core] Renamed WorldToScreen() to GetWorldToScreen()
 [core] Removed function SetCustomCursor()
 [core] Removed functions BeginDrawingEx(), BeginDrawingPro()
+[core] Replaced functions InitDisplay() + InitGraphics() with: InitGraphicsDevice()
 [core] Added support for field-of-view Y (fovy) on 3d Camera
 [core] Added 2D camera mode functions: Begin2dMode() - End2dMode()
 [core] Translate mouse inputs to Android touch/gestures internally
@@ -36,6 +37,7 @@ other changes:
 [rlgl] Improved 2D vs 3D drawing system (lines, triangles, quads)
 [rlgl] Improved DXT-ETC1 support on HTML5
 [rlgl] Review function: rlglUnproject()
+[rlgl] Removed function: rlglInitGraphics(), integrated into rlglInit()
 [rlgl] Updated Mesh and Shader structs
 [rlgl] Simplified internal (default) dynamic buffers
 [rlgl] Added support for indexed and dynamic mesh data
@@ -65,6 +67,7 @@ other changes:
 [models] Updated BoundingBox collision detections
 [models] Added color parameter to DrawBoundigBox()
 [models] Removed function: DrawQuad()
+[models] Removed function: SetModelTexture()
 [models] Redesigned DrawPlane() to use RL_TRIANGLES
 [models] Redesigned DrawRectangleV() to use RL_TRIANGLES
 [models] Redesign to accomodate new materials system: LoadMaterial()

+ 1 - 1
README.md

@@ -1,4 +1,4 @@
-<img src="http://www.raylib.com/img/fb_raylib_logo.png" width=256>
+<img src="https://github.com/raysan5/raylib/blob/master/logo/logo256x256.png" width=256>
 
 about
 -----

+ 35 - 21
examples/Makefile

@@ -78,44 +78,38 @@ endif
 #CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
 
 # define any directories containing required header files
+INCLUDES = -I. -I../src -I../src/external
+
 ifeq ($(PLATFORM),PLATFORM_RPI)
-    INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
+    INCLUDES += -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
 endif
 ifeq ($(PLATFORM),PLATFORM_DESKTOP)
     # add standard directories for GNU/Linux
     ifeq ($(PLATFORM_OS),LINUX)
-        INCLUDES = -I. -I../src -I/usr/local/include/raylib/
-    else ifeq ($(PLATFORM_OS),OSX)
-        INCLUDES = -I. -I../src
-    else
-        INCLUDES = -I. -I../../src -IC:/raylib/raylib/src
+        INCLUDES += -I/usr/local/include/raylib/
+    else ifeq ($(PLATFORM_OS),WINDOWS)
         # external libraries headers
         # GLFW3
-            INCLUDES += -I../../external/glfw3/include
+            INCLUDES += -I../src/external/glfw3/include
         # OpenAL Soft
-            INCLUDES += -I../../external/openal_soft/include
+            INCLUDES += -I../src/external/openal_soft/include
     endif
 endif
 
 # define library paths containing required libs
+LFLAGS = -L. -L../src
+
 ifeq ($(PLATFORM),PLATFORM_RPI)
-    LFLAGS = -L. -L../../src -L/opt/vc/lib
+    LFLAGS += -L/opt/vc/lib
 endif
 ifeq ($(PLATFORM),PLATFORM_DESKTOP)
     # add standard directories for GNU/Linux
-    ifeq ($(PLATFORM_OS),LINUX)
-        LFLAGS = -L. -L../../src
-    else ifeq ($(PLATFORM_OS),OSX)
-        LFLAGS = -L. -L../src
-    else
-        LFLAGS = -L. -L../../src -LC:/raylib/raylib/src
+    ifeq ($(PLATFORM_OS),WINDOWS)
         # external libraries to link with
         # GLFW3
-            LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
-        ifneq ($(PLATFORM_OS),OSX)
+            LFLAGS += -L../src/external/glfw3/lib/$(LIBPATH)
         # OpenAL Soft
-            LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
-        endif
+            LFLAGS += -L../src/external/openal_soft/lib/$(LIBPATH)
     endif
 endif
 
@@ -148,7 +142,7 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
 endif
 ifeq ($(PLATFORM),PLATFORM_WEB)
     # just adjust the correct path to libraylib.bc
-    LIBS = ../src/libraylib.bc
+    LIBS = ../release/html5/libraylib.bc
 endif
 
 # define additional parameters and flags for windows
@@ -178,6 +172,9 @@ EXAMPLES = \
     core_3d_picking \
     core_3d_camera_free \
     core_3d_camera_first_person \
+    core_2d_camera \
+    core_world_screen \
+    core_oculus_rift \
     shapes_logo_raylib \
     shapes_basic_shapes \
     shapes_colors_palette \
@@ -208,6 +205,7 @@ EXAMPLES = \
     shaders_shapes_textures \
     shaders_custom_uniform \
     shaders_postprocessing \
+    shaders_standard_lighting \
     audio_sound_loading \
     audio_music_stream \
     fix_dylib \
@@ -287,7 +285,19 @@ core_3d_camera_free: core_3d_camera_free.c
 # compile [core] example - 3d camera first person
 core_3d_camera_first_person: core_3d_camera_first_person.c
 	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)    
+
+# compile [core] example - 2d camera
+core_2d_camera: core_2d_camera.c
+	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
     
+# compile [core] example - world screen
+core_world_screen: core_world_screen.c
+	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
+
+# compile [core] example - oculus rift
+core_oculus_rift: core_oculus_rift.c
+	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
+
 # compile [shapes] example - raylib logo (with basic shapes)
 shapes_logo_raylib: shapes_logo_raylib.c
 	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
@@ -411,7 +421,11 @@ shaders_custom_uniform: shaders_custom_uniform.c
 # compile [shaders] example - postprocessing shader
 shaders_postprocessing: shaders_postprocessing.c
 	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
-    
+
+# compile [shaders] example - standard lighting
+shaders_standard_lighting: shaders_standard_lighting.c
+	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
+
 # compile [audio] example - sound loading and playing (WAV and OGG)
 audio_sound_loading: audio_sound_loading.c
 	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)

+ 6 - 6
examples/audio_music_stream.c

@@ -24,7 +24,7 @@ int main()
 
     InitAudioDevice();              // Initialize audio device
 
-    PlayMusicStream("resources/audio/guitar_noodling.ogg");         // Play music stream
+    PlayMusicStream(0, "resources/audio/guitar_noodling.ogg");         // Play music stream
 
     int framesCounter = 0;
     float timePlayed = 0.0f;
@@ -52,18 +52,18 @@ int main()
             {
                 volume = 1.0;
                 framesCounter = 0;
-                PlayMusicStream("resources/audio/another_file.ogg");
+                PlayMusicStream(1, "resources/audio/another_file.ogg");
             }
 
             SetMusicVolume(volume);
         }
 */
-        if (IsWindowMinimized()) PauseMusicStream();
-        else ResumeMusicStream();
+        if (IsWindowMinimized()) PauseMusicStream(0);
+        else ResumeMusicStream(0);
 
-        timePlayed = GetMusicTimePlayed()/GetMusicTimeLength()*100*4; // We scale by 4 to fit 400 pixels
+        timePlayed = GetMusicTimePlayed(0)/GetMusicTimeLength(0)*100*4; // We scale by 4 to fit 400 pixels
         
-        UpdateMusicStream();        // Update music buffer with new stream data
+        UpdateMusicStream(0);        // Update music buffer with new stream data
         //----------------------------------------------------------------------------------
 
         // Draw

+ 2 - 2
examples/core_2d_camera.c

@@ -23,8 +23,8 @@ int main()
     InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
     
     Rectangle player = { 400, 280, 40, 40 };
-    Rectangle buildings[MAX_BUILDINGS] = { 0, 0, 0, 0 };
-    Color buildColors[MAX_BUILDINGS] = { 80, 80, 80, 255 };
+    Rectangle buildings[MAX_BUILDINGS];
+    Color buildColors[MAX_BUILDINGS];
     
     int spacing = 0;
     

+ 2 - 2
examples/core_color_select.c

@@ -16,7 +16,7 @@ int main()
     // Initialization
     //--------------------------------------------------------------------------------------
     int screenWidth = 800;
-    int screenHeight = 400;
+    int screenHeight = 450;
 
     InitWindow(screenWidth, screenHeight, "raylib [core] example - color selection (collision detection)");
 
@@ -30,7 +30,7 @@ int main()
     for (int i = 0; i < 21; i++)
     {
         colorsRecs[i].x = 20 + 100*(i%7) + 10*(i%7);
-        colorsRecs[i].y = 40 + 100*(i/7) + 10*(i/7);
+        colorsRecs[i].y = 60 + 100*(i/7) + 10*(i/7);
         colorsRecs[i].width = 100;
         colorsRecs[i].height = 100;
     }

+ 17 - 18
examples/core_oculus_rift.c

@@ -30,11 +30,11 @@ int main()
     camera.position = (Vector3){ 5.0f, 5.0f, 5.0f };    // Camera position
     camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };      // Camera looking at point
     camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };          // Camera up vector (rotation towards target)
-    camera.fovy = 45.0f;                                // Camera field-of-view Y
+    camera.fovy = 60.0f;                                // Camera field-of-view Y
     
     Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
     
-    //SetTargetFPS(90);                   // Set our game to run at 90 frames-per-second
+    SetTargetFPS(90);                   // Set our game to run at 90 frames-per-second
     //--------------------------------------------------------------------------------------
 
     // Main game loop
@@ -43,31 +43,30 @@ int main()
         // Update
         //----------------------------------------------------------------------------------
         UpdateOculusTracking();
+        
+        if (IsKeyPressed(KEY_SPACE)) ToggleVR();
         //----------------------------------------------------------------------------------
 
         // Draw
         //----------------------------------------------------------------------------------
         BeginDrawing();
-        
+
             ClearBackground(RAYWHITE);
             
-            BeginOculusDrawing();
-            
-                for (int eye = 0; eye < 2; eye++)
-                {
-                    Begin3dMode(camera);
+            if (IsOculusReady()) BeginOculusDrawing();
+
+            Begin3dMode(camera);
+
+                DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
+                DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
                 
-                        SetOculusMatrix(eye);
-                        
-                        DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
-                        DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
-                        
-                        DrawGrid(10, 1.0f);
-                    
-                    End3dMode();
-                }
+                DrawGrid(10, 1.0f);
+            
+            End3dMode();
+            
+            if (IsOculusReady()) EndOculusDrawing();
             
-            EndOculusDrawing();
+            DrawFPS(10, 10);
 
         EndDrawing();
         //----------------------------------------------------------------------------------

+ 0 - 1
examples/core_world_screen.c

@@ -63,7 +63,6 @@ int main()
             
             DrawText("Enemy: 100 / 100", cubeScreenPosition.x - MeasureText("Enemy: 100 / 100", 20) / 2, cubeScreenPosition.y, 20, BLACK);
             DrawText("Text is always on top of the cube", (screenWidth - MeasureText("Text is always on top of the cube", 20)) / 2, 25, 20, GRAY);
-            
 
         EndDrawing();
         //----------------------------------------------------------------------------------

+ 1 - 1
examples/models_cubicmap.c

@@ -29,7 +29,7 @@ int main()
     
     // NOTE: By default each cube is mapped to one part of texture atlas
     Texture2D texture = LoadTexture("resources/cubicmap_atlas.png");    // Load map texture
-    SetModelTexture(&map, texture);                         // Bind texture to map model
+    map.material.texDiffuse = texture;                      // Set map diffuse texture
     
     Vector3 mapPosition = { -16.0f, 0.0f, -8.0f };          // Set model position
 

+ 1 - 1
examples/models_heightmap.c

@@ -26,7 +26,7 @@ int main()
     Image image = LoadImage("resources/heightmap.png");         // Load heightmap image (RAM)
     Texture2D texture = LoadTextureFromImage(image);            // Convert image to texture (VRAM)
     Model map = LoadHeightmap(image, (Vector3){ 16, 8, 16 });   // Load heightmap model with defined size
-    SetModelTexture(&map, texture);                             // Bind texture to model
+    map.material.texDiffuse = texture;                          // Set map diffuse texture
     Vector3 mapPosition = { -8.0f, 0.0f, -8.0f };               // Set model position (depends on model scaling!)
 
     UnloadImage(image);                 // Unload heightmap image from RAM, already uploaded to VRAM

+ 1 - 1
examples/models_obj_loading.c

@@ -25,7 +25,7 @@ int main()
 
     Model dwarf = LoadModel("resources/model/dwarf.obj");                   // Load OBJ model
     Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png");   // Load model texture
-    SetModelTexture(&dwarf, texture);                                       // Bind texture to model
+    dwarf.material.texDiffuse = texture;                                    // Set dwarf model diffuse texture
     Vector3 position = { 0.0f, 0.0f, 0.0f };                                // Set model position
 
     SetTargetFPS(60);   // Set our game to run at 60 frames-per-second

+ 12 - 4
examples/oculus_glfw_sample/rlgl_standalone.c

@@ -96,11 +96,19 @@ int main(void)
     
     // Initialize rlgl internal buffers and OpenGL state
     rlglInit();
-    rlglInitGraphics(0, 0, screenWidth, screenHeight);
-    rlClearColor(245, 245, 245, 255);   // Define clear color
-    rlEnableDepthTest();                // Enable DEPTH_TEST for 3D
     
-    Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
+    // Initialize viewport and internal projection/modelview matrices
+    rlViewport(0, 0, screenWidth, screenHeight);
+    rlMatrixMode(RL_PROJECTION);                        // Switch to PROJECTION matrix
+    rlLoadIdentity();                                   // Reset current matrix (PROJECTION)
+    rlOrtho(0, screenWidth, screenHeight, 0, 0.0f, 1.0f); // Orthographic projection with top-left corner at (0,0)
+    rlMatrixMode(RL_MODELVIEW);                         // Switch back to MODELVIEW matrix
+    rlLoadIdentity();                                   // Reset current matrix (MODELVIEW)
+
+    rlClearColor(245, 245, 245, 255);                   // Define clear color
+    rlEnableDepthTest();                                // Enable DEPTH_TEST for 3D
+    
+    Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };        // Cube default position (center)
     
     Camera camera;
     camera.position = (Vector3){ 5.0f, 5.0f, 5.0f };    // Camera position

+ 1 - 1
examples/oculus_glfw_sample/rlgl_standalone_stereo.c

@@ -184,7 +184,7 @@ int main(void)
 
             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
+            rlOrtho(0.0, screenWidth/2, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix
             rlMatrixMode(RL_MODELVIEW);                             // Enable internal modelview matrix
             rlLoadIdentity();                                       // Reset internal modelview matrix
 #endif

+ 66 - 0
examples/resources/shaders/glsl100/distortion.fs

@@ -0,0 +1,66 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+
+// Input uniform values
+uniform sampler2D texture0;
+
+// NOTE: Add here your custom variables
+const vec2 LeftLensCenter = vec2(0.2863248, 0.5);
+const vec2 RightLensCenter = vec2(0.7136753, 0.5);
+const vec2 LeftScreenCenter = vec2(0.25, 0.5);
+const vec2 RightScreenCenter = vec2(0.75, 0.5);
+const vec2 Scale = vec2(0.25, 0.45);    //vec2(0.1469278, 0.2350845);
+const vec2 ScaleIn = vec2(4, 2.2222);
+const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0);
+const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0);
+
+/*
+// Another set of default values
+ChromaAbCorrection = {1.0, 0.0, 1.0, 0}
+DistortionK = {1.0, 0.22, 0.24, 0}
+Scale = {0.25, 0.5*AspectRatio, 0, 0}
+ScaleIn = {4.0, 2/AspectRatio, 0, 0}
+Left Screen Center = {0.25, 0.5, 0, 0}
+Left Lens Center = {0.287994117, 0.5, 0, 0}
+Right Screen Center = {0.75, 0.5, 0, 0}
+Right Lens Center = {0.712005913, 0.5, 0, 0}
+*/
+
+void main()
+{
+    // The following two variables need to be set per eye
+    vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter;
+    vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter;
+    
+    // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter)
+    vec2 theta = (fragTexCoord - LensCenter)*ScaleIn;   // Scales to [-1, 1]
+    float rSq = theta.x*theta.x + theta.y*theta.y;
+    vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq);
+    //vec2 tc = LensCenter + Scale*theta1;
+    
+    // Detect whether blue texture coordinates are out of range since these will scaled out the furthest
+    vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq);
+    vec2 tcBlue = LensCenter + Scale*thetaBlue;
+
+    if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+    else
+    {
+        // Do blue texture lookup
+        float blue = texture2D(texture0, tcBlue).b;
+
+        // Do green lookup (no scaling)
+        vec2 tcGreen = LensCenter + Scale*theta1;
+        float green = texture2D(texture0, tcGreen).g;
+
+        // Do red scale and lookup
+        vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq);
+        vec2 tcRed = LensCenter + Scale*thetaRed;
+        float red = texture2D(texture0, tcRed).r;
+
+        gl_FragColor = vec4(red, green, blue, 1.0);
+    }
+}

+ 69 - 0
examples/resources/shaders/glsl330/distortion.fs

@@ -0,0 +1,69 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+
+// Input uniform values
+uniform sampler2D texture0;
+
+// Output fragment color
+out vec4 finalColor;
+
+// NOTE: Add here your custom variables
+const vec2 LeftLensCenter = vec2(0.288, 0.5);
+const vec2 RightLensCenter = vec2(0.712, 0.5);
+const vec2 LeftScreenCenter = vec2(0.25, 0.5);
+const vec2 RightScreenCenter = vec2(0.75, 0.5);
+uniform vec2 Scale = vec2(0.25, 0.45);    //vec2(0.1469278, 0.2350845);
+uniform vec2 ScaleIn = vec2(4, 2.2222);
+
+const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0);
+const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0);
+
+/*
+// Another set of default values
+ChromaAbCorrection = {1.0, 0.0, 1.0, 0}
+DistortionK = {1.0, 0.22, 0.24, 0}
+Scale = {0.25, 0.5*AspectRatio, 0, 0}
+ScaleIn = {4.0, 2/AspectRatio, 0, 0}
+Left Screen Center = {0.25, 0.5, 0, 0}
+Left Lens Center = {0.287994117, 0.5, 0, 0}
+Right Screen Center = {0.75, 0.5, 0, 0}
+Right Lens Center = {0.712005913, 0.5, 0, 0}
+*/
+
+void main()
+{
+    // The following two variables need to be set per eye
+    vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter;
+    vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter;
+    
+    // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter)
+    vec2 theta = (fragTexCoord - LensCenter)*ScaleIn;   // Scales to [-1, 1]
+    float rSq = theta.x*theta.x + theta.y*theta.y;
+    vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq);
+    //vec2 tc = LensCenter + Scale*theta1;
+    
+    // Detect whether blue texture coordinates are out of range since these will scaled out the furthest
+    vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq);
+    vec2 tcBlue = LensCenter + Scale*thetaBlue;
+
+    if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) finalColor = vec4(0.0, 0.0, 0.0, 1.0);
+    else
+    {
+        // Do blue texture lookup
+        float blue = texture(texture0, tcBlue).b;
+
+        // Do green lookup (no scaling)
+        vec2 tcGreen = LensCenter + Scale*theta1;
+        float green = texture(texture0, tcGreen).g;
+
+        // Do red scale and lookup
+        vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq);
+        vec2 tcRed = LensCenter + Scale*thetaRed;
+        float red = texture(texture0, tcRed).r;
+
+        finalColor = vec4(red, green, blue, 1.0);
+    }
+}
+

+ 1 - 1
examples/shaders_custom_uniform.c

@@ -34,7 +34,7 @@ int main()
 
     Model dwarf = LoadModel("resources/model/dwarf.obj");                   // Load OBJ model
     Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png");   // Load model texture (diffuse map)
-    SetModelTexture(&dwarf, texture);                                       // Bind texture to model
+    dwarf.material.texDiffuse = texture;                                    // Set dwarf model diffuse texture
 
     Vector3 position = { 0.0f, 0.0f, 0.0f };                                // Set model position
     

+ 1 - 1
examples/shaders_postprocessing.c

@@ -34,7 +34,7 @@ int main()
     
     Model dwarf = LoadModel("resources/model/dwarf.obj");                   // Load OBJ model
     Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png");   // Load model texture (diffuse map)
-    SetModelTexture(&dwarf, texture);                                       // Bind texture to model
+    dwarf.material.texDiffuse = texture;                                    // Set dwarf model diffuse texture
 
     Vector3 position = { 0.0f, 0.0f, 0.0f };                                // Set model position
     

+ 2 - 2
games/raylib_demo/raylib_demo.c

@@ -202,8 +202,8 @@ int main()
     camera = (Camera){{ 0.0, 12.0, 15.0 }, { 0.0, 3.0, 0.0 }, { 0.0, 1.0, 0.0 }};
 
     catTexture = LoadTexture("resources/catsham.png");   // Load model texture
-    cat = LoadModel("resources/cat.obj");                 // Load OBJ model
-    SetModelTexture(&cat, catTexture);
+    cat = LoadModel("resources/cat.obj");                // Load OBJ model
+    cat.material.texDiffuse = texture;                   // Set cat model diffuse texture
     
     fxWav = LoadSound("resources/audio/weird.wav");         // Load WAV audio file
     fxOgg = LoadSound("resources/audio/tanatana.ogg");      // Load OGG audio file

+ 155 - 0
shaders/glsl100/standard.fs

@@ -0,0 +1,155 @@
+#version 100
+
+precision mediump float;
+
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+uniform sampler2D texture0;
+uniform sampler2D texture1;
+uniform sampler2D texture2;
+
+uniform vec4 colAmbient;
+uniform vec4 colDiffuse;
+uniform vec4 colSpecular;
+uniform float glossiness;
+
+uniform int useNormal;
+uniform int useSpecular;
+
+uniform mat4 modelMatrix;
+uniform vec3 viewDir;
+
+struct Light {
+    int enabled;
+    int type;
+    vec3 position;
+    vec3 direction;
+    vec4 diffuse;
+    float intensity;
+    float radius;
+    float coneAngle;
+};
+
+const int maxLights = 8;
+uniform int lightsCount;
+uniform Light lights[maxLights];
+
+vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s)
+{
+    vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));
+    vec3 surfaceToLight = l.position - surfacePos;
+    
+    // Diffuse shading
+    float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1);
+    float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity;
+    
+    // Specular shading
+    float spec = 0.0;
+    if (diff > 0.0)
+    {
+        vec3 h = normalize(-l.direction + v);
+        spec = pow(dot(n, h), 3 + glossiness)*s;
+    }
+    
+    return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
+}
+
+vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)
+{
+    vec3 lightDir = normalize(-l.direction);
+    
+    // Diffuse shading
+    float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity;
+    
+    // Specular shading
+    float spec = 0.0;
+    if (diff > 0.0)
+    {
+        vec3 h = normalize(lightDir + v);
+        spec = pow(dot(n, h), 3 + glossiness)*s;
+    }
+    
+    // Combine results
+    return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);
+}
+
+vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)
+{
+    vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));
+    vec3 lightToSurface = normalize(surfacePos - l.position);
+    vec3 lightDir = normalize(-l.direction);
+    
+    // Diffuse shading
+    float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity;
+    
+    // Spot attenuation
+    float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0);
+    attenuation = dot(lightToSurface, -lightDir);
+    
+    float lightToSurfaceAngle = degrees(acos(attenuation));
+    if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;
+    
+    float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;
+    
+    // Combine diffuse and attenuation
+    float diffAttenuation = diff*attenuation;
+    
+    // Specular shading
+    float spec = 0.0;
+    if (diffAttenuation > 0.0)
+    {
+        vec3 h = normalize(lightDir + v);
+        spec = pow(dot(n, h), 3 + glossiness)*s;
+    }
+    
+    return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
+}
+
+void main()
+{
+    // Calculate fragment normal in screen space
+    // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale)
+    mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));
+    vec3 normal = normalize(normalMatrix*fragNormal);
+
+    // Normalize normal and view direction vectors
+    vec3 n = normalize(normal);
+    vec3 v = normalize(viewDir);
+
+    // Calculate diffuse texture color fetching
+    vec4 texelColor = texture2D(texture0, fragTexCoord);
+    vec3 lighting = colAmbient.rgb;
+    
+    // Calculate normal texture color fetching or set to maximum normal value by default
+    if (useNormal == 1)
+    {
+        n *= texture2D(texture1, fragTexCoord).rgb;
+        n = normalize(n);
+    }
+    
+    // Calculate specular texture color fetching or set to maximum specular value by default
+    float spec = 1.0;
+    if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r);
+    
+    for (int i = 0; i < lightsCount; i++)
+    {
+        // Check if light is enabled
+        if (lights[i].enabled == 1)
+        {
+            // Calculate lighting based on light type
+            switch (lights[i].type)
+            {
+                case 0: lighting += CalcPointLight(lights[i], n, v, spec); break;
+                case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break;
+                case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break;
+                default: break;
+            }
+        }
+    }
+    
+    // Calculate final fragment color
+    gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a);
+}

+ 23 - 0
shaders/glsl100/standard.vs

@@ -0,0 +1,23 @@
+#version 100
+
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec2 vertexTexCoord;
+attribute vec4 vertexColor;
+
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+uniform mat4 mvpMatrix;
+
+void main()
+{
+    fragPosition = vertexPosition;
+    fragTexCoord = vertexTexCoord;
+    fragColor = vertexColor;
+    fragNormal = vertexNormal;
+
+    gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+}

+ 0 - 0
examples/resources/shaders/standard.fs → shaders/glsl330/standard.fs


+ 0 - 0
examples/resources/shaders/standard.vs → shaders/glsl330/standard.vs


+ 1 - 0
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)

+ 92 - 62
src/core.c

@@ -238,8 +238,7 @@ extern void UnloadDefaultFont(void);        // [Module: text] Unloads default fo
 //----------------------------------------------------------------------------------
 // Module specific Functions Declaration
 //----------------------------------------------------------------------------------
-static void InitDisplay(int width, int height);         // Initialize display device and framebuffer
-static void InitGraphics(void);                         // Initialize OpenGL graphics
+static void InitGraphicsDevice(int width, int height);  // Initialize graphics device
 static void SetupFramebufferSize(int displayWidth, int displayHeight);
 static void InitTimer(void);                            // Initialize timer
 static double GetTime(void);                            // Returns time since InitTimer() was run
@@ -300,11 +299,8 @@ void InitWindow(int width, int height, const char *title)
     // Store window title (could be useful...)
     windowTitle = title;
 
-    // Init device display (monitor, LCD, ...)
-    InitDisplay(width, height);
-
-    // Init OpenGL graphics
-    InitGraphics();
+    // Init graphics device (display device and OpenGL context)
+    InitGraphicsDevice(width, height);
 
     // Load default font for convenience
     // NOTE: External function (defined in module: text)
@@ -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)

+ 20 - 1
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

+ 57 - 45
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);
 

+ 4 - 0
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

+ 2 - 2
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.

+ 2 - 2
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.

+ 9 - 71
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 */

+ 1 - 1
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
 

二進制
src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll


+ 37 - 41
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))

+ 2 - 2
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)

File diff suppressed because it is too large
+ 500 - 230
src/rlgl.c


+ 13 - 9
src/rlgl.h

@@ -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
 }

+ 3 - 3
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);

+ 3 - 3
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";

+ 1 - 6
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

Some files were not shown because too many files changed in this diff