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

This commit is contained in:
victorfisac
2016-07-05 11:57:05 +02:00
39 changed files with 1296 additions and 670 deletions

View File

@ -1,20 +1,20 @@
changelog 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: Only versions marked as 'Release' are available in installer, updates are only available as source.
NOTE: Current Release includes all previous updates. NOTE: Current Release includes all previous updates.
----------------------------------------------- -----------------------------------------------
Release: raylib 1.5.0 (23 June 2016) Release: raylib 1.5.0 (xx June 2016)
----------------------------------------------- -----------------------------------------------
NOTE: NOTE:
Probably this new version is the biggest boost of the library ever, lots of parts of the library have been redesigned, 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. lots of bugs have been solved and some **AMAZING** new features have been added.
HUGE changes: 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] 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 [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 [physac] REDESIGNED: Improved performance and simplified usage, physic objects are managed internally
@ -27,6 +27,7 @@ other changes:
[core] Renamed WorldToScreen() to GetWorldToScreen() [core] Renamed WorldToScreen() to GetWorldToScreen()
[core] Removed function SetCustomCursor() [core] Removed function SetCustomCursor()
[core] Removed functions BeginDrawingEx(), BeginDrawingPro() [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 support for field-of-view Y (fovy) on 3d Camera
[core] Added 2D camera mode functions: Begin2dMode() - End2dMode() [core] Added 2D camera mode functions: Begin2dMode() - End2dMode()
[core] Translate mouse inputs to Android touch/gestures internally [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 2D vs 3D drawing system (lines, triangles, quads)
[rlgl] Improved DXT-ETC1 support on HTML5 [rlgl] Improved DXT-ETC1 support on HTML5
[rlgl] Review function: rlglUnproject() [rlgl] Review function: rlglUnproject()
[rlgl] Removed function: rlglInitGraphics(), integrated into rlglInit()
[rlgl] Updated Mesh and Shader structs [rlgl] Updated Mesh and Shader structs
[rlgl] Simplified internal (default) dynamic buffers [rlgl] Simplified internal (default) dynamic buffers
[rlgl] Added support for indexed and dynamic mesh data [rlgl] Added support for indexed and dynamic mesh data
@ -65,6 +67,7 @@ other changes:
[models] Updated BoundingBox collision detections [models] Updated BoundingBox collision detections
[models] Added color parameter to DrawBoundigBox() [models] Added color parameter to DrawBoundigBox()
[models] Removed function: DrawQuad() [models] Removed function: DrawQuad()
[models] Removed function: SetModelTexture()
[models] Redesigned DrawPlane() to use RL_TRIANGLES [models] Redesigned DrawPlane() to use RL_TRIANGLES
[models] Redesigned DrawRectangleV() to use RL_TRIANGLES [models] Redesigned DrawRectangleV() to use RL_TRIANGLES
[models] Redesign to accomodate new materials system: LoadMaterial() [models] Redesign to accomodate new materials system: LoadMaterial()

View File

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

View File

@ -78,44 +78,38 @@ endif
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes #CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
# define any directories containing required header files # define any directories containing required header files
INCLUDES = -I. -I../src -I../src/external
ifeq ($(PLATFORM),PLATFORM_RPI) 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 endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# add standard directories for GNU/Linux # add standard directories for GNU/Linux
ifeq ($(PLATFORM_OS),LINUX) ifeq ($(PLATFORM_OS),LINUX)
INCLUDES = -I. -I../src -I/usr/local/include/raylib/ INCLUDES += -I/usr/local/include/raylib/
else ifeq ($(PLATFORM_OS),OSX) else ifeq ($(PLATFORM_OS),WINDOWS)
INCLUDES = -I. -I../src
else
INCLUDES = -I. -I../../src -IC:/raylib/raylib/src
# external libraries headers # external libraries headers
# GLFW3 # GLFW3
INCLUDES += -I../../external/glfw3/include INCLUDES += -I../src/external/glfw3/include
# OpenAL Soft # OpenAL Soft
INCLUDES += -I../../external/openal_soft/include INCLUDES += -I../src/external/openal_soft/include
endif endif
endif endif
# define library paths containing required libs # define library paths containing required libs
LFLAGS = -L. -L../src
ifeq ($(PLATFORM),PLATFORM_RPI) ifeq ($(PLATFORM),PLATFORM_RPI)
LFLAGS = -L. -L../../src -L/opt/vc/lib LFLAGS += -L/opt/vc/lib
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# add standard directories for GNU/Linux # add standard directories for GNU/Linux
ifeq ($(PLATFORM_OS),LINUX) ifeq ($(PLATFORM_OS),WINDOWS)
LFLAGS = -L. -L../../src
else ifeq ($(PLATFORM_OS),OSX)
LFLAGS = -L. -L../src
else
LFLAGS = -L. -L../../src -LC:/raylib/raylib/src
# external libraries to link with # external libraries to link with
# GLFW3 # GLFW3
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH) LFLAGS += -L../src/external/glfw3/lib/$(LIBPATH)
ifneq ($(PLATFORM_OS),OSX)
# OpenAL Soft # OpenAL Soft
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH) LFLAGS += -L../src/external/openal_soft/lib/$(LIBPATH)
endif
endif endif
endif endif
@ -148,7 +142,7 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(PLATFORM),PLATFORM_WEB)
# just adjust the correct path to libraylib.bc # just adjust the correct path to libraylib.bc
LIBS = ../src/libraylib.bc LIBS = ../release/html5/libraylib.bc
endif endif
# define additional parameters and flags for windows # define additional parameters and flags for windows
@ -178,6 +172,9 @@ EXAMPLES = \
core_3d_picking \ core_3d_picking \
core_3d_camera_free \ core_3d_camera_free \
core_3d_camera_first_person \ core_3d_camera_first_person \
core_2d_camera \
core_world_screen \
core_oculus_rift \
shapes_logo_raylib \ shapes_logo_raylib \
shapes_basic_shapes \ shapes_basic_shapes \
shapes_colors_palette \ shapes_colors_palette \
@ -208,6 +205,7 @@ EXAMPLES = \
shaders_shapes_textures \ shaders_shapes_textures \
shaders_custom_uniform \ shaders_custom_uniform \
shaders_postprocessing \ shaders_postprocessing \
shaders_standard_lighting \
audio_sound_loading \ audio_sound_loading \
audio_music_stream \ audio_music_stream \
fix_dylib \ fix_dylib \
@ -288,6 +286,18 @@ core_3d_camera_free: core_3d_camera_free.c
core_3d_camera_first_person: core_3d_camera_first_person.c core_3d_camera_first_person: core_3d_camera_first_person.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) $(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) # compile [shapes] example - raylib logo (with basic shapes)
shapes_logo_raylib: shapes_logo_raylib.c shapes_logo_raylib: shapes_logo_raylib.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
@ -412,6 +422,10 @@ shaders_custom_uniform: shaders_custom_uniform.c
shaders_postprocessing: shaders_postprocessing.c shaders_postprocessing: shaders_postprocessing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) $(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) # compile [audio] example - sound loading and playing (WAV and OGG)
audio_sound_loading: audio_sound_loading.c audio_sound_loading: audio_sound_loading.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)

View File

@ -24,7 +24,7 @@ int main()
InitAudioDevice(); // Initialize audio device 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; int framesCounter = 0;
float timePlayed = 0.0f; float timePlayed = 0.0f;
@ -52,18 +52,18 @@ int main()
{ {
volume = 1.0; volume = 1.0;
framesCounter = 0; framesCounter = 0;
PlayMusicStream("resources/audio/another_file.ogg"); PlayMusicStream(1, "resources/audio/another_file.ogg");
} }
SetMusicVolume(volume); SetMusicVolume(volume);
} }
*/ */
if (IsWindowMinimized()) PauseMusicStream(); if (IsWindowMinimized()) PauseMusicStream(0);
else ResumeMusicStream(); 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 // Draw

View File

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

View File

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

View File

@ -30,11 +30,11 @@ int main()
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position 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.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.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 }; 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 // Main game loop
@ -43,6 +43,8 @@ int main()
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
UpdateOculusTracking(); UpdateOculusTracking();
if (IsKeyPressed(KEY_SPACE)) ToggleVR();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -51,23 +53,20 @@ int main()
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
BeginOculusDrawing(); if (IsOculusReady()) BeginOculusDrawing();
for (int eye = 0; eye < 2; eye++)
{
Begin3dMode(camera); Begin3dMode(camera);
SetOculusMatrix(eye);
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
DrawGrid(10, 1.0f); DrawGrid(10, 1.0f);
End3dMode(); End3dMode();
}
EndOculusDrawing(); if (IsOculusReady()) EndOculusDrawing();
DrawFPS(10, 10);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -64,7 +64,6 @@ int main()
DrawText("Enemy: 100 / 100", cubeScreenPosition.x - MeasureText("Enemy: 100 / 100", 20) / 2, cubeScreenPosition.y, 20, BLACK); 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); 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(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
} }

View File

@ -29,7 +29,7 @@ int main()
// NOTE: By default each cube is mapped to one part of texture atlas // NOTE: By default each cube is mapped to one part of texture atlas
Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture 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 Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position

View File

@ -26,7 +26,7 @@ int main()
Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM) Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM)
Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM)
Model map = LoadHeightmap(image, (Vector3){ 16, 8, 16 }); // Load heightmap model with defined size 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!) 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 UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM

View File

@ -25,7 +25,7 @@ int main()
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture 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 Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second

View File

@ -96,11 +96,19 @@ int main(void)
// Initialize rlgl internal buffers and OpenGL state // Initialize rlgl internal buffers and OpenGL state
rlglInit(); rlglInit();
rlglInitGraphics(0, 0, screenWidth, screenHeight);
// 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 rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; // Cube default position (center)
Camera camera; Camera camera;
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position

View File

@ -184,7 +184,7 @@ int main(void)
rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix
rlLoadIdentity(); // Reset 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 rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix rlLoadIdentity(); // Reset internal modelview matrix
#endif #endif

View File

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

View File

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

View File

@ -34,7 +34,7 @@ int main()
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map) 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 Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position

View File

@ -34,7 +34,7 @@ int main()
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map) 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 Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position

View File

@ -203,7 +203,7 @@ int main()
catTexture = LoadTexture("resources/catsham.png"); // Load model texture catTexture = LoadTexture("resources/catsham.png"); // Load model texture
cat = LoadModel("resources/cat.obj"); // Load OBJ model cat = LoadModel("resources/cat.obj"); // Load OBJ model
SetModelTexture(&cat, catTexture); cat.material.texDiffuse = texture; // Set cat model diffuse texture
fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file
fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file

155
shaders/glsl100/standard.fs Normal file
View File

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

View File

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

View File

@ -51,6 +51,7 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
else else
# define raylib graphics api to use (OpenGL 1.1 by default) # define raylib graphics api to use (OpenGL 1.1 by default)
GRAPHICS ?= GRAPHICS_API_OPENGL_11 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 #GRAPHICS = GRAPHICS_API_OPENGL_33 # Uncomment to use OpenGL 3.3
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(PLATFORM),PLATFORM_WEB)

View File

@ -238,8 +238,7 @@ extern void UnloadDefaultFont(void); // [Module: text] Unloads default fo
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static void InitDisplay(int width, int height); // Initialize display device and framebuffer static void InitGraphicsDevice(int width, int height); // Initialize graphics device
static void InitGraphics(void); // Initialize OpenGL graphics
static void SetupFramebufferSize(int displayWidth, int displayHeight); static void SetupFramebufferSize(int displayWidth, int displayHeight);
static void InitTimer(void); // Initialize timer static void InitTimer(void); // Initialize timer
static double GetTime(void); // Returns time since InitTimer() was run 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...) // Store window title (could be useful...)
windowTitle = title; windowTitle = title;
// Init device display (monitor, LCD, ...) // Init graphics device (display device and OpenGL context)
InitDisplay(width, height); InitGraphicsDevice(width, height);
// Init OpenGL graphics
InitGraphics();
// Load default font for convenience // Load default font for convenience
// NOTE: External function (defined in module: text) // NOTE: External function (defined in module: text)
@ -447,6 +443,14 @@ void CloseWindow(void)
} }
#endif #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"); TraceLog(INFO, "Window closed successfully");
} }
@ -476,16 +480,14 @@ bool IsWindowMinimized(void)
} }
// Fullscreen toggle // Fullscreen toggle
// TODO: When destroying window context is lost and resources too, take care!
void ToggleFullscreen(void) void ToggleFullscreen(void)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
fullscreen = !fullscreen; // Toggle fullscreen flag fullscreen = !fullscreen; // Toggle fullscreen flag
rlglClose(); // De-init rlgl // NOTE: glfwSetWindowMonitor() doesn't work properly (bugs)
glfwDestroyWindow(window); // Destroy the current window (we will recreate it!) if (fullscreen) glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
else glfwSetWindowMonitor(window, NULL, 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
InitWindow(screenWidth, screenHeight, windowTitle);
#endif #endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
@ -519,6 +521,8 @@ void BeginDrawing(void)
updateTime = currentTime - previousTime; updateTime = currentTime - previousTime;
previousTime = currentTime; previousTime = currentTime;
//if (IsOculusReady()) BeginOculusDrawing();
rlClearScreenBuffers(); // Clear current framebuffers rlClearScreenBuffers(); // Clear current framebuffers
rlLoadIdentity(); // Reset current matrix (MODELVIEW) rlLoadIdentity(); // Reset current matrix (MODELVIEW)
rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here
@ -532,6 +536,8 @@ void EndDrawing(void)
{ {
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
//if (IsOculusReady()) EndOculusDrawing();
SwapBuffers(); // Copy back buffer to front buffer SwapBuffers(); // Copy back buffer to front buffer
PollInputEvents(); // Poll user events PollInputEvents(); // Poll user events
@ -611,7 +617,7 @@ void Begin3dMode(Camera camera)
// Ends 3D mode and returns to default 2D orthographic mode // Ends 3D mode and returns to default 2D orthographic mode
void End3dMode(void) void End3dMode(void)
{ {
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlglDraw(); // Process internal buffers (update + draw)
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
@ -1433,7 +1439,7 @@ bool IsButtonReleased(int button)
// Initialize display device and framebuffer // Initialize display device and framebuffer
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size // 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 // 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 screenWidth = width; // User desired width
screenHeight = height; // User desired height screenHeight = height; // User desired height
@ -1481,15 +1487,20 @@ static void InitDisplay(int width, int height)
// with forward compatibility to older OpenGL versions. // with forward compatibility to older OpenGL versions.
// For example, if using OpenGL 1.1, driver can provide a 3.3 context fordward compatible. // 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 glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0
TraceLog(INFO, "Trying to enable MSAA x4"); 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_MAJOR, 3); // Choose OpenGL major version (just hint)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor 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! 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) if (fullscreen)
{ {
// 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++)
{
if (modes[i].width >= screenWidth)
{
if (modes[i].height >= screenHeight)
{
displayWidth = modes[i].width;
displayHeight = modes[i].height;
break;
}
}
}
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 // At this point we need to manage render size vs screen size
// NOTE: This function uses and modifies global module variables: // NOTE: This function uses and modifies global module variables:
// screenWidth/screenHeight - renderWidth/renderHeight - downscaleView // screenWidth/screenHeight - renderWidth/renderHeight - downscaleView
SetupFramebufferSize(displayWidth, displayHeight); SetupFramebufferSize(displayWidth, displayHeight);
// TODO: SetupFramebufferSize() does not consider properly display video modes. window = glfwCreateWindow(displayWidth, displayHeight, windowTitle, glfwGetPrimaryMonitor(), NULL);
// 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.
int count; // NOTE: Full-screen change, not working properly...
const GLFWvidmode *modes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); //glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
for (int i = 0; i < count; i++)
{
// TODO: Check modes[i]->width;
// TODO: Check modes[i]->height;
}
window = glfwCreateWindow(screenWidth, screenHeight, windowTitle, glfwGetPrimaryMonitor(), NULL);
} }
else else
{ {
@ -1738,13 +1764,21 @@ static void InitDisplay(int width, int height)
TraceLog(INFO, "Viewport offsets: %i, %i", renderOffsetX, renderOffsetY); TraceLog(INFO, "Viewport offsets: %i, %i", renderOffsetX, renderOffsetY);
} }
#endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) #endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
}
// Initialize OpenGL graphics // Initialize OpenGL context (states and resources)
static void InitGraphics(void) rlglInit(screenWidth, screenHeight);
{
rlglInit(); // Init rlgl // Initialize screen viewport (area of the screen that you will actually draw to)
rlglInitGraphics(renderOffsetX, renderOffsetY, renderWidth, renderHeight); // Init graphics (OpenGL stuff) // 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 ClearBackground(RAYWHITE); // Default background color for raylib games :P
@ -1754,13 +1788,9 @@ static void InitGraphics(void)
} }
// Compute framebuffer size relative to screen size and display size // 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) 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) // Calculate renderWidth and renderHeight, we have the display size (input params) and the desired screen size (global var)
if ((screenWidth > displayWidth) || (screenHeight > displayHeight)) if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
{ {
@ -2109,8 +2139,14 @@ static void CursorEnterCallback(GLFWwindow *window, int enter)
// NOTE: Window resizing not allowed by default // NOTE: Window resizing not allowed by default
static void WindowSizeCallback(GLFWwindow *window, int width, int height) static void WindowSizeCallback(GLFWwindow *window, int width, int height)
{ {
// If window is resized, graphics device is re-initialized (but only ortho mode) // If window is resized, viewport and projection matrix needs to be re-calculated
rlglInitGraphics(0, 0, width, height); 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()) // Window size must be updated to be used on 3D mode to get new aspect ratio (Begin3dMode())
screenWidth = width; screenWidth = width;
@ -2119,9 +2155,6 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
renderHeight = height; renderHeight = height;
// NOTE: Postprocessing texture is not scaled to new size // 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 // GLFW3 WindowIconify Callback, runs when window is minimized/restored
@ -2188,11 +2221,8 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
} }
else else
{ {
// Init device display (monitor, LCD, ...) // Init graphics device (display device and OpenGL context)
InitDisplay(screenWidth, screenHeight); InitGraphicsDevice(screenWidth, screenHeight);
// Init OpenGL graphics
InitGraphics();
// Load default font for convenience // Load default font for convenience
// NOTE: External function (defined in module: text) // NOTE: External function (defined in module: text)
@ -2645,7 +2675,7 @@ static void *MouseThread(void *arg)
int mouseRelX = 0; int mouseRelX = 0;
int mouseRelY = 0; int mouseRelY = 0;
while(1) while (!windowShouldClose)
{ {
if (read(mouseStream, &mouse, sizeof(MouseEvent)) == (int)sizeof(MouseEvent)) if (read(mouseStream, &mouse, sizeof(MouseEvent)) == (int)sizeof(MouseEvent))
{ {
@ -2735,7 +2765,7 @@ static void *GamepadThread(void *arg)
// Read gamepad event // Read gamepad event
struct js_event gamepadEvent; struct js_event gamepadEvent;
while (1) while (!windowShouldClose)
{ {
for (int i = 0; i < MAX_GAMEPADS; i++) for (int i = 0; i < MAX_GAMEPADS; i++)
{ {
@ -2770,7 +2800,7 @@ static void *GamepadThread(void *arg)
return NULL; return NULL;
} }
#endif #endif // PLATFORM_RPI
// Plays raylib logo appearing animation // Plays raylib logo appearing animation
static void LogoAnimation(void) static void LogoAnimation(void)

View File

@ -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 // Normalized linear interpolation of quaternions
// NOTE: This function is a bad approximation of Slerp() // NOTE: This function is a bad approximation of Slerp()
// when the angle between the *this and b is large. // when the angle between the *this and b is large.
@ -1500,7 +1519,7 @@ public:
Quat Slerp(const Quat& b, T s) const Quat Slerp(const Quat& b, T s) const
{ {
Vector3<T> delta = (b * this->Inverted()).ToRotationVector(); 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 // Spherical linear interpolation: much faster for small rotations, accurate for large rotations. See FastTo/FromRotationVector

View File

@ -493,7 +493,7 @@ typedef enum ovrStatusBits_
/// Specifies the description of a single sensor. /// Specifies the description of a single sensor.
/// ///
/// \see ovrGetTrackerDesc /// \see ovr_GetTrackerDesc
/// ///
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTrackerDesc_ typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTrackerDesc_
{ {
@ -665,6 +665,18 @@ typedef enum ovrTextureFormat_
OVR_FORMAT_D32_FLOAT, OVR_FORMAT_D32_FLOAT,
OVR_FORMAT_D32_FLOAT_S8X24_UINT, 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. OVR_FORMAT_ENUMSIZE = 0x7fffffff ///< \internal Force type int32_t.
} ovrTextureFormat; } ovrTextureFormat;
@ -779,18 +791,20 @@ typedef enum ovrTouch_
ovrTouch_A = ovrButton_A, ovrTouch_A = ovrButton_A,
ovrTouch_B = ovrButton_B, ovrTouch_B = ovrButton_B,
ovrTouch_RThumb = ovrButton_RThumb, ovrTouch_RThumb = ovrButton_RThumb,
ovrTouch_RThumbRest = 0x00000008,
ovrTouch_RIndexTrigger = 0x00000010, ovrTouch_RIndexTrigger = 0x00000010,
// Bit mask of all the button touches on the right controller // 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_X = ovrButton_X,
ovrTouch_Y = ovrButton_Y, ovrTouch_Y = ovrButton_Y,
ovrTouch_LThumb = ovrButton_LThumb, ovrTouch_LThumb = ovrButton_LThumb,
ovrTouch_LThumbRest = 0x00000800,
ovrTouch_LIndexTrigger = 0x00001000, ovrTouch_LIndexTrigger = 0x00001000,
// Bit mask of all the button touches on the left controller // 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 // Finger pose state
// Derived internally based on distance, proximity to sensors and filtering. // Derived internally based on distance, proximity to sensors and filtering.
@ -959,36 +973,6 @@ extern "C" {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// ***** API Interfaces // ***** 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 /// Initializes LibOVR
/// ///
/// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT /// 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); 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 /// @name HMD Management
/// ///
@ -1153,7 +1166,7 @@ OVR_PUBLIC_FUNCTION(ovrTrackerDesc) ovr_GetTrackerDesc(ovrSession session, unsig
/// Creates a handle to a VR session. /// 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. /// 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] 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 /// \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 /// 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. /// 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 /// \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> /// <b>Example code</b>
/// \code{.cpp} /// \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); 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. /// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
/// \see 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. /// ovrTrackingState value. Use 0 to request the most recent tracking state.
/// \param[in] latencyMarker Specifies that this call is the point in time where /// \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 /// 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. /// \return Returns the ovrTrackingState that is predicted for the given absTime.
/// ///
/// \see ovrTrackingState, ovr_GetEyePoses, ovr_GetTimeInSeconds /// \see ovrTrackingState, ovr_GetEyePoses, ovr_GetTimeInSeconds
@ -1363,12 +1376,11 @@ OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetConnectedControllerTypes(ovrSession ses
/// ///
/// \see ovrControllerType /// \see ovrControllerType
/// ///
OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetControllerVibration(ovrSession session, ovrControllerType controllerType, OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetControllerVibration(ovrSession session, ovrControllerType controllerType, float frequency, float amplitude);
float frequency, float amplitude);
///@} ///@}
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// @name Layers // @name Layers
// //
@ -1768,7 +1780,7 @@ OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovr_GetRenderDesc(ovrSession session,
/// ovrLayerQuad layer1; /// ovrLayerQuad layer1;
/// ... /// ...
/// ovrLayerHeader* layers[2] = { &layer0.Header, &layer1.Header }; /// 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 /// \endcode
/// ///
/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true /// \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: /// App can toggle performance HUD modes as such:
/// \code{.cpp} /// \code{.cpp}
/// ovrPerfHudMode PerfHudMode = ovrPerfHud_LatencyTiming; /// ovrPerfHudMode PerfHudMode = ovrPerfHud_LatencyTiming;
/// ovr_SetInt(Hmd, OVR_PERF_HUD_MODE, (int)PerfHudMode); /// ovr_SetInt(session, OVR_PERF_HUD_MODE, (int)PerfHudMode);
/// \endcode /// \endcode
/// ///
typedef enum ovrPerfHudMode_ typedef enum ovrPerfHudMode_
@ -1864,7 +1876,7 @@ typedef enum ovrPerfHudMode_
/// App can toggle layer HUD modes as such: /// App can toggle layer HUD modes as such:
/// \code{.cpp} /// \code{.cpp}
/// ovrLayerHudMode LayerHudMode = ovrLayerHud_Info; /// ovrLayerHudMode LayerHudMode = ovrLayerHud_Info;
/// ovr_SetInt(Hmd, OVR_LAYER_HUD_MODE, (int)LayerHudMode); /// ovr_SetInt(session, OVR_LAYER_HUD_MODE, (int)LayerHudMode);
/// \endcode /// \endcode
/// ///
typedef enum ovrLayerHudMode_ typedef enum ovrLayerHudMode_
@ -1885,7 +1897,7 @@ typedef enum ovrLayerHudMode_
/// App can toggle the debug HUD modes as such: /// App can toggle the debug HUD modes as such:
/// \code{.cpp} /// \code{.cpp}
/// ovrDebugHudStereoMode DebugHudMode = ovrDebugHudStereo_QuadWithCrosshair; /// 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 /// \endcode
/// ///
/// The app can modify the visual properties of the stereo guide (i.e. quad, crosshair) /// 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. /// \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. /// \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 /// 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, OVR_PUBLIC_FUNCTION(const char*) ovr_GetString(ovrSession session, const char* propertyName,
const char* defaultVal); const char* defaultVal);

View File

@ -9,6 +9,10 @@
#define OVR_CAPI_Audio_h #define OVR_CAPI_Audio_h
#ifdef _WIN32 #ifdef _WIN32
// Prevents <Windows.h> from defining min() and max() macro symbols.
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h> #include <windows.h>
#include "OVR_CAPI.h" #include "OVR_CAPI.h"
#define OVR_AUDIO_MAX_DEVICE_STR_SIZE 128 #define OVR_AUDIO_MAX_DEVICE_STR_SIZE 128

View File

@ -25,7 +25,7 @@
/// \param[in] desc Specifies requested texture properties. See notes for more info about texture format. /// \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[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. /// \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 /// \return Returns an ovrResult indicating success or failure. In the case of failure, use
/// ovr_GetLastErrorInfo to get more information. /// 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. /// 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[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. /// \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 /// \return Returns an ovrResult indicating success or failure. In the case of failure, use
/// ovr_GetLastErrorInfo to get more information. /// ovr_GetLastErrorInfo to get more information.

View File

@ -15,7 +15,7 @@
/// \param[in] desc Specifies the requested texture properties. See notes for more info about texture format. /// \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 /// \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 /// 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 /// \return Returns an ovrResult indicating success or failure. In the case of failure, use
/// ovr_GetLastErrorInfo to get more information. /// 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] session Specifies an ovrSession previously returned by ovr_Create.
/// \param[in] desc Specifies the requested mirror texture description. /// \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. /// \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 /// \return Returns an ovrResult indicating success or failure. In the case of failure, use
/// ovr_GetLastErrorInfo to get more information. /// ovr_GetLastErrorInfo to get more information.

View File

@ -14,9 +14,6 @@
#ifndef OVR_RESULT_DEFINED #ifndef OVR_RESULT_DEFINED
#define OVR_RESULT_DEFINED ///< Allows ovrResult to be independently defined. #define OVR_RESULT_DEFINED ///< Allows ovrResult to be independently defined.
/// API call results are represented at the highest level by a single ovrResult. /// 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. /// This is a general success result. Use OVR_SUCCESS to test for success.
ovrSuccess = 0, 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 /// 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 /// rendered will not be visible on the HMD. Ideally the app should continue
/// calling SubmitFrame, but not do any rendering. When the result becomes /// calling SubmitFrame, but not do any rendering. When the result becomes
/// ovrSuccess, rendering should continue as usual. /// ovrSuccess, rendering should continue as usual.
ovrSuccess_NotVisible = 1000, ovrSuccess_NotVisible = 1000,
ovrSuccess_HMDFirmwareMismatch = 4100, ///< The HMD Firmware is out of date but is acceptable. } ovrSuccessTypes;
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
// Public error types
typedef enum ovrErrorType_ typedef enum ovrErrorType_
{ {
/* General errors */ /* General errors */
ovrError_MemoryAllocationFailure = -1000, ///< Failure to allocate memory. ovrError_MemoryAllocationFailure = -1000, ///< Failure to allocate memory.
ovrError_SocketCreationFailure = -1001, ///< Failure to create a socket.
ovrError_InvalidSession = -1002, ///< Invalid ovrSession parameter provided. ovrError_InvalidSession = -1002, ///< Invalid ovrSession parameter provided.
ovrError_Timeout = -1003, ///< The operation timed out. ovrError_Timeout = -1003, ///< The operation timed out.
ovrError_NotInitialized = -1004, ///< The system or component has not been initialized. 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. ovrError_ServiceDeadlockDetected = -1014, ///< The service watchdog discovered a deadlock.
/* Audio error range, reserved for Audio errors. */ /* Audio error range, reserved for Audio errors. */
ovrError_AudioReservedBegin = -2000, ///< First Audio error.
ovrError_AudioDeviceNotFound = -2001, ///< Failure to find the specified audio device. ovrError_AudioDeviceNotFound = -2001, ///< Failure to find the specified audio device.
ovrError_AudioComError = -2002, ///< Generic COM error. ovrError_AudioComError = -2002, ///< Generic COM error.
ovrError_AudioReservedEnd = -2999, ///< Last Audio error.
/* Initialization errors. */ /* Initialization errors. */
ovrError_Initialize = -3000, ///< Generic initialization error. ovrError_Initialize = -3000, ///< Generic initialization error.
@ -122,51 +116,6 @@ typedef enum ovrErrorType_
ovrError_DisplayManagerInit = -3019, ///< Initialization of the DisplayManager failed. ovrError_DisplayManagerInit = -3019, ///< Initialization of the DisplayManager failed.
ovrError_TrackerDriverInit = -3020, ///< Failed to get the interface for an attached tracker 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 */ /* Rendering errors */
ovrError_DisplayLost = -6000, ///< In the event of a system-wide graphics reset or cable unplug this is returned to the app. 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. 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_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; } 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. 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; } ovrErrorInfo;
#endif /* OVR_ErrorCode_h */ #endif /* OVR_ErrorCode_h */

View File

@ -19,7 +19,7 @@
// Master version numbers // Master version numbers
#define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning. #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_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_PATCH_VERSION 0
#define OVR_BUILD_NUMBER 0 #define OVR_BUILD_NUMBER 0

Binary file not shown.

View File

@ -40,7 +40,7 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#define CUBIC_MAP_HALF_BLOCK_SIZE 0.5 // ...
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
@ -808,13 +808,6 @@ void UnloadMaterial(Material material)
rlDeleteTextures(material.texSpecular.id); 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 // Generate a mesh from heightmap
static Mesh GenMeshHeightmap(Image heightmap, Vector3 size) static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
{ {
@ -1549,8 +1542,11 @@ BoundingBox CalculateBoundingBox(Mesh mesh)
// Detect and resolve cubicmap collisions // Detect and resolve cubicmap collisions
// NOTE: player position (or camera) is modified inside this function // 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) Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius)
{ {
#define CUBIC_MAP_HALF_BLOCK_SIZE 0.5
Color *cubicmapPixels = GetImageData(cubicmap); Color *cubicmapPixels = GetImageData(cubicmap);
// Detect the cell where the player is located // 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); locationCellX = floor(playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE);
locationCellY = floor(playerPosition->z - mapPosition.z + 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 -------------------------------------------------------------------------------------------- // Multiple Axis --------------------------------------------------------------------------------------------
// Axis x-, y- // Axis x-, y-
if (locationCellX > 0 && locationCellY > 0) if ((locationCellX > 0) && (locationCellY > 0))
{ {
if ((cubicmapPixels[locationCellY * 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)].r != 0))
{ {
if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < 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+ // 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) && if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0) &&
(cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0)) (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0))
{ {
if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - 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- // 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) && if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) &&
(cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0)) (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0))
{ {
if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < 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+ // 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) && if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) &&
(cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0)) (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0))
{ {
if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && 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)) ((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- // Axis x-
if (locationCellX > 0) 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) 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+ // Axis x+
if (locationCellX < cubicmap.width - 1) 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) 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- // Axis y-
if (locationCellY > 0) 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) 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+ // Axis y+
if (locationCellY < cubicmap.height - 1) 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) 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 ------------------------------------------------------------------------------------------------------- // Diagonals -------------------------------------------------------------------------------------------------------
// Axis x-, y- // Axis x-, y-
if (locationCellX > 0 && locationCellY > 0) if ((locationCellX > 0) && (locationCellY > 0))
{ {
if ((cubicmapPixels[locationCellY * 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)].r == 0) &&
(cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX - 1)].r != 0)) (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX - 1)].r != 0))
{ {
if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < 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+ // 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) && if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r == 0) &&
(cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r == 0) && (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r == 0) &&
(cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX - 1)].r != 0)) (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX - 1)].r != 0))
{ {
if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - 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- // 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) && if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r == 0) &&
(cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r == 0) && (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r == 0) &&
(cubicmapPixels[(locationCellY - 1) * cubicmap.width + (locationCellX + 1)].r != 0)) (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX + 1)].r != 0))
{ {
if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < 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+ // 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) && if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r == 0) &&
(cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r == 0) && (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r == 0) &&
(cubicmapPixels[(locationCellY + 1) * cubicmap.width + (locationCellX + 1)].r != 0)) (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX + 1)].r != 0))
{ {
if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && 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)) ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))

View File

@ -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 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) Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
void UnloadModel(Model model); // Unload 3d model from memory 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 LoadMaterial(const char *fileName); // Load material data (from file)
Material LoadDefaultMaterial(void); // Load default material (uses default models shader) 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 InitOculusDevice(void); // Init Oculus Rift device
void CloseOculusDevice(void); // Close Oculus Rift device void CloseOculusDevice(void); // Close Oculus Rift device
void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) 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 BeginOculusDrawing(void); // Begin Oculus drawing configuration
void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) 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) // Audio Loading and Playing Functions (Module: audio)

View File

@ -31,6 +31,7 @@
#include <stdio.h> // Required for: fopen(), fclose(), fread()... [Used only on ReadTextFile()] #include <stdio.h> // Required for: fopen(), fclose(), fread()... [Used only on ReadTextFile()]
#include <stdlib.h> // Required for: malloc(), free(), rand() #include <stdlib.h> // Required for: malloc(), free(), rand()
#include <string.h> // Required for: strcmp(), strlen(), strtok() #include <string.h> // Required for: strcmp(), strlen(), strtok()
#include <math.h> // Required for: atan()
#ifndef RLGL_STANDALONE #ifndef RLGL_STANDALONE
#include "raymath.h" // Required for Vector3 and Matrix functions #include "raymath.h" // Required for Vector3 and Matrix functions
@ -44,6 +45,10 @@
#endif #endif
#endif #endif
#if defined(GRAPHICS_API_OPENGL_21)
#define GRAPHICS_API_OPENGL_33
#endif
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX #include <OpenGL/gl3.h> // OpenGL 3 library for OSX
@ -68,10 +73,11 @@
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()]
#endif #endif
#if !defined(GRAPHICS_API_OPENGL_11) #if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_STANDARD_SHADER)
#include "standard_shader.h" // Standard shader to embed #include "standard_shader.h" // Standard shader to embed
#endif #endif
//#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code
#if defined(RLGL_OCULUS_SUPPORT) #if defined(RLGL_OCULUS_SUPPORT)
#include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL #include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
#endif #endif
@ -130,6 +136,12 @@
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2)
#define glClearDepth glClearDepthf
#define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER
#define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER
#endif
// Default vertex attribute names on shader to set location points // Default vertex attribute names on shader to set location points
#define DEFAULT_ATTRIB_POSITION_NAME "vertexPosition" // shader-location = 0 #define DEFAULT_ATTRIB_POSITION_NAME "vertexPosition" // shader-location = 0
#define DEFAULT_ATTRIB_TEXCOORD_NAME "vertexTexCoord" // shader-location = 1 #define DEFAULT_ATTRIB_TEXCOORD_NAME "vertexTexCoord" // shader-location = 1
@ -235,7 +247,7 @@ static bool useTempBuffer = false;
static Shader defaultShader; static Shader defaultShader;
static Shader standardShader; // Lazy initialization when GetStandardShader() static Shader standardShader; // Lazy initialization when GetStandardShader()
static Shader currentShader; // By default, defaultShader static Shader currentShader; // By default, defaultShader
static bool standardShaderLoaded = false; static bool standardShaderLoaded = false; // Flag to track if standard shader has been loaded
// Flags for supported extensions // Flags for supported extensions
static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension) static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension)
@ -262,6 +274,14 @@ static OculusMirror mirror; // Oculus mirror texture and fbo
static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain
#endif #endif
static bool oculusReady = false; // Oculus device ready flag
static bool oculusSimulator = false; // Oculus device simulator
static bool vrEnabled = false; // VR experience enabled (Oculus device or simulator)
static bool vrControl = true; // VR controlled by user code, instead of internally
static RenderTexture2D stereoFbo;
static Shader distortionShader;
// Compressed textures support flags // Compressed textures support flags
static bool texCompDXTSupported = false; // DDS texture compression support static bool texCompDXTSupported = false; // DDS texture compression support
static bool npotSupported = false; // NPOT textures full support static bool npotSupported = false; // NPOT textures full support
@ -274,11 +294,15 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
//static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted //static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted
#endif #endif
static int blendMode = 0; static int blendMode = 0; // Track current blending mode
// White texture useful for plain color polys (required by shader) // White texture useful for plain color polys (required by shader)
static unsigned int whiteTexture; static unsigned int whiteTexture;
// Default framebuffer size (required by Oculus device)
static int screenWidth; // Default framebuffer width
static int screenHeight; // Default framebuffer height
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -294,15 +318,18 @@ static void UnloadStandardShader(void); // Unload standard shader
static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads) static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads)
static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data
static void DrawDefaultBuffers(void); // Draw default internal buffers vertex data static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers vertex data
static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU
// Set internal projection and modelview matrix depending on eyes tracking data
static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView);
static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array
static char *ReadTextFile(const char *fileName); static char *ReadTextFile(const char *fileName);
#endif #endif
#if defined(RLGL_OCULUS_SUPPORT) // Oculus Rift functions #if defined(RLGL_OCULUS_SUPPORT)
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers
static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers
@ -465,7 +492,8 @@ void rlOrtho(double left, double right, double bottom, double top, double near,
#endif #endif
// Set the viewport area (trasnformation from normalized device coordinates to window coordinates) // Set the viewport area (transformation from normalized device coordinates to window coordinates)
// NOTE: Updates global variables: screenWidth, screenHeight
void rlViewport(int x, int y, int width, int height) void rlViewport(int x, int y, int width, int height)
{ {
glViewport(x, y, width, height); glViewport(x, y, width, height);
@ -857,6 +885,8 @@ void rlDeleteRenderTextures(RenderTexture2D target)
if (target.id != 0) glDeleteFramebuffers(1, &target.id); if (target.id != 0) glDeleteFramebuffers(1, &target.id);
if (target.texture.id != 0) glDeleteTextures(1, &target.texture.id); if (target.texture.id != 0) glDeleteTextures(1, &target.texture.id);
if (target.depth.id != 0) glDeleteTextures(1, &target.depth.id); if (target.depth.id != 0) glDeleteTextures(1, &target.depth.id);
TraceLog(INFO, "[FBO ID %i] Unloaded render texture data from VRAM (GPU)", target.id);
#endif #endif
} }
@ -916,6 +946,8 @@ int rlGetVersion(void)
{ {
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
return OPENGL_11; return OPENGL_11;
#elif defined(GRAPHICS_API_OPENGL_21)
return OPENGL_21;
#elif defined(GRAPHICS_API_OPENGL_33) #elif defined(GRAPHICS_API_OPENGL_33)
return OPENGL_33; return OPENGL_33;
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
@ -927,8 +959,8 @@ int rlGetVersion(void)
// Module Functions Definition - rlgl Functions // Module Functions Definition - rlgl Functions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Init OpenGL 3.3+ required data // Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states
void rlglInit(void) void rlglInit(int width, int height)
{ {
// Check OpenGL information and capabilities // Check OpenGL information and capabilities
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1074,18 +1106,7 @@ void rlglInit(void)
// Initialize buffers, default shaders and default textures // Initialize buffers, default shaders and default textures
//---------------------------------------------------------- //----------------------------------------------------------
// Set default draw mode // Init default white texture
currentDrawMode = RL_TRIANGLES;
// Reset projection and modelview matrices
projection = MatrixIdentity();
modelview = MatrixIdentity();
currentMatrix = &modelview;
// Initialize matrix stack
for (int i = 0; i < MATRIX_STACK_SIZE; i++) stack[i] = MatrixIdentity();
// Create default white texture for plain colors (required by shader)
unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes)
whiteTexture = rlglLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1); whiteTexture = rlglLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1);
@ -1097,7 +1118,8 @@ void rlglInit(void)
defaultShader = LoadDefaultShader(); defaultShader = LoadDefaultShader();
currentShader = defaultShader; currentShader = defaultShader;
LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads) // Init default vertex arrays buffers (lines, triangles, quads)
LoadDefaultBuffers();
// Init temp vertex buffer, used when transformation required (translate, rotate, scale) // Init temp vertex buffer, used when transformation required (translate, rotate, scale)
tempBuffer = (Vector3 *)malloc(sizeof(Vector3)*TEMP_VERTEX_BUFFER_SIZE); tempBuffer = (Vector3 *)malloc(sizeof(Vector3)*TEMP_VERTEX_BUFFER_SIZE);
@ -1115,7 +1137,50 @@ void rlglInit(void)
drawsCounter = 1; drawsCounter = 1;
draws[drawsCounter - 1].textureId = whiteTexture; draws[drawsCounter - 1].textureId = whiteTexture;
currentDrawMode = RL_TRIANGLES; // Set default draw mode
// Init internal matrix stack (emulating OpenGL 1.1)
for (int i = 0; i < MATRIX_STACK_SIZE; i++) stack[i] = MatrixIdentity();
// Init internal projection and modelview matrices
projection = MatrixIdentity();
modelview = MatrixIdentity();
currentMatrix = &modelview;
#endif // defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Initialize OpenGL default states
//----------------------------------------------------------
// Init state: Depth test
glDepthFunc(GL_LEQUAL); // Type of depth testing to apply
glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D)
// Init state: Blending mode
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed)
glEnable(GL_BLEND); // Enable color blending (required to work with transparencies)
// Init state: Culling
// NOTE: All shapes/models triangles are drawn CCW
glCullFace(GL_BACK); // Cull the back face (default)
glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
glEnable(GL_CULL_FACE); // Enable backface culling
#if defined(GRAPHICS_API_OPENGL_11)
// Init state: Color hints (deprecated in OpenGL 3.0+)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation
glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation)
#endif #endif
// Init state: Color/Depth buffers clear
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black)
glClearDepth(1.0f); // Set clear depth value (default)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D)
// Store screen size into global variables
screenWidth = width;
screenHeight = height;
TraceLog(INFO, "OpenGL default states initialized successfully");
} }
// Vertex Buffer Object deinitialization (memory free) // Vertex Buffer Object deinitialization (memory free)
@ -1145,76 +1210,32 @@ void rlglClose(void)
void rlglDraw(void) void rlglDraw(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
/* // NOTE: In a future version, models could be stored in a stack...
for (int i = 0; i < modelsCount; i++) //for (int i = 0; i < modelsCount; i++) rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform);
{
rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform); // NOTE: Default buffers upload and draw
}
*/
// NOTE: Default buffers always drawn at the end
UpdateDefaultBuffers(); UpdateDefaultBuffers();
DrawDefaultBuffers();
if (vrEnabled && vrControl) DrawDefaultBuffers(2);
else DrawDefaultBuffers(1);
#endif #endif
} }
// Initialize Graphics Device (OpenGL stuff)
// NOTE: Stores global variables screenWidth and screenHeight
void rlglInitGraphics(int offsetX, int offsetY, int width, int height)
{
// NOTE: Required! viewport must be recalculated if screen resized!
glViewport(offsetX/2, offsetY/2, width - offsetX, height - offsetY); // Set viewport width and height
// NOTE: Don't confuse glViewport with the transformation matrix
// NOTE: glViewport just defines the area of the context that you will actually draw to.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black)
//glClearDepth(1.0f); // Clear depth buffer (default)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D
glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D)
glDepthFunc(GL_LEQUAL); // Type of depth testing to apply
glEnable(GL_BLEND); // Enable color blending (required to work with transparencies)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed)
#if defined(GRAPHICS_API_OPENGL_11)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation (Deprecated in OGL 3.0)
// Other options: GL_FASTEST, GL_DONT_CARE (default)
#endif
rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix
rlLoadIdentity(); // Reset current matrix (PROJECTION)
rlOrtho(0, width - offsetX, height - offsetY, 0, 0.0f, 1.0f); // Config orthographic mode: top-left corner --> (0,0)
rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
// NOTE: All shapes/models triangles are drawn CCW
glEnable(GL_CULL_FACE); // Enable backface culling (Disabled by default)
//glCullFace(GL_BACK); // Cull the Back face (default)
//glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
#if defined(GRAPHICS_API_OPENGL_11)
glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) (Deprecated on OpenGL 3.3+)
// Possible options: GL_SMOOTH (Color interpolation) or GL_FLAT (no interpolation)
#endif
TraceLog(INFO, "OpenGL graphic device initialized successfully");
}
// Load OpenGL extensions // Load OpenGL extensions
// NOTE: External loader function could be passed as a pointer // NOTE: External loader function could be passed as a pointer
void rlglLoadExtensions(void *loader) void rlglLoadExtensions(void *loader)
{ {
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33)
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions");
else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully");
if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); #if defined(GRAPHICS_API_OPENGL_21)
if (GLAD_GL_VERSION_2_1) TraceLog(INFO, "OpenGL 2.1 profile supported");
#elif defined(GRAPHICS_API_OPENGL_33)
if(GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported");
else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported"); else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
#endif
// With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans // With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
//if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object //if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object
@ -1629,7 +1650,7 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic)
if (dynamic) drawHint = GL_DYNAMIC_DRAW; if (dynamic) drawHint = GL_DYNAMIC_DRAW;
GLuint vaoId = 0; // Vertex Array Objects (VAO) GLuint vaoId = 0; // Vertex Array Objects (VAO)
GLuint vboId[7]; // Vertex Buffer Objects (VBOs) GLuint vboId[7] = { 0 }; // Vertex Buffer Objects (VBOs)
if (vaoSupported) if (vaoSupported)
{ {
@ -1725,7 +1746,6 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*mesh->triangleCount*3, mesh->indices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*mesh->triangleCount*3, mesh->indices, GL_STATIC_DRAW);
} }
mesh->vboId[0] = vboId[0]; // Vertex position VBO mesh->vboId[0] = vboId[0]; // Vertex position VBO
mesh->vboId[1] = vboId[1]; // Texcoords VBO mesh->vboId[1] = vboId[1]; // Texcoords VBO
mesh->vboId[2] = vboId[2]; // Normals VBO mesh->vboId[2] = vboId[2]; // Normals VBO
@ -1848,8 +1868,15 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
#endif #endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
int eyesCount = 1;
if (vrEnabled) eyesCount = 2;
glUseProgram(material.shader.id); glUseProgram(material.shader.id);
// Upload to shader material.colDiffuse
float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse);
// At this point the modelview matrix just contains the view matrix (camera) // At this point the modelview matrix just contains the view matrix (camera)
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() // That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
Matrix matView = modelview; // View matrix (camera) Matrix matView = modelview; // View matrix (camera)
@ -1858,16 +1885,6 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
// Calculate model-view matrix combining matModel and matView // Calculate model-view matrix combining matModel and matView
Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates
// Calculate model-view-projection matrix (MVP)
Matrix matMVP = MatrixMultiply(matModelView, matProjection); // Transform to screen-space coordinates
// Send combined model-view-projection matrix to shader
glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP));
// Upload to shader material.colDiffuse
float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse);
// Check if using standard shader to get location points // Check if using standard shader to get location points
// NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations) // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations)
if (material.shader.id == standardShader.id) if (material.shader.id == standardShader.id)
@ -1945,13 +1962,23 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
glEnableVertexAttribArray(material.shader.normalLoc); glEnableVertexAttribArray(material.shader.normalLoc);
} }
// Bind mesh VBO data: vertex colors (shader-location = 3, if available) , tangents, texcoords2 (if available) // Bind mesh VBO data: vertex colors (shader-location = 3, if available)
if (material.shader.colorLoc != -1) if (material.shader.colorLoc != -1)
{
if (mesh.vboId[3] != 0)
{ {
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]); glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]);
glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(material.shader.colorLoc); glEnableVertexAttribArray(material.shader.colorLoc);
} }
else
{
// Set default value for unused attribute
// NOTE: Required when using default shader and no VAO support
glVertexAttrib4f(material.shader.colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
glDisableVertexAttribArray(material.shader.colorLoc);
}
}
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available) // Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
if (material.shader.tangentLoc != -1) if (material.shader.tangentLoc != -1)
@ -1972,9 +1999,21 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]);
} }
for (int eye = 0; eye < eyesCount; eye++)
{
if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView);
else modelview = matModelView;
// Calculate model-view-projection matrix (MVP)
Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates
// Send combined model-view-projection matrix to shader
glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP));
// Draw call! // Draw call!
if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw
else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
}
if (material.texNormal.id != 0) if (material.texNormal.id != 0)
{ {
@ -1999,6 +2038,10 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
} }
glUseProgram(0); // Unbind shader program glUseProgram(0); // Unbind shader program
// Restore projection/modelview matrices
projection = matProjection;
modelview = matView;
#endif #endif
} }
@ -2314,7 +2357,7 @@ int GetShaderLocation(Shader shader, const char *uniformName)
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
location = glGetUniformLocation(shader.id, uniformName); location = glGetUniformLocation(shader.id, uniformName);
if (location == -1) TraceLog(WARNING, "[SHDR ID %i] Shader location for %s could not be found", shader.id, uniformName); if (location == -1) TraceLog(DEBUG, "[SHDR ID %i] Shader location for %s could not be found", shader.id, uniformName);
#endif #endif
return location; return location;
} }
@ -2461,22 +2504,28 @@ void DestroyLight(Light light)
#endif #endif
} }
#if defined(RLGL_OCULUS_SUPPORT) // Init Oculus Rift device (or Oculus device simulator)
// Init Oculus Rift device
// NOTE: Device initialization should be done before window creation?
void InitOculusDevice(void) void InitOculusDevice(void)
{ {
#if defined(RLGL_OCULUS_SUPPORT)
// Initialize Oculus device // Initialize Oculus device
ovrResult result = ovr_Initialize(NULL); ovrResult result = ovr_Initialize(NULL);
if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device"); if (OVR_FAILURE(result))
{
TraceLog(WARNING, "OVR: Could not initialize Oculus device");
oculusReady = false;
}
else
{
result = ovr_Create(&session, &luid); result = ovr_Create(&session, &luid);
if (OVR_FAILURE(result)) if (OVR_FAILURE(result))
{ {
TraceLog(WARNING, "OVR: Could not create Oculus session"); TraceLog(WARNING, "OVR: Could not create Oculus session");
ovr_Shutdown(); ovr_Shutdown();
oculusReady = false;
} }
else
{
hmdDesc = ovr_GetHmdDesc(session); hmdDesc = ovr_GetHmdDesc(session);
TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName);
@ -2497,21 +2546,74 @@ void InitOculusDevice(void)
// Recenter OVR tracking origin // Recenter OVR tracking origin
ovr_RecenterTrackingOrigin(session); ovr_RecenterTrackingOrigin(session);
oculusReady = true;
vrEnabled = true;
}
}
#else
oculusReady = false;
#endif
if (!oculusReady)
{
TraceLog(WARNING, "VR: Initializing Oculus simulator");
// Initialize framebuffer and textures for stereo rendering
stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight);
// Load oculus-distortion shader (oculus parameters setup internally)
// TODO: Embed coulus distortion shader (in this function like default shader?)
distortionShader = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs");
oculusSimulator = true;
vrEnabled = true;
}
} }
// Close Oculus Rift device // Close Oculus Rift device (or Oculus device simulator)
void CloseOculusDevice(void) void CloseOculusDevice(void)
{ {
#if defined(RLGL_OCULUS_SUPPORT)
if (oculusReady)
{
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
ovr_Destroy(session); // Free Oculus session data ovr_Destroy(session); // Free Oculus session data
ovr_Shutdown(); // Close Oculus device connection ovr_Shutdown(); // Close Oculus device connection
}
else
#endif
{
// Unload stereo framebuffer and texture
rlDeleteRenderTextures(stereoFbo);
// Unload oculus-distortion shader
UnloadShader(distortionShader);
}
oculusReady = false;
}
// Detect if oculus device is available
bool IsOculusReady(void)
{
return (oculusReady || oculusSimulator) && vrEnabled;
}
// Enable/Disable VR experience (Oculus device or simulator)
void ToggleVR(void)
{
vrEnabled = !vrEnabled;
} }
// Update Oculus Rift tracking (position and orientation) // Update Oculus Rift tracking (position and orientation)
void UpdateOculusTracking(void) void UpdateOculusTracking(void)
{ {
#if defined(RLGL_OCULUS_SUPPORT)
if (oculusReady)
{
frameIndex++; frameIndex++;
ovrPosef eyePoses[2]; ovrPosef eyePoses[2];
@ -2519,31 +2621,126 @@ void UpdateOculusTracking(void)
layer.eyeLayer.RenderPose[0] = eyePoses[0]; layer.eyeLayer.RenderPose[0] = eyePoses[0];
layer.eyeLayer.RenderPose[1] = eyePoses[1]; layer.eyeLayer.RenderPose[1] = eyePoses[1];
// Get session status information
ovrSessionStatus sessionStatus;
ovr_GetSessionStatus(session, &sessionStatus);
if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit...");
if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
//if (sessionStatus.HmdPresent) // HMD is present.
//if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR.
//if (sessionStatus.HmdMounted) // HMD is on the user's head.
//if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD.
}
else
#endif
{
// TODO: Use alternative inputs (mouse, keyboard) to simulate tracking data (eyes position/orientation)
}
} }
void SetOculusMatrix(int eye) // Set internal projection and modelview matrix depending on eyes tracking data
static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView)
{ {
rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); if (vrEnabled)
{
Matrix eyeProjection = matProjection;
Matrix eyeModelView = matModelView;
Quaternion eyeRPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, #if defined(RLGL_OCULUS_SUPPORT)
if (oculusReady)
{
rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y,
layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h);
Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x,
layer.eyeLayer.RenderPose[eye].Orientation.y, layer.eyeLayer.RenderPose[eye].Orientation.y,
layer.eyeLayer.RenderPose[eye].Orientation.z, layer.eyeLayer.RenderPose[eye].Orientation.z,
layer.eyeLayer.RenderPose[eye].Orientation.w }; layer.eyeLayer.RenderPose[eye].Orientation.w };
QuaternionInvert(&eyeRPose); QuaternionInvert(&eyeRenderPose);
Matrix eyeOrientation = QuaternionToMatrix(eyeRPose); Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose);
Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x,
-layer.eyeLayer.RenderPose[eye].Position.y, -layer.eyeLayer.RenderPose[eye].Position.y,
-layer.eyeLayer.RenderPose[eye].Position.z); -layer.eyeLayer.RenderPose[eye].Position.z);
Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement
Matrix modelEyeView = MatrixMultiply(modelview, eyeView); // Using internal camera modelview matrix eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement
SetMatrixModelview(modelEyeView); eyeProjection = layer.eyeProjections[eye];
SetMatrixProjection(layer.eyeProjections[eye]); }
else
#endif
{
// Setup viewport and projection/modelview matrices using tracking data
rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight);
static float IPD = 0.064f; // InterpupillaryDistance
float HScreenSize = 0.14976f;
float VScreenSize = 0.0936f; // HScreenSize/(1280.0f/800.0f)
float VScreenCenter = 0.04675f;
float EyeToScreenDistance = 0.041f;
float LensSeparationDistance = 0.064f; //0.0635f (DK1)
// NOTE: fovy value obtained from device parameters (Oculus Rift CV1)
float halfScreenDistance = VScreenSize/2.0f;
float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG;
float viewCenter = (float)HScreenSize*0.25f;
float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f;
float projectionCenterOffset = eyeProjectionShift/(float)HScreenSize; //4.0f*eyeProjectionShift/(float)HScreenSize;
/*
static float scale[2] = { 0.25, 0.45 };
if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01;
else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01;
else if (IsKeyDown(KEY_UP)) scale[1] += 0.01;
else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01;
SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2);
if (IsKeyDown(KEY_N)) IPD += 0.02;
else if (IsKeyDown(KEY_M)) IPD -= 0.02;
*/
// The matrixes for offsetting the projection and view for each eye, to achieve stereo effect
Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f };
// Camera movement might seem more natural if we model the head.
// Our axis of rotation is the base of our head, so we might want to add
// some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions.
Vector3 viewOffset = { -IPD/2.0f, 0.075f, 0.045f };
// Negate the left eye versions
if (eye == 0)
{
projectionOffset.x *= -1.0f;
viewOffset.x *= -1.0f;
}
// Adjust the view and projection matrixes
// View matrix is translated based on the eye offset
Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0);
Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z);
Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z);
eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection
eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview
MatrixTranspose(&eyeProjection);
}
SetMatrixModelview(eyeModelView); // ERROR! We are modifying modelview for next eye!!!
SetMatrixProjection(eyeProjection);
}
} }
// Begin Oculus drawing configuration
void BeginOculusDrawing(void) void BeginOculusDrawing(void)
{ {
#if defined(RLGL_OCULUS_SUPPORT)
if (oculusReady)
{
GLuint currentTexId; GLuint currentTexId;
int currentIndex; int currentIndex;
@ -2553,9 +2750,13 @@ void BeginOculusDrawing(void)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded
}
//glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) else
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Same as rlClearScreenBuffers() #endif
{
// Setup framebuffer for stereo rendering
rlEnableRenderTexture(stereoFbo.id);
}
// NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
// and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then: // and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
@ -2563,11 +2764,19 @@ void BeginOculusDrawing(void)
// - Do NOT enable GL_FRAMEBUFFER_SRGB // - Do NOT enable GL_FRAMEBUFFER_SRGB
//glEnable(GL_FRAMEBUFFER_SRGB); //glEnable(GL_FRAMEBUFFER_SRGB);
//glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
rlClearScreenBuffers(); // Clear current framebuffer(s) rlClearScreenBuffers(); // Clear current framebuffer(s)
vrControl = true;
} }
// End Oculus drawing process (and desktop mirror)
void EndOculusDrawing(void) void EndOculusDrawing(void)
{ {
#if defined(RLGL_OCULUS_SUPPORT)
if (oculusReady)
{
// Unbind current framebuffer (Oculus buffer)
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
@ -2578,14 +2787,65 @@ void EndOculusDrawing(void)
// Blit mirror texture to back buffer // Blit mirror texture to back buffer
BlitOculusMirror(session, mirror); BlitOculusMirror(session, mirror);
}
// Get session status information else
ovrSessionStatus sessionStatus;
ovr_GetSessionStatus(session, &sessionStatus);
if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit...");
if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
}
#endif #endif
{
// Unbind current framebuffer
rlDisableRenderTexture();
rlClearScreenBuffers(); // Clear current framebuffer
// Set viewport to default framebuffer size (screen size)
rlViewport(0, 0, screenWidth, screenHeight);
// Let rlgl reconfigure internal matrices
rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix
rlLoadIdentity(); // Reset internal projection matrix
rlOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix
// Draw RenderTexture (stereoFbo) using distortion shader
currentShader = distortionShader;
rlEnableTexture(stereoFbo.texture.id);
rlPushMatrix();
rlBegin(RL_QUADS);
rlColor4ub(255, 255, 255, 255);
rlNormal3f(0.0f, 0.0f, 1.0f);
// Bottom-left corner for texture and quad
rlTexCoord2f(0.0f, 1.0f);
rlVertex2f(0.0f, 0.0f);
// Bottom-right corner for texture and quad
rlTexCoord2f(0.0f, 0.0f);
rlVertex2f(0.0f, stereoFbo.texture.height);
// Top-right corner for texture and quad
rlTexCoord2f(1.0f, 0.0f);
rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height);
// Top-left corner for texture and quad
rlTexCoord2f(1.0f, 1.0f);
rlVertex2f(stereoFbo.texture.width, 0.0f);
rlEnd();
rlPopMatrix();
rlDisableTexture();
UpdateDefaultBuffers();
DrawDefaultBuffers(1);
currentShader = defaultShader;
}
rlDisableDepthTest();
vrControl = false;
}
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Definition // Module specific Functions Definition
@ -2746,20 +3006,25 @@ static Shader LoadDefaultShader(void)
Shader shader; Shader shader;
// Vertex shader directly defined, no external file required // Vertex shader directly defined, no external file required
#if defined(GRAPHICS_API_OPENGL_33) char vDefaultShaderStr[] =
char vShaderStr[] = "#version 330 \n" #if defined(GRAPHICS_API_OPENGL_21)
"in vec3 vertexPosition; \n" "#version 120 \n"
"in vec2 vertexTexCoord; \n"
"in vec4 vertexColor; \n"
"out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
char vShaderStr[] = "#version 100 \n" "#version 100 \n"
#endif
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
"attribute vec3 vertexPosition; \n" "attribute vec3 vertexPosition; \n"
"attribute vec2 vertexTexCoord; \n" "attribute vec2 vertexTexCoord; \n"
"attribute vec4 vertexColor; \n" "attribute vec4 vertexColor; \n"
"varying vec2 fragTexCoord; \n" "varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n" "varying vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
"#version 330 \n"
"in vec3 vertexPosition; \n"
"in vec2 vertexTexCoord; \n"
"in vec4 vertexColor; \n"
"out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n"
#endif #endif
"uniform mat4 mvpMatrix; \n" "uniform mat4 mvpMatrix; \n"
"void main() \n" "void main() \n"
@ -2770,31 +3035,36 @@ static Shader LoadDefaultShader(void)
"} \n"; "} \n";
// Fragment shader directly defined, no external file required // Fragment shader directly defined, no external file required
#if defined(GRAPHICS_API_OPENGL_33) char fDefaultShaderStr[] =
char fShaderStr[] = "#version 330 \n" #if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n"
"precision mediump float; \n" // precision required for OpenGL ES2 (WebGL)
#endif
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
"varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
"#version 330 \n"
"in vec2 fragTexCoord; \n" "in vec2 fragTexCoord; \n"
"in vec4 fragColor; \n" "in vec4 fragColor; \n"
"out vec4 finalColor; \n" "out vec4 finalColor; \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
char fShaderStr[] = "#version 100 \n"
"precision mediump float; \n" // precision required for OpenGL ES2 (WebGL)
"varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n"
#endif #endif
"uniform sampler2D texture0; \n" "uniform sampler2D texture0; \n"
"uniform vec4 colDiffuse; \n" "uniform vec4 colDiffuse; \n"
"void main() \n" "void main() \n"
"{ \n" "{ \n"
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
" vec4 texelColor = texture(texture0, fragTexCoord); \n"
" finalColor = texelColor*colDiffuse*fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
" vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0 " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0
" gl_FragColor = texelColor*colDiffuse*fragColor; \n" " gl_FragColor = texelColor*colDiffuse*fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
" vec4 texelColor = texture(texture0, fragTexCoord); \n"
" finalColor = texelColor*colDiffuse*fragColor; \n"
#endif #endif
"} \n"; "} \n";
shader.id = LoadShaderProgram(vShaderStr, fShaderStr); shader.id = LoadShaderProgram(vDefaultShaderStr, fDefaultShaderStr);
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Default shader loaded successfully", shader.id); if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Default shader loaded successfully", shader.id);
else TraceLog(WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id); else TraceLog(WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id);
@ -2813,6 +3083,7 @@ static Shader LoadStandardShader(void)
{ {
Shader shader; Shader shader;
#if !defined(RLGL_NO_STANDARD_SHADER)
// Load standard shader (embeded in standard_shader.h) // Load standard shader (embeded in standard_shader.h)
shader.id = LoadShaderProgram(vStandardShaderStr, fStandardShaderStr); shader.id = LoadShaderProgram(vStandardShaderStr, fStandardShaderStr);
@ -2828,6 +3099,10 @@ static Shader LoadStandardShader(void)
TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded, using default shader", shader.id); TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded, using default shader", shader.id);
shader = GetDefaultShader(); shader = GetDefaultShader();
} }
#else
shader = defaultShader;
TraceLog(WARNING, "[SHDR ID %i] Standard shader not available, using default shader", shader.id);
#endif
return shader; return shader;
} }
@ -2878,12 +3153,13 @@ static void UnloadDefaultShader(void)
static void UnloadStandardShader(void) static void UnloadStandardShader(void)
{ {
glUseProgram(0); glUseProgram(0);
#if !defined(RLGL_NO_STANDARD_SHADER)
//glDetachShader(defaultShader, vertexShader); //glDetachShader(defaultShader, vertexShader);
//glDetachShader(defaultShader, fragmentShader); //glDetachShader(defaultShader, fragmentShader);
//glDeleteShader(vertexShader); // Already deleted on shader compilation //glDeleteShader(vertexShader); // Already deleted on shader compilation
//glDeleteShader(fragmentShader); // Already deleted on shader compilation //glDeleteShader(fragmentShader); // Already deleted on shader compilation
glDeleteProgram(standardShader.id); glDeleteProgram(standardShader.id);
#endif
} }
@ -3009,7 +3285,7 @@ static void LoadDefaultBuffers(void)
glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers VAO initialized successfully (triangles)", triangles.vaoId); if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers VAO initialized successfully (triangles)", triangles.vaoId);
else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers VBOs initialized successfully(triangles)", triangles.vboId[0], triangles.vboId[1]); else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers VBOs initialized successfully (triangles)", triangles.vboId[0], triangles.vboId[1]);
// Upload and link quads vertex buffers // Upload and link quads vertex buffers
if (vaoSupported) if (vaoSupported)
@ -3131,8 +3407,15 @@ static void UpdateDefaultBuffers(void)
// Draw default internal buffers vertex data // Draw default internal buffers vertex data
// NOTE: We draw in this order: lines, triangles, quads // NOTE: We draw in this order: lines, triangles, quads
static void DrawDefaultBuffers(void) static void DrawDefaultBuffers(int eyesCount)
{ {
Matrix matProjection = projection;
Matrix matModelView = modelview;
for (int eye = 0; eye < eyesCount; eye++)
{
if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView);
// Set current shader and upload current MVP matrix // Set current shader and upload current MVP matrix
if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0))
{ {
@ -3247,11 +3530,11 @@ static void DrawDefaultBuffers(void)
glBindTexture(GL_TEXTURE_2D, draws[i].textureId); glBindTexture(GL_TEXTURE_2D, draws[i].textureId);
// NOTE: The final parameter tells the GPU the offset in bytes from the start of the index buffer to the location of the first index to process // NOTE: The final parameter tells the GPU the offset in bytes from the start of the index buffer to the location of the first index to process
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*indicesOffset)); glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*indicesOffset));
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*indicesOffset)); glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*indicesOffset));
#endif #endif
//GLenum err; //GLenum err;
//if ((err = glGetError()) != GL_NO_ERROR) TraceLog(INFO, "OpenGL error: %i", (int)err); //GL_INVALID_ENUM! //if ((err = glGetError()) != GL_NO_ERROR) TraceLog(INFO, "OpenGL error: %i", (int)err); //GL_INVALID_ENUM!
@ -3270,6 +3553,7 @@ static void DrawDefaultBuffers(void)
if (vaoSupported) glBindVertexArray(0); // Unbind VAO if (vaoSupported) glBindVertexArray(0); // Unbind VAO
glUseProgram(0); // Unbind shader program glUseProgram(0); // Unbind shader program
}
// Reset draws counter // Reset draws counter
drawsCounter = 1; drawsCounter = 1;
@ -3287,6 +3571,10 @@ static void DrawDefaultBuffers(void)
// Reset depth for next draw // Reset depth for next draw
currentDepth = -1.0f; currentDepth = -1.0f;
// Restore projection/modelview matrices
projection = matProjection;
modelview = matModelView;
} }
// Unload default internal buffers vertex data from CPU and GPU // Unload default internal buffers vertex data from CPU and GPU
@ -3682,7 +3970,10 @@ static void BlitOculusMirror(ovrSession session, OculusMirror mirror)
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId); glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0);
#if defined(GRAPHICS_API_OPENGL_33)
// NOTE: glBlitFramebuffer() requires extension: GL_EXT_framebuffer_blit (not available in OpenGL ES 2.0)
glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
#endif
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
} }

