Updated Oculus sample to Oculus SDK 1.4
Still working on the sample but almost finished. Some rlgl internals redesign required and it will be ready!
This commit is contained in:
parent
d17a0cee1a
commit
8f91ed81c5
18 changed files with 9807 additions and 9286 deletions
Binary file not shown.
|
@ -137,14 +137,14 @@ OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f proj
|
||||||
/// Computes offset eye poses based on headPose returned by ovrTrackingState.
|
/// 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] 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
|
/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
|
||||||
/// of the two vectors for both eyes.
|
/// of the two vectors for both eyes.
|
||||||
/// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to
|
/// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to
|
||||||
/// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose.
|
/// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose.
|
||||||
///
|
///
|
||||||
OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose,
|
OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose,
|
||||||
const ovrVector3f HmdToEyeOffset[2],
|
const ovrVector3f hmdToEyeOffset[2],
|
||||||
ovrPosef outEyePoses[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] 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
|
/// \param[in] frameIndex Specifies the targeted frame index, or 0 to refer to one frame after
|
||||||
/// the last time ovr_SubmitFrame was called.
|
/// 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
|
/// \param[in] latencyMarker Specifies that this call is the point in time where
|
||||||
/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer
|
/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer
|
||||||
/// provides "SensorSampleTimestamp", that will override the value stored here.
|
/// provides "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] outEyePoses The predicted eye poses.
|
||||||
/// \param[out] outSensorSampleTime The time when this function was called. May be NULL, in which case it is ignored.
|
/// \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,
|
OVR_PUBLIC_FUNCTION(void) ovr_GetEyePoses(ovrSession session, long long frameIndex, ovrBool latencyMarker,
|
||||||
const ovrVector3f HmdToEyeOffset[2],
|
const ovrVector3f hmdToEyeOffset[2],
|
||||||
ovrPosef outEyePoses[2],
|
ovrPosef outEyePoses[2],
|
||||||
double* outSensorSampleTime);
|
double* outSensorSampleTime);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/********************************************************************************//**
|
/********************************************************************************//**
|
||||||
\file OVR_Math.h
|
\file OVR_Math.h
|
||||||
\brief Implementation of 3D primitives such as vectors, matrices.
|
\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
|
#ifndef OVR_Math_h
|
||||||
|
@ -1754,7 +1754,7 @@ public:
|
||||||
: Rotation(s.Rotation), Translation(s.Translation)
|
: Rotation(s.Rotation), Translation(s.Translation)
|
||||||
{
|
{
|
||||||
// Ensure normalized rotation if converting from float to double
|
// 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();
|
Rotation.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/********************************************************************************//**
|
/********************************************************************************//**
|
||||||
\file OVR_CAPI.h
|
\file OVR_CAPI.h
|
||||||
\brief C Interface to the Oculus PC SDK tracking and rendering library.
|
\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.
|
#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.
|
/// call. This flag requires that RenderTarget binding also be specified.
|
||||||
ovrTextureMisc_AllowGenerateMips = 0x0002,
|
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.
|
ovrTextureMisc_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
|
||||||
} ovrTextureFlags;
|
} ovrTextureFlags;
|
||||||
|
|
||||||
|
@ -695,7 +700,7 @@ typedef enum ovrTextureMiscFlags_
|
||||||
/// \see ovr_CreateTextureSwapChainDX
|
/// \see ovr_CreateTextureSwapChainDX
|
||||||
/// \see ovr_CreateTextureSwapChainGL
|
/// \see ovr_CreateTextureSwapChainGL
|
||||||
///
|
///
|
||||||
typedef struct
|
typedef struct ovrTextureSwapChainDesc_
|
||||||
{
|
{
|
||||||
ovrTextureType Type;
|
ovrTextureType Type;
|
||||||
ovrTextureFormat Format;
|
ovrTextureFormat Format;
|
||||||
|
@ -705,7 +710,7 @@ typedef struct
|
||||||
int MipLevels;
|
int MipLevels;
|
||||||
int SampleCount; ///< Current only supported on depth textures
|
int SampleCount; ///< Current only supported on depth textures
|
||||||
ovrBool StaticImage; ///< Not buffered in a chain. For images that don't change
|
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.
|
unsigned int BindFlags; ///< ovrTextureBindFlags. Not used for GL.
|
||||||
} ovrTextureSwapChainDesc;
|
} ovrTextureSwapChainDesc;
|
||||||
|
|
||||||
|
@ -714,12 +719,12 @@ typedef struct
|
||||||
/// \see ovr_CreateMirrorTextureDX
|
/// \see ovr_CreateMirrorTextureDX
|
||||||
/// \see ovr_CreateMirrorTextureGL
|
/// \see ovr_CreateMirrorTextureGL
|
||||||
///
|
///
|
||||||
typedef struct
|
typedef struct ovrMirrorTextureDesc_
|
||||||
{
|
{
|
||||||
ovrTextureFormat Format;
|
ovrTextureFormat Format;
|
||||||
int Width;
|
int Width;
|
||||||
int Height;
|
int Height;
|
||||||
unsigned int MiscFlags; ///< ovrTextureMiscFlags
|
unsigned int MiscFlags; ///< ovrTextureFlags
|
||||||
} ovrMirrorTextureDesc;
|
} ovrMirrorTextureDesc;
|
||||||
|
|
||||||
typedef struct ovrTextureSwapChainData* ovrTextureSwapChain;
|
typedef struct ovrTextureSwapChainData* ovrTextureSwapChain;
|
||||||
|
@ -987,8 +992,8 @@ extern "C" {
|
||||||
/// Initializes LibOVR
|
/// Initializes LibOVR
|
||||||
///
|
///
|
||||||
/// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT
|
/// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT
|
||||||
/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo, can be called
|
/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo and ovr_Detect, can
|
||||||
/// unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually
|
/// 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.
|
/// 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.
|
/// Calling ovr_Initialize twice does not require two matching calls to ovr_Shutdown.
|
||||||
/// If already initialized, the return value is ovr_Success.
|
/// 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
|
/// \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
|
/// to display pixels at the center of distortion. 1.0 is the default value. Lower
|
||||||
/// values can improve performance, higher values give improved quality.
|
/// 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.
|
/// \return Returns the texture width and height size.
|
||||||
///
|
///
|
||||||
OVR_PUBLIC_FUNCTION(ovrSizei) ovr_GetFovTextureSize(ovrSession session, ovrEyeType eye, ovrFovPort fov,
|
OVR_PUBLIC_FUNCTION(ovrSizei) ovr_GetFovTextureSize(ovrSession session, ovrEyeType eye, ovrFovPort fov,
|
||||||
|
|
|
@ -67,8 +67,8 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainDX(ovrSession session,
|
||||||
///
|
///
|
||||||
/// <b>Example code</b>
|
/// <b>Example code</b>
|
||||||
/// \code{.cpp}
|
/// \code{.cpp}
|
||||||
/// ovr_GetTextureSwapChainBuffer(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
|
/// ovr_GetTextureSwapChainBufferDX(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
|
||||||
/// ovr_GetTextureSwapChainBuffer(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
|
/// ovr_GetTextureSwapChainBufferDX(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession session,
|
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
|
/// 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.
|
/// 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_GetMirrorTextureBufferDX
|
||||||
/// \see ovr_DestroyMirrorTexture
|
/// \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
|
/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
|
||||||
/// ovr_GetLastErrorInfo to get more information.
|
/// ovr_GetLastErrorInfo to get more information.
|
||||||
///
|
///
|
||||||
|
/// <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,
|
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session,
|
||||||
ovrMirrorTexture mirrorTexture,
|
ovrMirrorTexture mirrorTexture,
|
||||||
IID iid,
|
IID iid,
|
||||||
|
|
|
@ -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_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_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_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. */
|
/* Audio error range, reserved for Audio errors. */
|
||||||
ovrError_AudioReservedBegin = -2000, ///< First Audio error.
|
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_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_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_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_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_TrackerFirmwareMismatch = -4101, ///< The sensor Firmware is out of date and is unacceptable.
|
||||||
ovrError_BootloaderDeviceDetected = -4102, ///< A bootloader HMD is detected by the service.
|
ovrError_BootloaderDeviceDetected = -4102, ///< A bootloader HMD is detected by the service.
|
||||||
ovrError_TrackerCalibrationError = -4103, ///< The sensor calibration is missing or incorrect.
|
ovrError_TrackerCalibrationError = -4103, ///< The sensor calibration is missing or incorrect.
|
||||||
ovrError_ControllerFirmwareMismatch = -4104, ///< The controller firmware is out of date and is unacceptable.
|
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_IMUTooManyLostSamples = -4200, ///< Too many lost IMU samples.
|
||||||
ovrError_IMURateError = -4201, ///< IMU rate is outside of the expected range.
|
ovrError_IMURateError = -4201, ///< IMU rate is outside of the expected range.
|
||||||
ovrError_FeatureReportFailure = -4202, ///< A feature report has failed.
|
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 */
|
/* Synchronization errors */
|
||||||
ovrError_Incomplete = -5000, ///<Requested async work not yet complete.
|
ovrError_Incomplete = -5000, ///< Requested async work not yet complete.
|
||||||
ovrError_Abandoned = -5001, ///<Requested async work was abandoned and result is incomplete.
|
ovrError_Abandoned = -5001, ///< Requested async work was abandoned and result is incomplete.
|
||||||
|
|
||||||
/* Rendering errors */
|
/* Rendering errors */
|
||||||
ovrError_DisplayLost = -6000, ///<In the event of a system-wide graphics reset or cable unplug this is returned to the app.
|
ovrError_DisplayLost = -6000, ///< In the event of a system-wide graphics reset or cable unplug this is returned to the app.
|
||||||
ovrError_TextureSwapChainFull = -6001, ///<ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain.
|
ovrError_TextureSwapChainFull = -6001, ///< ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain.
|
||||||
ovrError_TextureSwapChainInvalid = -6002, ///<The ovrTextureSwapChain is in an incomplete or inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first.
|
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 */
|
/* 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.
|
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.
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
// Master version numbers
|
// Master version numbers
|
||||||
#define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning.
|
#define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning.
|
||||||
#define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change LibOVR/Projects/Windows/LibOVR.props in parallel.
|
#define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change LibOVR/Projects/Windows/LibOVR.props in parallel.
|
||||||
#define OVR_MINOR_VERSION 3 //
|
#define OVR_MINOR_VERSION 4 //
|
||||||
#define OVR_PATCH_VERSION 0
|
#define OVR_PATCH_VERSION 0
|
||||||
#define OVR_BUILD_NUMBER 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
|
@ -4,11 +4,11 @@
|
||||||
*
|
*
|
||||||
* NOTE: This example requires raylib module [rlgl]
|
* 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
|
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
|
||||||
*
|
*
|
||||||
* Compile example using:
|
* 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)
|
* 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)
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
@ -21,72 +21,103 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define GLAD_IMPLEMENTATION
|
||||||
#include "glad.h" // Extensions loading library
|
#include "glad.h" // Extensions loading library
|
||||||
#include <GLFW/glfw3.h> // Windows/Context and inputs management
|
#include <GLFW/glfw3.h> // Windows/Context and inputs management
|
||||||
|
|
||||||
#include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
|
|
||||||
|
|
||||||
#define RLGL_STANDALONE
|
#define RLGL_STANDALONE
|
||||||
#include "rlgl.h"
|
#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
|
// OVR device variables
|
||||||
ovrSession session;
|
ovrSession session;
|
||||||
ovrHmdDesc hmdDesc;
|
ovrHmdDesc hmdDesc;
|
||||||
ovrGraphicsLuid luid;
|
ovrGraphicsLuid luid;
|
||||||
|
#endif
|
||||||
|
|
||||||
// OVR OpenGL required variables
|
unsigned int frameIndex = 0;
|
||||||
GLuint fbo = 0;
|
|
||||||
GLuint depthBuffer = 0;
|
|
||||||
ovrTextureSwapChain eyeTexture;
|
|
||||||
|
|
||||||
GLuint mirrorFbo = 0;
|
#define RED (Color){ 230, 41, 55, 255 } // Red
|
||||||
ovrMirrorTexture mirrorTexture;
|
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
|
||||||
ovrEyeRenderDesc eyeRenderDescs[2];
|
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
|
||||||
Matrix eyeProjections[2];
|
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
|
||||||
|
|
||||||
ovrLayerEyeFov eyeLayer;
|
|
||||||
ovrViewScaleDesc viewScaleDesc;
|
|
||||||
|
|
||||||
Vector2 renderTargetSize = { 0, 0 };
|
|
||||||
Vector2 mirrorSize;
|
|
||||||
unsigned int frame = 0;
|
|
||||||
|
|
||||||
// GLFW variables
|
|
||||||
GLFWwindow *window = NULL;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// 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; // layer 1
|
||||||
|
Matrix eyeProjections[2];
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} OculusLayer;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
|
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// 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);
|
||||||
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, ...);
|
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);
|
static Matrix FromOvrMatrix(ovrMatrix4f ovrM);
|
||||||
void DrawGrid(int slices, float spacing);
|
static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height);
|
||||||
void DrawCube(Vector3 position, float width, float height, float length, Color color);
|
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
|
// Main Entry point
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
int main()
|
int main(void)
|
||||||
{
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 1080;
|
||||||
|
int screenHeight = 600;
|
||||||
|
|
||||||
|
#if defined(PLATFORM_OCULUS)
|
||||||
ovrResult result = ovr_Initialize(NULL);
|
ovrResult result = ovr_Initialize(NULL);
|
||||||
if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device");
|
if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device");
|
||||||
|
|
||||||
|
@ -106,37 +137,14 @@ int main()
|
||||||
TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber);
|
TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber);
|
||||||
TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
|
TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
|
||||||
|
|
||||||
|
screenWidth = hmdDesc.Resolution.w/2;
|
||||||
viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
|
screenHeight = hmdDesc.Resolution.h/2;
|
||||||
memset(&eyeLayer, 0, sizeof(ovrLayerEyeFov));
|
#endif
|
||||||
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;
|
|
||||||
|
|
||||||
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
|
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
|
||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
|
glfwSetErrorCallback(ErrorCallback);
|
||||||
|
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
{
|
{
|
||||||
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
|
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
|
||||||
|
@ -149,9 +157,8 @@ int main()
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
|
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);
|
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib oculus sample", NULL, NULL);
|
||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
|
@ -160,146 +167,129 @@ int main()
|
||||||
}
|
}
|
||||||
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
|
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
|
||||||
|
|
||||||
glfwSetErrorCallback(ErrorCallback);
|
|
||||||
glfwSetKeyCallback(window, KeyCallback);
|
glfwSetKeyCallback(window, KeyCallback);
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(0);
|
||||||
|
|
||||||
|
// Load OpenGL 3.3 extensions
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||||
{
|
{
|
||||||
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
|
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
|
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
// Initialize OVR OpenGL swap chain textures
|
#if defined(PLATFORM_OCULUS)
|
||||||
ovrTextureSwapChainDesc desc = {};
|
// Initialize Oculus Buffers
|
||||||
desc.Type = ovrTexture_2D;
|
OculusLayer layer = InitOculusLayer(session);
|
||||||
desc.ArraySize = 1;
|
OculusBuffer buffer = LoadOculusBuffer(session, layer.width, layer.height);
|
||||||
desc.Width = renderTargetSize.x;
|
OculusMirror mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2);
|
||||||
desc.Height = renderTargetSize.y;
|
layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
|
||||||
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);
|
|
||||||
|
|
||||||
// Recenter OVR tracking origin
|
// Recenter OVR tracking origin
|
||||||
ovr_RecenterTrackingOrigin(session);
|
ovr_RecenterTrackingOrigin(session);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initialize rlgl internal buffers and OpenGL state
|
// Initialize rlgl internal buffers and OpenGL state
|
||||||
rlglInit();
|
rlglInit();
|
||||||
rlglInitGraphics(0, 0, mirrorSize.x, mirrorSize.y);
|
rlglInitGraphics(0, 0, screenWidth, screenHeight);
|
||||||
rlClearColor(245, 245, 245, 255); // Define clear color
|
rlClearColor(245, 245, 245, 255); // Define clear color
|
||||||
glEnable(GL_DEPTH_TEST);
|
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
|
||||||
|
|
||||||
Vector2 position = { mirrorSize.x/2 - 100, mirrorSize.y/2 - 100 };
|
|
||||||
Vector2 size = { 200, 200 };
|
Vector2 size = { 200, 200 };
|
||||||
Color color = { 180, 20, 20, 255 };
|
|
||||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
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))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
frame++;
|
#if defined(PLATFORM_OCULUS)
|
||||||
|
frameIndex++;
|
||||||
|
|
||||||
ovrPosef eyePoses[2];
|
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
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
int curIndex;
|
#if defined(PLATFORM_OCULUS)
|
||||||
ovr_GetTextureSwapChainCurrentIndex(session, eyeTexture, &curIndex);
|
SetOculusBuffer(session, buffer);
|
||||||
GLuint curTexId;
|
#endif
|
||||||
ovr_GetTextureSwapChainBufferGL(session, eyeTexture, curIndex, &curTexId);
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
rlClearScreenBuffers(); // Clear current framebuffers
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, curTexId, 0);
|
|
||||||
|
#if defined(PLATFORM_OCULUS)
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
for (int eye = 0; eye < 2; eye++)
|
for (int eye = 0; eye < 2; eye++)
|
||||||
{
|
{
|
||||||
glViewport(eyeLayer.Viewport[eye].Pos.x, eyeLayer.Viewport[eye].Pos.y,
|
glViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h);
|
||||||
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));
|
|
||||||
|
|
||||||
// NOTE: Nothing is drawn until rlglDraw()
|
Quaternion eyeRPose = (Quaternion){ eyePoses[eye].Orientation.x, eyePoses[eye].Orientation.y, eyePoses[eye].Orientation.z, eyePoses[eye].Orientation.w };
|
||||||
DrawRectangleV(position, size, color);
|
QuaternionInvert(&eyeRPose);
|
||||||
//DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, color);
|
Matrix eyeOrientation = QuaternionToMatrix(eyeRPose);
|
||||||
//DrawGrid(10, 1.0f);
|
Matrix eyeTranslation = MatrixTranslate(-eyePoses[eye].Position.x, -eyePoses[eye].Position.y, -eyePoses[eye].Position.z);
|
||||||
|
|
||||||
// NOTE: rlglDraw() must be modified to support an external modelview-projection matrix
|
Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation);
|
||||||
// TODO: Still working on it (now uses internal mvp)
|
Matrix modelview = MatrixMultiply(matView, eyeView);
|
||||||
|
Matrix mvp = MatrixMultiply(modelview, 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);
|
||||||
|
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||||
|
Matrix mvp = MatrixMultiply(matView, matProj);
|
||||||
|
#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(mvp);
|
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);
|
||||||
|
|
||||||
|
#if defined(PLATFORM_OCULUS)
|
||||||
}
|
}
|
||||||
|
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
UnsetOculusBuffer(buffer);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
||||||
ovr_CommitTextureSwapChain(session, eyeTexture);
|
ovr_CommitTextureSwapChain(session, buffer.textureChain);
|
||||||
ovrLayerHeader *headerList = &eyeLayer.Header;
|
|
||||||
ovr_SubmitFrame(session, frame, &viewScaleDesc, &headerList, 1);
|
ovrLayerHeader *layers = &layer.eyeLayer.Header;
|
||||||
|
ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1);
|
||||||
|
|
||||||
// Blit mirror texture to back buffer
|
// Blit mirror texture to back buffer
|
||||||
GLuint mirrorTextureId;
|
BlitOculusMirror(session, mirror);
|
||||||
ovr_GetMirrorTextureBufferGL(session, mirrorTexture, &mirrorTextureId);
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mirrorFbo);
|
// Get session status information
|
||||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0);
|
ovrSessionStatus sessionStatus;
|
||||||
glBlitFramebuffer(0, 0, mirrorSize.x, mirrorSize.y, 0, mirrorSize.y, mirrorSize.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
ovr_GetSessionStatus(session, &sessionStatus);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
if (sessionStatus.ShouldQuit) TraceLog(LOG_WARNING, "OVR: Session should quit...");
|
||||||
|
if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -307,20 +297,20 @@ int main()
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
if (mirrorFbo) glDeleteFramebuffers(1, &mirrorFbo);
|
#if defined(PLATFORM_OCULUS)
|
||||||
if (mirrorTexture) ovr_DestroyMirrorTexture(session, mirrorTexture);
|
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
|
||||||
|
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
|
||||||
|
#endif
|
||||||
|
|
||||||
if (fbo) glDeleteFramebuffers(1, &fbo);
|
rlglClose(); // Unload rlgl internal buffers and default shader/texture
|
||||||
if (depthBuffer) glDeleteTextures(1, &depthBuffer);
|
|
||||||
if (eyeTexture) ovr_DestroyTextureSwapChain(session, eyeTexture);
|
|
||||||
|
|
||||||
rlglClose();
|
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
|
#if defined(PLATFORM_OCULUS)
|
||||||
ovr_Destroy(session); // Must be called after glfwTerminate()
|
ovr_Destroy(session); // Must be called after glfwTerminate()
|
||||||
ovr_Shutdown();
|
ovr_Shutdown();
|
||||||
|
#endif
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -330,24 +320,22 @@ int main()
|
||||||
// Module specific Functions Definitions
|
// Module specific Functions Definitions
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
|
// GLFW3: Error callback
|
||||||
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
static void ErrorCallback(int error, const char* description)
|
||||||
{
|
{
|
||||||
rlBegin(RL_TRIANGLES);
|
TraceLog(LOG_ERROR, description);
|
||||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
}
|
||||||
|
|
||||||
rlVertex2i(position.x, position.y);
|
// GLFW3: Keyboard callback
|
||||||
rlVertex2i(position.x, position.y + size.y);
|
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||||
rlVertex2i(position.x + size.x, position.y + size.y);
|
{
|
||||||
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||||
rlVertex2i(position.x, position.y);
|
{
|
||||||
rlVertex2i(position.x + size.x, position.y + size.y);
|
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||||
rlVertex2i(position.x + size.x, position.y);
|
}
|
||||||
rlEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a trace log message
|
// Output a trace log message
|
||||||
// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
|
|
||||||
static void TraceLog(int msgType, const char *text, ...)
|
static void TraceLog(int msgType, const char *text, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -370,30 +358,52 @@ static void TraceLog(int msgType, const char *text, ...)
|
||||||
//if (msgType == LOG_ERROR) exit(1);
|
//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;
|
rlBegin(RL_TRIANGLES);
|
||||||
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
rmat.m0 = ovrmat.M[0][0];
|
|
||||||
rmat.m1 = ovrmat.M[1][0];
|
rlVertex2i(position.x, position.y);
|
||||||
rmat.m2 = ovrmat.M[2][0];
|
rlVertex2i(position.x, position.y + size.y);
|
||||||
rmat.m3 = ovrmat.M[3][0];
|
rlVertex2i(position.x + size.x, position.y + size.y);
|
||||||
rmat.m4 = ovrmat.M[0][1];
|
|
||||||
rmat.m5 = ovrmat.M[1][1];
|
rlVertex2i(position.x, position.y);
|
||||||
rmat.m6 = ovrmat.M[2][1];
|
rlVertex2i(position.x + size.x, position.y + size.y);
|
||||||
rmat.m7 = ovrmat.M[3][1];
|
rlVertex2i(position.x + size.x, position.y);
|
||||||
rmat.m8 = ovrmat.M[0][2];
|
rlEnd();
|
||||||
rmat.m9 = ovrmat.M[1][2];
|
}
|
||||||
rmat.m10 = ovrmat.M[2][2];
|
|
||||||
rmat.m11 = ovrmat.M[3][2];
|
// Draw a grid centered at (0, 0, 0)
|
||||||
rmat.m12 = ovrmat.M[0][3];
|
static void DrawGrid(int slices, float spacing)
|
||||||
rmat.m13 = ovrmat.M[1][3];
|
{
|
||||||
rmat.m14 = ovrmat.M[2][3];
|
int halfSlices = slices / 2;
|
||||||
rmat.m15 = ovrmat.M[3][3];
|
|
||||||
|
rlBegin(RL_LINES);
|
||||||
//MatrixTranspose(&rmat);
|
for(int i = -halfSlices; i <= halfSlices; i++)
|
||||||
|
{
|
||||||
return rmat;
|
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
|
// Draw cube
|
||||||
|
@ -471,34 +481,279 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c
|
||||||
rlPopMatrix();
|
rlPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a grid centered at (0, 0, 0)
|
// Draw cube wires
|
||||||
void DrawGrid(int slices, float spacing)
|
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);
|
rlPushMatrix();
|
||||||
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);
|
rlTranslatef(position.x, position.y, position.z);
|
||||||
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
|
//rlRotatef(45, 0, 1, 0);
|
||||||
|
|
||||||
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
|
rlBegin(RL_LINES);
|
||||||
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
}
|
|
||||||
rlEnd();
|
// 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;
|
||||||
|
desc.SampleCount = 1;
|
||||||
|
desc.StaticImage = ovrFalse;
|
||||||
|
|
||||||
|
ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain);
|
||||||
|
|
||||||
|
//eyeLayer.ColorTexture[0] = 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, ¤tIndex);
|
||||||
|
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
|
||||||
|
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded
|
||||||
|
|
||||||
|
//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)
|
||||||
|
{
|
||||||
|
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
|
|
@ -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, ¤tIndex);
|
|
||||||
ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 213 KiB |
BIN
examples/oculus_glfw_sample/raylib_OculusRiftCV1_test02.png
Normal file
BIN
examples/oculus_glfw_sample/raylib_OculusRiftCV1_test02.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 340 KiB |
BIN
examples/oculus_glfw_sample/raylib_OculusRiftCV1_test03.png
Normal file
BIN
examples/oculus_glfw_sample/raylib_OculusRiftCV1_test03.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 179 KiB |
|
@ -9,7 +9,7 @@
|
||||||
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
|
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
|
||||||
*
|
*
|
||||||
* Compile example using:
|
* 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)
|
* 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)
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
|
@ -18,23 +18,168 @@
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "glad.h"
|
#define GLAD_IMPLEMENTATION
|
||||||
#include <GLFW/glfw3.h>
|
#include "glad.h" // Extensions loading library
|
||||||
|
#include <GLFW/glfw3.h> // Windows/Context and inputs management
|
||||||
|
|
||||||
#define RLGL_STANDALONE
|
#define RLGL_STANDALONE
|
||||||
#include "rlgl.h"
|
#include "rlgl.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.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
|
// 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)
|
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||||
{
|
{
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
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);
|
// Output a trace log message
|
||||||
|
static void TraceLog(int msgType, const char *text, ...)
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
// Main Entry point
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
int main(void)
|
|
||||||
{
|
{
|
||||||
const int screenWidth = 800;
|
va_list args;
|
||||||
const int screenHeight = 450;
|
va_start(args, text);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
switch(msgType)
|
||||||
{
|
{
|
||||||
printf("Cannot load GL extensions.\n");
|
case LOG_INFO: fprintf(stdout, "INFO: "); break;
|
||||||
exit(1);
|
case LOG_ERROR: fprintf(stdout, "ERROR: "); break;
|
||||||
|
case LOG_WARNING: fprintf(stdout, "WARNING: "); break;
|
||||||
|
case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rlglInit();
|
vfprintf(stdout, text, args);
|
||||||
rlglInitGraphics(0, 0, screenWidth, screenHeight);
|
fprintf(stdout, "\n");
|
||||||
rlClearColor(245, 245, 245, 255); // Define clear color
|
|
||||||
|
va_end(args);
|
||||||
Vector2 position = { screenWidth/2 - 100, screenHeight/2 - 100 };
|
|
||||||
Vector2 size = { 200, 200 };
|
//if (msgType == LOG_ERROR) exit(1);
|
||||||
Color color = { 180, 20, 20, 255 };
|
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window))
|
|
||||||
{
|
|
||||||
rlClearScreenBuffers();
|
|
||||||
|
|
||||||
DrawRectangleV(position, size, color);
|
|
||||||
|
|
||||||
rlglDraw();
|
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
|
||||||
glfwPollEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
rlglClose();
|
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
|
||||||
glfwTerminate();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
|
||||||
// Module specific Functions Definitions
|
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
|
||||||
{
|
{
|
||||||
rlBegin(RL_TRIANGLES);
|
rlBegin(RL_TRIANGLES);
|
||||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
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 + size.y);
|
||||||
rlVertex2i(position.x + size.x, position.y);
|
rlVertex2i(position.x + size.x, position.y);
|
||||||
rlEnd();
|
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();
|
||||||
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(RAYMATH_STANDALONE)
|
#if defined(RAYMATH_STANDALONE)
|
||||||
// Vector2 type
|
// Vector2 type
|
||||||
typedef struct Vector2 {
|
typedef struct Vector2 {
|
||||||
float x;
|
float x;
|
||||||
float y;
|
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 float QuaternionLength(Quaternion quat); // Compute the length of a quaternion
|
||||||
RMDEF void QuaternionNormalize(Quaternion *q); // Normalize provided 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 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 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
|
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;
|
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
|
// Calculate two quaternion multiplication
|
||||||
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
|
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -130,47 +130,43 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||||
COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
|
COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
|
||||||
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
|
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
|
||||||
} TextureFormat;
|
} TextureFormat;
|
||||||
|
|
||||||
// Bounding box type
|
|
||||||
typedef struct BoundingBox {
|
|
||||||
Vector3 min;
|
|
||||||
Vector3 max;
|
|
||||||
} BoundingBox;
|
|
||||||
|
|
||||||
// Mesh with vertex data type
|
// Vertex data definning a mesh
|
||||||
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
|
|
||||||
typedef struct Mesh {
|
typedef struct Mesh {
|
||||||
int vertexCount; // num vertices
|
int vertexCount; // number of vertices stored in arrays
|
||||||
float *vertices; // vertex position (XYZ - 3 components per vertex)
|
int triangleCount; // number of triangles stored (indexed or not)
|
||||||
float *texcoords; // vertex texture coordinates (UV - 2 components per vertex)
|
float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0)
|
||||||
float *texcoords2; // vertex second texture coordinates (useful for lightmaps)
|
float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
|
||||||
float *normals; // vertex normals (XYZ - 3 components per vertex)
|
float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
|
||||||
float *tangents; // vertex tangents (XYZ - 3 components per vertex)
|
float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
|
||||||
unsigned char *colors; // vertex colors (RGBA - 4 components per vertex)
|
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)
|
||||||
BoundingBox bounds; // mesh limits defined by min and max points
|
unsigned short *indices;// vertex indices (in case vertex data comes indexed)
|
||||||
|
|
||||||
unsigned int vaoId; // OpenGL Vertex Array Object id
|
unsigned int vaoId; // OpenGL Vertex Array Object id
|
||||||
unsigned int vboId[6]; // OpenGL Vertex Buffer Objects id (6 types of vertex data)
|
unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
|
||||||
} Mesh;
|
} Mesh;
|
||||||
|
|
||||||
// Shader type
|
// Shader type (generic shader)
|
||||||
typedef struct Shader {
|
typedef struct Shader {
|
||||||
unsigned int id; // Shader program id
|
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)
|
|
||||||
|
|
||||||
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader)
|
// Vertex attributes locations (default locations)
|
||||||
int mapNormalLoc; // Normal map texture uniform location point (fragment shader)
|
int vertexLoc; // Vertex attribute location point (default-location = 0)
|
||||||
int mapSpecularLoc; // Specular map texture uniform location point (fragment shader)
|
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;
|
} Shader;
|
||||||
|
|
||||||
// Texture2D type
|
// Texture2D type
|
||||||
|
@ -192,27 +188,46 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||||
|
|
||||||
// Material type
|
// Material type
|
||||||
typedef struct Material {
|
typedef struct Material {
|
||||||
Shader shader;
|
Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular)
|
||||||
|
|
||||||
Texture2D texDiffuse; // Diffuse texture
|
Texture2D texDiffuse; // Diffuse texture
|
||||||
Texture2D texNormal; // Normal texture
|
Texture2D texNormal; // Normal texture
|
||||||
Texture2D texSpecular; // Specular texture
|
Texture2D texSpecular; // Specular texture
|
||||||
|
|
||||||
|
Color colDiffuse; // Diffuse color
|
||||||
|
Color colAmbient; // Ambient color
|
||||||
|
Color colSpecular; // Specular color
|
||||||
|
|
||||||
Color colDiffuse;
|
float glossiness; // Glossiness level (Ranges from 0 to 1000)
|
||||||
Color colAmbient;
|
|
||||||
Color colSpecular;
|
|
||||||
|
|
||||||
float glossiness;
|
|
||||||
float normalDepth;
|
|
||||||
} Material;
|
} 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)
|
// Color blending modes (pre-defined)
|
||||||
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
|
||||||
#endif
|
#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 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 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 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
|
// 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 rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
|
||||||
void rlEnableDepthTest(void); // Enable depth test
|
void rlEnableDepthTest(void); // Enable depth test
|
||||||
void rlDisableDepthTest(void); // Disable 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 rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
|
||||||
void rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) from GPU
|
void rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) from GPU
|
||||||
void rlDeleteShader(unsigned int id); // Delete OpenGL shader program 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 rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...)
|
||||||
void rlglClose(void); // De-init rlgl
|
void rlglClose(void); // De-init rlgl
|
||||||
void rlglDraw(Matrix mvp); // Draw VAO/VBO
|
void rlglDraw(Matrix mvp); // Draw VAO/VBO
|
||||||
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
|
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
|
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU
|
||||||
|
@ -281,35 +299,43 @@ 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 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
|
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,
|
void rlglLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
|
||||||
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h
|
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
|
||||||
Model rlglLoadModel(Mesh mesh); // Upload vertex data into GPU and provided VAO/VBO ids
|
void rlglUnloadMesh(Mesh *mesh); // Unload mesh data from CPU and GPU
|
||||||
void rlglDrawModel(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color, bool wires);
|
|
||||||
|
|
||||||
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
|
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)
|
unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
|
||||||
void *rlglReadTexturePixels(Texture2D texture); // Read texture pixel data
|
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)
|
#if defined(RLGL_STANDALONE)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Shaders System Functions (Module: rlgl)
|
// Shaders System Functions (Module: rlgl)
|
||||||
// NOTE: This functions are useless when using OpenGL 1.1
|
// NOTE: This functions are useless when using OpenGL 1.1
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
|
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 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
|
Shader GetDefaultShader(void); // Get default shader
|
||||||
void SetModelShader(Model *model, Shader shader); // Link a shader to a model
|
Shader GetStandardShader(void); // Get default shader
|
||||||
|
Texture2D GetDefaultTexture(void); // Get default texture
|
||||||
|
|
||||||
int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
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 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 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 SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
|
||||||
|
|
||||||
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue