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

This commit is contained in:
victorfisac
2016-06-07 23:41:34 +02:00
123 changed files with 23726 additions and 41906 deletions

6
.gitignore vendored
View File

@ -65,4 +65,8 @@ DerivedData/
src/libraylib.a
# oculus example
!examples/oculus_glfw_sample/LibOVRRT32_1.dll
!examples/oculus_glfw_sample/LibOVRRT32_1.dll
# external libraries DLLs
!src/external/glfw3/lib/win32/glfw3.dll
!src/external/openal_soft/lib/win32/OpenAL32.dll

View File

@ -11,6 +11,8 @@
#include "raylib.h"
#define MAX_BUILDINGS 100
int main()
{
// Initialization
@ -20,16 +22,31 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
Rectangle player = { 400, 280, 40, 40 };
Rectangle buildings[MAX_BUILDINGS] = { 0, 0, 0, 0 };
Color buildColors[MAX_BUILDINGS] = { 80, 80, 80, 255 };
int spacing = 0;
for (int i = 0; i < MAX_BUILDINGS; i++)
{
buildings[i].width = GetRandomValue(50, 200);
buildings[i].height = GetRandomValue(100, 800);
buildings[i].y = screenHeight - 130 - buildings[i].height;
buildings[i].x = -6000 + spacing;
spacing += buildings[i].width;
buildColors[i] = (Color){ GetRandomValue(200, 240), GetRandomValue(200, 240), GetRandomValue(200, 250), 255 };
}
Camera2D camera;
camera.target = (Vector2){ player.x + 20, player.y + 20 };
camera.offset = (Vector2){ 0, 0 };
camera.target = (Vector2){ 400, 200 };
camera.rotation = 0.0f;
camera.zoom = 1.0f;
Rectangle player = { 400, 200, 40, 40 };
camera.target = (Vector2){ player.x + 20, player.y + 20 };
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
@ -38,24 +55,36 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyDown(KEY_RIGHT)) player.x -= 2;
else if (IsKeyDown(KEY_LEFT)) player.x += 2;
else if (IsKeyDown(KEY_UP)) player.y -= 2;
else if (IsKeyDown(KEY_DOWN)) player.y += 2;
if (IsKeyDown(KEY_RIGHT))
{
player.x += 2; // Player movement
camera.offset.x -= 2; // Camera displacement with player movement
}
else if (IsKeyDown(KEY_LEFT))
{
player.x -= 2; // Player movement
camera.offset.x += 2; // Camera displacement with player movement
}
// Camera target follows player
camera.target = (Vector2){ player.x + 20, player.y + 20 };
if (IsKeyDown(KEY_R)) camera.rotation--;
else if (IsKeyDown(KEY_F)) camera.rotation++;
// Camera rotation controls
if (IsKeyDown(KEY_A)) camera.rotation--;
else if (IsKeyDown(KEY_S)) camera.rotation++;
// Camera controls
if (IsKeyDown(KEY_R)) camera.rotation--;
else if (IsKeyDown(KEY_F)) camera.rotation++;
// Limit camera rotation to 80 degrees (-40 to 40)
if (camera.rotation > 40) camera.rotation = 40;
else if (camera.rotation < -40) camera.rotation = -40;
// Camera zoom controls
camera.zoom += ((float)GetMouseWheelMove()*0.05f);
if (IsKeyPressed(KEY_Z))
if (camera.zoom > 3.0f) camera.zoom = 3.0f;
else if (camera.zoom < 0.1f) camera.zoom = 0.1f;
// Camera reset (zoom and rotation)
if (IsKeyPressed(KEY_R))
{
camera.zoom = 1.0f;
camera.rotation = 0.0f;
@ -64,17 +93,38 @@ int main()
// Draw
//----------------------------------------------------------------------------------
BeginDrawingEx(camera);
BeginDrawing();
ClearBackground(RAYWHITE);
Begin2dMode(camera);
DrawText("2D CAMERA TEST", 20, 20, 20, GRAY);
DrawRectangle(-6000, 320, 13000, 8000, DARKGRAY);
for (int i = 0; i < MAX_BUILDINGS; i++) DrawRectangleRec(buildings[i], buildColors[i]);
DrawRectangleRec(player, RED);
DrawRectangle(camera.target.x, -500, 1, screenHeight*4, GREEN);
DrawRectangle(-500, camera.target.y, screenWidth*4, 1, GREEN);
End2dMode();
DrawRectangle(0, 300, screenWidth, 50, GRAY);
DrawRectangleRec(player, RED);
DrawText("SCREEN AREA", 640, 10, 20, RED);
DrawRectangle(camera.origin.x, 0, 1, screenHeight, GREEN);
DrawRectangle(0, camera.origin.y, screenWidth, 1, GREEN);
DrawRectangle(0, 0, screenWidth, 5, RED);
DrawRectangle(0, 5, 5, screenHeight - 10, RED);
DrawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, RED);
DrawRectangle(0, screenHeight - 5, screenWidth, 5, RED);
DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f));
DrawRectangleLines( 10, 10, 250, 113, BLUE);
DrawText("Free 2d camera controls:", 20, 20, 10, BLACK);
DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY);
DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY);
DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY);
DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------

View File

@ -0,0 +1,72 @@
/*******************************************************************************************
*
* raylib [core] example - Oculus Rift CV1
*
* 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)
*
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 1080;
int screenHeight = 600;
InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift");
InitOculusDevice();
// Define the camera to look into our 3d world
Camera camera;
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
SetTargetFPS(90); // Set our game to run at 90 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateOculusTracking();
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
Begin3dMode(camera);
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
DrawGrid(10, 1.0f);
End3dMode();
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseOculusdevice(); // Close Oculus Rift device
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -137,14 +137,14 @@ OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f proj
/// Computes offset eye poses based on headPose returned by ovrTrackingState.
///
/// \param[in] headPose Indicates the HMD position and orientation to use for the calculation.
/// \param[in] HmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
/// \param[in] hmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
/// of the two vectors for both eyes.
/// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to
/// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose.
///
OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose,
const ovrVector3f HmdToEyeOffset[2],
const ovrVector3f hmdToEyeOffset[2],
ovrPosef outEyePoses[2]);
@ -158,17 +158,17 @@ OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose,
/// \param[in] hmd Specifies an ovrSession previously returned by ovr_Create.
/// \param[in] frameIndex Specifies the targeted frame index, or 0 to refer to one frame after
/// the last time ovr_SubmitFrame was called.
/// \param[in] HmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
/// of the two vectors for both eyes.
/// \param[in] latencyMarker Specifies that this call is the point in time where
/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer
/// provides "SensorSampleTimestamp", that will override the value stored here.
/// \param[in] hmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
/// of the two vectors for both eyes.
/// \param[out] outEyePoses The predicted eye poses.
/// \param[out] outSensorSampleTime The time when this function was called. May be NULL, in which case it is ignored.
///
OVR_PUBLIC_FUNCTION(void) ovr_GetEyePoses(ovrSession session, long long frameIndex, ovrBool latencyMarker,
const ovrVector3f HmdToEyeOffset[2],
const ovrVector3f hmdToEyeOffset[2],
ovrPosef outEyePoses[2],
double* outSensorSampleTime);

View File

@ -1,7 +1,7 @@
/********************************************************************************//**
\file OVR_Math.h
\brief Implementation of 3D primitives such as vectors, matrices.
\copyright Copyright 2015 Oculus VR, LLC All Rights reserved.
\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
*************************************************************************************/
#ifndef OVR_Math_h
@ -1754,7 +1754,7 @@ public:
: Rotation(s.Rotation), Translation(s.Translation)
{
// Ensure normalized rotation if converting from float to double
if (sizeof(T) > sizeof(Math<T>::OtherFloatType))
if (sizeof(T) > sizeof(typename Math<T>::OtherFloatType))
Rotation.Normalize();
}

View File

@ -1,7 +1,7 @@
/********************************************************************************//**
\file OVR_CAPI.h
\brief C Interface to the Oculus PC SDK tracking and rendering library.
\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
\copyright Copyright 2014 Oculus VR, LLC All Rights reserved.
************************************************************************************/
#ifndef OVR_CAPI_h // We don't use version numbers within this name, as all versioned variations of this file are currently mutually exclusive.
@ -687,6 +687,11 @@ typedef enum ovrTextureMiscFlags_
/// call. This flag requires that RenderTarget binding also be specified.
ovrTextureMisc_AllowGenerateMips = 0x0002,
/// Texture swap chain contains protected content, and requires
/// HDCP connection in order to display to HMD. Also prevents
/// mirroring or other redirection of any frame containing this contents
ovrTextureMisc_ProtectedContent = 0x0004,
ovrTextureMisc_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
} ovrTextureFlags;
@ -695,7 +700,7 @@ typedef enum ovrTextureMiscFlags_
/// \see ovr_CreateTextureSwapChainDX
/// \see ovr_CreateTextureSwapChainGL
///
typedef struct
typedef struct ovrTextureSwapChainDesc_
{
ovrTextureType Type;
ovrTextureFormat Format;
@ -705,7 +710,7 @@ typedef struct
int MipLevels;
int SampleCount; ///< Current only supported on depth textures
ovrBool StaticImage; ///< Not buffered in a chain. For images that don't change
unsigned int MiscFlags; ///< ovrTextureMiscFlags
unsigned int MiscFlags; ///< ovrTextureFlags
unsigned int BindFlags; ///< ovrTextureBindFlags. Not used for GL.
} ovrTextureSwapChainDesc;
@ -714,12 +719,12 @@ typedef struct
/// \see ovr_CreateMirrorTextureDX
/// \see ovr_CreateMirrorTextureGL
///
typedef struct
typedef struct ovrMirrorTextureDesc_
{
ovrTextureFormat Format;
int Width;
int Height;
unsigned int MiscFlags; ///< ovrTextureMiscFlags
unsigned int MiscFlags; ///< ovrTextureFlags
} ovrMirrorTextureDesc;
typedef struct ovrTextureSwapChainData* ovrTextureSwapChain;
@ -987,8 +992,8 @@ extern "C" {
/// Initializes LibOVR
///
/// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT
/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo, can be called
/// unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually
/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo and ovr_Detect, can
/// be called unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually
/// followed by a call to ovr_Shutdown. ovr_Initialize calls are idempotent.
/// Calling ovr_Initialize twice does not require two matching calls to ovr_Shutdown.
/// If already initialized, the return value is ovr_Success.
@ -1696,6 +1701,14 @@ OVR_PUBLIC_FUNCTION(void) ovr_DestroyMirrorTexture(ovrSession session, ovrMirror
/// \param[in] pixelsPerDisplayPixel Specifies the ratio of the number of render target pixels
/// to display pixels at the center of distortion. 1.0 is the default value. Lower
/// values can improve performance, higher values give improved quality.
///
/// <b>Example code</b>
/// \code{.cpp}
/// ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session);
/// ovrSizei eyeSizeLeft = ovr_GetFovTextureSize(session, ovrEye_Left, hmdDesc.DefaultEyeFov[ovrEye_Left], 1.0f);
/// ovrSizei eyeSizeRight = ovr_GetFovTextureSize(session, ovrEye_Right, hmdDesc.DefaultEyeFov[ovrEye_Right], 1.0f);
/// \endcode
///
/// \return Returns the texture width and height size.
///
OVR_PUBLIC_FUNCTION(ovrSizei) ovr_GetFovTextureSize(ovrSession session, ovrEyeType eye, ovrFovPort fov,

View File

@ -67,8 +67,8 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainDX(ovrSession session,
///
/// <b>Example code</b>
/// \code{.cpp}
/// ovr_GetTextureSwapChainBuffer(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
/// ovr_GetTextureSwapChainBuffer(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
/// ovr_GetTextureSwapChainBufferDX(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
/// ovr_GetTextureSwapChainBufferDX(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
/// \endcode
///
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession session,
@ -102,6 +102,21 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession sessio
/// compositor continues to treat is as sRGB. Failure to do so will cause the compositor to apply unexpected gamma conversions leading to
/// gamma-curve artifacts.
///
///
/// <b>Example code</b>
/// \code{.cpp}
/// ovrMirrorTexture mirrorTexture = nullptr;
/// ovrMirrorTextureDesc mirrorDesc = {};
/// mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
/// mirrorDesc.Width = mirrorWindowWidth;
/// mirrorDesc.Height = mirrorWindowHeight;
/// ovrResult result = ovr_CreateMirrorTextureDX(session, d3d11Device, &mirrorDesc, &mirrorTexture);
/// [...]
/// // Destroy the texture when done with it.
/// ovr_DestroyMirrorTexture(session, mirrorTexture);
/// mirrorTexture = nullptr;
/// \endcode
///
/// \see ovr_GetMirrorTextureBufferDX
/// \see ovr_DestroyMirrorTexture
///
@ -120,6 +135,15 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureDX(ovrSession session,
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
/// ovr_GetLastErrorInfo to get more information.
///
/// <b>Example code</b>
/// \code{.cpp}
/// ID3D11Texture2D* d3d11Texture = nullptr;
/// ovr_GetMirrorTextureBufferDX(session, mirrorTexture, IID_PPV_ARGS(&d3d11Texture));
/// d3d11DeviceContext->CopyResource(d3d11TextureBackBuffer, d3d11Texture);
/// d3d11Texture->Release();
/// dxgiSwapChain->Present(0, 0);
/// \endcode
///
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session,
ovrMirrorTexture mirrorTexture,
IID iid,

View File

@ -91,6 +91,7 @@ typedef enum ovrErrorType_
ovrError_InvalidHeadsetOrientation = -1011, ///< The headset was in an invalid orientation for the requested operation (e.g. vertically oriented during ovr_RecenterPose).
ovrError_ClientSkippedDestroy = -1012, ///< The client failed to call ovr_Destroy on an active session before calling ovr_Shutdown. Or the client crashed.
ovrError_ClientSkippedShutdown = -1013, ///< The client failed to call ovr_Shutdown or the client crashed.
ovrError_ServiceDeadlockDetected = -1014, ///< The service watchdog discovered a deadlock.
/* Audio error range, reserved for Audio errors. */
ovrError_AudioReservedBegin = -2000, ///< First Audio error.
@ -140,25 +141,42 @@ typedef enum ovrErrorType_
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.
ovrError_Incomplete = -5000, ///< Requested async work not yet complete.
ovrError_Abandoned = -5001, ///< Requested async work was abandoned and result is incomplete.
/* Rendering errors */
ovrError_DisplayLost = -6000, ///<In the event of a system-wide graphics reset or cable unplug this is returned to the app.
ovrError_TextureSwapChainFull = -6001, ///<ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain.
ovrError_TextureSwapChainInvalid = -6002, ///<The ovrTextureSwapChain is in an incomplete or inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first.
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_TextureSwapChainInvalid = -6002, ///< The ovrTextureSwapChain is in an incomplete or inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first.
ovrError_GraphicsDeviceReset = -6003, ///< Graphics device has been reset (TDR, etc...)
ovrError_DisplayRemoved = -6004, ///< HMD removed from the display adapter
ovrError_ContentProtectionNotAvailable = -6005,///<Content protection is not available for the display
ovrError_ApplicationInvisible = -6006, ///< Application declared itself as an invisible type and is not allowed to submit frames.
ovrError_Disallowed = -6007, ///< The given request is disallowed under the current conditions.
ovrError_DisplayPluggedIncorrectly = -6008, ///< Display portion of HMD is plugged into an incompatible port (ex: IGP)
/* Fatal errors */
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.

View File

@ -19,7 +19,7 @@
// Master version numbers
#define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning.
#define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change LibOVR/Projects/Windows/LibOVR.props in parallel.
#define OVR_MINOR_VERSION 3 //
#define OVR_MINOR_VERSION 4 //
#define OVR_PATCH_VERSION 0
#define OVR_BUILD_NUMBER 0

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -4,11 +4,11 @@
*
* NOTE: This example requires raylib module [rlgl]
*
* Compile rlgl using:
* Compile rlgl module using:
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
*
* Compile example using:
* gcc -o oculus_glfw_sample.exe oculus_glfw_sample.c rlgl.o glad.o -L. -lLibOVRRT32_1 -lglfw3 -lopengl32 -lgdi32 -std=c99
* gcc -o oculus_glfw_sample.exe oculus_glfw_sample.c rlgl.o -L. -lLibOVRRT32_1 -lglfw3 -lopengl32 -lgdi32 -std=c99
*
* 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)
@ -21,72 +21,145 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define GLAD_IMPLEMENTATION
#include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h> // Windows/Context and inputs management
#include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
#define RLGL_STANDALONE
#include "rlgl.h"
#define PLATFORM_OCULUS
#if defined(PLATFORM_OCULUS)
#include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
#endif
#if defined(PLATFORM_OCULUS)
// OVR device variables
ovrSession session;
ovrHmdDesc hmdDesc;
ovrGraphicsLuid luid;
#endif
// OVR OpenGL required variables
GLuint fbo = 0;
GLuint depthBuffer = 0;
ovrTextureSwapChain eyeTexture;
unsigned int frameIndex = 0;
GLuint mirrorFbo = 0;
ovrMirrorTexture mirrorTexture;
ovrEyeRenderDesc eyeRenderDescs[2];
Matrix eyeProjections[2];
ovrLayerEyeFov eyeLayer;
ovrViewScaleDesc viewScaleDesc;
Vector2 renderTargetSize = { 0, 0 };
Vector2 mirrorSize;
unsigned int frame = 0;
// GLFW variables
GLFWwindow *window = NULL;
#define RED (Color){ 230, 41, 55, 255 } // Red
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#if defined(PLATFORM_OCULUS)
typedef struct OculusBuffer {
ovrTextureSwapChain textureChain;
GLuint depthId;
GLuint fboId;
int width;
int height;
} OculusBuffer;
typedef struct OculusMirror {
ovrMirrorTexture texture;
GLuint fboId;
int width;
int height;
} OculusMirror;
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
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static void ErrorCallback(int error, const char* description)
{
fputs(description, stderr);
}
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
static void ErrorCallback(int error, const char* description);
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void TraceLog(int msgType, const char *text, ...);
// Drawing functions (uses rlgl functionality)
static void DrawGrid(int slices, float spacing);
static void DrawCube(Vector3 position, float width, float height, float length, Color color);
static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
#if defined(PLATFORM_OCULUS)
// Oculus Rift functions
static Matrix FromOvrMatrix(ovrMatrix4f ovrM);
void DrawGrid(int slices, float spacing);
void DrawCube(Vector3 position, float width, float height, float length, Color color);
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height);
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer);
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer);
static void UnsetOculusBuffer(OculusBuffer buffer);
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);
static OculusLayer InitOculusLayer(ovrSession session);
#endif
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main()
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 1080; // Mirror screen width (set to hmdDesc.Resolution.w/2)
int screenHeight = 600; // Mirror screen height (set to hmdDesc.Resolution.h/2)
// NOTE: Mirror screen size can be set to any desired resolution!
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib oculus sample", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
// Load OpenGL 3.3 extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1);
}
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
//--------------------------------------------------------
#if defined(PLATFORM_OCULUS)
ovrResult result = ovr_Initialize(NULL);
if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device");
@ -106,200 +179,128 @@ int main()
TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber);
TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
memset(&eyeLayer, 0, sizeof(ovrLayerEyeFov));
eyeLayer.Header.Type = ovrLayerType_EyeFov;
eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
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, 1000.0f, ovrProjection_ClipRangeOpenGL);
// NOTE struct ovrMatrix4f { float M[4][4] }
eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection);
viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset;
//screenWidth = hmdDesc.Resolution.w/2;
//screenHeight = hmdDesc.Resolution.h/2;
eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov;
ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, eyeLayer.Fov[eye], 1.0f);
eyeLayer.Viewport[eye].Size = eyeSize;
eyeLayer.Viewport[eye].Pos.x = renderTargetSize.x;
eyeLayer.Viewport[eye].Pos.y = 0;
renderTargetSize.y = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h);
renderTargetSize.x += eyeSize.w;
}
// Make the on screen window 1/2 the resolution of the device
mirrorSize.x = hmdDesc.Resolution.w/2;
mirrorSize.y = hmdDesc.Resolution.h/2;
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
if (!glfwInit())
{
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
//glfwWindowHint(GLFW_DECORATED, GL_FALSE); // Mandatory on Oculus Rift to avoid program crash? --> NO
window = glfwCreateWindow(mirrorSize.x, mirrorSize.y, "raylib oculus sample", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetErrorCallback(ErrorCallback);
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1);
}
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
// Initialize OVR OpenGL swap chain textures
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Width = renderTargetSize.x;
desc.Height = renderTargetSize.y;
desc.MipLevels = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
result = ovr_CreateTextureSwapChainGL(session, &desc, &eyeTexture);
eyeLayer.ColorTexture[0] = eyeTexture;
if (!OVR_SUCCESS(result)) TraceLog(LOG_WARNING, "Failed to create swap textures");
int length = 0;
result = ovr_GetTextureSwapChainLength(session, eyeTexture, &length);
if (!OVR_SUCCESS(result) || !length) TraceLog(LOG_WARNING, "Unable to count swap chain textures");
for (int i = 0; i < length; ++i)
{
GLuint chainTexId;
ovr_GetTextureSwapChainBufferGL(session, eyeTexture, 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
glGenFramebuffers(1, &fbo);
glGenRenderbuffers(1, &depthBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, renderTargetSize.x, renderTargetSize.y);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
// Setup mirror texture
ovrMirrorTextureDesc mirrorDesc;
memset(&mirrorDesc, 0, sizeof(mirrorDesc));
mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
mirrorDesc.Width = mirrorSize.x;
mirrorDesc.Height = mirrorSize.y;
if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirrorTexture))) TraceLog(LOG_WARNING, "Could not create mirror texture");
glGenFramebuffers(1, &mirrorFbo);
// Initialize Oculus Buffers
OculusLayer layer = InitOculusLayer(session);
OculusBuffer buffer = LoadOculusBuffer(session, layer.width, layer.height);
OculusMirror mirror = LoadOculusMirror(session, screenWidth, screenHeight);
layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
// Recenter OVR tracking origin
ovr_RecenterTrackingOrigin(session);
#endif
// Initialize rlgl internal buffers and OpenGL state
rlglInit();
rlglInitGraphics(0, 0, mirrorSize.x, mirrorSize.y);
rlClearColor(245, 245, 245, 255); // Define clear color
glEnable(GL_DEPTH_TEST);
rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector2 position = { mirrorSize.x/2 - 100, mirrorSize.y/2 - 100 };
Vector2 size = { 200, 200 };
Color color = { 180, 20, 20, 255 };
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
Camera camera;
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
//--------------------------------------------------------------------------------------
// Main game loop
while (!glfwWindowShouldClose(window))
{
// Update
//----------------------------------------------------------------------------------
frame++;
#if defined(PLATFORM_OCULUS)
frameIndex++;
ovrPosef eyePoses[2];
ovr_GetEyePoses(session, frame, ovrTrue, viewScaleDesc.HmdToEyeOffset, eyePoses, &eyeLayer.SensorSampleTime);
ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime);
layer.eyeLayer.RenderPose[0] = eyePoses[0];
layer.eyeLayer.RenderPose[1] = eyePoses[1];
#endif
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
int curIndex;
ovr_GetTextureSwapChainCurrentIndex(session, eyeTexture, &curIndex);
GLuint curTexId;
ovr_GetTextureSwapChainBufferGL(session, eyeTexture, curIndex, &curTexId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, curTexId, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#if defined(PLATFORM_OCULUS)
SetOculusBuffer(session, buffer);
#endif
rlClearScreenBuffers(); // Clear current framebuffer(s)
#if defined(PLATFORM_OCULUS)
for (int eye = 0; eye < 2; eye++)
{
glViewport(eyeLayer.Viewport[eye].Pos.x, eyeLayer.Viewport[eye].Pos.y,
eyeLayer.Viewport[eye].Size.w, eyeLayer.Viewport[eye].Size.h);
eyeLayer.RenderPose[eye] = eyePoses[eye];
// Convert struct ovrPosef { ovrQuatf Orientation; ovrVector3f Position; } to Matrix
// TODO: Review maths!
Matrix eyeOrientation = QuaternionToMatrix((Quaternion){ -eyePoses[eye].Orientation.x, -eyePoses[eye].Orientation.y, -eyePoses[eye].Orientation.z, -eyePoses[eye].Orientation.w });
Matrix eyePosition = MatrixTranslate(-eyePoses[eye].Position.x, -eyePoses[eye].Position.y, -eyePoses[eye].Position.z);
Matrix mvp = MatrixMultiply(eyeProjections[eye], MatrixMultiply(eyeOrientation, eyePosition));
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);
// NOTE: Nothing is drawn until rlglDraw()
DrawRectangleV(position, size, color);
//DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, color);
//DrawGrid(10, 1.0f);
Quaternion eyeRPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x,
layer.eyeLayer.RenderPose[eye].Orientation.y,
layer.eyeLayer.RenderPose[eye].Orientation.z,
layer.eyeLayer.RenderPose[eye].Orientation.w };
QuaternionInvert(&eyeRPose);
Matrix eyeOrientation = QuaternionToMatrix(eyeRPose);
Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x,
-layer.eyeLayer.RenderPose[eye].Position.y,
-layer.eyeLayer.RenderPose[eye].Position.z);
Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation);
Matrix modelview = MatrixMultiply(matView, eyeView);
SetMatrixModelview(modelview);
SetMatrixProjection(layer.eyeProjections[eye]);
#else
// Calculate projection matrix (from perspective) and view matrix from camera look at
Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj);
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
#endif
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
DrawGrid(10, 1.0f);
// NOTE: Internal buffers drawing (3D data)
rlglDraw();
// NOTE: rlglDraw() must be modified to support an external modelview-projection matrix
// TODO: Still working on it (now uses internal mvp)
rlglDraw(mvp);
#if !defined(PLATFORM_OCULUS)
// Draw '2D' elements in the scene (GUI)
// TODO: 2D drawing on Oculus Rift: requires an ovrLayerQuad layer
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
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 600.0f, 20.0f }, DARKGRAY);
// NOTE: Internal buffers drawing (2D data)
rlglDraw();
#endif
#if defined(PLATFORM_OCULUS)
}
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
ovr_CommitTextureSwapChain(session, eyeTexture);
ovrLayerHeader *headerList = &eyeLayer.Header;
ovr_SubmitFrame(session, frame, &viewScaleDesc, &headerList, 1);
UnsetOculusBuffer(buffer);
ovr_CommitTextureSwapChain(session, buffer.textureChain);
ovrLayerHeader *layers = &layer.eyeLayer.Header;
ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1);
// Blit mirror texture to back buffer
GLuint mirrorTextureId;
ovr_GetMirrorTextureBufferGL(session, mirrorTexture, &mirrorTextureId);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFbo);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0);
glBlitFramebuffer(0, 0, mirrorSize.x, mirrorSize.y, 0, mirrorSize.y, mirrorSize.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
BlitOculusMirror(session, mirror);
// Get session status information
ovrSessionStatus sessionStatus;
ovr_GetSessionStatus(session, &sessionStatus);
if (sessionStatus.ShouldQuit) TraceLog(LOG_WARNING, "OVR: Session should quit...");
if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
#endif
glfwSwapBuffers(window);
glfwPollEvents();
//----------------------------------------------------------------------------------
@ -307,20 +308,18 @@ int main()
// De-Initialization
//--------------------------------------------------------------------------------------
if (mirrorFbo) glDeleteFramebuffers(1, &mirrorFbo);
if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture);
#if defined(PLATFORM_OCULUS)
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
if (fbo) glDeleteFramebuffers(1, &fbo);
if (depthBuffer) glDeleteTextures(1, &depthBuffer);
if (eyeTexture) ovr_DestroyTextureSwapChain(session, eyeTexture);
ovr_Destroy(session); // Must be called after glfwTerminate() --> no
ovr_Shutdown();
#endif
rlglClose();
rlglClose(); // Unload rlgl internal buffers and default shader/texture
glfwDestroyWindow(window);
glfwTerminate();
ovr_Destroy(session); // Must be called after glfwTerminate()
ovr_Shutdown();
//--------------------------------------------------------------------------------------
return 0;
@ -330,24 +329,22 @@ int main()
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
// GLFW3: Error callback
static void ErrorCallback(int error, const char* description)
{
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
TraceLog(LOG_ERROR, description);
}
rlVertex2i(position.x, position.y);
rlVertex2i(position.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y);
rlEnd();
// GLFW3: Keyboard callback
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
// 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;
@ -370,30 +367,52 @@ static void TraceLog(int msgType, const char *text, ...)
//if (msgType == LOG_ERROR) exit(1);
}
static Matrix FromOvrMatrix(ovrMatrix4f ovrmat)
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{
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;
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y);
rlEnd();
}
// Draw a grid centered at (0, 0, 0)
static void DrawGrid(int slices, float spacing)
{
int halfSlices = slices / 2;
rlBegin(RL_LINES);
for(int i = -halfSlices; i <= halfSlices; i++)
{
if (i == 0)
{
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
}
else
{
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
}
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
}
rlEnd();
}
// Draw cube
@ -471,34 +490,282 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c
rlPopMatrix();
}
// Draw a grid centered at (0, 0, 0)
void DrawGrid(int slices, float spacing)
// Draw cube wires
void DrawCubeWires(Vector3 position, float width, float height, float length, Color color)
{
int halfSlices = slices / 2;
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlBegin(RL_LINES);
for(int i = -halfSlices; i <= halfSlices; i++)
{
if (i == 0)
{
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
}
else
{
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
}
rlPushMatrix();
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
rlTranslatef(position.x, position.y, position.z);
//rlRotatef(45, 0, 1, 0);
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
}
rlEnd();
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face -----------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
// Back Face ------------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
// Top Face -------------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Back
// Bottom Face ---------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right Back
rlEnd();
rlPopMatrix();
}
#if defined(PLATFORM_OCULUS)
// 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;
}
// 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(LOG_WARNING, "OVR: Failed to create swap textures buffer");
int textureCount = 0;
ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount);
if (!OVR_SUCCESS(result) || !textureCount) TraceLog(LOG_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);
}
// Set current Oculus buffer
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer)
{
GLuint currentTexId;
int currentIndex;
ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, &currentIndex);
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, &currentTexId);
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
//glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Same as rlClearScreenBuffers()
// NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
// and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
// - Require OculusBuffer format to be OVR_FORMAT_R8G8B8A8_UNORM_SRGB
// - Do NOT enable GL_FRAMEBUFFER_SRGB
//glEnable(GL_FRAMEBUFFER_SRGB);
}
// Unset Oculus buffer
static void UnsetOculusBuffer(OculusBuffer buffer)
{
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
// 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(LOG_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);
}
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);
glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
// Requires: session, hmdDesc
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;
}
#endif