View File

@ -48,25 +48,31 @@
// Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33 // 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_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 //#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 // 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 #define GRAPHICS_API_OPENGL_11
#endif #endif
// Security check in case multiple GRAPHICS_API_OPENGL_* defined // Security check in case multiple GRAPHICS_API_OPENGL_* defined
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
#if defined(GRAPHICS_API_OPENGL_21)
#undef GRAPHICS_API_OPENGL_21
#endif
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
#undef GRAPHICS_API_OPENGL_33 #undef GRAPHICS_API_OPENGL_33
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
#undef GRAPHICS_API_OPENGL_ES2 #undef GRAPHICS_API_OPENGL_ES2
#endif #endif
#endif #endif
#if defined(GRAPHICS_API_OPENGL_21)
#define GRAPHICS_API_OPENGL_33
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // 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 { 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) #if defined(RLGL_STANDALONE)
#ifndef __cplusplus #ifndef __cplusplus
@ -292,10 +298,9 @@ int rlGetVersion(void); // Returns current OpenGL versio
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - rlgl functionality // 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 rlglClose(void); // De-init rlgl
void rlglDraw(void); // Draw VAO/VBO void rlglDraw(void); // Draw VAO/VBO
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
void rlglLoadExtensions(void *loader); // Load OpenGL extensions void rlglLoadExtensions(void *loader); // Load OpenGL extensions
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU 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, ...); void TraceLog(int msgType, const char *text, ...);
#endif #endif
#if defined(RLGL_OCULUS_SUPPORT)
void InitOculusDevice(void); // Init Oculus Rift device void InitOculusDevice(void); // Init Oculus Rift device
void CloseOculusDevice(void); // Close Oculus Rift device void CloseOculusDevice(void); // Close Oculus Rift device
void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) 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 BeginOculusDrawing(void); // Begin Oculus drawing configuration
void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) 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 #ifdef __cplusplus
} }

