Browse Source

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

victorfisac 9 năm trước cách đây
mục cha
commit
1aecd5be07
39 tập tin đã thay đổi với 1149 bổ sung544 xóa
  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. BIN
      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
 

BIN
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)

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 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

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác