diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/Makefile | 85 | ||||
| -rw-r--r-- | examples/audio_standalone.c | 2 | ||||
| -rw-r--r-- | examples/core_oculus_rift.c | 469 | ||||
| -rw-r--r-- | examples/text_ttf_loading.c | 2 |
4 files changed, 507 insertions, 51 deletions
diff --git a/examples/Makefile b/examples/Makefile index 98129990..22438f2f 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -5,15 +5,15 @@ # NOTE: By default examples are compiled using raylib static library and OpenAL Soft shared library # # Copyright (c) 2013-2016 Ramon Santamaria (@raysan5) -# -# This software is provided "as-is", without any express or implied warranty. In no event +# +# This software is provided "as-is", without any express or implied warranty. In no event # will the authors be held liable for any damages arising from the use of this software. # -# Permission is granted to anyone to use this software for any purpose, including commercial +# Permission is granted to anyone to use this software for any purpose, including commercial # applications, and to alter it and redistribute it freely, subject to the following restrictions: # -# 1. The origin of this software must not be misrepresented; you must not claim that you -# wrote the original software. If you use this software in a product, an acknowledgment +# 1. The origin of this software must not be misrepresented; you must not claim that you +# wrote the original software. If you use this software in a product, an acknowledgment # in the product documentation would be appreciated but is not required. # # 2. Altered source versions must be plainly marked as such, and must not be misrepresented @@ -66,21 +66,34 @@ endif endif # define compiler flags: -# -O2 defines optimization level -# -s strip unnecessary data from build -# -Wall turns on most, but not all, compiler warnings -# -std=c99 use standard C from 1999 revision -ifeq ($(PLATFORM),PLATFORM_RPI) - CFLAGS = -O2 -s -Wall -std=gnu99 -fgnu89-inline -else - CFLAGS = -O2 -s -Wall -std=c99 +# -O2 defines optimization level +# -Og enable debugging +# -s strip unnecessary data from build +# -Wall turns on most, but not all, compiler warnings +# -std=c99 defines C language mode (standard C from 1999 revision) +# -std=gnu99 defines C language mode (GNU C from 1999 revision) +# -fgnu89-inline declaring inline functions support (GCC optimized) +# -Wno-missing-braces ignore invalid warning (GCC bug 53119) +# -D_DEFAULT_SOURCE use with -std=c99 on Linux to enable timespec and drflac +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),WINDOWS) + CFLAGS = -O2 -s -Wall -std=c99 + endif + ifeq ($(PLATFORM_OS),LINUX) + CFLAGS = -O2 -s -Wall -std=c99 -D_DEFAULT_SOURCE + endif + ifeq ($(PLATFORM_OS),OSX) + CFLAGS = -O2 -s -Wall -std=c99 + endif endif ifeq ($(PLATFORM),PLATFORM_WEB) CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 -s ASSERTIONS=1 --preload-file resources #-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing #-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) endif - +ifeq ($(PLATFORM),PLATFORM_RPI) + CFLAGS = -O2 -s -Wall -std=gnu99 -fgnu89-inline +endif #CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes # define raylib release directory for compiled library @@ -110,9 +123,7 @@ ifeq ($(PLATFORM),PLATFORM_RPI) endif ifeq ($(PLATFORM),PLATFORM_DESKTOP) # add standard directories for GNU/Linux - ifeq ($(PLATFORM_OS),LINUX) - INCLUDES += -I/usr/local/include/raylib/ - else ifeq ($(PLATFORM_OS),WINDOWS) + ifeq ($(PLATFORM_OS),WINDOWS) # external libraries headers # GLFW3 INCLUDES += -I../src/external/glfw3/include @@ -207,7 +218,6 @@ EXAMPLES = \ core_3d_camera_first_person \ core_2d_camera \ core_world_screen \ - core_oculus_rift \ shapes_logo_raylib \ shapes_basic_shapes \ shapes_colors_palette \ @@ -327,19 +337,19 @@ core_3d_camera_free: core_3d_camera_free.c # compile [core] example - 3d camera first person core_3d_camera_first_person: core_3d_camera_first_person.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + $(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) +#core_oculus_rift: core_oculus_rift.c +# $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) # compile [shapes] example - raylib logo (with basic shapes) shapes_logo_raylib: shapes_logo_raylib.c @@ -376,31 +386,31 @@ textures_srcrec_dstrec: textures_srcrec_dstrec.c # compile [textures] example - texture to image textures_to_image: textures_to_image.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [textures] example - texture raw data textures_raw_data: textures_raw_data.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [textures] example - texture formats loading textures_formats_loading: textures_formats_loading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [textures] example - texture particles trail blending textures_particles_trail_blending: textures_particles_trail_blending.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [textures] example - texture image processing textures_image_processing: textures_image_processing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [textures] example - texture image drawing textures_image_drawing: textures_image_drawing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [text] example - sprite fonts loading text_sprite_fonts: text_sprite_fonts.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [text] example - bmfonts and ttf loading text_bmfont_ttf: text_bmfont_ttf.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) @@ -436,7 +446,7 @@ models_geometric_shapes: models_geometric_shapes.c # compile [models] example - box collisions models_box_collisions: models_box_collisions.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [models] example - basic window models_planes: models_planes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) @@ -464,15 +474,15 @@ models_ray_picking: models_ray_picking.c # compile [shaders] example - model shader shaders_model_shader: shaders_model_shader.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [shaders] example - shapes texture shader shaders_shapes_textures: shaders_shapes_textures.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [shaders] example - custom uniform in shader shaders_custom_uniform: shaders_custom_uniform.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + # compile [shaders] example - postprocessing shader shaders_postprocessing: shaders_postprocessing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) @@ -497,13 +507,6 @@ audio_module_playing: audio_module_playing.c audio_raw_stream: audio_raw_stream.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) -# Linux Fix to timespect from -ifeq ($(PLATFORM),PLATFORM_DESKTOP) - ifeq ($(PLATFORM_OS),LINUX) - CFLAGS += -D_POSIX_C_SOURCE=199309L - endif -endif - # compile [physac] example - physics demo physics_demo: physics_demo.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -lpthread -D$(PLATFORM) $(WINFLAGS) @@ -523,7 +526,7 @@ physics_restitution: physics_restitution.c # compile [physac] example - physics shatter physics_shatter: physics_shatter.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -lpthread -D$(PLATFORM) $(WINFLAGS) - + # fix dylib install path name for each executable (MAC) fix_dylib: ifeq ($(PLATFORM_OS),OSX) diff --git a/examples/audio_standalone.c b/examples/audio_standalone.c index d090bb83..3edf8895 100644 --- a/examples/audio_standalone.c +++ b/examples/audio_standalone.c @@ -29,7 +29,7 @@ #endif #include "audio.h" -#if defined(__linux) +#if defined(__linux__) #include <stdio.h> #include <termios.h> diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index eb628cd7..f1b0bd3b 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -3,7 +3,12 @@ * raylib [core] example - Oculus Rift CV1 * * Compile example using: -* gcc -o $(NAME_PART).exe $(FILE_NAME) -L. -L..\src\external\OculusSDK\LibOVR -lLibOVRRT32_1 -lraylib -lglfw3 -lopengl32 -lgdi32 -std=c99 +* gcc -o $(NAME_PART).exe $(FILE_NAME) -I..\src\external -I..\src\external\OculusSDK\LibOVR\Include / +* -L. -L..\src\external\OculusSDK\LibOVR -lLibOVRRT32_1 -lraylib -lglfw3 -lopengl32 -lgdi32 -std=c99 / +* -Wl,-allow-multiple-definition +* +* #define SUPPORT_OCULUS_RIFT_CV1 / RLGL_OCULUS_SUPPORT +* Enable Oculus Rift CV1 functionality * * This example has been created using raylib 1.5 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) @@ -14,6 +19,95 @@ #include "raylib.h" +#include "glad.h" // Required for: OpenGL types and functions declarations +#include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality + +#include <string.h> // Required for: memset() +#include <stdlib.h> // Required for: exit() +#include <stdio.h> // required for: vfprintf() +#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() + +#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code +#if defined(RLGL_OCULUS_SUPPORT) + #include "OVR_CAPI_GL.h" // Oculus SDK for OpenGL +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// TraceLog message types +typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; + +#if defined(RLGL_OCULUS_SUPPORT) +// Oculus buffer type +typedef struct OculusBuffer { + ovrTextureSwapChain textureChain; + GLuint depthId; + GLuint fboId; + int width; + int height; +} OculusBuffer; + +// Oculus mirror texture type +typedef struct OculusMirror { + ovrMirrorTexture texture; + GLuint fboId; + int width; + int height; +} OculusMirror; + +// Oculus layer type +typedef struct OculusLayer { + ovrViewScaleDesc viewScaleDesc; + ovrLayerEyeFov eyeLayer; // layer 0 + //ovrLayerQuad quadLayer; // TODO: layer 1: '2D' quad for GUI + Matrix eyeProjections[2]; + int width; + int height; +} OculusLayer; +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +#if defined(RLGL_OCULUS_SUPPORT) +// OVR device variables +static ovrSession session; // Oculus session (pointer to ovrHmdStruct) +static ovrHmdDesc hmdDesc; // Oculus device descriptor parameters +static ovrGraphicsLuid luid; // Oculus locally unique identifier for the program (64 bit) +static OculusLayer layer; // Oculus drawing layer (similar to photoshop) +static OculusBuffer buffer; // Oculus internal buffers (texture chain and fbo) +static OculusMirror mirror; // Oculus mirror texture and fbo +static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain +#endif + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +#if defined(RLGL_OCULUS_SUPPORT) +static bool InitOculusDevice(void); // Initialize Oculus device (returns true if success) +static void CloseOculusDevice(void); // Close Oculus device +static void UpdateOculusTracking(Camera *camera); // Update Oculus head position-orientation tracking +static void BeginOculusDrawing(void); // Setup Oculus buffers for drawing +static void EndOculusDrawing(void); // Finish Oculus drawing and blit framebuffer to mirror + +static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers +static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers +static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers +static void UnloadOculusMirror(ovrSession session, OculusMirror mirror); // Unload Oculus mirror buffers +static void BlitOculusMirror(ovrSession session, OculusMirror mirror); // Copy Oculus screen buffer to mirror texture +static OculusLayer InitOculusLayer(ovrSession session); // Init Oculus layer (similar to photoshop) +static Matrix FromOvrMatrix(ovrMatrix4f ovrM); // Convert from Oculus ovrMatrix4f struct to raymath Matrix struct +#endif + +static void TraceLog(int msgType, const char *text, ...); + int main() { // Initialization @@ -25,8 +119,9 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift"); - // NOTE: If device is not available, it fallbacks to default device (simulator) - InitVrDevice(HMD_OCULUS_RIFT_CV1); // Init VR device (Oculus Rift CV1) + bool vrDeviceReady = InitOculusDevice(); // Init VR device Oculus Rift CV1 + + if (!vrDeviceReady) InitVrSimulator(HMD_OCULUS_RIFT_CV1); // Init VR simulator if device fails // Define the camera to look into our 3d world Camera camera; @@ -47,10 +142,10 @@ int main() { // Update //---------------------------------------------------------------------------------- - if (IsVrSimulator()) UpdateCamera(&camera); // Update camera (simulator mode) - else if (IsVrDeviceReady()) UpdateVrTracking(&camera); // Update camera with device tracking data - - if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); // Toggle VR mode + if (!vrDeviceReady) UpdateCamera(&camera); // Update camera (simulator mode) + else UpdateOculusTracking(&camera); // Update camera with device tracking data + + if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); // Toggle VR mode //---------------------------------------------------------------------------------- // Draw @@ -58,6 +153,9 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); + + if (vrDeviceReady) BeginOculusDrawing(); + else BeginVrDrawing(); Begin3dMode(camera); @@ -67,6 +165,9 @@ int main() DrawGrid(40, 1.0f); End3dMode(); + + if (vrDeviceReady) EndOculusDrawing(); + else EndVrDrawing(); DrawFPS(10, 10); @@ -76,10 +177,362 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - CloseVrDevice(); // Close VR device + if (vrDeviceReady) CloseOculusDevice(); + else CloseVrSimulator(); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; } + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +#if defined(RLGL_OCULUS_SUPPORT) +// Set internal projection and modelview matrix depending on eyes tracking data +static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) +{ + Matrix eyeProjection = matProjection; + Matrix eyeModelView = matModelView; + + glViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, + layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); + + Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, + layer.eyeLayer.RenderPose[eye].Orientation.w }; + QuaternionInvert(&eyeRenderPose); + Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); + Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, + -layer.eyeLayer.RenderPose[eye].Position.y, + -layer.eyeLayer.RenderPose[eye].Position.z); + + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement + eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + + eyeProjection = layer.eyeProjections[eye]; +} + +// Initialize Oculus device (returns true if success) +static bool InitOculusDevice(void) +{ + bool oculusReady = false; + + ovrResult result = ovr_Initialize(NULL); + + if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device"); + else + { + result = ovr_Create(&session, &luid); + if (OVR_FAILURE(result)) + { + TraceLog(WARNING, "OVR: Could not create Oculus session"); + ovr_Shutdown(); + } + else + { + hmdDesc = ovr_GetHmdDesc(session); + + TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); + TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); + TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); + TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); + //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); + TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); + + // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... + // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) + + // Initialize Oculus Buffers + layer = InitOculusLayer(session); + buffer = LoadOculusBuffer(session, layer.width, layer.height); + mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... + layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); + + // Recenter OVR tracking origin + ovr_RecenterTrackingOrigin(session); + + oculusReady = true; + } + } + + return oculusReady; +} + +// Close Oculus device (and unload buffers) +static void CloseOculusDevice(void) +{ + UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer + UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers + + ovr_Destroy(session); // Free Oculus session data + ovr_Shutdown(); // Close Oculus device connection +} + +// Update Oculus head position-orientation tracking +static void UpdateOculusTracking(Camera *camera) +{ + frameIndex++; + + ovrPosef eyePoses[2]; + ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); + + layer.eyeLayer.RenderPose[0] = eyePoses[0]; + layer.eyeLayer.RenderPose[1] = eyePoses[1]; + + // TODO: Update external camera with eyePoses data (position, orientation) + // NOTE: We can simplify to simple camera if we consider IPD and HMD device configuration again later + // it will be useful for the user to draw, lets say, billboards oriented to camera + + // 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. +} + +// Setup Oculus buffers for drawing +static void BeginOculusDrawing(void) +{ + GLuint currentTexId; + int currentIndex; + + ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0); + //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded +} + +// Finish Oculus drawing and blit framebuffer to mirror +static void EndOculusDrawing(void) +{ + // Unbind current framebuffer (Oculus buffer) + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + ovr_CommitTextureSwapChain(session, buffer.textureChain); + + ovrLayerHeader *layers = &layer.eyeLayer.Header; + ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); + + // Blit mirror texture to back buffer + BlitOculusMirror(session, mirror); +} + +// Load Oculus required buffers: texture-swap-chain, fbo, texture-depth +static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) +{ + OculusBuffer buffer; + buffer.width = width; + buffer.height = height; + + // Create OVR texture chain + ovrTextureSwapChainDesc desc = {}; + desc.Type = ovrTexture_2D; + desc.ArraySize = 1; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; // Requires glEnable(GL_FRAMEBUFFER_SRGB); + desc.SampleCount = 1; + desc.StaticImage = ovrFalse; + + ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain); + + if (!OVR_SUCCESS(result)) TraceLog(WARNING, "OVR: Failed to create swap textures buffer"); + + int textureCount = 0; + ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount); + + if (!OVR_SUCCESS(result) || !textureCount) TraceLog(WARNING, "OVR: Unable to count swap chain textures"); + + for (int i = 0; i < textureCount; ++i) + { + GLuint chainTexId; + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, i, &chainTexId); + glBindTexture(GL_TEXTURE_2D, chainTexId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + glBindTexture(GL_TEXTURE_2D, 0); + + /* + // Setup framebuffer object (using depth texture) + glGenFramebuffers(1, &buffer.fboId); + glGenTextures(1, &buffer.depthId); + glBindTexture(GL_TEXTURE_2D, buffer.depthId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + */ + + // Setup framebuffer object (using depth renderbuffer) + glGenFramebuffers(1, &buffer.fboId); + glGenRenderbuffers(1, &buffer.depthId); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); + glBindRenderbuffer(GL_RENDERBUFFER, buffer.depthId); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, buffer.width, buffer.height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer.depthId); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + return buffer; +} + +// Unload texture required buffers +static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer) +{ + if (buffer.textureChain) + { + ovr_DestroyTextureSwapChain(session, buffer.textureChain); + buffer.textureChain = NULL; + } + + if (buffer.depthId != 0) glDeleteTextures(1, &buffer.depthId); + if (buffer.fboId != 0) glDeleteFramebuffers(1, &buffer.fboId); +} + +// Load Oculus mirror buffers +static OculusMirror LoadOculusMirror(ovrSession session, int width, int height) +{ + OculusMirror mirror; + mirror.width = width; + mirror.height = height; + + ovrMirrorTextureDesc mirrorDesc; + memset(&mirrorDesc, 0, sizeof(mirrorDesc)); + mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + mirrorDesc.Width = mirror.width; + mirrorDesc.Height = mirror.height; + + if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(WARNING, "Could not create mirror texture"); + + glGenFramebuffers(1, &mirror.fboId); + + return mirror; +} + +// Unload Oculus mirror buffers +static void UnloadOculusMirror(ovrSession session, OculusMirror mirror) +{ + if (mirror.fboId != 0) glDeleteFramebuffers(1, &mirror.fboId); + if (mirror.texture) ovr_DestroyMirrorTexture(session, mirror.texture); +} + +// Copy Oculus screen buffer to mirror texture +static void BlitOculusMirror(ovrSession session, OculusMirror mirror) +{ + GLuint mirrorTextureId; + + ovr_GetMirrorTextureBufferGL(session, mirror.texture, &mirrorTextureId); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0); +#if defined(GRAPHICS_API_OPENGL_33) + // NOTE: glBlitFramebuffer() requires extension: GL_EXT_framebuffer_blit (not available in OpenGL ES 2.0) + glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); +#endif + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); +} + +// Init Oculus layer (similar to photoshop) +static OculusLayer InitOculusLayer(ovrSession session) +{ + OculusLayer layer = { 0 }; + + layer.viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f; + + memset(&layer.eyeLayer, 0, sizeof(ovrLayerEyeFov)); + layer.eyeLayer.Header.Type = ovrLayerType_EyeFov; + layer.eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; + + ovrEyeRenderDesc eyeRenderDescs[2]; + + for (int eye = 0; eye < 2; eye++) + { + eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]); + ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(eyeRenderDescs[eye].Fov, 0.01f, 10000.0f, ovrProjection_None); //ovrProjection_ClipRangeOpenGL); + layer.eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection); // NOTE: struct ovrMatrix4f { float M[4][4] } --> struct Matrix + + layer.viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset; + layer.eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov; + + ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, layer.eyeLayer.Fov[eye], 1.0f); + layer.eyeLayer.Viewport[eye].Size = eyeSize; + layer.eyeLayer.Viewport[eye].Pos.x = layer.width; + layer.eyeLayer.Viewport[eye].Pos.y = 0; + + layer.height = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h); + layer.width += eyeSize.w; + } + + return layer; +} + +// Convert from Oculus ovrMatrix4f struct to raymath Matrix struct +static Matrix FromOvrMatrix(ovrMatrix4f ovrmat) +{ + Matrix rmat; + + rmat.m0 = ovrmat.M[0][0]; + rmat.m1 = ovrmat.M[1][0]; + rmat.m2 = ovrmat.M[2][0]; + rmat.m3 = ovrmat.M[3][0]; + rmat.m4 = ovrmat.M[0][1]; + rmat.m5 = ovrmat.M[1][1]; + rmat.m6 = ovrmat.M[2][1]; + rmat.m7 = ovrmat.M[3][1]; + rmat.m8 = ovrmat.M[0][2]; + rmat.m9 = ovrmat.M[1][2]; + rmat.m10 = ovrmat.M[2][2]; + rmat.m11 = ovrmat.M[3][2]; + rmat.m12 = ovrmat.M[0][3]; + rmat.m13 = ovrmat.M[1][3]; + rmat.m14 = ovrmat.M[2][3]; + rmat.m15 = ovrmat.M[3][3]; + + MatrixTranspose(&rmat); + + return rmat; +} +#endif + +// Output a trace log message +// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning +static void TraceLog(int msgType, const char *text, ...) +{ + va_list args; + va_start(args, text); + + switch (msgType) + { + case INFO: fprintf(stdout, "INFO: "); break; + case ERROR: fprintf(stdout, "ERROR: "); break; + case WARNING: fprintf(stdout, "WARNING: "); break; + case DEBUG: fprintf(stdout, "DEBUG: "); break; + default: break; + } + + vfprintf(stdout, text, args); + fprintf(stdout, "\n"); + + va_end(args); + + if (msgType == ERROR) exit(1); +} + diff --git a/examples/text_ttf_loading.c b/examples/text_ttf_loading.c index 10025c2f..4aa0bef4 100644 --- a/examples/text_ttf_loading.c +++ b/examples/text_ttf_loading.c @@ -5,7 +5,7 @@ * This example has been created using raylib 1.3.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2015 Ramon Santamaria (Ray San - [email protected]) +* Copyright (c) 2015 Ramon Santamaria (@raysan5) * ********************************************************************************************/ |