View File

@ -1,498 +0,0 @@
/*******************************************************************************************
*
* raylib Oculus minimum sample (OpenGL 3.3 Core)
*
* NOTE: This example requires raylib module [rlgl]
*
* Compile rlgl using:
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
*
* Compile example using:
* gcc -o oculus_glfw_sample.exe oculus_glfw_sample.c rlgl.o glad.o -L. -lLibOVRRT32_1 -lglfw3 -lopengl32 -lgdi32 -std=c99
*
* 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)
*
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#if defined(_WIN32)
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#define OVR_OS_WIN32
#elif defined(__APPLE__)
#define GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_NSGL
#define OVR_OS_MAC
#elif defined(__linux__)
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#define OVR_OS_LINUX
#endif
#include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
//#include "GL/CAPI_GLE.h" // stripped-down GLEW/GLAD library to manage extensions (really required?)
//#include "Extras/OVR_Math.h" // math utilities C++ (really required?)
#define RLGL_STANDALONE
#include "rlgl.h"
#include <stdlib.h>
#include <stdio.h>
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct OculusBuffer {
ovrTextureSwapChain textureChain;
GLuint depthId;
GLuint fboId;
int width;
int height;
} OculusBuffer;
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height);
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer);
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer);
static void UnsetOculusBuffer(OculusBuffer buffer);
static void ErrorCallback(int error, const char* description)
{
fputs(description, stderr);
}
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
static void TraceLog(int msgType, const char *text, ...);
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
ovrSession session;
ovrGraphicsLuid luid; // Useless for OpenGL since SDK 0.7
ovrHmdDesc hmdDesc;
ovrResult result = ovr_Initialize(NULL);
if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device");
result = ovr_Create(&session, &luid);
if (OVR_FAILURE(result))
{
TraceLog(LOG_WARNING, "OVR: Could not create Oculus session");
ovr_Shutdown();
}
hmdDesc = ovr_GetHmdDesc(session);
TraceLog(LOG_INFO, "OVR: Product Name: %s", hmdDesc.ProductName);
TraceLog(LOG_INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer);
TraceLog(LOG_INFO, "OVR: Product ID: %i", hmdDesc.ProductId);
TraceLog(LOG_INFO, "OVR: Product Type: %i", hmdDesc.Type);
TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber);
TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
int screenWidth = hmdDesc.Resolution.w/2 + 100; // Added 100 pixels for testing
int screenHeight = hmdDesc.Resolution.h/2 + 100; // Added 100 pixels for testing
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
GLFWwindow *window;
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
glfwWindowHint(GLFW_DECORATED, GL_FALSE); // Mandatory on Oculus Rift to avoid program crash!
window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1);
}
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
rlglInit();
rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color
Vector2 position = { screenWidth/2 - 100, screenHeight/2 - 100 };
Vector2 size = { 200, 200 };
Color color = { 180, 20, 20, 255 };
//---------------------------------------------------------------------------
OculusBuffer eyeRenderBuffer[2];
GLuint mirrorFBO = 0;
ovrMirrorTexture mirrorTexture = NULL;
bool isVisible = true;
long long frameIndex = 0;
// Make eyes render buffers
ovrSizei recommendedTexSizeLeft = ovr_GetFovTextureSize(session, ovrEye_Left, hmdDesc.DefaultEyeFov[0], 1.0f);
eyeRenderBuffer[0] = LoadOculusBuffer(session, recommendedTexSizeLeft.w, recommendedTexSizeLeft.h);
ovrSizei recommendedTexSizeRight = ovr_GetFovTextureSize(session, ovrEye_Right, hmdDesc.DefaultEyeFov[1], 1.0f);
eyeRenderBuffer[1] = LoadOculusBuffer(session, recommendedTexSizeRight.w, recommendedTexSizeRight.h);
// Note: the mirror window can be any size, for this sample we use 1/2 the HMD resolution
ovrSizei windowSize = { hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2 };
// Define mirror texture descriptor
ovrMirrorTextureDesc mirrorDesc;
memset(&mirrorDesc, 0, sizeof(mirrorDesc));
mirrorDesc.Width = windowSize.w;
mirrorDesc.Height = windowSize.h;
mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
// Create mirror texture and an FBO used to copy mirror texture to back buffer
result = ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirrorTexture);
if (!OVR_SUCCESS(result)) TraceLog(LOG_WARNING, "OVR: Failed to create mirror texture");
// Configure the mirror read buffer
GLuint texId;
ovr_GetMirrorTextureBufferGL(session, mirrorTexture, &texId);
glGenFramebuffers(1, &mirrorFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFBO);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
glDeleteFramebuffers(1, &mirrorFBO);
TraceLog(LOG_WARNING, "OVR: Could not initialize mirror framebuffers");
}
glClearColor(1.0f, 0.1f, 0.1f, 0.0f);
glEnable(GL_DEPTH_TEST);
ovr_RecenterTrackingOrigin(session);
// FloorLevel will give tracking poses where the floor height is 0
ovr_SetTrackingOriginType(session, ovrTrackingOrigin_FloorLevel);
//--------------------------------------------------------------------------------------
// Main loop
while (!glfwWindowShouldClose(window))
{
// Update
//----------------------------------------------------------------------------------
frameIndex++;
// TODO: Update game here!
// Call ovr_GetRenderDesc each frame to get the ovrEyeRenderDesc, as the returned values (e.g. HmdToEyeOffset) may change at runtime.
ovrEyeRenderDesc eyeRenderDesc[2];
eyeRenderDesc[0] = ovr_GetRenderDesc(session, ovrEye_Left, hmdDesc.DefaultEyeFov[0]);
eyeRenderDesc[1] = ovr_GetRenderDesc(session, ovrEye_Right, hmdDesc.DefaultEyeFov[1]);
// Get eye poses, feeding in correct IPD offset
ovrPosef eyeRenderPose[2];
ovrVector3f hmdToEyeOffset[2] = { eyeRenderDesc[0].HmdToEyeOffset, eyeRenderDesc[1].HmdToEyeOffset };
double sensorSampleTime; // sensorSampleTime is fed into the layer later
ovr_GetEyePoses(session, frameIndex, ovrTrue, hmdToEyeOffset, eyeRenderPose, &sensorSampleTime);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
// Clear screen to red color
glClearColor(1.0f, 0.1f, 0.1f, 0.0f);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (isVisible)
{
for (int eye = 0; eye < 2; ++eye)
{
SetOculusBuffer(session, eyeRenderBuffer[eye]);
// TODO: Get view and projection matrices for the eye
// Sample using Oculus OVR_Math.h (C++)
/*
Matrix4f projection[eye] = Matrix4f(ovrMatrix4f_Projection(eyeRenderDesc[eye].Fov, 0.01f, 10000.0f, ovrProjection_None));
Matrix4f eyeOrientation[eye] = Matrix4f(Quatf(eyeRenderPose[eye].Orientation).Inverted());
Matrix4f eyePose[eye] = Matrix4f::Translation(-Vector3f(eyeRenderPose[eye].Position));
Matrix4f mvp = projection[eye]*eyeOrientation[eye]*eyePose[eye];
*/
// Sample using custom raymath.h (C) -INCOMPLETE-
/*
Matrix projection = MatrixPerspective(eyeRenderDesc[eye].Fov, ((double)screenWidth/(double)screenHeight), 0.01, 1000.0);
Matrix eyeOrientation = QuaternionToMatrix((Quaternion){ -eyeRenderPose[eye].Orientation.x, -eyeRenderPose[eye].Orientation.y,
-eyeRenderPose[eye].Orientation.z, -eyeRenderPose[eye].Orientation.w });
Matrix eyePose = MatrixTranslate(-eyeRenderPose[eye].Position.x, -eyeRenderPose[eye].Position.y, -eyeRenderPose[eye].Position.z);
Matrix mvp = MatrixMultiply(projection, MatrixMultiply(eyeOrientation, eyePose));
*/
// Render everything
// TODO: Pass calculated mvp matrix to default shader to consider projection and orientation!
//DrawRectangleV(position, size, color);
//rlglDraw();
UnsetOculusBuffer(eyeRenderBuffer[eye]);
// Commit changes to the textures so they get picked up frame
ovr_CommitTextureSwapChain(session, eyeRenderBuffer[eye].textureChain);
}
}
// Set up positional data
ovrViewScaleDesc viewScaleDesc;
viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
viewScaleDesc.HmdToEyeOffset[0] = hmdToEyeOffset[0];
viewScaleDesc.HmdToEyeOffset[1] = hmdToEyeOffset[1];
// Create the main eye layer
ovrLayerEyeFov eyeLayer;
eyeLayer.Header.Type = ovrLayerType_EyeFov;
eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; // Because OpenGL
for (int eye = 0; eye < 2; eye++)
{
eyeLayer.ColorTexture[eye] = eyeRenderBuffer[eye].textureChain;
eyeLayer.Viewport[eye] = (ovrRecti){ eyeRenderBuffer[eye].width, eyeRenderBuffer[eye].height };
eyeLayer.Fov[eye] = hmdDesc.DefaultEyeFov[eye];
eyeLayer.RenderPose[eye] = eyeRenderPose[eye];
eyeLayer.SensorSampleTime = sensorSampleTime;
}
// Append all the layers to global list
ovrLayerHeader *layerList = &eyeLayer.Header;
ovrResult result = ovr_SubmitFrame(session, frameIndex, NULL, &layerList, 1);
// exit the rendering loop if submit returns an error, will retry on ovrError_DisplayLost
if (!OVR_SUCCESS(result)) return 1;
isVisible = (result == ovrSuccess);
// Get session status information
ovrSessionStatus sessionStatus;
ovr_GetSessionStatus(session, &sessionStatus);
if (sessionStatus.ShouldQuit) TraceLog(LOG_WARNING, "OVR: Session should quit.");
if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
// Blit mirror texture to back buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
GLint w = mirrorDesc.Width;
GLint h = mirrorDesc.Height;
glBlitFramebuffer(0, h, w, 0, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glfwSwapBuffers(window);
glfwPollEvents();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
if (mirrorFBO) glDeleteFramebuffers(1, &mirrorFBO);
if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture);
for (int eye = 0; eye < 2; eye++) UnloadOculusBuffer(session, eyeRenderBuffer[eye]);
rlglClose();
glfwDestroyWindow(window);
glfwTerminate();
ovr_Destroy(session); // Must be called after glfwTerminate()
ovr_Shutdown();
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
// 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;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain);
int textureCount = 0;
ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount);
if (OVR_SUCCESS(result))
{
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);
}
}
// Generate framebuffer
glGenFramebuffers(1, &buffer.fboId);
// Create Depth texture
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);
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)
{
glDeleteTextures(1, &buffer.depthId);
buffer.depthId = 0;
}
if (buffer.fboId)
{
glDeleteFramebuffers(1, &buffer.fboId);
buffer.fboId = 0;
}
}
// Set current Oculus buffer
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer)
{
GLuint currentTexId;
int currentIndex;
ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, &currentIndex);
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, &currentTexId);
glBindFramebuffer(GL_FRAMEBUFFER, buffer.fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0);
glViewport(0, 0, buffer.width, buffer.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_FRAMEBUFFER_SRGB);
}
// Unset Oculus buffer
static void UnsetOculusBuffer(OculusBuffer buffer)
{
glBindFramebuffer(GL_FRAMEBUFFER, buffer.fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
}
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y);
rlEnd();
}
// 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 LOG_INFO: fprintf(stdout, "INFO: "); break;
case LOG_ERROR: fprintf(stdout, "ERROR: "); break;
case LOG_WARNING: fprintf(stdout, "WARNING: "); break;
case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break;
default: break;
}
vfprintf(stdout, text, args);
fprintf(stdout, "\n");
va_end(args);
//if (msgType == LOG_ERROR) exit(1);
}

View File

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

View File

@ -9,7 +9,7 @@
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
*
* Compile example using:
* gcc -o $(NAME_PART).exe $(FILE_NAME) rlgl.o glad.o -lglfw3 -lopengl32 -lgdi32 -std=c99
* gcc -o $(NAME_PART).exe $(FILE_NAME) rlgl.o -lglfw3 -lopengl32 -lgdi32 -std=c99
*
* 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)
@ -18,23 +18,168 @@
*
********************************************************************************************/
#include "glad.h"
#include <GLFW/glfw3.h>
#define GLAD_IMPLEMENTATION
#include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h> // Windows/Context and inputs management
#define RLGL_STANDALONE
#include "rlgl.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define RED (Color){ 230, 41, 55, 255 } // Red
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
//----------------------------------------------------------------------------------
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static void ErrorCallback(int error, const char* description)
static void ErrorCallback(int error, const char* description);
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void TraceLog(int msgType, const char *text, ...);
// Drawing functions (uses rlgl functionality)
static void DrawGrid(int slices, float spacing);
static void DrawCube(Vector3 position, float width, float height, float length, Color color);
static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main(void)
{
fputs(description, stderr);
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// Load OpenGL 3.3 extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1);
}
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
//--------------------------------------------------------
// Initialize rlgl internal buffers and OpenGL state
rlglInit();
rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector2 size = { 200, 200 };
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
Camera camera;
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
//--------------------------------------------------------------------------------------
// Main game loop
while (!glfwWindowShouldClose(window))
{
// Update
//----------------------------------------------------------------------------------
// ...
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
rlClearScreenBuffers(); // Clear current framebuffer
// Calculate projection matrix (from perspective) and view matrix from camera look at
Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj);
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
Matrix mvp = MatrixMultiply(matView, matProj);
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
DrawGrid(10, 1.0f);
// NOTE: Internal buffers drawing (3D data)
rlglDraw(mvp);
matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0);
MatrixTranspose(&matProj);
matView = MatrixIdentity();
mvp = MatrixMultiply(matView, matProj);
// TODO: 2D drawing on Oculus Rift: requires an ovrLayerQuad layer
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 300.0f, 20.0f }, DARKGRAY);
// NOTE: Internal buffers drawing (2D data)
rlglDraw(mvp);
glfwSwapBuffers(window);
glfwPollEvents();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
rlglClose(); // Unload rlgl internal buffers and default shader/texture
glfwDestroyWindow(window);
glfwTerminate();
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
// GLFW3: Error callback
static void ErrorCallback(int error, const char* description)
{
TraceLog(LOG_ERROR, description);
}
// GLFW3: Keyboard callback
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
@ -43,79 +188,31 @@ static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, i
}
}
void DrawRectangleV(Vector2 position, Vector2 size, Color color);
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main(void)
// Output a trace log message
static void TraceLog(int msgType, const char *text, ...)
{
const int screenWidth = 800;
const int screenHeight = 450;
GLFWwindow *window;
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit()) exit(EXIT_FAILURE);
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
va_list args;
va_start(args, text);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
switch(msgType)
{
printf("Cannot load GL extensions.\n");
exit(1);
case LOG_INFO: fprintf(stdout, "INFO: "); break;
case LOG_ERROR: fprintf(stdout, "ERROR: "); break;
case LOG_WARNING: fprintf(stdout, "WARNING: "); break;
case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break;
default: break;
}
rlglInit();
rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color
Vector2 position = { screenWidth/2 - 100, screenHeight/2 - 100 };
Vector2 size = { 200, 200 };
Color color = { 180, 20, 20, 255 };
while (!glfwWindowShouldClose(window))
{
rlClearScreenBuffers();
DrawRectangleV(position, size, color);
rlglDraw();
glfwSwapBuffers(window);
glfwPollEvents();
}
rlglClose();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
vfprintf(stdout, text, args);
fprintf(stdout, "\n");
va_end(args);
//if (msgType == LOG_ERROR) exit(1);
}
//----------------------------------------------------------------------------------
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
@ -128,4 +225,181 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color)
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y);
rlEnd();
}
}
// Draw a grid centered at (0, 0, 0)
static void DrawGrid(int slices, float spacing)
{
int halfSlices = slices / 2;
rlBegin(RL_LINES);
for(int i = -halfSlices; i <= halfSlices; i++)
{
if (i == 0)
{
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
}
else
{
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
}
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
}
rlEnd();
}
// Draw cube
// NOTE: Cube position is the center position
void DrawCube(Vector3 position, float width, float height, float length, Color color)
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlPushMatrix();
// NOTE: Be careful! Function order matters (rotate -> scale -> translate)
rlTranslatef(position.x, position.y, position.z);
//rlScalef(2.0f, 2.0f, 2.0f);
//rlRotatef(45, 0, 1, 0);
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face -----------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
// Back Face ------------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Top Face -------------------------------------------------------
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x-width/2, y+height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right
// Bottom Face ----------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left
// Right face -----------------------------------------------------
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left
// Left Face ------------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right
rlEnd();
rlPopMatrix();
}
// Draw cube wires
void DrawCubeWires(Vector3 position, float width, float height, float length, Color color)
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlPushMatrix();
rlTranslatef(position.x, position.y, position.z);
//rlRotatef(45, 0, 1, 0);
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face -----------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
// Back Face ------------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
// Top Face -------------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Back
// Bottom Face ---------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right Back
rlEnd();
rlPopMatrix();
}

View File

@ -73,7 +73,7 @@
//----------------------------------------------------------------------------------
#if defined(RAYMATH_STANDALONE)
// Vector2 type
// Vector2 type
typedef struct Vector2 {
float x;
float y;
@ -158,6 +158,7 @@ RMDEF void PrintMatrix(Matrix m); // Print matrix ut
//------------------------------------------------------------------------------------
RMDEF float QuaternionLength(Quaternion quat); // Compute the length of a quaternion
RMDEF void QuaternionNormalize(Quaternion *q); // Normalize provided quaternion
RMDEF void QuaternionInvert(Quaternion *quat); // Invert provided quaternion
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calculate two quaternion multiplication
RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); // Calculates spherical linear interpolation between two quaternions
RMDEF Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion for a given rotation matrix
@ -908,6 +909,23 @@ RMDEF void QuaternionNormalize(Quaternion *q)
q->w *= ilength;
}
// Invert provided quaternion
RMDEF void QuaternionInvert(Quaternion *quat)
{
float length = QuaternionLength(*quat);
float lengthSq = length*length;
if (lengthSq != 0.0)
{
float i = 1.0f/lengthSq;
quat->x *= -i;
quat->y *= -i;
quat->z *= -i;
quat->w *= i;
}
}
// Calculate two quaternion multiplication
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
{

File diff suppressed because it is too large Load Diff

View File

@ -32,15 +32,15 @@
//#define RLGL_STANDALONE // NOTE: To use rlgl as standalone lib, just uncomment this line
#ifndef RLGL_STANDALONE
#include "raylib.h" // Required for typedef(s): Model, Shader, Texture2D
#include "utils.h" // Required for function TraceLog()
#include "raylib.h" // Required for: Model, Shader, Texture2D
#include "utils.h" // Required for: TraceLog()
#endif
#ifdef RLGL_STANDALONE
#define RAYMATH_STANDALONE
#endif
#include "raymath.h" // Required for types: Vector3, Matrix
#include "raymath.h" // Required for: Vector3, Matrix
// Select desired OpenGL version
// NOTE: Those preprocessor defines are only used on rlgl module,
@ -130,47 +130,43 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
} TextureFormat;
// Bounding box type
typedef struct BoundingBox {
Vector3 min;
Vector3 max;
} BoundingBox;
// Mesh with vertex data type
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
// Vertex data definning a mesh
typedef struct Mesh {
int vertexCount; // num vertices
float *vertices; // vertex position (XYZ - 3 components per vertex)
float *texcoords; // vertex texture coordinates (UV - 2 components per vertex)
float *texcoords2; // vertex second texture coordinates (useful for lightmaps)
float *normals; // vertex normals (XYZ - 3 components per vertex)
float *tangents; // vertex tangents (XYZ - 3 components per vertex)
unsigned char *colors; // vertex colors (RGBA - 4 components per vertex)
BoundingBox bounds; // mesh limits defined by min and max points
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[6]; // OpenGL Vertex Buffer Objects id (6 types of vertex data)
int vertexCount; // number of vertices stored in arrays
int triangleCount; // number of triangles stored (indexed or not)
float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0)
float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4)
unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
unsigned short *indices;// vertex indices (in case vertex data comes indexed)
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh;
// Shader type
// Shader type (generic shader)
typedef struct Shader {
unsigned int id; // Shader program id
// Variable attributes
int vertexLoc; // Vertex attribute location point (vertex shader)
int texcoordLoc; // Texcoord attribute location point (vertex shader)
int normalLoc; // Normal attribute location point (vertex shader)
int colorLoc; // Color attibute location point (vertex shader)
// Uniforms
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Color uniform location point (fragment shader)
unsigned int id; // Shader program id
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader)
int mapNormalLoc; // Normal map texture uniform location point (fragment shader)
int mapSpecularLoc; // Specular map texture uniform location point (fragment shader)
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
int normalLoc; // Normal attribute location point (default-location = 2)
int colorLoc; // Color attibute location point (default-location = 3)
int tangentLoc; // Tangent attribute location point (default-location = 4)
int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Color uniform location point (fragment shader)
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader;
// Texture2D type
@ -192,27 +188,46 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Material type
typedef struct Material {
Shader shader;
Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular)
Texture2D texDiffuse; // Diffuse texture
Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture
Texture2D texDiffuse; // Diffuse texture
Texture2D texNormal; // Normal texture
Texture2D texSpecular; // Specular texture
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
Color colDiffuse;
Color colAmbient;
Color colSpecular;
float glossiness;
float normalDepth;
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material;
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees)
} Camera;
// Light type
typedef struct LightData {
unsigned int id; // Light unique id
int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
bool enabled; // Light enabled
Vector3 position; // Light position
Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Light attenuation radius light intensity reduced with distance (world distance)
Color diffuse; // Light diffuse color
float intensity; // Light intensity level
float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light;
// Light types
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
// 3d Model type
typedef struct Model {
Mesh mesh;
Matrix transform;
Material material;
} Model;
// Color blending modes (pre-defined)
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
#endif
@ -234,6 +249,7 @@ void rlScalef(float x, float y, float z); // Multiply the current matrix b
void rlMultMatrixf(float *mat); // Multiply the current matrix by another matrix
void rlFrustum(double left, double right, double bottom, double top, double near, double far);
void rlOrtho(double left, double right, double bottom, double top, double near, double far);
void rlViewport(int x, int y, int width, int height); // Set the viewport area
//------------------------------------------------------------------------------------
// Functions Declaration - Vertex level operations
@ -259,6 +275,8 @@ void rlEnableRenderTexture(unsigned int id); // Enable render texture (fbo)
void rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
void rlEnableDepthTest(void); // Enable depth test
void rlDisableDepthTest(void); // Disable depth test
void rlEnableWireMode(void); // Enable wire mode
void rlDisableWireMode(void); // Disable wire mode
void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
void rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) from GPU
void rlDeleteShader(unsigned int id); // Delete OpenGL shader program from GPU
@ -273,7 +291,7 @@ int rlGetVersion(void); // Returns current OpenGL versio
//------------------------------------------------------------------------------------
void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...)
void rlglClose(void); // De-init rlgl
void rlglDraw(Matrix mvp); // Draw VAO/VBO
void rlglDraw(void); // Draw VAO/VBO
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU
@ -281,35 +299,46 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a textur
void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data
void rlglGenerateMipmaps(Texture2D texture); // Generate mipmap data for selected texture
// NOTE: There is a set of shader related functions that are available to end user,
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h
Model rlglLoadModel(Mesh mesh); // Upload vertex data into GPU and provided VAO/VBO ids
void rlglDrawModel(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color, bool wires);
void rlglLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex); // Update vertex data on GPU (upload new data to one buffer)
void rlglDrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
void rlglUnloadMesh(Mesh *mesh); // Unload mesh data from CPU and GPU
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
void *rlglReadTexturePixels(Texture2D texture); // Read texture pixel data
// NOTE: There is a set of shader related functions that are available to end user,
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h
#if defined(RLGL_STANDALONE)
//------------------------------------------------------------------------------------
// Shaders System Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load custom shader strings and return program id
void UnloadShader(Shader shader); // Unload a custom shader from memory
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
void SetDefaultShader(void); // Set default shader to be used in batch draw
void SetModelShader(Model *model, Shader shader); // Link a shader to a model
Shader GetDefaultShader(void); // Get default shader
Shader GetStandardShader(void); // Get default shader
Texture2D GetDefaultTexture(void); // Get default texture
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
void BeginShaderMode(Shader shader); // Begin custom shader drawing
void EndShaderMode(void); // End custom shader drawing (use default shader)
void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
void DestroyLight(Light light); // Destroy a light and take it out of the list
#endif
#ifdef __cplusplus

View File

@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 fragTintColor;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
@ -16,7 +16,7 @@ out vec4 finalColor;
void main()
{
// Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor;
vec4 texelColor = texture(texture0, fragTexCoord)*colDiffuse*fragColor;
// Convert texel color to grayscale using NTSC conversion weights
float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));

View File

@ -11,7 +11,6 @@ uniform sampler2D texture0;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform vec4 colTint;
uniform vec4 colAmbient;
uniform vec4 colDiffuse;
uniform vec4 colSpecular;
@ -55,7 +54,7 @@ vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s)
spec = pow(dot(n, h), 3 + glossiness)*s;
}
return (diff*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb);
return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
}
vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)
@ -74,7 +73,7 @@ vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)
}
// Combine results
return (diff*l.intensity*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb);
return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);
}
vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)
@ -89,8 +88,10 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)
// 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
@ -104,7 +105,7 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)
spec = pow(dot(n, h), 3 + glossiness)*s;
}
return falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb);
return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
}
void main()
@ -123,7 +124,7 @@ void main()
vec3 lighting = colAmbient.rgb;
// Calculate normal texture color fetching or set to maximum normal value by default
if(useNormal == 1)
if (useNormal == 1)
{
n *= texture(texture1, fragTexCoord).rgb;
n = normalize(n);
@ -131,7 +132,7 @@ void main()
// Calculate specular texture color fetching or set to maximum specular value by default
float spec = 1.0;
if(useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);
if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);
for (int i = 0; i < lightsCount; i++)
{
@ -150,5 +151,5 @@ void main()
}
// Calculate final fragment color
finalColor = vec4(texelColor.rgb*lighting*colTint.rgb, texelColor.a*colTint.a);
finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a);
}

View File

@ -33,7 +33,7 @@ int main()
Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
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 (diffuse map)
SetModelTexture(&dwarf, texture); // Bind texture to model
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
@ -94,10 +94,12 @@ int main()
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
SetCustomShader(shader);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
SetDefaultShader();
BeginShaderMode(shader);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
EndShaderMode();
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY);

View File

@ -33,7 +33,7 @@ int main()
Camera camera = {{ 3.0f, 3.0f, 3.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
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 (diffuse map)
SetModelTexture(&dwarf, texture); // Bind texture to model
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
@ -80,10 +80,12 @@ int main()
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
SetCustomShader(shader);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
SetDefaultShader();
BeginShaderMode(shader);
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
EndShaderMode();
DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, DARKGRAY);

View File

@ -65,16 +65,16 @@ int main()
// Activate our custom shader to be applied on next shapes/textures drawings
SetCustomShader(shader);
BeginShaderMode(shader);
DrawText("USING CUSTOM SHADER", 190, 40, 10, RED);
DrawText("USING CUSTOM SHADER", 190, 40, 10, RED);
DrawRectangle(250 - 60, 90, 120, 60, RED);
DrawRectangleGradient(250 - 90, 170, 180, 130, MAROON, GOLD);
DrawRectangleLines(250 - 40, 320, 80, 60, ORANGE);
DrawRectangle(250 - 60, 90, 120, 60, RED);
DrawRectangleGradient(250 - 90, 170, 180, 130, MAROON, GOLD);
DrawRectangleLines(250 - 40, 320, 80, 60, ORANGE);
// Activate our default shader for next drawings
SetDefaultShader();
EndShaderMode();
DrawText("USING DEFAULT SHADER", 370, 40, 10, RED);
@ -89,12 +89,12 @@ int main()
DrawPoly((Vector2){430, 320}, 6, 80, 0, BROWN);
// Activate our custom shader to be applied on next shapes/textures drawings
SetCustomShader(shader);
BeginShaderMode(shader);
DrawTexture(sonic, 380, -10, WHITE); // Using custom shader
DrawTexture(sonic, 380, -10, WHITE); // Using custom shader
// Activate our default shader for next drawings
SetDefaultShader();
EndShaderMode();
EndDrawing();
//----------------------------------------------------------------------------------

View File

@ -33,21 +33,19 @@ int main()
Camera camera = {{ 4.0f, 4.0f, 4.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Material material = LoadStandardMaterial();
material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture
material.texNormal = LoadTexture("resources/model/dwarf_normal.png"); // Load model normal texture
material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture
material.texNormal = LoadTexture("resources/model/dwarf_normal.png"); // Load model normal texture
material.texSpecular = LoadTexture("resources/model/dwarf_specular.png"); // Load model specular texture
material.colDiffuse = (Color){255, 255, 255, 255};
material.colDiffuse = WHITE;
material.colAmbient = (Color){0, 0, 10, 255};
material.colSpecular = (Color){255, 255, 255, 255};
material.colSpecular = WHITE;
material.glossiness = 50.0f;
dwarf.material = material; // Apply material to model
Model dwarf2 = LoadModel("resources/model/dwarf.obj"); // Load OBJ model
Light spotLight = CreateLight(LIGHT_SPOT, (Vector3){3.0f, 5.0f, 2.0f}, (Color){255, 255, 255, 255});
spotLight->target = (Vector3){0.0f, 0.0f, 0.0f};
@ -91,7 +89,9 @@ int main()
DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture
DrawLights(); // Draw all created lights in 3D world
DrawLight(spotLight); // Draw spot light
DrawLight(dirLight); // Draw directional light
DrawLight(pointLight); // Draw point light
DrawGrid(10, 1.0f); // Draw a grid

View File

@ -102,20 +102,22 @@ int main()
ClearBackground(DARKGRAY);
SetBlendMode(blending);
BeginBlendMode(blending);
// Draw active particles
for (int i = 0; i < MAX_PARTICLES; i++)
{
if (mouseTail[i].active) DrawTexturePro(smoke, (Rectangle){ 0, 0, smoke.width, smoke.height },
(Rectangle){ mouseTail[i].position.x, mouseTail[i].position.y, smoke.width*mouseTail[i].size, smoke.height*mouseTail[i].size },
(Vector2){ smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2 }, mouseTail[i].rotation,
Fade(mouseTail[i].color, mouseTail[i].alpha));
}
// Draw active particles
for (int i = 0; i < MAX_PARTICLES; i++)
{
if (mouseTail[i].active) DrawTexturePro(smoke, (Rectangle){ 0, 0, smoke.width, smoke.height },
(Rectangle){ mouseTail[i].position.x, mouseTail[i].position.y, smoke.width*mouseTail[i].size, smoke.height*mouseTail[i].size },
(Vector2){ smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2 }, mouseTail[i].rotation,
Fade(mouseTail[i].color, mouseTail[i].alpha));
}
DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, RAYWHITE);
EndBlendMode();
if (blending == BLEND_ALPHA) DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, RAYWHITE);
DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, BLACK);
if (blending == BLEND_ALPHA) DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, BLACK);
else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE);
EndDrawing();

View File

@ -1,73 +0,0 @@
The OpenGL Extension Wrangler Library
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
Copyright (C) 2002, Lev Povalahev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
Mesa 3-D graphics library
Version: 7.0
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyright (c) 2007 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,506 +0,0 @@
/**********************************************************************************************
*
* raylib 1.2 (www.raylib.com)
*
* A simple and easy-to-use library to learn videogames programming
*
* Features:
* Library written in plain C code (C99)
* Uses C# PascalCase/camelCase notation
* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2)
* Unique OpenGL abstraction layer [rlgl]
* Powerful fonts module with SpriteFonts support
* Multiple textures support, including DDS and mipmaps generation
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
* Powerful math module for Vector and Matrix operations [raymath]
* Audio loading and playing with streaming support (WAV and OGG)
* Multiplatform support, including Android devices, Raspberry Pi and HTML5
*
* Used external libs:
* GLFW3 (www.glfw.org) for window/context management and input
* GLEW for OpenGL extensions loading (3.3+ and ES2)
* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
* stb_image_write (Sean Barret) for image writting (PNG)
* stb_vorbis (Sean Barret) for ogg audio loading
* OpenAL Soft for audio device/context management
* tinfl for data decompression (DEFLATE algorithm)
*
* Some design decisions:
* 32bit Colors - All defined color are always RGBA
* 32bit Textures - All loaded images are converted automatically to RGBA textures
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
* One custom default font is loaded automatically when InitWindow()
* If using OpenGL 3.3+ or ES2, one default shader is loaded automatically (internally defined)
*
* -- LICENSE (raylib v1.2, September 2014) --
*
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* 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
* 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
* 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
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef RAYLIB_H
#define RAYLIB_H
// Choose your platform here or just define it at compile time: -DPLATFORM_DESKTOP
//#define PLATFORM_DESKTOP // Windows, Linux or OSX
//#define PLATFORM_ANDROID // Android device
//#define PLATFORM_RPI // Raspberry Pi
//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
// Security check in case no PLATFORM_* defined
#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI) && !defined(PLATFORM_WEB)
#define PLATFORM_DESKTOP
#endif
#if defined(PLATFORM_ANDROID)
#include <android_native_app_glue.h> // Defines android_app struct
#endif
//----------------------------------------------------------------------------------
// Some basic Defines
//----------------------------------------------------------------------------------
#ifndef PI
#define PI 3.14159265358979323846
#endif
#define DEG2RAD (PI / 180.0f)
#define RAD2DEG (180.0f / PI)
// raylib Config Flags
#define FLAG_FULLSCREEN_MODE 1
#define FLAG_SHOW_LOGO 2
#define FLAG_SHOW_MOUSE_CURSOR 4
#define FLAG_CENTERED_MODE 8
#define FLAG_MSAA_4X_HINT 16
// Keyboard Function Keys
#define KEY_SPACE 32
#define KEY_ESCAPE 256
#define KEY_ENTER 257
#define KEY_BACKSPACE 259
#define KEY_RIGHT 262
#define KEY_LEFT 263
#define KEY_DOWN 264
#define KEY_UP 265
#define KEY_F1 290
#define KEY_F2 291
#define KEY_F3 292
#define KEY_F4 293
#define KEY_F5 294
#define KEY_F6 295
#define KEY_F7 296
#define KEY_F8 297
#define KEY_F9 298
#define KEY_F10 299
#define KEY_LEFT_SHIFT 340
#define KEY_LEFT_CONTROL 341
#define KEY_LEFT_ALT 342
#define KEY_RIGHT_SHIFT 344
#define KEY_RIGHT_CONTROL 345
#define KEY_RIGHT_ALT 346
// Mouse Buttons
#define MOUSE_LEFT_BUTTON 0
#define MOUSE_RIGHT_BUTTON 1
#define MOUSE_MIDDLE_BUTTON 2
// Gamepad Number
#define GAMEPAD_PLAYER1 0
#define GAMEPAD_PLAYER2 1
#define GAMEPAD_PLAYER3 2
#define GAMEPAD_PLAYER4 3
// Gamepad Buttons
// NOTE: Adjusted for a PS3 USB Controller
#define GAMEPAD_BUTTON_A 2
#define GAMEPAD_BUTTON_B 1
#define GAMEPAD_BUTTON_X 3
#define GAMEPAD_BUTTON_Y 4
#define GAMEPAD_BUTTON_R1 7
#define GAMEPAD_BUTTON_R2 5
#define GAMEPAD_BUTTON_L1 6
#define GAMEPAD_BUTTON_L2 8
#define GAMEPAD_BUTTON_SELECT 9
#define GAMEPAD_BUTTON_START 10
// TODO: Review Xbox360 USB Controller Buttons
// Some Basic Colors
// NOTE: Custom raylib color palette for amazing visuals on WHITE background
#define LIGHTGRAY (Color){ 200, 200, 200, 255 } // Light Gray
#define GRAY (Color){ 130, 130, 130, 255 } // Gray
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
#define GOLD (Color){ 255, 203, 0, 255 } // Gold
#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
#define PINK (Color){ 255, 109, 194, 255 } // Pink
#define RED (Color){ 230, 41, 55, 255 } // Red
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
#define GREEN (Color){ 0, 228, 48, 255 } // Green
#define LIME (Color){ 0, 158, 47, 255 } // Lime
#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
#define BLUE (Color){ 0, 121, 241, 255 } // Blue
#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
#define BROWN (Color){ 127, 106, 79, 255 } // Brown
#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
#define WHITE (Color){ 255, 255, 255, 255 } // White
#define BLACK (Color){ 0, 0, 0, 255 } // Black
#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Boolean type
typedef enum { false, true } bool;
// byte type
typedef unsigned char byte;
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
// Color type, RGBA (32bit)
typedef struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} Color;
// Rectangle type
typedef struct Rectangle {
int x;
int y;
int width;
int height;
} Rectangle;
// Image type, bpp always RGBA (32bit)
// NOTE: Data stored in CPU memory (RAM)
typedef struct Image {
Color *pixels;
int width;
int height;
} Image;
// Texture2D type, bpp always RGBA (32bit)
// NOTE: Data stored in GPU memory
typedef struct Texture2D {
unsigned int id; // OpenGL id
int width;
int height;
} Texture2D;
// Character type (one font glyph)
typedef struct Character {
int value; //char value = ' '; (int)value = 32;
int x;
int y;
int w;
int h;
} Character;
// SpriteFont type, includes texture and charSet array data
typedef struct SpriteFont {
Texture2D texture;
int numChars;
Character *charSet;
} SpriteFont;
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position;
Vector3 target;
Vector3 up;
} Camera;
// Vertex data definning a mesh
typedef struct VertexData {
int vertexCount;
float *vertices; // 3 components per vertex
float *texcoords; // 2 components per vertex
float *normals; // 3 components per vertex
unsigned char *colors; // 4 components per vertex
} VertexData;
// 3d Model type
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
typedef struct Model {
VertexData mesh;
unsigned int vaoId;
unsigned int vboId[4];
unsigned int textureId;
//Matrix transform;
} Model;
// Sound source type
typedef struct Sound {
unsigned int source;
unsigned int buffer;
} Sound;
// Wave type, defines audio wave data
typedef struct Wave {
void *data; // Buffer data pointer
unsigned int dataSize; // Data size in bytes
unsigned int sampleRate;
short bitsPerSample;
short channels;
} Wave;
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
//------------------------------------------------------------------------------------
// Global Variables Definition
//------------------------------------------------------------------------------------
// It's lonely here...
//------------------------------------------------------------------------------------
// Window and Graphics Device Functions (Module: core)
//------------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
void InitWindow(int width, int height, struct android_app *state); // Init Android activity
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
#endif
void CloseWindow(void); // Close Window and Terminate Context
bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
#endif
int GetScreenWidth(void); // Get current screen width
int GetScreenHeight(void); // Get current screen height
int GetKeyPressed(void); // Get latest key pressed
void ClearBackground(Color color); // Sets Background Color
void BeginDrawing(void); // Setup drawing canvas to start drawing
void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering)
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
void SetTargetFPS(int fps); // Set target FPS (maximum)
float GetFPS(void); // Returns current FPS
float GetFrameTime(void); // Returns time in seconds for one frame
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
int GetHexValue(Color color); // Returns hexadecimal value for a Color
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
void SetupFlags(char flags); // Enable some window configurations
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
bool IsKeyPressed(int key); // Detect if a key has been pressed once
bool IsKeyDown(int key); // Detect if a key is being pressed
bool IsKeyReleased(int key); // Detect if a key has been released once
bool IsKeyUp(int key); // Detect if a key is NOT being pressed
bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
int GetMouseX(void); // Returns mouse position X
int GetMouseY(void); // Returns mouse position Y
Vector2 GetMousePosition(void); // Returns mouse position XY
void SetMousePosition(Vector2 position); // Set mouse position XY
int GetMouseWheelMove(void); // Returns mouse wheel movement Y
#endif
#if defined(PLATFORM_DESKTOP)
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
#endif
#if defined(PLATFORM_ANDROID)
bool IsScreenTouched(void); // Detect screen touch event
int GetTouchX(void); // Returns touch position X
int GetTouchY(void); // Returns touch position Y
Vector2 GetTouchPosition(void); // Returns touch position XY
#endif
//------------------------------------------------------------------------------------
// Basic Shapes Drawing Functions (Module: shapes)
//------------------------------------------------------------------------------------
void DrawPixel(int posX, int posY, Color color); // Draw a pixel
void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
//------------------------------------------------------------------------------------
// Texture Loading and Drawing Functions (Module: textures)
//------------------------------------------------------------------------------------
Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
Texture2D LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps)
Texture2D CreateTexture(Image image, bool genMipmaps); // [DEPRECATED] Same as LoadTextureFromImage()
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
void ConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
float rotation, Color tint);
//------------------------------------------------------------------------------------
// Font Loading and Text Drawing Functions (Module: text)
//------------------------------------------------------------------------------------
SpriteFont GetDefaultFont(void); // Get the default SpriteFont
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
int fontSize, int spacing, Color tint);
int MeasureText(const char *text, int fontSize); // Measure string width for default font
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height)
void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
//------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4]); // Draw a quad
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
void DrawGizmo(Vector3 position); // Draw simple gizmo
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale); // Draw gizmo with extended parameters
//DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
void UnloadModel(Model model); // Unload 3d model from memory
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
void DrawModelEx(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color tint); // Draw a model with extended parameters
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires (with texture if set)
void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------
void InitAudioDevice(void); // Initialize audio device and context
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
Sound LoadSound(char *fileName); // Load sound to memory
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
void UnloadSound(Sound sound); // Unload sound
void PlaySound(Sound sound); // Play a sound
void PauseSound(Sound sound); // Pause a sound
void StopSound(Sound sound); // Stop playing a sound
bool SoundIsPlaying(Sound sound); // Check if a sound is currently playing
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
void PlayMusicStream(char *fileName); // Start music playing (open stream)
void StopMusicStream(void); // Stop music playing (close stream)
void PauseMusicStream(void); // Pause music playing
void ResumeMusicStream(void); // Resume playing paused music
bool MusicIsPlaying(void); // Check if music is playing
void SetMusicVolume(float volume); // Set volume for music (1.0 is max level)
float GetMusicTimeLength(void); // Get current music time length (in seconds)
float GetMusicTimePlayed(void); // Get current music time played (in seconds)
#ifdef __cplusplus
}
#endif
#endif // RAYLIB_H

View File

View File

View File

@ -1,506 +0,0 @@
/**********************************************************************************************
*
* raylib 1.2 (www.raylib.com)
*
* A simple and easy-to-use library to learn videogames programming
*
* Features:
* Library written in plain C code (C99)
* Uses C# PascalCase/camelCase notation
* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2)
* Unique OpenGL abstraction layer [rlgl]
* Powerful fonts module with SpriteFonts support
* Multiple textures support, including DDS and mipmaps generation
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
* Powerful math module for Vector and Matrix operations [raymath]
* Audio loading and playing with streaming support (WAV and OGG)
* Multiplatform support, including Android devices, Raspberry Pi and HTML5
*
* Used external libs:
* GLFW3 (www.glfw.org) for window/context management and input
* GLEW for OpenGL extensions loading (3.3+ and ES2)
* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
* stb_image_write (Sean Barret) for image writting (PNG)
* stb_vorbis (Sean Barret) for ogg audio loading
* OpenAL Soft for audio device/context management
* tinfl for data decompression (DEFLATE algorithm)
*
* Some design decisions:
* 32bit Colors - All defined color are always RGBA
* 32bit Textures - All loaded images are converted automatically to RGBA textures
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
* One custom default font is loaded automatically when InitWindow()
* If using OpenGL 3.3+ or ES2, one default shader is loaded automatically (internally defined)
*
* -- LICENSE (raylib v1.2, September 2014) --
*
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* 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
* 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
* 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
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef RAYLIB_H
#define RAYLIB_H
// Choose your platform here or just define it at compile time: -DPLATFORM_DESKTOP
//#define PLATFORM_DESKTOP // Windows, Linux or OSX
//#define PLATFORM_ANDROID // Android device
//#define PLATFORM_RPI // Raspberry Pi
//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
// Security check in case no PLATFORM_* defined
#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI) && !defined(PLATFORM_WEB)
#define PLATFORM_DESKTOP
#endif
#if defined(PLATFORM_ANDROID)
#include <android_native_app_glue.h> // Defines android_app struct
#endif
//----------------------------------------------------------------------------------
// Some basic Defines
//----------------------------------------------------------------------------------
#ifndef PI
#define PI 3.14159265358979323846
#endif
#define DEG2RAD (PI / 180.0f)
#define RAD2DEG (180.0f / PI)
// raylib Config Flags
#define FLAG_FULLSCREEN_MODE 1
#define FLAG_SHOW_LOGO 2
#define FLAG_SHOW_MOUSE_CURSOR 4
#define FLAG_CENTERED_MODE 8
#define FLAG_MSAA_4X_HINT 16
// Keyboard Function Keys
#define KEY_SPACE 32
#define KEY_ESCAPE 256
#define KEY_ENTER 257
#define KEY_BACKSPACE 259
#define KEY_RIGHT 262
#define KEY_LEFT 263
#define KEY_DOWN 264
#define KEY_UP 265
#define KEY_F1 290
#define KEY_F2 291
#define KEY_F3 292
#define KEY_F4 293
#define KEY_F5 294
#define KEY_F6 295
#define KEY_F7 296
#define KEY_F8 297
#define KEY_F9 298
#define KEY_F10 299
#define KEY_LEFT_SHIFT 340
#define KEY_LEFT_CONTROL 341
#define KEY_LEFT_ALT 342
#define KEY_RIGHT_SHIFT 344
#define KEY_RIGHT_CONTROL 345
#define KEY_RIGHT_ALT 346
// Mouse Buttons
#define MOUSE_LEFT_BUTTON 0
#define MOUSE_RIGHT_BUTTON 1
#define MOUSE_MIDDLE_BUTTON 2
// Gamepad Number
#define GAMEPAD_PLAYER1 0
#define GAMEPAD_PLAYER2 1
#define GAMEPAD_PLAYER3 2
#define GAMEPAD_PLAYER4 3
// Gamepad Buttons
// NOTE: Adjusted for a PS3 USB Controller
#define GAMEPAD_BUTTON_A 2
#define GAMEPAD_BUTTON_B 1
#define GAMEPAD_BUTTON_X 3
#define GAMEPAD_BUTTON_Y 4
#define GAMEPAD_BUTTON_R1 7
#define GAMEPAD_BUTTON_R2 5
#define GAMEPAD_BUTTON_L1 6
#define GAMEPAD_BUTTON_L2 8
#define GAMEPAD_BUTTON_SELECT 9
#define GAMEPAD_BUTTON_START 10
// TODO: Review Xbox360 USB Controller Buttons
// Some Basic Colors
// NOTE: Custom raylib color palette for amazing visuals on WHITE background
#define LIGHTGRAY (Color){ 200, 200, 200, 255 } // Light Gray
#define GRAY (Color){ 130, 130, 130, 255 } // Gray
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
#define GOLD (Color){ 255, 203, 0, 255 } // Gold
#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
#define PINK (Color){ 255, 109, 194, 255 } // Pink
#define RED (Color){ 230, 41, 55, 255 } // Red
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
#define GREEN (Color){ 0, 228, 48, 255 } // Green
#define LIME (Color){ 0, 158, 47, 255 } // Lime
#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
#define BLUE (Color){ 0, 121, 241, 255 } // Blue
#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
#define BROWN (Color){ 127, 106, 79, 255 } // Brown
#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
#define WHITE (Color){ 255, 255, 255, 255 } // White
#define BLACK (Color){ 0, 0, 0, 255 } // Black
#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Boolean type
typedef enum { false, true } bool;
// byte type
typedef unsigned char byte;
// Vector2 type
typedef struct Vector2 {
float x;
float y;
} Vector2;
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
// Color type, RGBA (32bit)
typedef struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} Color;
// Rectangle type
typedef struct Rectangle {
int x;
int y;
int width;
int height;
} Rectangle;
// Image type, bpp always RGBA (32bit)
// NOTE: Data stored in CPU memory (RAM)
typedef struct Image {
Color *pixels;
int width;
int height;
} Image;
// Texture2D type, bpp always RGBA (32bit)
// NOTE: Data stored in GPU memory
typedef struct Texture2D {
unsigned int id; // OpenGL id
int width;
int height;
} Texture2D;
// Character type (one font glyph)
typedef struct Character {
int value; //char value = ' '; (int)value = 32;
int x;
int y;
int w;
int h;
} Character;
// SpriteFont type, includes texture and charSet array data
typedef struct SpriteFont {
Texture2D texture;
int numChars;
Character *charSet;
} SpriteFont;
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position;
Vector3 target;
Vector3 up;
} Camera;
// Vertex data definning a mesh
typedef struct VertexData {
int vertexCount;
float *vertices; // 3 components per vertex
float *texcoords; // 2 components per vertex
float *normals; // 3 components per vertex
unsigned char *colors; // 4 components per vertex
} VertexData;
// 3d Model type
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
typedef struct Model {
VertexData mesh;
unsigned int vaoId;
unsigned int vboId[4];
unsigned int textureId;
//Matrix transform;
} Model;
// Sound source type
typedef struct Sound {
unsigned int source;
unsigned int buffer;
} Sound;
// Wave type, defines audio wave data
typedef struct Wave {
void *data; // Buffer data pointer
unsigned int dataSize; // Data size in bytes
unsigned int sampleRate;
short bitsPerSample;
short channels;
} Wave;
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
//------------------------------------------------------------------------------------
// Global Variables Definition
//------------------------------------------------------------------------------------
// It's lonely here...
//------------------------------------------------------------------------------------
// Window and Graphics Device Functions (Module: core)
//------------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
void InitWindow(int width, int height, struct android_app *state); // Init Android activity
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
#endif
void CloseWindow(void); // Close Window and Terminate Context
bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
#endif
int GetScreenWidth(void); // Get current screen width
int GetScreenHeight(void); // Get current screen height
int GetKeyPressed(void); // Get latest key pressed
void ClearBackground(Color color); // Sets Background Color
void BeginDrawing(void); // Setup drawing canvas to start drawing
void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering)
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
void SetTargetFPS(int fps); // Set target FPS (maximum)
float GetFPS(void); // Returns current FPS
float GetFrameTime(void); // Returns time in seconds for one frame
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
int GetHexValue(Color color); // Returns hexadecimal value for a Color
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
void SetupFlags(char flags); // Enable some window configurations
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
bool IsKeyPressed(int key); // Detect if a key has been pressed once
bool IsKeyDown(int key); // Detect if a key is being pressed
bool IsKeyReleased(int key); // Detect if a key has been released once
bool IsKeyUp(int key); // Detect if a key is NOT being pressed
bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
int GetMouseX(void); // Returns mouse position X
int GetMouseY(void); // Returns mouse position Y
Vector2 GetMousePosition(void); // Returns mouse position XY
void SetMousePosition(Vector2 position); // Set mouse position XY
int GetMouseWheelMove(void); // Returns mouse wheel movement Y
#endif
#if defined(PLATFORM_DESKTOP)
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
#endif
#if defined(PLATFORM_ANDROID)
bool IsScreenTouched(void); // Detect screen touch event
int GetTouchX(void); // Returns touch position X
int GetTouchY(void); // Returns touch position Y
Vector2 GetTouchPosition(void); // Returns touch position XY
#endif
//------------------------------------------------------------------------------------
// Basic Shapes Drawing Functions (Module: shapes)
//------------------------------------------------------------------------------------
void DrawPixel(int posX, int posY, Color color); // Draw a pixel
void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
//------------------------------------------------------------------------------------
// Texture Loading and Drawing Functions (Module: textures)
//------------------------------------------------------------------------------------
Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
Texture2D LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps)
Texture2D CreateTexture(Image image, bool genMipmaps); // [DEPRECATED] Same as LoadTextureFromImage()
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
void ConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
float rotation, Color tint);
//------------------------------------------------------------------------------------
// Font Loading and Text Drawing Functions (Module: text)
//------------------------------------------------------------------------------------
SpriteFont GetDefaultFont(void); // Get the default SpriteFont
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
int fontSize, int spacing, Color tint);
int MeasureText(const char *text, int fontSize); // Measure string width for default font
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height)
void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
//------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4]); // Draw a quad
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
void DrawGizmo(Vector3 position); // Draw simple gizmo
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale); // Draw gizmo with extended parameters
//DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
void UnloadModel(Model model); // Unload 3d model from memory
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
void DrawModelEx(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color tint); // Draw a model with extended parameters
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires (with texture if set)
void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------
void InitAudioDevice(void); // Initialize audio device and context
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
Sound LoadSound(char *fileName); // Load sound to memory
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
void UnloadSound(Sound sound); // Unload sound
void PlaySound(Sound sound); // Play a sound
void PauseSound(Sound sound); // Pause a sound
void StopSound(Sound sound); // Stop playing a sound
bool SoundIsPlaying(Sound sound); // Check if a sound is currently playing
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
void PlayMusicStream(char *fileName); // Start music playing (open stream)
void StopMusicStream(void); // Stop music playing (close stream)
void PauseMusicStream(void); // Pause music playing
void ResumeMusicStream(void); // Resume playing paused music
bool MusicIsPlaying(void); // Check if music is playing
void SetMusicVolume(float volume); // Set volume for music (1.0 is max level)
float GetMusicTimeLength(void); // Get current music time length (in seconds)
float GetMusicTimePlayed(void); // Get current music time played (in seconds)
#ifdef __cplusplus
}
#endif
#endif // RAYLIB_H

Binary file not shown.

View File

@ -8,14 +8,14 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 fragTintColor;
uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
void main()
{
// Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor;
vec4 texelColor = texture(texture0, fragTexCoord)*colDiffuse*fragColor;
// Convert texel color to grayscale using NTSC conversion weights
float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));

View File

@ -8,7 +8,7 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 fragTintColor;
uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
@ -19,5 +19,5 @@ void main()
// NOTE: Implement here your fragment shader code
gl_FragColor = texelColor*fragTintColor;
gl_FragColor = texelColor*colDiffuse;
}

View File

@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 fragTintColor;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
@ -16,7 +16,7 @@ out vec4 finalColor;
void main()
{
// Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor;
vec4 texelColor = texture(texture0, fragTexCoord)*colDiffuse*fragColor;
// Convert texel color to grayscale using NTSC conversion weights
float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114));

View File

@ -6,7 +6,7 @@ in vec3 fragNormal;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 fragTintColor;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
@ -44,7 +44,7 @@ vec3 DiffuseLighting(in vec3 N, in vec3 L)
// Lambertian reflection calculation
float diffuse = clamp(dot(N, L), 0, 1);
return (fragTintColor.xyz*lightDiffuseColor*lightIntensity*diffuse);
return (colDiffuse.xyz*lightDiffuseColor*lightIntensity*diffuse);
}
// Calculate specular lighting component

View File

@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 fragTintColor;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
@ -20,5 +20,5 @@ void main()
// NOTE: Implement here your fragment shader code
finalColor = texelColor*fragTintColor;
finalColor = texelColor*colDiffuse;
}

View File

@ -3,30 +3,30 @@ project (raylib)
SET(PLATFORM_TO_USE "PLATFORM_DESKTOP" CACHE STRING "Platform to compile for")
SET_PROPERTY(CACHE PLATFORM_TO_USE PROPERTY STRINGS PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB)
set(CMAKE_C_FLAGS "-O1 -Wall -std=gnu99 -fgnu89-inline")
set(CMAKE_C_FLAGS "-O1 -Wall -std=gnu99 -fgnu89-inline -Wno-missing-braces")
IF(${PLATFORM_TO_USE} MATCHES "PLATFORM_DESKTOP")
add_definitions(-DPLATFORM_DESKTOP, -DGRAPHICS_API_OPENGL_33)
include_directories("." "src/" "external/openal_soft/include" "external/glew/include" "external/glfw3/include")
include_directories("." "external/" "external/openal_soft/include" "external/glfw3/include")
ENDIF()
IF(${PLATFORM_TO_USE} MATCHES "PLATFORM_RPI")
add_definitions(-DPLATFORM_RPI, -GRAPHICS_API_OPENGL_ES2)
include_directories("." "/opt/vc/include" "/opt/vc/include/interface/vmcs_host/linux" "/opt/vc/include/interface/vcos/pthreads")
include_directories("." "external/" "/opt/vc/include" "/opt/vc/include/interface/vmcs_host/linux" "/opt/vc/include/interface/vcos/pthreads")
ENDIF()
IF(${PLATFORM_TO_USE} MATCHES "PLATFORM_WEB")
add_definitions(-DPLATFORM_WEB, -GRAPHICS_API_OPENGL_ES2)
include_directories("." "src/" "external/openal_soft/include" "external/glew/include" "external/glfw3/include")
include_directories("." "external/" "external/openal_soft/include" "external/glfw3/include")
ENDIF()
file(GLOB SOURCES "src/*.c")
file(GLOB SOURCES "*.c" "external/*.c")
add_library(raylib STATIC ${SOURCES})
install(TARGETS raylib DESTINATION lib/)
install(TARGETS raylib DESTINATION ../lib/)

View File

@ -69,38 +69,33 @@ else
endif
# define compiler flags:
# -O1 defines optimization level
# -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, faster)
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline
# -O1 defines optimization level
# -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, faster)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -Wno-missing-braces
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
# define any directories containing required header files
ifeq ($(PLATFORM),PLATFORM_RPI)
INCLUDES = -I. -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads
INCLUDES = -I. -Iexternal -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads
else
INCLUDES = -I. -I../src
# external libraries headers
# GLFW3
INCLUDES += -I../external/glfw3/include
# OpenAL Soft
INCLUDES += -I../external/openal_soft/include
# STB libraries and others
INCLUDES = -I. -Iexternal
# GLFW3 library
INCLUDES += -Iexternal/glfw3/include
# OpenAL Soft library
INCLUDES += -Iexternal/openal_soft/include
endif
# define all object files required
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
OBJS = core.o rlgl.o glad.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o
else
#GLAD only required on desktop platform
OBJS = core.o rlgl.o shapes.o text.o textures.o models.o audio.o stb_vorbis.o utils.o camera.o gestures.o
endif
OBJS = core.o rlgl.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o
# typing 'make' will invoke the default target entry called 'all',
# in this case, the 'default' target entry is basic_game
# in this case, the 'default' target entry is raylib
all: raylib
# compile raylib library
@ -120,10 +115,6 @@ core.o: core.c
rlgl.o: rlgl.c
$(CC) -c rlgl.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
# compile glad module
glad.o: glad.c
$(CC) -c glad.c $(CFLAGS) $(INCLUDES)
# compile shapes module
shapes.o: shapes.c
$(CC) -c shapes.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
@ -144,10 +135,6 @@ models.o: models.c
audio.o: audio.c
$(CC) -c audio.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
# compile stb_vorbis library
stb_vorbis.o: stb_vorbis.c
$(CC) -c stb_vorbis.c -O1 $(INCLUDES) -D$(PLATFORM)
# compile utils module
utils.o: utils.c
$(CC) -c utils.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
@ -160,6 +147,10 @@ camera.o: camera.c
gestures.o: gestures.c
$(CC) -c gestures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
# compile stb_vorbis library
stb_vorbis.o: external/stb_vorbis.c
$(CC) -c external/stb_vorbis.c -O1 $(INCLUDES) -D$(PLATFORM)
# clean everything
clean:
ifeq ($(PLATFORM),PLATFORM_DESKTOP)

View File

@ -37,22 +37,22 @@ LOCAL_MODULE := raylib
# Module source files
LOCAL_SRC_FILES :=\
../../src/core.c \
../../src/rlgl.c \
../../src/textures.c \
../../src/text.c \
../../src/shapes.c \
../../src/gestures.c \
../../src/models.c \
../../src/utils.c \
../../src/audio.c \
../../src/stb_vorbis.c \
../../core.c \
../../rlgl.c \
../../textures.c \
../../text.c \
../../shapes.c \
../../gestures.c \
../../models.c \
../../utils.c \
../../audio.c \
../../stb_vorbis.c \
# Required includes paths (.h)
LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include $(LOCAL_PATH)/../../src
LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include $(LOCAL_PATH)/../..
# Required flags for compilation: defines PLATFORM_ANDROID and GRAPHICS_API_OPENGL_ES2
LOCAL_CFLAGS := -Wall -std=c99 -g -DPLATFORM_ANDROID -DGRAPHICS_API_OPENGL_ES2
LOCAL_CFLAGS := -Wall -std=c99 -Wno-missing-braces -DPLATFORM_ANDROID -DGRAPHICS_API_OPENGL_ES2
# Build the static library libraylib.a
include $(BUILD_STATIC_LIBRARY)

View File

@ -35,26 +35,29 @@
#include "raylib.h"
#endif
#include "AL/al.h" // OpenAL basic header
#include "AL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work)
#include "AL/alext.h" // extensions for other format types
#include "AL/al.h" // OpenAL basic header
#include "AL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work)
#include "AL/alext.h" // OpenAL extensions for other format types
#include <stdlib.h> // Declares malloc() and free() for memory management
#include <string.h> // Required for strcmp()
#include <stdio.h> // Used for .WAV loading
#include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strcmp(), strncmp()
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
#if defined(AUDIO_STANDALONE)
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog())
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#else
#include "utils.h" // rRES data decompression utility function
// NOTE: Includes Android fopen function map
#include "utils.h" // Required for: DecompressData()
// NOTE: Includes Android fopen() function map
#endif
//#define STB_VORBIS_HEADER_ONLY
#include "stb_vorbis.h" // OGG loading functions
#include "external/stb_vorbis.h" // OGG loading functions
#define JAR_XM_IMPLEMENTATION
#include "jar_xm.h" // For playing .xm files
#include "external/jar_xm.h" // XM loading functions
#define JAR_MOD_IMPLEMENTATION
#include "external/jar_mod.h" // MOD loading functions
//----------------------------------------------------------------------------------
// Defines and Macros
@ -86,24 +89,45 @@ typedef struct MixChannel_t {
unsigned char mixChannel; // 0-3 or mixA-mixD, each mix channel can receive up to one dedicated audio stream
bool floatingPoint; // if false then the short datatype is used instead
bool playing; // false if paused
ALenum alFormat; // openAL format specifier
ALuint alSource; // openAL source
ALuint alBuffer[MAX_STREAM_BUFFERS]; // openAL sample buffer
ALenum alFormat; // OpenAL format specifier
ALuint alSource; // OpenAL source
ALuint alBuffer[MAX_STREAM_BUFFERS]; // OpenAL sample buffer
} MixChannel_t;
// Music type (file streaming from memory)
// NOTE: Anything longer than ~10 seconds should be streamed into a mix channel...
typedef struct Music {
stb_vorbis *stream;
jar_xm_context_t *chipctx; // Stores jar_xm mixc
jar_xm_context_t *xmctx; // XM chiptune context
jar_mod_context_t modctx; // MOD chiptune context
MixChannel_t *mixc; // mix channel
int totalSamplesLeft;
unsigned int totalSamplesLeft;
float totalLengthSeconds;
bool loop;
bool chipTune; // True if chiptune is loaded
bool chipTune; // chiptune is loaded?
} Music;
// Audio errors registered
typedef enum {
ERROR_RAW_CONTEXT_CREATION = 1,
ERROR_XM_CONTEXT_CREATION = 2,
ERROR_MOD_CONTEXT_CREATION = 4,
ERROR_MIX_CHANNEL_CREATION = 8,
ERROR_MUSIC_CHANNEL_CREATION = 16,
ERROR_LOADING_XM = 32,
ERROR_LOADING_MOD = 64,
ERROR_LOADING_WAV = 128,
ERROR_LOADING_OGG = 256,
ERROR_OUT_OF_MIX_CHANNELS = 512,
ERROR_EXTENSION_NOT_RECOGNIZED = 1024,
ERROR_UNABLE_TO_OPEN_RRES_FILE = 2048,
ERROR_INVALID_RRES_FILE = 4096,
ERROR_INVALID_RRES_RESOURCE = 8192,
ERROR_UNINITIALIZED_CHANNELS = 16384
} AudioError;
#if defined(AUDIO_STANDALONE)
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
#endif
@ -111,9 +135,11 @@ typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static MixChannel_t* mixChannelsActive_g[MAX_MIX_CHANNELS]; // What mix channels are currently active
static Music musicChannels_g[MAX_MUSIC_STREAMS]; // Current music loaded, up to two can play at the same time
static MixChannel_t *mixChannels_g[MAX_MIX_CHANNELS]; // What mix channels are currently active
static bool musicEnabled_g = false;
static Music currentMusic[MAX_MUSIC_STREAMS]; // Current music loaded, up to two can play at the same time
static int lastAudioError = 0; // Registers last audio error
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
@ -125,10 +151,9 @@ static void UnloadWave(Wave wave); // Unload wave data
static bool BufferMusicStream(int index, int numBuffers); // Fill music buffers with data
static void EmptyMusicStream(int index); // Empty music buffers
static MixChannel_t* InitMixChannel(unsigned short sampleRate, unsigned char mixChannel, unsigned char channels, bool floatingPoint); // For streaming into mix channels.
static void CloseMixChannel(MixChannel_t* mixc); // Frees mix channel
static int BufferMixChannel(MixChannel_t* mixc, void *data, int numberElements); // Pushes more audio data into mixc mix channel, if NULL is passed it pauses
static MixChannel_t *InitMixChannel(unsigned short sampleRate, unsigned char mixChannel, unsigned char channels, bool floatingPoint); // For streaming into mix channels.
static void CloseMixChannel(MixChannel_t *mixc); // Frees mix channel
static int BufferMixChannel(MixChannel_t *mixc, void *data, int numberElements); // Pushes more audio data into mixc mix channel, if NULL is passed it pauses
static int FillAlBufferWithSilence(MixChannel_t *mixc, ALuint buffer); // Fill buffer with zeros, returns number processed
static void ResampleShortToFloat(short *shorts, float *floats, unsigned short len); // Pass two arrays of the same legnth in
static void ResampleByteToFloat(char *chars, float *floats, unsigned short len); // Pass two arrays of same length in
@ -149,13 +174,13 @@ void InitAudioDevice(void)
// Open and initialize a device with default settings
ALCdevice *device = alcOpenDevice(NULL);
if(!device) TraceLog(ERROR, "Audio device could not be opened");
if (!device) TraceLog(ERROR, "Audio device could not be opened");
ALCcontext *context = alcCreateContext(device, NULL);
if(context == NULL || alcMakeContextCurrent(context) == ALC_FALSE)
if ((context == NULL) || (alcMakeContextCurrent(context) == ALC_FALSE))
{
if(context != NULL) alcDestroyContext(context);
if (context != NULL) alcDestroyContext(context);
alcCloseDevice(device);
@ -173,11 +198,10 @@ void InitAudioDevice(void)
// Close the audio device for all contexts
void CloseAudioDevice(void)
{
for(int index=0; index<MAX_MUSIC_STREAMS; index++)
for (int index=0; index<MAX_MUSIC_STREAMS; index++)
{
if(currentMusic[index].mixc) StopMusicStream(index); // Stop music streaming and close current stream
if (musicChannels_g[index].mixc) StopMusicStream(index); // Stop music streaming and close current stream
}
ALCdevice *device;
ALCcontext *context = alcGetCurrentContext();
@ -195,9 +219,12 @@ void CloseAudioDevice(void)
bool IsAudioDeviceReady(void)
{
ALCcontext *context = alcGetCurrentContext();
if (context == NULL) return false;
else{
else
{
ALCdevice *device = alcGetContextsDevice(context);
if (device == NULL) return false;
else return true;
}
@ -210,33 +237,30 @@ bool IsAudioDeviceReady(void)
// For streaming into mix channels.
// The mixChannel is what audio muxing channel you want to operate on, 0-3 are the ones available. Each mix channel can only be used one at a time.
// exmple usage is InitMixChannel(48000, 0, 2, true); // mixchannel 1, 48khz, stereo, floating point
static MixChannel_t* InitMixChannel(unsigned short sampleRate, unsigned char mixChannel, unsigned char channels, bool floatingPoint)
static MixChannel_t *InitMixChannel(unsigned short sampleRate, unsigned char mixChannel, unsigned char channels, bool floatingPoint)
{
if(mixChannel >= MAX_MIX_CHANNELS) return NULL;
if(!IsAudioDeviceReady()) InitAudioDevice();
if (mixChannel >= MAX_MIX_CHANNELS) return NULL;
if (!IsAudioDeviceReady()) InitAudioDevice();
if(!mixChannelsActive_g[mixChannel]){
MixChannel_t *mixc = (MixChannel_t*)malloc(sizeof(MixChannel_t));
if (!mixChannels_g[mixChannel])
{
MixChannel_t *mixc = (MixChannel_t *)malloc(sizeof(MixChannel_t));
mixc->sampleRate = sampleRate;
mixc->channels = channels;
mixc->mixChannel = mixChannel;
mixc->floatingPoint = floatingPoint;
mixChannelsActive_g[mixChannel] = mixc;
mixChannels_g[mixChannel] = mixc;
// setup openAL format
if(channels == 1)
// Setup OpenAL format
if (channels == 1)
{
if(floatingPoint)
mixc->alFormat = AL_FORMAT_MONO_FLOAT32;
else
mixc->alFormat = AL_FORMAT_MONO16;
if (floatingPoint) mixc->alFormat = AL_FORMAT_MONO_FLOAT32;
else mixc->alFormat = AL_FORMAT_MONO16;
}
else if(channels == 2)
else if (channels == 2)
{
if(floatingPoint)
mixc->alFormat = AL_FORMAT_STEREO_FLOAT32;
else
mixc->alFormat = AL_FORMAT_STEREO16;
if (floatingPoint) mixc->alFormat = AL_FORMAT_STEREO_FLOAT32;
else mixc->alFormat = AL_FORMAT_STEREO16;
}
// Create an audio source
@ -249,10 +273,8 @@ static MixChannel_t* InitMixChannel(unsigned short sampleRate, unsigned char mix
// Create Buffer
alGenBuffers(MAX_STREAM_BUFFERS, mixc->alBuffer);
//fill buffers
int x;
for(x=0;x<MAX_STREAM_BUFFERS;x++)
FillAlBufferWithSilence(mixc, mixc->alBuffer[x]);
// Fill buffers
for (int i = 0; i < MAX_STREAM_BUFFERS; i++) FillAlBufferWithSilence(mixc, mixc->alBuffer[i]);
alSourceQueueBuffers(mixc->alSource, MAX_STREAM_BUFFERS, mixc->alBuffer);
mixc->playing = true;
@ -260,30 +282,33 @@ static MixChannel_t* InitMixChannel(unsigned short sampleRate, unsigned char mix
return mixc;
}
return NULL;
}
// Frees buffer in mix channel
static void CloseMixChannel(MixChannel_t* mixc)
static void CloseMixChannel(MixChannel_t *mixc)
{
if(mixc){
if (mixc)
{
alSourceStop(mixc->alSource);
mixc->playing = false;
//flush out all queued buffers
// Flush out all queued buffers
ALuint buffer = 0;
int queued = 0;
alGetSourcei(mixc->alSource, AL_BUFFERS_QUEUED, &queued);
while (queued > 0)
{
alSourceUnqueueBuffers(mixc->alSource, 1, &buffer);
queued--;
}
//delete source and buffers
// Delete source and buffers
alDeleteSources(1, &mixc->alSource);
alDeleteBuffers(MAX_STREAM_BUFFERS, mixc->alBuffer);
mixChannelsActive_g[mixc->mixChannel] = NULL;
mixChannels_g[mixc->mixChannel] = NULL;
free(mixc);
mixc = NULL;
}
@ -292,39 +317,46 @@ static void CloseMixChannel(MixChannel_t* mixc)
// Pushes more audio data into mixc mix channel, only one buffer per call
// Call "BufferMixChannel(mixc, NULL, 0)" if you want to pause the audio.
// @Returns number of samples that where processed.
static int BufferMixChannel(MixChannel_t* mixc, void *data, int numberElements)
static int BufferMixChannel(MixChannel_t *mixc, void *data, int numberElements)
{
if(!mixc || mixChannelsActive_g[mixc->mixChannel] != mixc) return 0; // when there is two channels there must be an even number of samples
if (!mixc || (mixChannels_g[mixc->mixChannel] != mixc)) return 0; // When there is two channels there must be an even number of samples
if (!data || !numberElements)
{ // pauses audio until data is given
if(mixc->playing){
if (!data || !numberElements)
{
// Pauses audio until data is given
if (mixc->playing)
{
alSourcePause(mixc->alSource);
mixc->playing = false;
}
return 0;
}
else if(!mixc->playing)
{ // restart audio otherwise
else if (!mixc->playing)
{
// Restart audio otherwise
alSourcePlay(mixc->alSource);
mixc->playing = true;
}
ALuint buffer = 0;
alSourceUnqueueBuffers(mixc->alSource, 1, &buffer);
if(!buffer) return 0;
if(mixc->floatingPoint) // process float buffers
if (!buffer) return 0;
if (mixc->floatingPoint)
{
float *ptr = (float*)data;
// Process float buffers
float *ptr = (float *)data;
alBufferData(buffer, mixc->alFormat, ptr, numberElements*sizeof(float), mixc->sampleRate);
}
else // process short buffers
else
{
short *ptr = (short*)data;
// Process short buffers
short *ptr = (short *)data;
alBufferData(buffer, mixc->alFormat, ptr, numberElements*sizeof(short), mixc->sampleRate);
}
alSourceQueueBuffers(mixc->alSource, 1, &buffer);
return numberElements;
@ -333,15 +365,18 @@ static int BufferMixChannel(MixChannel_t* mixc, void *data, int numberElements)
// fill buffer with zeros, returns number processed
static int FillAlBufferWithSilence(MixChannel_t *mixc, ALuint buffer)
{
if(mixc->floatingPoint){
float pcm[MUSIC_BUFFER_SIZE_FLOAT] = {0.f};
if (mixc->floatingPoint)
{
float pcm[MUSIC_BUFFER_SIZE_FLOAT] = { 0.0f };
alBufferData(buffer, mixc->alFormat, pcm, MUSIC_BUFFER_SIZE_FLOAT*sizeof(float), mixc->sampleRate);
return MUSIC_BUFFER_SIZE_FLOAT;
}
else
{
short pcm[MUSIC_BUFFER_SIZE_SHORT] = {0};
short pcm[MUSIC_BUFFER_SIZE_SHORT] = { 0 };
alBufferData(buffer, mixc->alFormat, pcm, MUSIC_BUFFER_SIZE_SHORT*sizeof(short), mixc->sampleRate);
return MUSIC_BUFFER_SIZE_SHORT;
}
}
@ -351,13 +386,10 @@ static int FillAlBufferWithSilence(MixChannel_t *mixc, ALuint buffer)
// ResampleShortToFloat(sh,fl,3);
static void ResampleShortToFloat(short *shorts, float *floats, unsigned short len)
{
int x;
for(x=0;x<len;x++)
for (int i = 0; i < len; i++)
{
if(shorts[x] < 0)
floats[x] = (float)shorts[x] / 32766.f;
else
floats[x] = (float)shorts[x] / 32767.f;
if (shorts[i] < 0) floats[i] = (float)shorts[i]/32766.0f;
else floats[i] = (float)shorts[i]/32767.0f;
}
}
@ -366,54 +398,49 @@ static void ResampleShortToFloat(short *shorts, float *floats, unsigned short le
// ResampleByteToFloat(ch,fl,3);
static void ResampleByteToFloat(char *chars, float *floats, unsigned short len)
{
int x;
for(x=0;x<len;x++)
for (int i = 0; i < len; i++)
{
if(chars[x] < 0)
floats[x] = (float)chars[x] / 127.f;
else
floats[x] = (float)chars[x] / 128.f;
if (chars[i] < 0) floats[i] = (float)chars[i]/127.0f;
else floats[i] = (float)chars[i]/128.0f;
}
}
// used to output raw audio streams, returns negative numbers on error
// used to output raw audio streams, returns negative numbers on error, + number represents the mix channel index
// if floating point is false the data size is 16bit short, otherwise it is float 32bit
RawAudioContext InitRawAudioContext(int sampleRate, int channels, bool floatingPoint)
{
int mixIndex;
for(mixIndex = 0; mixIndex < MAX_MIX_CHANNELS; mixIndex++) // find empty mix channel slot
for (mixIndex = 0; mixIndex < MAX_MIX_CHANNELS; mixIndex++) // find empty mix channel slot
{
if(mixChannelsActive_g[mixIndex] == NULL) break;
else if(mixIndex == MAX_MIX_CHANNELS - 1) return -1; // error
if (mixChannels_g[mixIndex] == NULL) break;
else if (mixIndex == (MAX_MIX_CHANNELS - 1)) return ERROR_OUT_OF_MIX_CHANNELS; // error
}
if(InitMixChannel(sampleRate, mixIndex, channels, floatingPoint))
return mixIndex;
else
return -2; // error
if (InitMixChannel(sampleRate, mixIndex, channels, floatingPoint)) return mixIndex;
else return ERROR_RAW_CONTEXT_CREATION; // error
}
void CloseRawAudioContext(RawAudioContext ctx)
{
if(mixChannelsActive_g[ctx])
CloseMixChannel(mixChannelsActive_g[ctx]);
if (mixChannels_g[ctx]) CloseMixChannel(mixChannels_g[ctx]);
}
int BufferRawAudioContext(RawAudioContext ctx, void *data, int numberElements)
// if 0 is returned, the buffers are still full and you need to keep trying with the same data until a + number is returned.
// any + number returned is the number of samples that was processed and passed into buffer.
// data either needs to be array of floats or shorts.
int BufferRawAudioContext(RawAudioContext ctx, void *data, unsigned short numberElements)
{
int numBuffered = 0;
if(ctx >= 0)
if (ctx >= 0)
{
MixChannel_t* mixc = mixChannelsActive_g[ctx];
MixChannel_t* mixc = mixChannels_g[ctx];
numBuffered = BufferMixChannel(mixc, data, numberElements);
}
return numBuffered;
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Sounds loading and playing (.WAV)
//----------------------------------------------------------------------------------
@ -431,7 +458,13 @@ Sound LoadSound(char *fileName)
if (strcmp(GetExtension(fileName),"wav") == 0) wave = LoadWAV(fileName);
else if (strcmp(GetExtension(fileName),"ogg") == 0) wave = LoadOGG(fileName);
else TraceLog(WARNING, "[%s] Sound extension not recognized, it can't be loaded", fileName);
else
{
TraceLog(WARNING, "[%s] Sound extension not recognized, it can't be loaded", fileName);
// TODO: Find a better way to register errors (similar to glGetError())
lastAudioError = ERROR_EXTENSION_NOT_RECOGNIZED;
}
if (wave.data != NULL)
{
@ -558,6 +591,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
if (rresFile == NULL)
{
TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
lastAudioError = ERROR_UNABLE_TO_OPEN_RRES_FILE;
}
else
{
@ -572,6 +606,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S'))
{
TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName);
lastAudioError = ERROR_INVALID_RRES_FILE;
}
else
{
@ -662,6 +697,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
else
{
TraceLog(WARNING, "[%s] Required resource do not seem to be a valid SOUND resource", rresName);
lastAudioError = ERROR_INVALID_RRES_RESOURCE;
}
}
else
@ -763,119 +799,156 @@ void SetSoundPitch(Sound sound, float pitch)
// Start music playing (open stream)
// returns 0 on success
int PlayMusicStream(int musicIndex, char *fileName)
int PlayMusicStream(int index, char *fileName)
{
int mixIndex;
if(currentMusic[musicIndex].stream || currentMusic[musicIndex].chipctx) return 1; // error
if (musicChannels_g[index].stream || musicChannels_g[index].xmctx) return ERROR_UNINITIALIZED_CHANNELS; // error
for(mixIndex = 0; mixIndex < MAX_MIX_CHANNELS; mixIndex++) // find empty mix channel slot
for (mixIndex = 0; mixIndex < MAX_MIX_CHANNELS; mixIndex++) // find empty mix channel slot
{
if(mixChannelsActive_g[mixIndex] == NULL) break;
else if(mixIndex == MAX_MIX_CHANNELS - 1) return 2; // error
if (mixChannels_g[mixIndex] == NULL) break;
else if (mixIndex == (MAX_MIX_CHANNELS - 1)) return ERROR_OUT_OF_MIX_CHANNELS; // error
}
if (strcmp(GetExtension(fileName),"ogg") == 0)
{
// Open audio stream
currentMusic[musicIndex].stream = stb_vorbis_open_filename(fileName, NULL, NULL);
musicChannels_g[index].stream = stb_vorbis_open_filename(fileName, NULL, NULL);
if (currentMusic[musicIndex].stream == NULL)
if (musicChannels_g[index].stream == NULL)
{
TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
return 3; // error
return ERROR_LOADING_OGG; // error
}
else
{
// Get file info
stb_vorbis_info info = stb_vorbis_get_info(currentMusic[musicIndex].stream);
stb_vorbis_info info = stb_vorbis_get_info(musicChannels_g[index].stream);
TraceLog(INFO, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
TraceLog(INFO, "[%s] Ogg channels: %i", fileName, info.channels);
TraceLog(DEBUG, "[%s] Temp memory required: %i", fileName, info.temp_memory_required);
currentMusic[musicIndex].loop = true; // We loop by default
musicChannels_g[index].loop = true; // We loop by default
musicEnabled_g = true;
currentMusic[musicIndex].totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic[musicIndex].stream) * info.channels;
currentMusic[musicIndex].totalLengthSeconds = stb_vorbis_stream_length_in_seconds(currentMusic[musicIndex].stream);
musicChannels_g[index].totalSamplesLeft = (unsigned int)stb_vorbis_stream_length_in_samples(musicChannels_g[index].stream) * info.channels;
musicChannels_g[index].totalLengthSeconds = stb_vorbis_stream_length_in_seconds(musicChannels_g[index].stream);
if (info.channels == 2){
currentMusic[musicIndex].mixc = InitMixChannel(info.sample_rate, mixIndex, 2, false);
currentMusic[musicIndex].mixc->playing = true;
if (info.channels == 2)
{
musicChannels_g[index].mixc = InitMixChannel(info.sample_rate, mixIndex, 2, false);
musicChannels_g[index].mixc->playing = true;
}
else{
currentMusic[musicIndex].mixc = InitMixChannel(info.sample_rate, mixIndex, 1, false);
currentMusic[musicIndex].mixc->playing = true;
else
{
musicChannels_g[index].mixc = InitMixChannel(info.sample_rate, mixIndex, 1, false);
musicChannels_g[index].mixc->playing = true;
}
if(!currentMusic[musicIndex].mixc) return 4; // error
if (!musicChannels_g[index].mixc) return ERROR_LOADING_OGG; // error
}
}
else if (strcmp(GetExtension(fileName),"xm") == 0)
{
// only stereo is supported for xm
if(!jar_xm_create_context_from_file(&currentMusic[musicIndex].chipctx, 48000, fileName))
if (!jar_xm_create_context_from_file(&musicChannels_g[index].xmctx, 48000, fileName))
{
currentMusic[musicIndex].chipTune = true;
currentMusic[musicIndex].loop = true;
jar_xm_set_max_loop_count(currentMusic[musicIndex].chipctx, 0); // infinite number of loops
currentMusic[musicIndex].totalSamplesLeft = jar_xm_get_remaining_samples(currentMusic[musicIndex].chipctx);
currentMusic[musicIndex].totalLengthSeconds = ((float)currentMusic[musicIndex].totalSamplesLeft) / 48000.f;
musicChannels_g[index].chipTune = true;
musicChannels_g[index].loop = true;
jar_xm_set_max_loop_count(musicChannels_g[index].xmctx, 0); // infinite number of loops
musicChannels_g[index].totalSamplesLeft = (unsigned int)jar_xm_get_remaining_samples(musicChannels_g[index].xmctx);
musicChannels_g[index].totalLengthSeconds = ((float)musicChannels_g[index].totalSamplesLeft) / 48000.f;
musicEnabled_g = true;
TraceLog(INFO, "[%s] XM number of samples: %i", fileName, currentMusic[musicIndex].totalSamplesLeft);
TraceLog(INFO, "[%s] XM track length: %11.6f sec", fileName, currentMusic[musicIndex].totalLengthSeconds);
TraceLog(INFO, "[%s] XM number of samples: %i", fileName, musicChannels_g[index].totalSamplesLeft);
TraceLog(INFO, "[%s] XM track length: %11.6f sec", fileName, musicChannels_g[index].totalLengthSeconds);
currentMusic[musicIndex].mixc = InitMixChannel(48000, mixIndex, 2, false);
if(!currentMusic[musicIndex].mixc) return 5; // error
currentMusic[musicIndex].mixc->playing = true;
musicChannels_g[index].mixc = InitMixChannel(48000, mixIndex, 2, true);
if (!musicChannels_g[index].mixc) return ERROR_XM_CONTEXT_CREATION; // error
musicChannels_g[index].mixc->playing = true;
}
else
{
TraceLog(WARNING, "[%s] XM file could not be opened", fileName);
return 6; // error
return ERROR_LOADING_XM; // error
}
}
else if (strcmp(GetExtension(fileName),"mod") == 0)
{
jar_mod_init(&musicChannels_g[index].modctx);
if (jar_mod_load_file(&musicChannels_g[index].modctx, fileName))
{
musicChannels_g[index].chipTune = true;
musicChannels_g[index].loop = true;
musicChannels_g[index].totalSamplesLeft = (unsigned int)jar_mod_max_samples(&musicChannels_g[index].modctx);
musicChannels_g[index].totalLengthSeconds = ((float)musicChannels_g[index].totalSamplesLeft) / 48000.f;
musicEnabled_g = true;
TraceLog(INFO, "[%s] MOD number of samples: %i", fileName, musicChannels_g[index].totalSamplesLeft);
TraceLog(INFO, "[%s] MOD track length: %11.6f sec", fileName, musicChannels_g[index].totalLengthSeconds);
musicChannels_g[index].mixc = InitMixChannel(48000, mixIndex, 2, false);
if (!musicChannels_g[index].mixc) return ERROR_MOD_CONTEXT_CREATION; // error
musicChannels_g[index].mixc->playing = true;
}
else
{
TraceLog(WARNING, "[%s] MOD file could not be opened", fileName);
return ERROR_LOADING_MOD; // error
}
}
else
{
TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
return 7; // error
return ERROR_EXTENSION_NOT_RECOGNIZED; // error
}
return 0; // normal return
}
// Stop music playing for individual music index of currentMusic array (close stream)
// Stop music playing for individual music index of musicChannels_g array (close stream)
void StopMusicStream(int index)
{
if (index < MAX_MUSIC_STREAMS && currentMusic[index].mixc)
if (index < MAX_MUSIC_STREAMS && musicChannels_g[index].mixc)
{
CloseMixChannel(currentMusic[index].mixc);
CloseMixChannel(musicChannels_g[index].mixc);
if (currentMusic[index].chipTune)
if (musicChannels_g[index].chipTune && musicChannels_g[index].xmctx)
{
jar_xm_free_context(currentMusic[index].chipctx);
}
else
{
stb_vorbis_close(currentMusic[index].stream);
jar_xm_free_context(musicChannels_g[index].xmctx);
musicChannels_g[index].xmctx = 0;
}
else if (musicChannels_g[index].chipTune && musicChannels_g[index].modctx.mod_loaded) jar_mod_unload(&musicChannels_g[index].modctx);
else stb_vorbis_close(musicChannels_g[index].stream);
if(!getMusicStreamCount()) musicEnabled_g = false;
if(currentMusic[index].stream || currentMusic[index].chipctx)
if (!GetMusicStreamCount()) musicEnabled_g = false;
if (musicChannels_g[index].stream || musicChannels_g[index].xmctx)
{
currentMusic[index].stream = NULL;
currentMusic[index].chipctx = NULL;
musicChannels_g[index].stream = NULL;
musicChannels_g[index].xmctx = NULL;
}
}
}
//get number of music channels active at this time, this does not mean they are playing
int getMusicStreamCount(void)
int GetMusicStreamCount(void)
{
int musicCount = 0;
for(int musicIndex = 0; musicIndex < MAX_MUSIC_STREAMS; musicIndex++) // find empty music slot
if(currentMusic[musicIndex].stream != NULL || currentMusic[musicIndex].chipTune) musicCount++;
// Find empty music slot
for (int musicIndex = 0; musicIndex < MAX_MUSIC_STREAMS; musicIndex++)
{
if(musicChannels_g[musicIndex].stream != NULL || musicChannels_g[musicIndex].chipTune) musicCount++;
}
return musicCount;
}
@ -884,11 +957,11 @@ int getMusicStreamCount(void)
void PauseMusicStream(int index)
{
// Pause music stream if music available!
if (index < MAX_MUSIC_STREAMS && currentMusic[index].mixc && musicEnabled_g)
if (index < MAX_MUSIC_STREAMS && musicChannels_g[index].mixc && musicEnabled_g)
{
TraceLog(INFO, "Pausing music stream");
alSourcePause(currentMusic[index].mixc->alSource);
currentMusic[index].mixc->playing = false;
alSourcePause(musicChannels_g[index].mixc->alSource);
musicChannels_g[index].mixc->playing = false;
}
}
@ -897,13 +970,16 @@ void ResumeMusicStream(int index)
{
// Resume music playing... if music available!
ALenum state;
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc){
alGetSourcei(currentMusic[index].mixc->alSource, AL_SOURCE_STATE, &state);
if (index < MAX_MUSIC_STREAMS && musicChannels_g[index].mixc)
{
alGetSourcei(musicChannels_g[index].mixc->alSource, AL_SOURCE_STATE, &state);
if (state == AL_PAUSED)
{
TraceLog(INFO, "Resuming music stream");
alSourcePlay(currentMusic[index].mixc->alSource);
currentMusic[index].mixc->playing = true;
alSourcePlay(musicChannels_g[index].mixc->alSource);
musicChannels_g[index].mixc->playing = true;
}
}
}
@ -914,8 +990,10 @@ bool IsMusicPlaying(int index)
bool playing = false;
ALint state;
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc){
alGetSourcei(currentMusic[index].mixc->alSource, AL_SOURCE_STATE, &state);
if (index < MAX_MUSIC_STREAMS && musicChannels_g[index].mixc)
{
alGetSourcei(musicChannels_g[index].mixc->alSource, AL_SOURCE_STATE, &state);
if (state == AL_PLAYING) playing = true;
}
@ -925,30 +1003,28 @@ bool IsMusicPlaying(int index)
// Set volume for music
void SetMusicVolume(int index, float volume)
{
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc){
alSourcef(currentMusic[index].mixc->alSource, AL_GAIN, volume);
if (index < MAX_MUSIC_STREAMS && musicChannels_g[index].mixc)
{
alSourcef(musicChannels_g[index].mixc->alSource, AL_GAIN, volume);
}
}
// Set pitch for music
void SetMusicPitch(int index, float pitch)
{
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc){
alSourcef(currentMusic[index].mixc->alSource, AL_PITCH, pitch);
if (index < MAX_MUSIC_STREAMS && musicChannels_g[index].mixc)
{
alSourcef(musicChannels_g[index].mixc->alSource, AL_PITCH, pitch);
}
}
// Get current music time length (in seconds)
// Get music time length (in seconds)
float GetMusicTimeLength(int index)
{
float totalSeconds;
if (currentMusic[index].chipTune)
{
totalSeconds = currentMusic[index].totalLengthSeconds;
}
else
{
totalSeconds = stb_vorbis_stream_length_in_seconds(currentMusic[index].stream);
}
if (musicChannels_g[index].chipTune) totalSeconds = (float)musicChannels_g[index].totalLengthSeconds;
else totalSeconds = stb_vorbis_stream_length_in_seconds(musicChannels_g[index].stream);
return totalSeconds;
}
@ -957,19 +1033,25 @@ float GetMusicTimeLength(int index)
float GetMusicTimePlayed(int index)
{
float secondsPlayed = 0.0f;
if(index < MAX_MUSIC_STREAMS && currentMusic[index].mixc)
if (index < MAX_MUSIC_STREAMS && musicChannels_g[index].mixc)
{
if (currentMusic[index].chipTune)
if (musicChannels_g[index].chipTune && musicChannels_g[index].xmctx)
{
uint64_t samples;
jar_xm_get_position(currentMusic[index].chipctx, NULL, NULL, NULL, &samples);
secondsPlayed = (float)samples / (48000 * currentMusic[index].mixc->channels); // Not sure if this is the correct value
jar_xm_get_position(musicChannels_g[index].xmctx, NULL, NULL, NULL, &samples);
secondsPlayed = (float)samples / (48000.f * musicChannels_g[index].mixc->channels); // Not sure if this is the correct value
}
else if(musicChannels_g[index].chipTune && musicChannels_g[index].modctx.mod_loaded)
{
long numsamp = jar_mod_current_samples(&musicChannels_g[index].modctx);
secondsPlayed = (float)numsamp / (48000.f);
}
else
{
int totalSamples = stb_vorbis_stream_length_in_samples(currentMusic[index].stream) * currentMusic[index].mixc->channels;
int samplesPlayed = totalSamples - currentMusic[index].totalSamplesLeft;
secondsPlayed = (float)samplesPlayed / (currentMusic[index].mixc->sampleRate * currentMusic[index].mixc->channels);
int totalSamples = stb_vorbis_stream_length_in_samples(musicChannels_g[index].stream) * musicChannels_g[index].mixc->channels;
int samplesPlayed = totalSamples - musicChannels_g[index].totalSamplesLeft;
secondsPlayed = (float)samplesPlayed / (musicChannels_g[index].mixc->sampleRate * musicChannels_g[index].mixc->channels);
}
}
@ -986,22 +1068,33 @@ static bool BufferMusicStream(int index, int numBuffers)
short pcm[MUSIC_BUFFER_SIZE_SHORT];
float pcmf[MUSIC_BUFFER_SIZE_FLOAT];
int size = 0; // Total size of data steamed in L+R samples for xm floats, individual L or R for ogg shorts
bool active = true; // We can get more data from stream (not finished)
int size = 0; // Total size of data steamed in L+R samples for xm floats, individual L or R for ogg shorts
bool active = true; // We can get more data from stream (not finished)
if (currentMusic[index].chipTune) // There is no end of stream for xmfiles, once the end is reached zeros are generated for non looped chiptunes.
if (musicChannels_g[index].chipTune) // There is no end of stream for xmfiles, once the end is reached zeros are generated for non looped chiptunes.
{
if(currentMusic[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_SHORT)
size = MUSIC_BUFFER_SIZE_SHORT / 2;
else
size = currentMusic[index].totalSamplesLeft / 2;
for(int x=0; x<numBuffers; x++)
for (int i = 0; i < numBuffers; i++)
{
jar_xm_generate_samples_16bit(currentMusic[index].chipctx, pcm, size); // reads 2*readlen shorts and moves them to buffer+size memory location
BufferMixChannel(currentMusic[index].mixc, pcm, size * 2);
currentMusic[index].totalSamplesLeft -= size * 2;
if(currentMusic[index].totalSamplesLeft <= 0)
if (musicChannels_g[index].modctx.mod_loaded)
{
if (musicChannels_g[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_SHORT) size = MUSIC_BUFFER_SIZE_SHORT/2;
else size = musicChannels_g[index].totalSamplesLeft/2;
jar_mod_fillbuffer(&musicChannels_g[index].modctx, pcm, size, 0 );
BufferMixChannel(musicChannels_g[index].mixc, pcm, size*2);
}
else if (musicChannels_g[index].xmctx)
{
if (musicChannels_g[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_FLOAT) size = MUSIC_BUFFER_SIZE_FLOAT/2;
else size = musicChannels_g[index].totalSamplesLeft/2;
jar_xm_generate_samples(musicChannels_g[index].xmctx, pcmf, size); // reads 2*readlen shorts and moves them to buffer+size memory location
BufferMixChannel(musicChannels_g[index].mixc, pcmf, size*2);
}
musicChannels_g[index].totalSamplesLeft -= size;
if (musicChannels_g[index].totalSamplesLeft <= 0)
{
active = false;
break;
@ -1010,17 +1103,16 @@ static bool BufferMusicStream(int index, int numBuffers)
}
else
{
if(currentMusic[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_SHORT)
size = MUSIC_BUFFER_SIZE_SHORT;
else
size = currentMusic[index].totalSamplesLeft;
if (musicChannels_g[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_SHORT) size = MUSIC_BUFFER_SIZE_SHORT;
else size = musicChannels_g[index].totalSamplesLeft;
for(int x=0; x<numBuffers; x++)
for (int i = 0; i < numBuffers; i++)
{
int streamedBytes = stb_vorbis_get_samples_short_interleaved(currentMusic[index].stream, currentMusic[index].mixc->channels, pcm, size);
BufferMixChannel(currentMusic[index].mixc, pcm, streamedBytes * currentMusic[index].mixc->channels);
currentMusic[index].totalSamplesLeft -= streamedBytes * currentMusic[index].mixc->channels;
if(currentMusic[index].totalSamplesLeft <= 0)
int streamedBytes = stb_vorbis_get_samples_short_interleaved(musicChannels_g[index].stream, musicChannels_g[index].mixc->channels, pcm, size);
BufferMixChannel(musicChannels_g[index].mixc, pcm, streamedBytes * musicChannels_g[index].mixc->channels);
musicChannels_g[index].totalSamplesLeft -= streamedBytes * musicChannels_g[index].mixc->channels;
if (musicChannels_g[index].totalSamplesLeft <= 0)
{
active = false;
break;
@ -1037,21 +1129,21 @@ static void EmptyMusicStream(int index)
ALuint buffer = 0;
int queued = 0;
alGetSourcei(currentMusic[index].mixc->alSource, AL_BUFFERS_QUEUED, &queued);
alGetSourcei(musicChannels_g[index].mixc->alSource, AL_BUFFERS_QUEUED, &queued);
while (queued > 0)
{
alSourceUnqueueBuffers(currentMusic[index].mixc->alSource, 1, &buffer);
alSourceUnqueueBuffers(musicChannels_g[index].mixc->alSource, 1, &buffer);
queued--;
}
}
//determine if a music stream is ready to be written to
// Determine if a music stream is ready to be written
static int IsMusicStreamReadyForBuffering(int index)
{
ALint processed = 0;
alGetSourcei(currentMusic[index].mixc->alSource, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(musicChannels_g[index].mixc->alSource, AL_BUFFERS_PROCESSED, &processed);
return processed;
}
@ -1062,37 +1154,35 @@ void UpdateMusicStream(int index)
bool active = true;
int numBuffers = IsMusicStreamReadyForBuffering(index);
if (currentMusic[index].mixc->playing && index < MAX_MUSIC_STREAMS && musicEnabled_g && currentMusic[index].mixc && numBuffers)
if (musicChannels_g[index].mixc->playing && (index < MAX_MUSIC_STREAMS) && musicEnabled_g && musicChannels_g[index].mixc && numBuffers)
{
active = BufferMusicStream(index, numBuffers);
if (!active && currentMusic[index].loop)
if (!active && musicChannels_g[index].loop)
{
if (currentMusic[index].chipTune)
if (musicChannels_g[index].chipTune)
{
currentMusic[index].totalSamplesLeft = currentMusic[index].totalLengthSeconds * 48000;
if(musicChannels_g[index].modctx.mod_loaded) jar_mod_seek_start(&musicChannels_g[index].modctx);
musicChannels_g[index].totalSamplesLeft = musicChannels_g[index].totalLengthSeconds * 48000;
}
else
{
stb_vorbis_seek_start(currentMusic[index].stream);
currentMusic[index].totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic[index].stream) * currentMusic[index].mixc->channels;
stb_vorbis_seek_start(musicChannels_g[index].stream);
musicChannels_g[index].totalSamplesLeft = stb_vorbis_stream_length_in_samples(musicChannels_g[index].stream) * musicChannels_g[index].mixc->channels;
}
active = true;
}
if (alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Error buffering data...");
alGetSourcei(currentMusic[index].mixc->alSource, AL_SOURCE_STATE, &state);
alGetSourcei(musicChannels_g[index].mixc->alSource, AL_SOURCE_STATE, &state);
if (state != AL_PLAYING && active) alSourcePlay(currentMusic[index].mixc->alSource);
if (state != AL_PLAYING && active) alSourcePlay(musicChannels_g[index].mixc->alSource);
if (!active) StopMusicStream(index);
}
else
return;
}
// Load WAV file into Wave structure

View File

@ -41,8 +41,9 @@
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
#ifndef true
#if !defined(_STDBOOL_H)
typedef enum { false, true } bool;
#define _STDBOOL_H
#endif
#endif
@ -50,6 +51,7 @@
typedef struct Sound {
unsigned int source;
unsigned int buffer;
AudioError error; // if there was any error during the creation or use of this Sound
} Sound;
// Wave type, defines audio wave data
@ -63,6 +65,7 @@ typedef struct Wave {
typedef int RawAudioContext;
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
@ -90,7 +93,7 @@ bool IsSoundPlaying(Sound sound); // Check if a so
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
int PlayMusicStream(int musicIndex, char *fileName); // Start music playing (open stream)
int PlayMusicStream(int index, char *fileName); // Start music playing (open stream)
void UpdateMusicStream(int index); // Updates buffers for music streaming
void StopMusicStream(int index); // Stop music playing (close stream)
void PauseMusicStream(int index); // Pause music playing
@ -99,7 +102,7 @@ bool IsMusicPlaying(int index); // Check if musi
void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level)
float GetMusicTimeLength(int index); // Get music time length (in seconds)
float GetMusicTimePlayed(int index); // Get current music time played (in seconds)
int getMusicStreamCount(void);
int GetMusicStreamCount(void);
void SetMusicPitch(int index, float pitch);
// used to output raw audio streams, returns negative numbers on error
@ -107,7 +110,7 @@ void SetMusicPitch(int index, float pitch);
RawAudioContext InitRawAudioContext(int sampleRate, int channels, bool floatingPoint);
void CloseRawAudioContext(RawAudioContext ctx);
int BufferRawAudioContext(RawAudioContext ctx, void *data, int numberElements); // returns number of elements buffered
int BufferRawAudioContext(RawAudioContext ctx, void *data, unsigned short numberElements); // returns number of elements buffered
#ifdef __cplusplus
}

View File

@ -30,7 +30,7 @@
#include "raylib.h"
#endif
#include <math.h>
#include <math.h> // Required for: sqrt(), sin(), cos()
//----------------------------------------------------------------------------------
// Defines and Macros

View File

@ -9,6 +9,7 @@
* PLATFORM_ANDROID - Only OpenGL ES 2.0 devices
* PLATFORM_RPI - Rapsberry Pi (tested on Raspbian)
* PLATFORM_WEB - Emscripten, HTML5
* PLATFORM_OCULUS - Oculus Rift CV1 (with desktop mirror)
*
* On PLATFORM_DESKTOP, the external lib GLFW3 (www.glfw.com) is used to manage graphic
* device, OpenGL context and input on multiple operating systems (Windows, Linux, OSX).
@ -53,14 +54,16 @@
#include <string.h> // String function definitions, memset()
#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
#if defined(PLATFORM_OCULUS)
#define PLATFORM_DESKTOP // Enable PLATFORM_DESKTOP code-base
#endif
#if defined(PLATFORM_DESKTOP)
#define GLAD_EXTENSIONS_LOADER
#if defined(GLEW_EXTENSIONS_LOADER)
#define GLEW_STATIC
#include <GL/glew.h> // GLEW extensions loading lib
#elif defined(GLAD_EXTENSIONS_LOADER)
#include "glad.h" // GLAD library: Manage OpenGL headers and extensions
#endif
#include "external/glad.h" // GLAD library: Manage OpenGL headers and extensions
#endif
#if defined(PLATFORM_OCULUS)
#include "../examples/oculus_glfw_sample/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
#endif
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
@ -135,7 +138,31 @@
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// ...
#if defined(PLATFORM_OCULUS)
typedef struct OculusBuffer {
ovrTextureSwapChain textureChain;
GLuint depthId;
GLuint fboId;
int width;
int height;
} OculusBuffer;
typedef struct OculusMirror {
ovrMirrorTexture texture;
GLuint fboId;
int width;
int height;
} OculusMirror;
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
@ -143,10 +170,13 @@
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
static GLFWwindow *window; // Native window (graphic device)
static bool windowMinimized = false;
#elif defined(PLATFORM_ANDROID)
#endif
#if defined(PLATFORM_ANDROID)
static struct android_app *app; // Android activity
static struct android_poll_source *source; // Android events polling source
static int ident, events; // Android ALooper_pollAll() variables
static const char *internalDataPath; // Android internal data path to write data (/data/data/<package>/files)
static bool windowReady = false; // Used to detect display initialization
static bool appEnabled = true; // Used to detec if app is active
@ -154,7 +184,9 @@ static bool contextRebindRequired = false; // Used to know context rebind r
static int previousButtonState[128] = { 1 }; // Required to check if button pressed/released once
static int currentButtonState[128] = { 1 }; // Required to check if button pressed/released once
#elif defined(PLATFORM_RPI)
#endif
#if defined(PLATFORM_RPI)
static EGL_DISPMANX_WINDOW_T nativeWindow; // Native window (graphic device)
// Keyboard input variables
@ -185,6 +217,17 @@ static uint64_t baseTime; // Base time measure for hi-res time
static bool windowShouldClose = false; // Flag to set window for closing
#endif
#if defined(PLATFORM_OCULUS)
// OVR device variables
static ovrSession session;
static ovrHmdDesc hmdDesc;
static ovrGraphicsLuid luid;
static OculusLayer layer;
static OculusBuffer buffer;
static OculusMirror mirror;
static unsigned int frameIndex = 0;
#endif
static unsigned int displayWidth, displayHeight; // Display width and height (monitor, device-screen, LCD, ...)
static int screenWidth, screenHeight; // Screen width and height (used render area)
static int renderWidth, renderHeight; // Framebuffer width and height (render area)
@ -194,6 +237,7 @@ static int renderOffsetX = 0; // Offset X from render area (must b
static int renderOffsetY = 0; // Offset Y from render area (must be divided by 2)
static bool fullscreen = false; // Fullscreen mode (useful only for PLATFORM_DESKTOP)
static Matrix downscaleView; // Matrix to downscale view (in case screen size bigger than display size)
static Matrix cameraView; // Store camera view matrix (required for Oculus Rift)
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
static const char *windowTitle; // Window text title...
@ -292,6 +336,19 @@ static void InitGamepad(void); // Init raw gamepad inpu
static void *GamepadThread(void *arg); // Mouse reading thread
#endif
#if defined(PLATFORM_OCULUS)
// Oculus Rift functions
static Matrix FromOvrMatrix(ovrMatrix4f ovrM);
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height);
static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer);
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer);
static void UnsetOculusBuffer(OculusBuffer buffer);
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);
static OculusLayer InitOculusLayer(ovrSession session);
#endif
//----------------------------------------------------------------------------------
// Module Functions Definition - Window and OpenGL Context Functions
//----------------------------------------------------------------------------------
@ -340,6 +397,11 @@ void InitWindow(int width, int height, const char *title)
//emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenInputCallback);
#endif
#if defined(PLATFORM_OCULUS)
// Recenter OVR tracking origin
ovr_RecenterTrackingOrigin(session);
#endif
mousePosition.x = (float)screenWidth/2.0f;
mousePosition.y = (float)screenHeight/2.0f;
@ -350,8 +412,9 @@ void InitWindow(int width, int height, const char *title)
LogoAnimation();
}
}
#endif
#elif defined(PLATFORM_ANDROID)
#if defined(PLATFORM_ANDROID)
// Android activity initialization
void InitWindow(int width, int height, struct android_app *state)
{
@ -363,6 +426,7 @@ void InitWindow(int width, int height, struct android_app *state)
screenHeight = height;
app = state;
internalDataPath = app->activity->internalDataPath;
// Set desired windows flags before initializing anything
ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
@ -424,7 +488,9 @@ void CloseWindow(void)
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
glfwDestroyWindow(window);
glfwTerminate();
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
// Close surface, context and display
if (display != EGL_NO_DISPLAY)
{
@ -447,9 +513,71 @@ void CloseWindow(void)
}
#endif
#if defined(PLATFORM_OCULUS)
ovr_Destroy(session); // Must be called after glfwTerminate()
ovr_Shutdown();
#endif
TraceLog(INFO, "Window closed successfully");
}
#if defined(PLATFORM_OCULUS)
// Init Oculus Rift device
// NOTE: Device initialization should be done before window creation?
void InitOculusDevice(void)
{
ovrResult result = ovr_Initialize(NULL);
if (OVR_FAILURE(result)) TraceLog(ERROR, "OVR: Could not initialize Oculus device");
result = ovr_Create(&session, &luid);
if (OVR_FAILURE(result))
{
TraceLog(WARNING, "OVR: Could not create Oculus session");
ovr_Shutdown();
}
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: Serian Number: %s", hmdDesc.SerialNumber);
TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
screenWidth = hmdDesc.Resolution.w/2;
screenHeight = 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);
layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
}
// Close Oculus Rift device
void CloseOculusDevice(void)
{
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
ovr_Destroy(session); // Must be called after glfwTerminate() --> REALLY???
ovr_Shutdown();
}
// Update Oculus Rift tracking (position and orientation)
void UpdateOculusTracking(void)
{
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];
}
#endif
// Detect if KEY_ESCAPE pressed or Close icon pressed
bool WindowShouldClose(void)
{
@ -458,7 +586,9 @@ bool WindowShouldClose(void)
while (windowMinimized) glfwPollEvents();
return (glfwWindowShouldClose(window));
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
return windowShouldClose;
#endif
}
@ -484,7 +614,9 @@ void ToggleFullscreen(void)
glfwDestroyWindow(window); // Destroy the current window (we will recreate it!)
InitWindow(screenWidth, screenHeight, windowTitle);
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
TraceLog(WARNING, "Could not toggle to windowed mode");
#endif
}
@ -514,6 +646,18 @@ void BeginDrawing(void)
currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called
updateTime = currentTime - previousTime;
previousTime = currentTime;
#if defined(PLATFORM_OCULUS)
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];
SetOculusBuffer(session, buffer);
#endif
rlClearScreenBuffers(); // Clear current framebuffers
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
@ -526,10 +670,51 @@ void BeginDrawing(void)
// End canvas drawing and Swap Buffers (Double Buffering)
void EndDrawing(void)
{
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
#if defined(PLATFORM_OCULUS)
for (int eye = 0; eye < 2; eye++)
{
rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h);
Quaternion eyeRPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x,
layer.eyeLayer.RenderPose[eye].Orientation.y,
layer.eyeLayer.RenderPose[eye].Orientation.z,
layer.eyeLayer.RenderPose[eye].Orientation.w };
QuaternionInvert(&eyeRPose);
Matrix eyeOrientation = QuaternionToMatrix(eyeRPose);
Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x,
-layer.eyeLayer.RenderPose[eye].Position.y,
-layer.eyeLayer.RenderPose[eye].Position.z);
Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation);
Matrix modelEyeView = MatrixMultiply(cameraView, eyeView); // Using internal camera modelview matrix
SetMatrixModelview(modelEyeView);
SetMatrixProjection(layer.eyeProjections[eye]);
#endif
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
#if defined(PLATFORM_OCULUS)
}
UnsetOculusBuffer(buffer);
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);
// 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);
#endif
SwapBuffers(); // Copy back buffer to front buffer
PollInputEvents(); // Poll user events
// Frame time control system
@ -599,8 +784,8 @@ void Begin3dMode(Camera camera)
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
// Setup Camera view
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
rlMultMatrixf(MatrixToFloat(matView)); // Multiply MODELVIEW matrix by view matrix (camera)
cameraView = MatrixLookAt(camera.position, camera.target, camera.up);
rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera)
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
}
@ -838,12 +1023,21 @@ void ClearDroppedFiles(void)
void StorageSaveValue(int position, int value)
{
FILE *storageFile = NULL;
char path[128];
#if defined(PLATFORM_ANDROID)
strcpy(path, internalDataPath);
strcat(path, "/");
strcat(path, STORAGE_FILENAME);
#else
strcpy(path, STORAGE_FILENAME);
#endif
// Try open existing file to append data
storageFile = fopen(STORAGE_FILENAME, "rb+");
storageFile = fopen(path, "rb+");
// If file doesn't exist, create a new storage data file
if (!storageFile) storageFile = fopen(STORAGE_FILENAME, "wb");
if (!storageFile) storageFile = fopen(path, "wb");
if (!storageFile) TraceLog(WARNING, "Storage data file could not be created");
else
@ -870,8 +1064,17 @@ int StorageLoadValue(int position)
{
int value = 0;
char path[128];
#if defined(PLATFORM_ANDROID)
strcpy(path, internalDataPath);
strcat(path, "/");
strcat(path, STORAGE_FILENAME);
#else
strcpy(path, STORAGE_FILENAME);
#endif
// Try open existing file to append data
FILE *storageFile = fopen(STORAGE_FILENAME, "rb");
FILE *storageFile = fopen(path, "rb");
if (!storageFile) TraceLog(WARNING, "Storage data file could not be found");
else
@ -1423,6 +1626,30 @@ static void InitDisplay(int width, int height)
// Downscale matrix is required in case desired screen area is bigger than display area
downscaleView = MatrixIdentity();
#if defined(PLATFORM_OCULUS)
ovrResult result = ovr_Initialize(NULL);
if (OVR_FAILURE(result)) TraceLog(ERROR, "OVR: Could not initialize Oculus device");
result = ovr_Create(&session, &luid);
if (OVR_FAILURE(result))
{
TraceLog(WARNING, "OVR: Could not create Oculus session");
ovr_Shutdown();
}
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: Serian Number: %s", hmdDesc.SerialNumber);
TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
screenWidth = hmdDesc.Resolution.w/2;
screenHeight = hmdDesc.Resolution.h/2;
#endif
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
glfwSetErrorCallback(ErrorCallback);
@ -1551,38 +1778,23 @@ static void InitDisplay(int width, int height)
#endif
glfwMakeContextCurrent(window);
#if defined(PLATFORM_OCULUS)
glfwSwapInterval(0);
#endif
#if defined(PLATFORM_DESKTOP)
// Extensions initialization for OpenGL 3.3
// Load OpenGL 3.3 extensions using GLAD
if (rlGetVersion() == OPENGL_33)
{
#if defined(GLEW_EXTENSIONS_LOADER)
// Initialize extensions using GLEW
glewExperimental = 1; // Needed for core profile
GLenum error = glewInit();
if (error != GLEW_OK) TraceLog(ERROR, "Failed to initialize GLEW - Error Code: %s\n", glewGetErrorString(error));
if (glewIsSupported("GL_VERSION_3_3")) TraceLog(INFO, "OpenGL 3.3 Core profile supported");
else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions");
else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully");
// With GLEW, we can check if an extension has been loaded in two ways:
//if (GLEW_ARB_vertex_array_object) { }
//if (glewIsSupported("GL_ARB_vertex_array_object")) { }
// NOTE: GLEW is a big library that loads ALL extensions, we can use some alternative to load only required ones
// Alternatives: glLoadGen, glad, libepoxy
#elif defined(GLAD_EXTENSIONS_LOADER)
// NOTE: glad is generated and contains only required OpenGL version and Core extensions
//if (!gladLoadGL()) TraceLog(ERROR, "Failed to initialize glad\n");
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) TraceLog(ERROR, "Failed to initialize glad\n"); // No GLFW3 in this module...
if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported");
else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
// 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
#endif
if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported");
else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
// 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
}
#endif
@ -1750,13 +1962,16 @@ static void InitDisplay(int width, int height)
static void InitGraphics(void)
{
rlglInit(); // Init rlgl
#if defined(PLATFORM_OCULUS)
//rlglInitOculus(); // Init rlgl for Oculus Rift (required textures)
#endif
rlglInitGraphics(renderOffsetX, renderOffsetY, renderWidth, renderHeight); // Init graphics (OpenGL stuff)
#if defined(PLATFORM_OCULUS)
// Initialize Oculus Buffers
layer = InitOculusLayer(session);
buffer = LoadOculusBuffer(session, layer.width, layer.height);
mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2);
layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
#endif
ClearBackground(RAYWHITE); // Default background color for raylib games :P
#if defined(PLATFORM_ANDROID)
@ -1864,7 +2079,9 @@ static double GetTime(void)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
return glfwGetTime();
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
uint64_t time = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
@ -1932,8 +2149,9 @@ static void PollInputEvents(void)
currentMouseWheelY = 0;
glfwPollEvents(); // Register keyboard/mouse events... and window events!
#elif defined(PLATFORM_ANDROID)
#endif
#if defined(PLATFORM_ANDROID)
// Register previous keys states
for (int i = 0; i < 128; i++) previousButtonState[i] = currentButtonState[i];
@ -1952,8 +2170,9 @@ static void PollInputEvents(void)
//ANativeActivity_finish(app->activity);
}
}
#elif defined(PLATFORM_RPI)
#endif
#if defined(PLATFORM_RPI)
// NOTE: Mouse input events polling is done asynchonously in another pthread - MouseThread()
// NOTE: Keyboard reading could be done using input_event(s) reading or just read from stdin,
@ -1961,7 +2180,6 @@ static void PollInputEvents(void)
ProcessKeyboard();
// NOTE: Gamepad (Joystick) input events polling is done asynchonously in another pthread - GamepadThread()
#endif
}
@ -1970,7 +2188,9 @@ static void SwapBuffers(void)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
glfwSwapBuffers(window);
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
eglSwapBuffers(display, surface);
#endif
}
@ -2058,10 +2278,10 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
gestureEvent.position[0] = GetMousePosition();
// Normalize gestureEvent.position[0] for screenWidth and screenHeight
gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].y /= (float)GetScreenHeight();
// Gesture data is sent to gestures system for processing
// Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent);
#endif
}
@ -2203,10 +2423,10 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Load default font for convenience
// NOTE: External function (defined in module: text)
LoadDefaultFont();
// TODO: GPU assets reload in case of lost focus (lost context)
// NOTE: This problem has been solved just unbinding and rebinding context from display
/*
/*
if (assetsReloadRequired)
{
for (int i = 0; i < assetsCount; i++)
@ -2454,7 +2674,7 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent
gestureEvent.position[1].y /= (float)GetScreenHeight();
// Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent); // Process obtained gestures data
ProcessGestureEvent(gestureEvent);
return 1;
}
@ -2739,9 +2959,9 @@ static void *GamepadThread(void *arg)
};
// Read gamepad event
struct js_event gamepadEvent;
struct js_event gamepadEvent;
while (1)
while (1)
{
for (int i = 0; i < MAX_GAMEPADS; i++)
{
@ -2772,12 +2992,220 @@ static void *GamepadThread(void *arg)
}
}
}
}
}
return NULL;
}
#endif
#if defined(PLATFORM_OCULUS)
// 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;
}
// 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);
}
// Set current Oculus buffer
static void SetOculusBuffer(ovrSession session, OculusBuffer buffer)
{
GLuint currentTexId;
int currentIndex;
ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, &currentIndex);
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, &currentTexId);
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
//glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Required if OculusBuffer format is OVR_FORMAT_R8G8B8A8_UNORM_SRGB
glEnable(GL_FRAMEBUFFER_SRGB);
}
// Unset Oculus buffer
static void UnsetOculusBuffer(OculusBuffer buffer)
{
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
// 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);
}
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);
glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
// Requires: session, hmdDesc
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;
}
#endif
// Plays raylib logo appearing animation
static void LogoAnimation(void)
{

View File

@ -9,21 +9,24 @@
* // This requires lots of memory on system.
* How to use:
* The four inputs t,b,c,d are defined as follows:
* t = current time in milliseconds
* b = starting position in only one dimension [X || Y || Z] your choice
* t = current time (in any unit measure, but same unit as duration)
* b = starting value to interpolate
* c = the total change in value of b that needs to occur
* d = total time it should take to complete
* d = total time it should take to complete (duration)
*
* Example:
* float speed = 1.f;
* float currentTime = 0.f;
* float currentPos[2] = {0,0};
* float finalPos[2] = {1,1};
* float startPosition[2] = currentPos;//x,y positions
* while(currentPos[0] < finalPos[0])
* currentPos[0] = EaseSineIn(currentTime, startPosition[0], startPosition[0]-finalPos[0], speed);
* currentPos[1] = EaseSineIn(currentTime, startPosition[1], startPosition[1]-finalPos[0], speed);
* currentTime += diffTime();
*
* int currentTime = 0;
* int duration = 100;
* float startPositionX = 0.0f;
* float finalPositionX = 30.0f;
* float currentPositionX = startPositionX;
*
* while (currentPositionX < finalPositionX)
* {
* currentPositionX = EaseSineIn(currentTime, startPositionX, finalPositionX - startPositionX, duration);
* currentTime++;
* }
*
* A port of Robert Penner's easing equations to C (http://robertpenner.com/easing/)
*
@ -87,7 +90,7 @@
#define EASEDEF extern
#endif
#include <math.h>
#include <math.h> // Required for: sin(), cos(), sqrt(), pow()
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
Copyright (c) 2002-2006 Marcus Geelnard
Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -18,4 +18,5 @@ freely, subject to the following restrictions:
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
distribution.

View File

@ -1,9 +1,9 @@
/*************************************************************************
* GLFW 3.1 - www.glfw.org
* GLFW 3.2 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
* Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@ -38,20 +38,30 @@ extern "C" {
* Doxygen documentation
*************************************************************************/
/*! @file glfw3native.h
* @brief The header of the native access functions.
*
* This is the header file of the native access functions. See @ref native for
* more information.
*/
/*! @defgroup native Native access
*
* **By using the native access functions you assert that you know what you're
* doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.**
*
* Before the inclusion of @ref glfw3native.h, you must define exactly one
* window system API macro and exactly one context creation API macro. Failure
* to do this will cause a compile-time error.
* Before the inclusion of @ref glfw3native.h, you may define exactly one
* window system API macro and zero or more context creation API macros.
*
* The chosen backends must match those the library was compiled for. Failure
* to do this will cause a link-time error.
*
* The available window API macros are:
* * `GLFW_EXPOSE_NATIVE_WIN32`
* * `GLFW_EXPOSE_NATIVE_COCOA`
* * `GLFW_EXPOSE_NATIVE_X11`
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
* * `GLFW_EXPOSE_NATIVE_MIR`
*
* The available context API macros are:
* * `GLFW_EXPOSE_NATIVE_WGL`
@ -86,20 +96,23 @@ extern "C" {
#elif defined(GLFW_EXPOSE_NATIVE_X11)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#else
#error "No window API selected"
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#elif defined(GLFW_EXPOSE_NATIVE_MIR)
#include <mir_toolkit/mir_client_library.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#elif defined(GLFW_EXPOSE_NATIVE_NSGL)
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#elif defined(GLFW_EXPOSE_NATIVE_GLX)
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
#include <GL/glx.h>
#elif defined(GLFW_EXPOSE_NATIVE_EGL)
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#else
#error "No context API selected"
#endif
@ -114,11 +127,10 @@ extern "C" {
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.1.
* @since Added in version 3.1.
*
* @ingroup native
*/
@ -130,11 +142,10 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.1.
* @since Added in version 3.1.
*
* @ingroup native
*/
@ -145,11 +156,10 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
* @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
@ -162,11 +172,10 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
* @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
@ -179,11 +188,10 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
* @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.1.
* @since Added in version 3.1.
*
* @ingroup native
*/
@ -194,11 +202,10 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
* @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
@ -211,11 +218,10 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
@ -228,11 +234,10 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
* @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
@ -243,11 +248,10 @@ GLFWAPI Display* glfwGetX11Display(void);
* @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.1.
* @since Added in version 3.1.
*
* @ingroup native
*/
@ -258,11 +262,10 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
* @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.1.
* @since Added in version 3.1.
*
* @ingroup native
*/
@ -273,11 +276,10 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
@ -290,15 +292,116 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
* @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
/*! @brief Returns the `GLXWindow` of the specified window.
*
* @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
/*! @brief Returns the `struct wl_display*` used by GLFW.
*
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
/*! @brief Returns the `struct wl_output*` of the specified monitor.
*
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
/*! @brief Returns the main `struct wl_surface*` of the specified window.
*
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_MIR)
/*! @brief Returns the `MirConnection*` used by GLFW.
*
* @return The `MirConnection*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI MirConnection* glfwGetMirDisplay(void);
/*! @brief Returns the Mir output ID of the specified monitor.
*
* @return The Mir output ID of the specified monitor, or zero if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
/*! @brief Returns the `MirSurface*` of the specified window.
*
* @return The `MirSurface*` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
@ -307,11 +410,10 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
@ -322,11 +424,10 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/
@ -337,11 +438,10 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred.
*
* @par Thread Safety
* This function may be called from any thread. Access is not synchronized.
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @par History
* Added in GLFW 3.0.
* @since Added in version 3.0.
*
* @ingroup native
*/

BIN
src/external/glfw3/lib/win32/glfw3.dll vendored Normal file

Binary file not shown.

BIN
src/external/glfw3/lib/win32/libglfw3.a vendored Normal file

Binary file not shown.

1587
src/external/jar_mod.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,8 @@
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
@ -348,6 +348,89 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64
#endif
#endif
#ifndef ALC_EXT_DEFAULT_FILTER_ORDER
#define ALC_EXT_DEFAULT_FILTER_ORDER 1
#define ALC_DEFAULT_FILTER_ORDER 0x1100
#endif
#ifndef AL_SOFT_deferred_updates
#define AL_SOFT_deferred_updates 1
#define AL_DEFERRED_UPDATES_SOFT 0xC002
typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void);
typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void);
AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void);
#endif
#endif
#ifndef AL_SOFT_block_alignment
#define AL_SOFT_block_alignment 1
#define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C
#define AL_PACK_BLOCK_ALIGNMENT_SOFT 0x200D
#endif
#ifndef AL_SOFT_MSADPCM
#define AL_SOFT_MSADPCM 1
#define AL_FORMAT_MONO_MSADPCM_SOFT 0x1302
#define AL_FORMAT_STEREO_MSADPCM_SOFT 0x1303
#endif
#ifndef AL_SOFT_source_length
#define AL_SOFT_source_length 1
/*#define AL_BYTE_LENGTH_SOFT 0x2009*/
/*#define AL_SAMPLE_LENGTH_SOFT 0x200A*/
/*#define AL_SEC_LENGTH_SOFT 0x200B*/
#endif
#ifndef ALC_SOFT_pause_device
#define ALC_SOFT_pause_device 1
typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);
typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device);
#ifdef AL_ALEXT_PROTOTYPES
ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device);
ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
#endif
#endif
#ifndef AL_EXT_BFORMAT
#define AL_EXT_BFORMAT 1
#define AL_FORMAT_BFORMAT2D_8 0x20021
#define AL_FORMAT_BFORMAT2D_16 0x20022
#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
#define AL_FORMAT_BFORMAT3D_8 0x20031
#define AL_FORMAT_BFORMAT3D_16 0x20032
#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033
#endif
#ifndef AL_EXT_MULAW_BFORMAT
#define AL_EXT_MULAW_BFORMAT 1
#define AL_FORMAT_BFORMAT2D_MULAW 0x10031
#define AL_FORMAT_BFORMAT3D_MULAW 0x10032
#endif
#ifndef ALC_SOFT_HRTF
#define ALC_SOFT_HRTF 1
#define ALC_HRTF_SOFT 0x1992
#define ALC_DONT_CARE_SOFT 0x0002
#define ALC_HRTF_STATUS_SOFT 0x1993
#define ALC_HRTF_DISABLED_SOFT 0x0000
#define ALC_HRTF_ENABLED_SOFT 0x0001
#define ALC_HRTF_DENIED_SOFT 0x0002
#define ALC_HRTF_REQUIRED_SOFT 0x0003
#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004
#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005
#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994
#define ALC_HRTF_SPECIFIER_SOFT 0x1995
#define ALC_HRTF_ID_SOFT 0x1996
typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index);
typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs);
#ifdef AL_ALEXT_PROTOTYPES
ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index);
ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs);
#endif
#endif
#ifdef __cplusplus
}
#endif

View File

@ -345,7 +345,7 @@ typedef struct {
/* Driving Presets */
#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \
{ 1.0000f, 0.0000f, 3.1623f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
{ 1.0000f, 0.0000f, 0.3162f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \
{ 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }

Binary file not shown.

View File

View File

@ -28,30 +28,30 @@
#if defined(GESTURES_STANDALONE)
#include "gestures.h"
#else
#include "raylib.h" // Required for typedef(s): Vector2, Gestures
#include "raylib.h" // Required for: Vector2, Gestures
#endif
#include <math.h> // Used for: atan2(), sqrt()
#include <stdint.h> // Defines int32_t, int64_t
#include <math.h> // Required for: atan2(), sqrt()
#include <stdint.h> // Required for: uint64_t
#if defined(_WIN32)
// Functions required to query time on Windows
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
#elif defined(__linux)
#include <sys/time.h> // Declares storage size of now
#include <time.h> // Used for clock functions
#include <sys/time.h> // Required for: timespec
#include <time.h> // Required for: clock_gettime()
#endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define FORCE_TO_SWIPE 0.0005f // Measured in normalized pixels / time
#define MINIMUM_DRAG 0.015f // Measured in normalized pixels [0..1]
#define MINIMUM_PINCH 0.005f // Measured in normalized pixels [0..1]
#define FORCE_TO_SWIPE 0.0005f // Measured in normalized screen units/time
#define MINIMUM_DRAG 0.015f // Measured in normalized screen units (0.0f to 1.0f)
#define MINIMUM_PINCH 0.005f // Measured in normalized screen units (0.0f to 1.0f)
#define TAP_TIMEOUT 300 // Time in milliseconds
#define PINCH_TIMEOUT 300 // Time in milliseconds
#define DOUBLETAP_RANGE 0.03f
#define DOUBLETAP_RANGE 0.03f // Measured in normalized screen units (0.0f to 1.0f)
//----------------------------------------------------------------------------------
// Types and Structures Definition

7684
src/glad.c

File diff suppressed because one or more lines are too long

Binary file not shown.

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