View File

@ -135,7 +135,7 @@ void DrawCircleV(Vector2 center, float radius, Color color)
} }
rlEnd(); 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 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); rlVertex2i(position.x + size.x, position.y);
rlEnd(); 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 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); rlVertex2i(posX + 1, posY + 1);
rlEnd(); 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, posY, width, 1, color);
DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color); DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color);

View File

@ -166,9 +166,9 @@ static const char fStandardShaderStr[] =
" else if(lights[i].type == 2) lighting += CalcSpotLight(lights[i], n, v, spec);\n" " else if(lights[i].type == 2) lighting += CalcSpotLight(lights[i], n, v, spec);\n"
" }\n" " }\n"
" }\n" " }\n"
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
" finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n"
#elif defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
" gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n" " 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 #endif
"}\n"; "}\n";

View File

@ -422,12 +422,7 @@ void UnloadTexture(Texture2D texture)
// Unload render texture from GPU memory // Unload render texture from GPU memory
void UnloadRenderTexture(RenderTexture2D target) void UnloadRenderTexture(RenderTexture2D target)
{ {
if (target.id != 0) if (target.id != 0) rlDeleteRenderTextures(target);
{
rlDeleteRenderTextures(target);
TraceLog(INFO, "[FBO ID %i] Unloaded render texture data from VRAM (GPU)", target.id);
}
} }
// Get pixel data from image in the form of Color struct array // Get pixel data from image in the form of Color struct array